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:
Kevin Roast
2012-07-12 15:08:54 +00:00
parent dc23ac823c
commit 9ce92f2404
5 changed files with 133 additions and 68 deletions

View File

@@ -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);
}
}
/**

View File

@@ -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();

View File

@@ -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