mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merged BRANCHES/DEV/V4.1-BUG-FIX to HEAD
39084: Merged BRANCHES/DEV/V3.4-BUG-FIX to BRANCHES/DEV/V4.1-BUG-FIX 39081: Fix for ALF-6139 and ALF-13959 - Incomplete site creation issues - latest Surf libs and related changes to allow atomic creation of multiple Surf objects in a single REST call. Originally authored by Dave Ward for 3.2 - now migrated to SpringSurf. Implemented ADMRemoteStore changes for above change to apply to 4.0. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@39205 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
package org.alfresco.repo.web.scripts.bean;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
@@ -31,6 +32,12 @@ import java.util.StringTokenizer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.query.CannedQueryPageDetails;
|
||||
import org.alfresco.query.PagingRequest;
|
||||
@@ -56,12 +63,16 @@ import org.alfresco.service.cmr.site.SiteInfo;
|
||||
import org.alfresco.service.cmr.site.SiteService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.apache.axis.utils.ByteArrayOutputStream;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.surf.util.URLDecoder;
|
||||
import org.springframework.extensions.webscripts.Status;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
import org.springframework.extensions.webscripts.WebScriptResponse;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* ADM Remote Store service.
|
||||
@@ -328,50 +339,7 @@ public class ADMRemoteStore extends BaseRemoteStore
|
||||
{
|
||||
try
|
||||
{
|
||||
// do not support filenames directly at the root - all objectypes must exist in a named child folder
|
||||
final String encpath = encodePath(path);
|
||||
final int off = encpath.lastIndexOf('/');
|
||||
if (off != -1)
|
||||
{
|
||||
// check we actually are the user we are creating a user specific path for
|
||||
String runAsUser = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
String userId = null;
|
||||
Matcher matcher;
|
||||
if ((matcher = USER_PATTERN_1.matcher(path)).matches())
|
||||
{
|
||||
userId = matcher.group(1);
|
||||
}
|
||||
else if ((matcher = USER_PATTERN_2.matcher(path)).matches())
|
||||
{
|
||||
userId = matcher.group(1);
|
||||
}
|
||||
if (userId != null && userId.equals(runAsUser))
|
||||
{
|
||||
runAsUser = AuthenticationUtil.getSystemUserName();
|
||||
}
|
||||
AuthenticationUtil.runAs(new RunAsWork<Void>()
|
||||
{
|
||||
@SuppressWarnings("synthetic-access")
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
final FileInfo parentFolder = resolveNodePath(encpath, true, false);
|
||||
if (parentFolder == null)
|
||||
{
|
||||
throw new IllegalStateException("Unable to aquire parent folder reference for path: " + path);
|
||||
}
|
||||
FileInfo fileInfo = fileFolderService.create(
|
||||
parentFolder.getNodeRef(), encpath.substring(off + 1), ContentModel.TYPE_CONTENT);
|
||||
|
||||
ContentWriter writer = contentService.getWriter(
|
||||
fileInfo.getNodeRef(), ContentModel.PROP_CONTENT, true);
|
||||
writer.guessMimetype(fileInfo.getName());
|
||||
writer.putContent(content);
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("createDocument: " + fileInfo.toString());
|
||||
return null;
|
||||
}
|
||||
}, runAsUser);
|
||||
}
|
||||
writeDocument(path, content);
|
||||
}
|
||||
catch (AccessDeniedException ae)
|
||||
{
|
||||
@@ -389,9 +357,103 @@ public class ADMRemoteStore extends BaseRemoteStore
|
||||
* @param content XML document containing multiple document contents to write
|
||||
*/
|
||||
@Override
|
||||
protected void createDocuments(WebScriptResponse res, String store, InputStream content)
|
||||
protected void createDocuments(WebScriptResponse res, String store, InputStream in)
|
||||
{
|
||||
// no implementation currently
|
||||
try
|
||||
{
|
||||
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
Document document;
|
||||
document = documentBuilder.parse(in);
|
||||
Element docEl = document.getDocumentElement();
|
||||
Transformer transformer = ADMRemoteStore.this.transformer.get();
|
||||
for (Node n = docEl.getFirstChild(); n != null; n = n.getNextSibling())
|
||||
{
|
||||
if (!(n instanceof Element))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
final String path = ((Element) n).getAttribute("path");
|
||||
|
||||
// Turn the first element child into a document
|
||||
Document doc = documentBuilder.newDocument();
|
||||
Node child;
|
||||
for (child = n.getFirstChild(); child != null ; child=child.getNextSibling())
|
||||
{
|
||||
if (child instanceof Element)
|
||||
{
|
||||
doc.appendChild(doc.importNode(child, true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(512);
|
||||
transformer.transform(new DOMSource(doc), new StreamResult(out));
|
||||
out.close();
|
||||
|
||||
writeDocument(path, new ByteArrayInputStream(out.toByteArray()));
|
||||
}
|
||||
}
|
||||
catch (AccessDeniedException ae)
|
||||
{
|
||||
res.setStatus(Status.STATUS_UNAUTHORIZED);
|
||||
}
|
||||
catch (FileExistsException feeErr)
|
||||
{
|
||||
res.setStatus(Status.STATUS_CONFLICT);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// various annoying checked SAX/IO exceptions related to XML processing can be thrown
|
||||
// none of them should occur if the XML document is well formed
|
||||
logger.error(e);
|
||||
res.setStatus(Status.STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeDocument(final String path, final InputStream content)
|
||||
{
|
||||
final String encpath = encodePath(path);
|
||||
final int off = encpath.lastIndexOf('/');
|
||||
if (off != -1)
|
||||
{
|
||||
// check we actually are the user we are creating a user specific path for
|
||||
String runAsUser = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
String userId = null;
|
||||
Matcher matcher;
|
||||
if ((matcher = USER_PATTERN_1.matcher(path)).matches())
|
||||
{
|
||||
userId = matcher.group(1);
|
||||
}
|
||||
else if ((matcher = USER_PATTERN_2.matcher(path)).matches())
|
||||
{
|
||||
userId = matcher.group(1);
|
||||
}
|
||||
if (userId != null && userId.equals(runAsUser))
|
||||
{
|
||||
runAsUser = AuthenticationUtil.getSystemUserName();
|
||||
}
|
||||
AuthenticationUtil.runAs(new RunAsWork<Void>()
|
||||
{
|
||||
@SuppressWarnings("synthetic-access")
|
||||
public Void doWork() throws Exception
|
||||
{
|
||||
final FileInfo parentFolder = resolveNodePath(encpath, true, false);
|
||||
if (parentFolder == null)
|
||||
{
|
||||
throw new IllegalStateException("Unable to aquire parent folder reference for path: " + path);
|
||||
}
|
||||
FileInfo fileInfo = fileFolderService.create(
|
||||
parentFolder.getNodeRef(), encpath.substring(off + 1), ContentModel.TYPE_CONTENT);
|
||||
|
||||
ContentWriter writer = contentService.getWriter(
|
||||
fileInfo.getNodeRef(), ContentModel.PROP_CONTENT, true);
|
||||
writer.guessMimetype(fileInfo.getName());
|
||||
writer.putContent(content);
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("createDocument: " + fileInfo.toString());
|
||||
return null;
|
||||
}
|
||||
}, runAsUser);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -31,8 +31,6 @@ import java.util.StringTokenizer;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
@@ -70,22 +68,6 @@ import org.w3c.dom.Node;
|
||||
public class AVMRemoteStore extends BaseRemoteStore
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(AVMRemoteStore.class);
|
||||
private static final TransformerFactory TRANSFORMER_FACTORY = TransformerFactory.newInstance();
|
||||
private static ThreadLocal<Transformer> transformer = new ThreadLocal<Transformer>()
|
||||
{
|
||||
@Override
|
||||
protected Transformer initialValue()
|
||||
{
|
||||
try
|
||||
{
|
||||
return TRANSFORMER_FACTORY.newTransformer();
|
||||
}
|
||||
catch (TransformerConfigurationException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
private String rootPath = "/";
|
||||
private AVMService avmService;
|
||||
private SearchService searchService;
|
||||
@@ -305,7 +287,7 @@ public class AVMRemoteStore extends BaseRemoteStore
|
||||
{
|
||||
try
|
||||
{
|
||||
Set<String> checkedPaths = new HashSet<String>(19);
|
||||
Set<String> checkedPaths = new HashSet<String>(16);
|
||||
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||
Document document = documentBuilder.parse(in);
|
||||
Element docEl = document.getDocumentElement();
|
||||
|
@@ -25,17 +25,19 @@ import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
|
||||
import org.alfresco.service.cmr.repository.ContentService;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.extensions.webscripts.AbstractWebScript;
|
||||
import org.springframework.extensions.webscripts.WebScriptException;
|
||||
import org.springframework.extensions.webscripts.WebScriptRequest;
|
||||
import org.springframework.extensions.webscripts.WebScriptResponse;
|
||||
import org.springframework.extensions.webscripts.WrappingWebScriptRequest;
|
||||
import org.springframework.extensions.webscripts.servlet.WebScriptServletRequest;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Remote Store service.
|
||||
@@ -102,6 +104,23 @@ public abstract class BaseRemoteStore extends AbstractWebScript
|
||||
protected String defaultStore;
|
||||
protected MimetypeService mimetypeService;
|
||||
|
||||
protected static final TransformerFactory TRANSFORMER_FACTORY = TransformerFactory.newInstance();
|
||||
protected static ThreadLocal<Transformer> transformer = new ThreadLocal<Transformer>()
|
||||
{
|
||||
@Override
|
||||
protected Transformer initialValue()
|
||||
{
|
||||
try
|
||||
{
|
||||
return TRANSFORMER_FACTORY.newTransformer();
|
||||
}
|
||||
catch (TransformerConfigurationException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param defaultStore the default store name of the store to process document requests against
|
||||
|
Reference in New Issue
Block a user