mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merged HEAD (5.2) to 5.2.N (5.2.1)
126376 jkaabimofrad: Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2) 119921 jkaabimofrad: Finished the requirements in RA-637. Added nodeType form data, the client provided content-type will be used if it is not null, and also support for model properties in the form data. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@126722 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -566,6 +566,11 @@ public class NodesImpl implements Nodes
|
|||||||
|
|
||||||
QName typeQName = nodeService.getType(nodeRef);
|
QName typeQName = nodeService.getType(nodeRef);
|
||||||
|
|
||||||
|
return getFolderOrDocumentFullInfo(nodeRef, getParentNodeRef(nodeRef), typeQName, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node getFolderOrDocumentFullInfo(NodeRef nodeRef, NodeRef parentNodeRef, QName nodeTypeQName, Parameters parameters)
|
||||||
|
{
|
||||||
List<String> selectParam = new ArrayList<>();
|
List<String> selectParam = new ArrayList<>();
|
||||||
selectParam.addAll(parameters.getSelectedProperties());
|
selectParam.addAll(parameters.getSelectedProperties());
|
||||||
|
|
||||||
@@ -573,7 +578,7 @@ public class NodesImpl implements Nodes
|
|||||||
selectParam.add(PARAM_SELECT_ASPECTNAMES);
|
selectParam.add(PARAM_SELECT_ASPECTNAMES);
|
||||||
selectParam.add(PARAM_SELECT_PROPERTIES);
|
selectParam.add(PARAM_SELECT_PROPERTIES);
|
||||||
|
|
||||||
return getFolderOrDocument(nodeRef, getParentNodeRef(nodeRef), typeQName, selectParam, null);
|
return getFolderOrDocument(nodeRef, parentNodeRef, nodeTypeQName, selectParam, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node getFolderOrDocument(final NodeRef nodeRef, NodeRef parentNodeRef, QName nodeTypeQName, List<String> selectParam, Map<String,UserInfo> mapUserInfo)
|
private Node getFolderOrDocument(final NodeRef nodeRef, NodeRef parentNodeRef, QName nodeTypeQName, List<String> selectParam, Map<String,UserInfo> mapUserInfo)
|
||||||
@@ -743,7 +748,7 @@ public class NodesImpl implements Nodes
|
|||||||
|
|
||||||
for (Entry<String, Object> entry : props.entrySet())
|
for (Entry<String, Object> entry : props.entrySet())
|
||||||
{
|
{
|
||||||
QName propQName = QName.createQName(entry.getKey(), namespaceService);
|
QName propQName = createQName(entry.getKey());
|
||||||
|
|
||||||
PropertyDefinition pd = dictionaryService.getProperty(propQName);
|
PropertyDefinition pd = dictionaryService.getProperty(propQName);
|
||||||
if (pd != null)
|
if (pd != null)
|
||||||
@@ -977,19 +982,8 @@ public class NodesImpl implements Nodes
|
|||||||
props = mapToNodeProperties(nodeInfo.getProperties());
|
props = mapToNodeProperties(nodeInfo.getProperties());
|
||||||
}
|
}
|
||||||
|
|
||||||
props.put(ContentModel.PROP_NAME, nodeName);
|
// Create the node
|
||||||
|
NodeRef nodeRef = createNodeImpl(parentNodeRef, nodeName, nodeTypeQName, props);
|
||||||
QName assocQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(nodeName));
|
|
||||||
|
|
||||||
NodeRef nodeRef;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
nodeRef = nodeService.createNode(parentNodeRef, ContentModel.ASSOC_CONTAINS, assocQName, nodeTypeQName, props).getChildRef();
|
|
||||||
}
|
|
||||||
catch (DuplicateChildNodeNameException dcne)
|
|
||||||
{
|
|
||||||
throw new ConstraintViolatedException(dcne.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> aspectNames = nodeInfo.getAspectNames();
|
List<String> aspectNames = nodeInfo.getAspectNames();
|
||||||
if (aspectNames != null)
|
if (aspectNames != null)
|
||||||
@@ -997,7 +991,7 @@ public class NodesImpl implements Nodes
|
|||||||
// node aspects - set any additional aspects
|
// node aspects - set any additional aspects
|
||||||
for (String aspectName : aspectNames)
|
for (String aspectName : aspectNames)
|
||||||
{
|
{
|
||||||
QName aspectQName = QName.createQName(aspectName, namespaceService);
|
QName aspectQName = createQName(aspectName);
|
||||||
if (EXCLUDED_ASPECTS.contains(aspectQName) || aspectQName.equals(ContentModel.ASPECT_AUDITABLE))
|
if (EXCLUDED_ASPECTS.contains(aspectQName) || aspectQName.equals(ContentModel.ASPECT_AUDITABLE))
|
||||||
{
|
{
|
||||||
continue; // ignore
|
continue; // ignore
|
||||||
@@ -1018,6 +1012,25 @@ public class NodesImpl implements Nodes
|
|||||||
return getFolderOrDocument(nodeRef.getId(), parameters);
|
return getFolderOrDocument(nodeRef.getId(), parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NodeRef createNodeImpl(NodeRef parentNodeRef, String nodeName, QName nodeTypeQName, Map<QName, Serializable> props)
|
||||||
|
{
|
||||||
|
if(props == null)
|
||||||
|
{
|
||||||
|
props = new HashMap<>(1);
|
||||||
|
}
|
||||||
|
props.put(ContentModel.PROP_NAME, nodeName);
|
||||||
|
|
||||||
|
QName assocQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(nodeName));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return nodeService.createNode(parentNodeRef, ContentModel.ASSOC_CONTAINS, assocQName, nodeTypeQName, props).getChildRef();
|
||||||
|
}
|
||||||
|
catch (DuplicateChildNodeNameException dcne)
|
||||||
|
{
|
||||||
|
throw new ConstraintViolatedException(dcne.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Node updateNode(String nodeId, Node nodeInfo, Parameters parameters)
|
public Node updateNode(String nodeId, Node nodeInfo, Parameters parameters)
|
||||||
{
|
{
|
||||||
final NodeRef nodeRef = validateNode(nodeId);
|
final NodeRef nodeRef = validateNode(nodeId);
|
||||||
@@ -1048,7 +1061,7 @@ public class NodesImpl implements Nodes
|
|||||||
if ((nodeType != null) && (! nodeType.isEmpty()))
|
if ((nodeType != null) && (! nodeType.isEmpty()))
|
||||||
{
|
{
|
||||||
// update node type - ensure that we are performing a specialise (we do not support generalise)
|
// update node type - ensure that we are performing a specialise (we do not support generalise)
|
||||||
QName destNodeTypeQName = QName.createQName(nodeType, namespaceService);
|
QName destNodeTypeQName = createQName(nodeType);
|
||||||
|
|
||||||
if ((! destNodeTypeQName.equals(nodeTypeQName)) && dictionaryService.isSubClass(destNodeTypeQName, nodeTypeQName))
|
if ((! destNodeTypeQName.equals(nodeTypeQName)) && dictionaryService.isSubClass(destNodeTypeQName, nodeTypeQName))
|
||||||
{
|
{
|
||||||
@@ -1067,7 +1080,7 @@ public class NodesImpl implements Nodes
|
|||||||
Set<QName> aspectQNames = new HashSet<>(aspectNames.size());
|
Set<QName> aspectQNames = new HashSet<>(aspectNames.size());
|
||||||
for (String aspectName : aspectNames)
|
for (String aspectName : aspectNames)
|
||||||
{
|
{
|
||||||
QName aspectQName = QName.createQName(aspectName, namespaceService);
|
QName aspectQName = createQName(aspectName);
|
||||||
aspectQNames.add(aspectQName);
|
aspectQNames.add(aspectQName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1186,7 +1199,10 @@ public class NodesImpl implements Nodes
|
|||||||
String fileName = null;
|
String fileName = null;
|
||||||
Content content = null;
|
Content content = null;
|
||||||
boolean autoRename = false;
|
boolean autoRename = false;
|
||||||
|
QName nodeTypeQName = null;
|
||||||
boolean overwrite = false; // If a fileName clashes for a versionable file
|
boolean overwrite = false; // If a fileName clashes for a versionable file
|
||||||
|
Map<String, Object> qnameStrProps = new HashMap<>();
|
||||||
|
Map<QName, Serializable> properties = null;
|
||||||
|
|
||||||
for (FormData.FormField field : formData.getFields())
|
for (FormData.FormField field : formData.getFields())
|
||||||
{
|
{
|
||||||
@@ -1208,27 +1224,50 @@ public class NodesImpl implements Nodes
|
|||||||
autoRename = Boolean.valueOf(field.getValue());
|
autoRename = Boolean.valueOf(field.getValue());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "nodetype":
|
||||||
|
nodeTypeQName = createQName(getStringOrNull(field.getValue()));
|
||||||
|
if (!dictionaryService.isSubClass(nodeTypeQName, ContentModel.TYPE_CONTENT))
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException("Can only upload type of cm:content: " + nodeTypeQName);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
// case "overwrite":
|
// case "overwrite":
|
||||||
// overwrite = Boolean.valueOf(field.getValue());
|
// overwrite = Boolean.valueOf(field.getValue());
|
||||||
// break;
|
// break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
final String propName = field.getName();
|
||||||
|
if (propName.indexOf(QName.NAMESPACE_PREFIX) > -1)
|
||||||
|
{
|
||||||
|
qnameStrProps.put(propName, field.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MNT-7213 When alf_data runs out of disk space, Share uploads
|
||||||
|
// result in a success message, but the files do not appear.
|
||||||
|
if (formData.getFields().length == 0)
|
||||||
|
{
|
||||||
|
throw new ConstraintViolatedException(" No disk space available");
|
||||||
|
}
|
||||||
|
// Ensure mandatory file attributes have been located. Need either
|
||||||
|
// destination, or site + container or updateNodeRef
|
||||||
|
if ((fileName == null || content == null))
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException("Required parameters are missing");
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// MNT-7213 When alf_data runs out of disk space, Share uploads
|
// Map the given properties, if any.
|
||||||
// result in a success message, but the files do not appear.
|
if (qnameStrProps.size() > 0)
|
||||||
if (formData.getFields().length == 0)
|
|
||||||
{
|
{
|
||||||
throw new ConstraintViolatedException(" No disk space available");
|
properties = mapToNodeProperties(qnameStrProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure mandatory file attributes have been located. Need either
|
|
||||||
// destination, or site + container or updateNodeRef
|
|
||||||
if ((fileName == null || content == null))
|
|
||||||
{
|
|
||||||
throw new InvalidArgumentException("Required parameters are missing");
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* Existing file handling
|
* Existing file handling
|
||||||
*/
|
*/
|
||||||
@@ -1262,7 +1301,7 @@ public class NodesImpl implements Nodes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new file.
|
// Create a new file.
|
||||||
return createNewFile(parentNodeRef, fileName, content);
|
return createNewFile(parentNodeRef, fileName, nodeTypeQName, content, properties, parameters);
|
||||||
|
|
||||||
// Do not clean formData temp files to allow for retries.
|
// Do not clean formData temp files to allow for retries.
|
||||||
// Temp files will be deleted later when GC call DiskFileItem#finalize() method or by temp file cleaner.
|
// Temp files will be deleted later when GC call DiskFileItem#finalize() method or by temp file cleaner.
|
||||||
@@ -1299,13 +1338,16 @@ public class NodesImpl implements Nodes
|
|||||||
/**
|
/**
|
||||||
* Helper to create a new node and writes its content to the repository.
|
* Helper to create a new node and writes its content to the repository.
|
||||||
*/
|
*/
|
||||||
private Node createNewFile(NodeRef parentNodeRef, String fileName, Content content)
|
private Node createNewFile(NodeRef parentNodeRef, String fileName, QName nodeType, Content content, Map<QName, Serializable> props, Parameters params)
|
||||||
{
|
{
|
||||||
FileInfo fileInfo = fileFolderService.create(parentNodeRef, fileName, ContentModel.TYPE_CONTENT);
|
if (nodeType == null)
|
||||||
NodeRef newFile = fileInfo.getNodeRef();
|
{
|
||||||
|
nodeType = ContentModel.TYPE_CONTENT;
|
||||||
|
}
|
||||||
|
NodeRef newFile = createNodeImpl(parentNodeRef, fileName, nodeType, props);
|
||||||
|
|
||||||
// Write content
|
// Write content
|
||||||
write(newFile, content, fileName, false, true);
|
write(newFile, content, fileName, true, true);
|
||||||
|
|
||||||
// Ensure the file is versionable (autoVersion = true, autoVersionProps = false)
|
// Ensure the file is versionable (autoVersion = true, autoVersionProps = false)
|
||||||
ensureVersioningEnabled(newFile, true, false);
|
ensureVersioningEnabled(newFile, true, false);
|
||||||
@@ -1314,12 +1356,7 @@ public class NodesImpl implements Nodes
|
|||||||
extractMetadata(newFile);
|
extractMetadata(newFile);
|
||||||
|
|
||||||
// Create the response
|
// Create the response
|
||||||
return createUploadResponse(parentNodeRef, newFile);
|
return getFolderOrDocumentFullInfo(newFile, parentNodeRef, nodeType, params);
|
||||||
}
|
|
||||||
|
|
||||||
private Node createUploadResponse(NodeRef parentNodeRef, NodeRef newFileNodeRef)
|
|
||||||
{
|
|
||||||
return getFolderOrDocument(newFileNodeRef, parentNodeRef, ContentModel.TYPE_CONTENT, Collections.<String>emptyList(), null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getStringOrNull(String value)
|
private String getStringOrNull(String value)
|
||||||
@@ -1338,7 +1375,7 @@ public class NodesImpl implements Nodes
|
|||||||
* @param content the content
|
* @param content the content
|
||||||
* @param fileName the uploaded file name
|
* @param fileName the uploaded file name
|
||||||
* @param applyMimeType If true, apply the mimeType from the Content object,
|
* @param applyMimeType If true, apply the mimeType from the Content object,
|
||||||
* else leave the original mimeType
|
* else leave the original mimeType (if the original type is null, then guess the mimeType)
|
||||||
* @param guessEncoding If true, guess the encoding from the underlying
|
* @param guessEncoding If true, guess the encoding from the underlying
|
||||||
* input stream, else use encoding set in the Content object as supplied
|
* input stream, else use encoding set in the Content object as supplied
|
||||||
*/
|
*/
|
||||||
@@ -1347,7 +1384,9 @@ public class NodesImpl implements Nodes
|
|||||||
ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
|
ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
|
||||||
InputStream is;
|
InputStream is;
|
||||||
String mimeType = content.getMimetype();
|
String mimeType = content.getMimetype();
|
||||||
if (!applyMimeType)
|
// Per RA-637 requirement the mimeType provided by the client takes precedent, however,
|
||||||
|
// if the mimeType is null, then it will be retrieved or guessed.
|
||||||
|
if (mimeType == null || !applyMimeType)
|
||||||
{
|
{
|
||||||
ContentData existingContentData = (ContentData) nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
|
ContentData existingContentData = (ContentData) nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
|
||||||
if (existingContentData != null)
|
if (existingContentData != null)
|
||||||
|
@@ -554,6 +554,9 @@ public class NodeApiTest extends AbstractBaseApiTest
|
|||||||
ContentInfo contentInfo = document.getContent();
|
ContentInfo contentInfo = document.getContent();
|
||||||
assertNotNull(contentInfo);
|
assertNotNull(contentInfo);
|
||||||
assertEquals(MimetypeMap.MIMETYPE_PDF, contentInfo.getMimeType());
|
assertEquals(MimetypeMap.MIMETYPE_PDF, contentInfo.getMimeType());
|
||||||
|
// Check there is no path info returned.
|
||||||
|
// The path info should only be returned when it is requested via a select statement.
|
||||||
|
assertNull(document.getPath());
|
||||||
|
|
||||||
// Retrieve the uploaded file
|
// Retrieve the uploaded file
|
||||||
response = getSingle(NodesEntityResource.class, user1, document.getId(), null, 200);
|
response = getSingle(NodesEntityResource.class, user1, document.getId(), null, 200);
|
||||||
@@ -587,11 +590,12 @@ public class NodeApiTest extends AbstractBaseApiTest
|
|||||||
// Check the upload response
|
// Check the upload response
|
||||||
assertEquals("quick-1.pdf", document.getName());
|
assertEquals("quick-1.pdf", document.getName());
|
||||||
|
|
||||||
// upload the same file again
|
// upload the same file again, and request the path info to be present in the response
|
||||||
response = post(getChildrenUrl(Nodes.PATH_MY), user1, new String(reqBody.getBody()), null, reqBody.getContentType(), 201);
|
response = post(getChildrenUrl(Nodes.PATH_MY), user1, new String(reqBody.getBody()), "?select=path", reqBody.getContentType(), 201);
|
||||||
document = jacksonUtil.parseEntry(response.getJsonResponse(), Document.class);
|
document = jacksonUtil.parseEntry(response.getJsonResponse(), Document.class);
|
||||||
// Check the upload response
|
// Check the upload response
|
||||||
assertEquals("quick-2.pdf", document.getName());
|
assertEquals("quick-2.pdf", document.getName());
|
||||||
|
assertNotNull(document.getPath());
|
||||||
|
|
||||||
response = getAll(getChildrenUrl(Nodes.PATH_MY), user1, paging, 200);
|
response = getAll(getChildrenUrl(Nodes.PATH_MY), user1, paging, 200);
|
||||||
pagingResult = parsePaging(response.getJsonResponse());
|
pagingResult = parsePaging(response.getJsonResponse());
|
||||||
@@ -619,6 +623,15 @@ public class NodeApiTest extends AbstractBaseApiTest
|
|||||||
// Try to upload a file without defining the required formData
|
// Try to upload a file without defining the required formData
|
||||||
reqBody = MultiPartBuilder.create().setAutoRename(true).build();
|
reqBody = MultiPartBuilder.create().setAutoRename(true).build();
|
||||||
post(getChildrenUrl(Nodes.PATH_MY), user1, new String(reqBody.getBody()), null, reqBody.getContentType(), 400);
|
post(getChildrenUrl(Nodes.PATH_MY), user1, new String(reqBody.getBody()), null, reqBody.getContentType(), 400);
|
||||||
|
|
||||||
|
// Test unsupported node type
|
||||||
|
reqBody = MultiPartBuilder.create()
|
||||||
|
.setFileData(new FileData(fileName2, file2, null))
|
||||||
|
.setAutoRename(true)
|
||||||
|
.setNodeType("cm:link")
|
||||||
|
.build();
|
||||||
|
post(getChildrenUrl(user1Home.getId()), user1, new String(reqBody.getBody()), null, reqBody.getContentType(), 400);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -643,7 +656,7 @@ public class NodeApiTest extends AbstractBaseApiTest
|
|||||||
final int numOfNodes = pagingResult.getCount().intValue();
|
final int numOfNodes = pagingResult.getCount().intValue();
|
||||||
|
|
||||||
MultiPartBuilder multiPartBuilder = MultiPartBuilder.create()
|
MultiPartBuilder multiPartBuilder = MultiPartBuilder.create()
|
||||||
.setFileData(new FileData(fileName, file, MimetypeMap.MIMETYPE_TEXT_PLAIN));
|
.setFileData(new FileData(fileName, file, null));
|
||||||
MultiPartRequest reqBody = multiPartBuilder.build();
|
MultiPartRequest reqBody = multiPartBuilder.build();
|
||||||
// Try to upload
|
// Try to upload
|
||||||
response = post(getChildrenUrl(folderA_Ref), userOneN1.getId(), new String(reqBody.getBody()), null, reqBody.getContentType(), 201);
|
response = post(getChildrenUrl(folderA_Ref), userOneN1.getId(), new String(reqBody.getBody()), null, reqBody.getContentType(), 201);
|
||||||
@@ -652,6 +665,7 @@ public class NodeApiTest extends AbstractBaseApiTest
|
|||||||
assertEquals(fileName, document.getName());
|
assertEquals(fileName, document.getName());
|
||||||
ContentInfo contentInfo = document.getContent();
|
ContentInfo contentInfo = document.getContent();
|
||||||
assertNotNull(contentInfo);
|
assertNotNull(contentInfo);
|
||||||
|
// As the client didn't set the mimeType, the API must guess it.
|
||||||
assertEquals(MimetypeMap.MIMETYPE_TEXT_PLAIN, contentInfo.getMimeType());
|
assertEquals(MimetypeMap.MIMETYPE_TEXT_PLAIN, contentInfo.getMimeType());
|
||||||
|
|
||||||
// Retrieve the uploaded file
|
// Retrieve the uploaded file
|
||||||
@@ -683,6 +697,51 @@ public class NodeApiTest extends AbstractBaseApiTest
|
|||||||
.build();
|
.build();
|
||||||
// userTwoN1 tries to upload a new file into the folderA of userOneN1
|
// userTwoN1 tries to upload a new file into the folderA of userOneN1
|
||||||
post(getChildrenUrl(folderA_Ref), userTwoN1.getId(), new String(reqBody.getBody()), null, reqBody.getContentType(), 403);
|
post(getChildrenUrl(folderA_Ref), userTwoN1.getId(), new String(reqBody.getBody()), null, reqBody.getContentType(), 403);
|
||||||
|
|
||||||
|
// Test upload with properties
|
||||||
|
response = post(getChildrenUrl(folderA_Ref), userOneN1.getId(), new String(reqBody.getBody()), null, reqBody.getContentType(), 201);
|
||||||
|
document = jacksonUtil.parseEntry(response.getJsonResponse(), Document.class);
|
||||||
|
// Check the upload response
|
||||||
|
assertEquals(fileName2, document.getName());
|
||||||
|
contentInfo = document.getContent();
|
||||||
|
assertNotNull(contentInfo);
|
||||||
|
assertEquals(MimetypeMap.MIMETYPE_TEXT_PLAIN, contentInfo.getMimeType());
|
||||||
|
assertNotNull(document.getProperties());
|
||||||
|
assertNull(document.getProperties().get("cm:title"));
|
||||||
|
assertNull(document.getProperties().get("cm:description"));
|
||||||
|
|
||||||
|
// upload a file with properties. Also, set autoRename=true
|
||||||
|
Map<String, String> props = new HashMap<>(2);
|
||||||
|
props.put("cm:title", "test title");
|
||||||
|
props.put("cm:description", "test description");
|
||||||
|
reqBody = MultiPartBuilder.create()
|
||||||
|
.setFileData(new FileData(fileName2, file2, MimetypeMap.MIMETYPE_TEXT_PLAIN))
|
||||||
|
.setAutoRename(true)
|
||||||
|
.setProperties(props)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
response = post(getChildrenUrl(folderA_Ref), userOneN1.getId(), new String(reqBody.getBody()), null, reqBody.getContentType(), 201);
|
||||||
|
document = jacksonUtil.parseEntry(response.getJsonResponse(), Document.class);
|
||||||
|
// Check the upload response
|
||||||
|
// "quick-2-1.txt" => fileName2 + autoRename
|
||||||
|
assertEquals("quick-2-1.txt", document.getName());
|
||||||
|
contentInfo = document.getContent();
|
||||||
|
assertNotNull(contentInfo);
|
||||||
|
assertEquals(MimetypeMap.MIMETYPE_TEXT_PLAIN, contentInfo.getMimeType());
|
||||||
|
assertNotNull(document.getProperties());
|
||||||
|
assertEquals("test title", document.getProperties().get("cm:title"));
|
||||||
|
assertEquals("test description", document.getProperties().get("cm:description"));
|
||||||
|
|
||||||
|
// Test unknown property name
|
||||||
|
props = new HashMap<>(1);
|
||||||
|
props.put("unknownPrefix" + System.currentTimeMillis() + ":description", "test description");
|
||||||
|
reqBody = MultiPartBuilder.create()
|
||||||
|
.setFileData(new FileData(fileName2, file2, MimetypeMap.MIMETYPE_TEXT_PLAIN))
|
||||||
|
.setAutoRename(true)
|
||||||
|
.setProperties(props)
|
||||||
|
.build();
|
||||||
|
// Prop prefix is unknown
|
||||||
|
post(getChildrenUrl(folderA_Ref), userOneN1.getId(), new String(reqBody.getBody()), null, reqBody.getContentType(), 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -37,7 +37,11 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <i><b>multipart/form-data</b></i> builder.
|
* <i><b>multipart/form-data</b></i> builder.
|
||||||
@@ -54,10 +58,12 @@ public class MultiPartBuilder
|
|||||||
private String updateNodeRef;
|
private String updateNodeRef;
|
||||||
private String description;
|
private String description;
|
||||||
private String contentTypeQNameStr;
|
private String contentTypeQNameStr;
|
||||||
private List<String> aspects;
|
private List<String> aspects = Collections.emptyList();
|
||||||
private Boolean majorVersion;
|
private Boolean majorVersion;
|
||||||
private Boolean overwrite;
|
private Boolean overwrite;
|
||||||
private Boolean autoRename;
|
private Boolean autoRename;
|
||||||
|
private String nodeType;
|
||||||
|
private Map<String, String> properties = Collections.emptyMap();
|
||||||
|
|
||||||
private MultiPartBuilder()
|
private MultiPartBuilder()
|
||||||
{
|
{
|
||||||
@@ -73,10 +79,12 @@ public class MultiPartBuilder
|
|||||||
this.updateNodeRef = that.updateNodeRef;
|
this.updateNodeRef = that.updateNodeRef;
|
||||||
this.description = that.description;
|
this.description = that.description;
|
||||||
this.contentTypeQNameStr = that.contentTypeQNameStr;
|
this.contentTypeQNameStr = that.contentTypeQNameStr;
|
||||||
this.aspects = that.aspects;
|
this.aspects = new ArrayList<>(that.aspects);
|
||||||
this.majorVersion = that.majorVersion;
|
this.majorVersion = that.majorVersion;
|
||||||
this.overwrite = that.overwrite;
|
this.overwrite = that.overwrite;
|
||||||
this.autoRename = that.autoRename;
|
this.autoRename = that.autoRename;
|
||||||
|
this.nodeType = that.nodeType;
|
||||||
|
this.properties = new HashMap<>(that.properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MultiPartBuilder create()
|
public static MultiPartBuilder create()
|
||||||
@@ -161,9 +169,21 @@ public class MultiPartBuilder
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MultiPartBuilder setNodeType(String nodeType)
|
||||||
|
{
|
||||||
|
this.nodeType = nodeType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultiPartBuilder setProperties(Map<String, String> properties)
|
||||||
|
{
|
||||||
|
this.properties = properties;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
private String getAspects(List<String> aspects)
|
private String getAspects(List<String> aspects)
|
||||||
{
|
{
|
||||||
if (aspects != null)
|
if (!aspects.isEmpty())
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder(aspects.size() * 2);
|
StringBuilder sb = new StringBuilder(aspects.size() * 2);
|
||||||
for (String str : aspects)
|
for (String str : aspects)
|
||||||
@@ -243,7 +263,11 @@ public class MultiPartBuilder
|
|||||||
|
|
||||||
if (fileData != null)
|
if (fileData != null)
|
||||||
{
|
{
|
||||||
parts.add(new FilePart("filedata", fileData.getFileName(), fileData.getFile(), fileData.getMimetype(), null));
|
FilePart fp = new FilePart("filedata", fileData.getFileName(), fileData.getFile(), fileData.getMimetype(), null);
|
||||||
|
// Get rid of the default values added upon FilePart instantiation
|
||||||
|
fp.setCharSet(null);
|
||||||
|
fp.setContentType(fileData.getMimetype());
|
||||||
|
parts.add(fp);
|
||||||
addPartIfNotNull(parts, "filename", fileData.getFileName());
|
addPartIfNotNull(parts, "filename", fileData.getFileName());
|
||||||
}
|
}
|
||||||
addPartIfNotNull(parts, "siteid", siteId);
|
addPartIfNotNull(parts, "siteid", siteId);
|
||||||
@@ -257,6 +281,15 @@ public class MultiPartBuilder
|
|||||||
addPartIfNotNull(parts, "majorversion", majorVersion);
|
addPartIfNotNull(parts, "majorversion", majorVersion);
|
||||||
addPartIfNotNull(parts, "overwrite", overwrite);
|
addPartIfNotNull(parts, "overwrite", overwrite);
|
||||||
addPartIfNotNull(parts, "autoRename", autoRename);
|
addPartIfNotNull(parts, "autoRename", autoRename);
|
||||||
|
addPartIfNotNull(parts, "nodeType", nodeType);
|
||||||
|
|
||||||
|
if (!properties.isEmpty())
|
||||||
|
{
|
||||||
|
for (Entry<String, String> prop : properties.entrySet())
|
||||||
|
{
|
||||||
|
parts.add(new StringPart(prop.getKey(), prop.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MultipartRequestEntity req = new MultipartRequestEntity(parts.toArray(new Part[parts.size()]), new HttpMethodParams());
|
MultipartRequestEntity req = new MultipartRequestEntity(parts.toArray(new Part[parts.size()]), new HttpMethodParams());
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user