From 5f08bf7da5f4af0eff7a116c86d2bca62dacd6ff Mon Sep 17 00:00:00 2001 From: Ancuta Morarasu Date: Wed, 11 May 2016 12:06:45 +0000 Subject: [PATCH] Merged HEAD (5.2) to 5.2.N (5.2.1) 126546 jkaabimofrad: Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2) 124063 jvonka: RA-885: Nodes (FileFolder) API - upload (create node with file content) improvements - guess mimetype if (multi-)part Content-Type field is missing or is default binary mime type (application/octet-stream) - ignore filename override if null or empty git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@126892 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../org/alfresco/rest/api/impl/NodesImpl.java | 24 ++++++++------ .../alfresco/rest/api/tests/NodeApiTest.java | 32 ++++++++++++++++--- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/source/java/org/alfresco/rest/api/impl/NodesImpl.java b/source/java/org/alfresco/rest/api/impl/NodesImpl.java index 5d68bc2b6e..b8f28ee086 100644 --- a/source/java/org/alfresco/rest/api/impl/NodesImpl.java +++ b/source/java/org/alfresco/rest/api/impl/NodesImpl.java @@ -49,6 +49,7 @@ import org.alfresco.query.PagingRequest; import org.alfresco.query.PagingResults; import org.alfresco.repo.action.executer.ContentMetadataExtracter; import org.alfresco.repo.content.ContentLimitViolationException; +import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.model.Repository; import org.alfresco.repo.model.filefolder.FileFolderServiceImpl; import org.alfresco.repo.node.getchildren.GetChildrenCannedQuery; @@ -153,12 +154,14 @@ public class NodesImpl implements Nodes { private static final Log logger = LogFactory.getLog(NodesImpl.class); - private static enum Type + private enum Type { // Note: ordered DOCUMENT, FOLDER } + private static final String DEFAULT_MIMETYPE = MimetypeMap.MIMETYPE_BINARY; + private NodeService nodeService; private DictionaryService dictionaryService; private FileFolderService fileFolderService; @@ -171,7 +174,6 @@ public class NodesImpl implements Nodes private PersonService personService; private OwnableService ownableService; private AuthorityService authorityService; - private SiteServiceInternal siteServiceInternal; private BehaviourFilter behaviourFilter; @@ -1817,9 +1819,9 @@ public class NodesImpl implements Nodes { String mimeType = contentInfo.mimeType; // Manage MimeType - if (mimeType == null) + if ((mimeType == null) || mimeType.equals(DEFAULT_MIMETYPE)) { - // the mimeType was not provided via the contentInfo, so try to guess + // the mimeType was not provided (or was the default binary mimeType) via the contentInfo, so try to guess final String fileName = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME); mimeType = mimetypeService.guessMimetype(fileName); } @@ -1871,13 +1873,17 @@ public class NodesImpl implements Nodes switch (field.getName().toLowerCase()) { case "filename": - fileName = getStringOrNull(field.getValue()); + String str = getStringOrNull(field.getValue()); + if ((str != null) && (! str.isEmpty())) + { + fileName = str; + } break; case "filedata": if (field.getIsFile()) { - fileName = fileName != null ? fileName : field.getFilename(); + fileName = (fileName != null ? fileName : field.getFilename()); content = field.getContent(); } break; @@ -1929,7 +1935,7 @@ public class NodesImpl implements Nodes } // Ensure mandatory file attributes have been located. Need either // destination, or site + container or updateNodeRef - if ((fileName == null || content == null)) + if ((fileName == null) || fileName.isEmpty() || (content == null)) { throw new InvalidArgumentException("Required parameters are missing"); } @@ -2051,8 +2057,8 @@ public class NodesImpl implements Nodes protected void write(NodeRef nodeRef, Content content) { ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true); - // Per RA-637 requirement the mimeType provided by the client takes precedence, however, - // if the mimeType is null, then it will be guessed. + // Per RA-637 & RA-885 requirement the mimeType provided by the client takes precedence, however, + // if the mimeType is null (or default binary mimeType) then it will be guessed. setWriterContentType(writer, new ContentInfoWrapper(content), nodeRef, true); writer.putContent(content.getInputStream()); } diff --git a/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java b/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java index a5a6ada815..cd26072f3d 100644 --- a/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java +++ b/source/test-java/org/alfresco/rest/api/tests/NodeApiTest.java @@ -864,20 +864,44 @@ public class NodeApiTest extends AbstractBaseApiTest assertNotNull(paging); assertEquals(numOfNodes + 3, pagingResult.getCount().intValue()); + // upload without specifying content type or without overriding filename - hence guess mimetype and use file's name + final String fileName1 = "quick-1.txt"; + final File file1 = getResourceFile(fileName1); + reqBody = MultiPartBuilder.create() + .setFileData(new FileData(null, file1, null)) + .build(); + response = post(getNodeChildrenUrl(Nodes.PATH_MY), user1, reqBody.getBody(), null, reqBody.getContentType(), 201); + document = jacksonUtil.parseEntry(response.getJsonResponse(), Document.class); + // Check the upload response + assertEquals(fileName1, document.getName()); + assertEquals(MimetypeMap.MIMETYPE_TEXT_PLAIN, document.getContent().getMimeType()); + + // upload with "default" binary content type and override filename - hence guess mimetype & use overridden name + final String fileName2 = "quick-2.txt"; + final String fileName2b = "quick-2b.txt"; + final File file2 = getResourceFile(fileName2); + reqBody = MultiPartBuilder.create() + .setFileData(new FileData(fileName2b, file2, MimetypeMap.MIMETYPE_BINARY)) + .build(); + response = post(getNodeChildrenUrl(Nodes.PATH_MY), user1, reqBody.getBody(), null, reqBody.getContentType(), 201); + document = jacksonUtil.parseEntry(response.getJsonResponse(), Document.class); + // Check the upload response + assertEquals(fileName2b, document.getName()); + assertEquals(MimetypeMap.MIMETYPE_TEXT_PLAIN, document.getContent().getMimeType()); + // User2 tries to upload a new file into the user1's home folder. response = getSingle(NodesEntityResource.class, user1, Nodes.PATH_MY, null, 200); Folder user1Home = RestApiUtil.parseRestApiEntry(response.getJsonResponse(), Folder.class); - final String fileName2 = "quick-2.txt"; - final File file2 = getResourceFile(fileName2); + final File file3 = getResourceFile(fileName2); reqBody = MultiPartBuilder.create() - .setFileData(new FileData(fileName2, file2, MimetypeMap.MIMETYPE_TEXT_PLAIN)) + .setFileData(new FileData(fileName2, file3, MimetypeMap.MIMETYPE_TEXT_PLAIN)) .build(); post(getNodeChildrenUrl(user1Home.getId()), user2, reqBody.getBody(), null, reqBody.getContentType(), 403); response = getAll(getNodeChildrenUrl(Nodes.PATH_MY), user1, paging, 200); pagingResult = parsePaging(response.getJsonResponse()); assertNotNull(paging); - assertEquals("Access Denied. The file shouldn't have been uploaded.", numOfNodes + 3, pagingResult.getCount().intValue()); + assertEquals("Access Denied. The file shouldn't have been uploaded.", numOfNodes + 5, pagingResult.getCount().intValue()); // User1 tries to upload a file into a document rather than a folder! post(getNodeChildrenUrl(document.getId()), user1, reqBody.getBody(), null, reqBody.getContentType(), 400);