Swift – SE.S21 Share - DM Remote Store:

- Special character (path/pattern encoding) support and fixes

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@28452 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast
2011-06-17 11:44:38 +00:00
parent 0ac12a3aad
commit 88f762622b

View File

@@ -54,6 +54,7 @@ import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.extensions.surf.util.URLDecoder;
import org.springframework.extensions.webscripts.Status; import org.springframework.extensions.webscripts.Status;
import org.springframework.extensions.webscripts.WebScriptException; import org.springframework.extensions.webscripts.WebScriptException;
import org.springframework.extensions.webscripts.WebScriptResponse; import org.springframework.extensions.webscripts.WebScriptResponse;
@@ -157,10 +158,11 @@ public class ADMRemoteStore extends BaseRemoteStore
@SuppressWarnings("synthetic-access") @SuppressWarnings("synthetic-access")
public Void doWork() throws Exception public Void doWork() throws Exception
{ {
final FileInfo fileInfo = resolveFilePath(path); final String encpath = encodePath(path);
final FileInfo fileInfo = resolveFilePath(encpath);
if (fileInfo == null) if (fileInfo == null)
{ {
throw new WebScriptException("Unable to locate file: " + path); throw new WebScriptException("Unable to locate file: " + encpath);
} }
Writer out = res.getWriter(); Writer out = res.getWriter();
@@ -191,7 +193,8 @@ public class ADMRemoteStore extends BaseRemoteStore
@SuppressWarnings("synthetic-access") @SuppressWarnings("synthetic-access")
public Void doWork() throws Exception public Void doWork() throws Exception
{ {
final FileInfo fileInfo = resolveFilePath(path); final String encpath = encodePath(path);
final FileInfo fileInfo = resolveFilePath(encpath);
if (fileInfo == null || fileInfo.isFolder()) if (fileInfo == null || fileInfo.isFolder())
{ {
res.setStatus(Status.STATUS_NOT_FOUND); res.setStatus(Status.STATUS_NOT_FOUND);
@@ -204,7 +207,7 @@ public class ADMRemoteStore extends BaseRemoteStore
reader = contentService.getReader(fileInfo.getNodeRef(), ContentModel.PROP_CONTENT); reader = contentService.getReader(fileInfo.getNodeRef(), ContentModel.PROP_CONTENT);
if (reader == null || !reader.exists()) if (reader == null || !reader.exists())
{ {
throw new WebScriptException("No content found for file: " + path); throw new WebScriptException("No content found for file: " + encpath);
} }
// establish mimetype // establish mimetype
@@ -212,10 +215,10 @@ public class ADMRemoteStore extends BaseRemoteStore
if (mimetype == null || mimetype.length() == 0) if (mimetype == null || mimetype.length() == 0)
{ {
mimetype = MimetypeMap.MIMETYPE_BINARY; mimetype = MimetypeMap.MIMETYPE_BINARY;
int extIndex = path.lastIndexOf('.'); int extIndex = encpath.lastIndexOf('.');
if (extIndex != -1) if (extIndex != -1)
{ {
String ext = path.substring(extIndex + 1); String ext = encpath.substring(extIndex + 1);
String mt = mimetypeService.getMimetypesByExtension().get(ext); String mt = mimetypeService.getMimetypesByExtension().get(ext);
if (mt != null) if (mt != null)
{ {
@@ -244,19 +247,19 @@ public class ADMRemoteStore extends BaseRemoteStore
{ {
// the client cut the connection - our mission was accomplished apart from a little error message // the client cut the connection - our mission was accomplished apart from a little error message
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Client aborted stream read:\n\tnode: " + path + "\n\tcontent: " + reader); logger.debug("Client aborted stream read:\n\tnode: " + encpath + "\n\tcontent: " + reader);
} }
catch (ContentIOException e2) catch (ContentIOException e2)
{ {
if (logger.isInfoEnabled()) if (logger.isInfoEnabled())
logger.info("Client aborted stream read:\n\tnode: " + path + "\n\tcontent: " + reader); logger.info("Client aborted stream read:\n\tnode: " + encpath + "\n\tcontent: " + reader);
} }
catch (Throwable err) catch (Throwable err)
{ {
if (err.getCause() instanceof SocketException) if (err.getCause() instanceof SocketException)
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Client aborted stream read:\n\tnode: " + path + "\n\tcontent: " + reader); logger.debug("Client aborted stream read:\n\tnode: " + encpath + "\n\tcontent: " + reader);
} }
else else
{ {
@@ -291,7 +294,8 @@ public class ADMRemoteStore extends BaseRemoteStore
@SuppressWarnings("synthetic-access") @SuppressWarnings("synthetic-access")
public Void doWork() throws Exception public Void doWork() throws Exception
{ {
final FileInfo fileInfo = resolveFilePath(path); final String encpath = encodePath(path);
final FileInfo fileInfo = resolveFilePath(encpath);
Writer out = res.getWriter(); Writer out = res.getWriter();
out.write(Boolean.toString(fileInfo != null && !fileInfo.isFolder())); out.write(Boolean.toString(fileInfo != null && !fileInfo.isFolder()));
@@ -319,12 +323,13 @@ public class ADMRemoteStore extends BaseRemoteStore
try try
{ {
// do not support filenames directly at the root - all objectypes must exist in a named child folder // do not support filenames directly at the root - all objectypes must exist in a named child folder
final int off = path.lastIndexOf('/'); final String encpath = encodePath(path);
final int off = encpath.lastIndexOf('/');
if (off != -1) if (off != -1)
{ {
FileInfo parentFolder = resolveNodePath(path, true, false); FileInfo parentFolder = resolveNodePath(encpath, true, false);
FileInfo fileInfo = this.fileFolderService.create( FileInfo fileInfo = this.fileFolderService.create(
parentFolder.getNodeRef(), encodePath(path.substring(off + 1)), ContentModel.TYPE_CONTENT); parentFolder.getNodeRef(), encpath.substring(off + 1), ContentModel.TYPE_CONTENT);
this.contentService.getWriter( this.contentService.getWriter(
fileInfo.getNodeRef(), ContentModel.PROP_CONTENT, true).putContent(content); fileInfo.getNodeRef(), ContentModel.PROP_CONTENT, true).putContent(content);
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
@@ -363,7 +368,8 @@ public class ADMRemoteStore extends BaseRemoteStore
@Override @Override
protected void updateDocument(final WebScriptResponse res, String store, final String path, final InputStream content) protected void updateDocument(final WebScriptResponse res, String store, final String path, final InputStream content)
{ {
final FileInfo fileInfo = resolveFilePath(path); final String encpath = encodePath(path);
final FileInfo fileInfo = resolveFilePath(encpath);
if (fileInfo == null || fileInfo.isFolder()) if (fileInfo == null || fileInfo.isFolder())
{ {
res.setStatus(Status.STATUS_NOT_FOUND); res.setStatus(Status.STATUS_NOT_FOUND);
@@ -388,7 +394,8 @@ public class ADMRemoteStore extends BaseRemoteStore
@Override @Override
protected void deleteDocument(final WebScriptResponse res, final String store, final String path) protected void deleteDocument(final WebScriptResponse res, final String store, final String path)
{ {
final FileInfo fileInfo = resolveFilePath(path); final String encpath = encodePath(path);
final FileInfo fileInfo = resolveFilePath(encpath);
if (fileInfo == null || fileInfo.isFolder()) if (fileInfo == null || fileInfo.isFolder())
{ {
res.setStatus(Status.STATUS_NOT_FOUND); res.setStatus(Status.STATUS_NOT_FOUND);
@@ -423,7 +430,8 @@ public class ADMRemoteStore extends BaseRemoteStore
{ {
res.setContentType("text/plain;charset=UTF-8"); res.setContentType("text/plain;charset=UTF-8");
final FileInfo fileInfo = resolveNodePath(path, false, true); final String encpath = encodePath(path);
final FileInfo fileInfo = resolveNodePath(encpath, false, true);
if (fileInfo == null || !fileInfo.isFolder()) if (fileInfo == null || !fileInfo.isFolder())
{ {
res.setStatus(Status.STATUS_NOT_FOUND); res.setStatus(Status.STATUS_NOT_FOUND);
@@ -432,7 +440,7 @@ public class ADMRemoteStore extends BaseRemoteStore
try try
{ {
outputFileNodes(res.getWriter(), fileInfo, aquireSurfConfigRef(path, false), "*", recurse); outputFileNodes(res.getWriter(), fileInfo, aquireSurfConfigRef(encpath, false), "*", recurse);
} }
catch (AccessDeniedException ae) catch (AccessDeniedException ae)
{ {
@@ -470,15 +478,31 @@ public class ADMRemoteStore extends BaseRemoteStore
{ {
res.setContentType("text/plain;charset=UTF-8"); res.setContentType("text/plain;charset=UTF-8");
String filePattern = pattern; String filePattern;
if (filePattern == null || filePattern.length() == 0) if (pattern == null || pattern.length() == 0)
{ {
filePattern = "*"; filePattern = "*";
} }
else
{
// need to ensure match pattern is path encoded - but don't encode * character!
StringBuilder buf = new StringBuilder(pattern.length());
for (StringTokenizer t = new StringTokenizer(pattern, "*"); t.hasMoreTokens(); /**/)
{
buf.append(encodePath(t.nextToken()));
if (t.hasMoreTokens())
{
buf.append('*');
}
}
// ensure the escape character is itself escaped
filePattern = buf.toString().replace("\\", "\\\\");
}
// ensure we pass in the file pattern as it is used as part of the folder match - i.e. // ensure we pass in the file pattern as it is used as part of the folder match - i.e.
// for a site component set e.g. /alfresco/site-data/components/page.*.site~xyz~dashboard.xml // for a site component set e.g. /alfresco/site-data/components/page.*.site~xyz~dashboard.xml
final FileInfo fileInfo = resolveNodePath(path, pattern, false, true); final String encpath = encodePath(path);
final FileInfo fileInfo = resolveNodePath(encpath, filePattern, false, true);
if (fileInfo == null || !fileInfo.isFolder()) if (fileInfo == null || !fileInfo.isFolder())
{ {
res.setStatus(Status.STATUS_NOT_FOUND); res.setStatus(Status.STATUS_NOT_FOUND);
@@ -486,11 +510,14 @@ public class ADMRemoteStore extends BaseRemoteStore
} }
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("listDocuments() pattern: " + pattern); logger.debug("listDocuments() pattern: " + filePattern);
try try
{ {
outputFileNodes(res.getWriter(), fileInfo, aquireSurfConfigRef(path + "/" + pattern, false), pattern, false); outputFileNodes(
res.getWriter(), fileInfo,
aquireSurfConfigRef(encpath + "/" + filePattern, false),
filePattern, false);
} }
catch (AccessDeniedException ae) catch (AccessDeniedException ae)
{ {
@@ -557,7 +584,7 @@ public class ADMRemoteStore extends BaseRemoteStore
{ {
// break down the path into its component elements // break down the path into its component elements
List<String> pathElements = new ArrayList<String>(4); List<String> pathElements = new ArrayList<String>(4);
final StringTokenizer t = new StringTokenizer(encodePath(path), "/"); final StringTokenizer t = new StringTokenizer(path, "/");
// the store requires paths of the form /alfresco/site-data/<objecttype>[/<folder>]/<file>.xml // the store requires paths of the form /alfresco/site-data/<objecttype>[/<folder>]/<file>.xml
if (t.countTokens() >= 3) if (t.countTokens() >= 3)
{ {
@@ -757,8 +784,8 @@ public class ADMRemoteStore extends BaseRemoteStore
} }
out.write("/alfresco/site-data/"); out.write("/alfresco/site-data/");
out.write(displayPath.toString()); out.write(URLDecoder.decode(displayPath.toString()));
out.write(file.getName()); out.write(URLDecoder.decode(file.getName()));
out.write('\n'); out.write('\n');
if (debug) logger.debug(" /alfresco/site-data/" + displayPath.toString() + file.getName()); if (debug) logger.debug(" /alfresco/site-data/" + displayPath.toString() + file.getName());
} }