diff --git a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/RMNodesImpl.java b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/RMNodesImpl.java index 7e763a7a53..e9b7f71de9 100644 --- a/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/RMNodesImpl.java +++ b/rm-community/rm-community-repo/source/java/org/alfresco/rm/rest/api/impl/RMNodesImpl.java @@ -64,6 +64,8 @@ import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.namespace.QName; import org.alfresco.util.Pair; import org.alfresco.util.ParameterCheck; +import org.apache.commons.lang.StringUtils; +import org.springframework.extensions.webscripts.servlet.FormData; import net.sf.acegisecurity.vote.AccessDecisionVoter; @@ -205,14 +207,14 @@ public class RMNodesImpl extends NodesImpl implements RMNodes boolean isSpecialContainer = isFilePlan || isTransferContainer || isUnfiledContainer || isHoldsContainer; // DELETE - if(!isSpecialContainer && + if(!isSpecialContainer && capabilityService.getCapability("Delete").evaluate(nodeRef) == AccessDecisionVoter.ACCESS_GRANTED) { allowableOperations.add(OP_DELETE); } // CREATE - if(type != RMNodeType.FILE && + if(type != RMNodeType.FILE && !isTransferContainer && capabilityService.getCapability("FillingPermissionOnly").evaluate(nodeRef) == AccessDecisionVoter.ACCESS_GRANTED) { @@ -350,11 +352,41 @@ public class RMNodesImpl extends NodesImpl implements RMNodes NodeRef parentNodeRef = getOrCreatePath(parentFolderNodeId, relativePath, nodeTypeQName); // Set relative path to null as we pass the last element from the path - nodeInfo.setRelativePath(null); + nodeInfo.setRelativePath(null); return super.createNode(parentNodeRef.getId(), nodeInfo, parameters); } + @Override + public Node upload(String parentFolderNodeId, FormData formData, Parameters parameters) + { + if (formData == null || !formData.getIsMultiPart()) + { + throw new InvalidArgumentException("The request content-type is not multipart: "+parentFolderNodeId); + } + + for (FormData.FormField field : formData.getFields()) + { + if(field.getName().equalsIgnoreCase("relativepath")) + { + // Create the path if it does not exist + getOrCreatePath(parentFolderNodeId, getStringOrNull(field.getValue()), ContentModel.TYPE_CONTENT); + break; + } + } + + return super.upload(parentFolderNodeId, formData, parameters); + } + + private String getStringOrNull(String value) + { + if (StringUtils.isNotEmpty(value)) + { + return value.equalsIgnoreCase("null") ? null : value; + } + return null; + } + @Override public NodeRef getOrCreatePath(String parentFolderNodeId, String relativePath, QName nodeTypeQName) { @@ -407,7 +439,7 @@ public class RMNodesImpl extends NodesImpl implements RMNodes * Starting from the latest existing element create the rest of the elements */ QName parentNodeType = nodeService.getType(parentNodeRef); - if(dictionaryService.isSubClass(parentNodeType, RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER) || + if(dictionaryService.isSubClass(parentNodeType, RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER) || dictionaryService.isSubClass(parentNodeType, RecordsManagementModel.TYPE_UNFILED_RECORD_CONTAINER)) { for (String pathElement : pathElements) @@ -416,9 +448,9 @@ public class RMNodesImpl extends NodesImpl implements RMNodes parentNodeRef = fileFolderService.create(parentNodeRef, pathElement, RecordsManagementModel.TYPE_UNFILED_RECORD_FOLDER).getNodeRef(); } } - else + else { - /* Outside the unfiled record container the path elements are record categories + /* Outside the unfiled record container the path elements are record categories * except the last element which is a record folder if the created node is of type content */ Iterator iterator = pathElements.iterator(); diff --git a/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/ig-core-api.yaml b/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/ig-core-api.yaml index b1897925c2..e5bb9abf19 100644 --- a/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/ig-core-api.yaml +++ b/rm-community/rm-community-rest-api-explorer/src/main/webapp/definitions/ig-core-api.yaml @@ -229,7 +229,7 @@ paths: This API method also supports node creation using application/json. - You must specify at least a **name** and **nodeType**. + You must specify at least a **name** and **nodeType**. You can create a category like this: ```JSON @@ -289,7 +289,7 @@ paths: } ``` - You can create an empty electronic record and use the record endpoint to create content: + You can create an empty electronic record: ```JSON { "name":"My Electronic Record", @@ -306,7 +306,7 @@ paths: } ``` The **relativePath** specifies the container structure to create relative to the node **nodeId**. Containers in the - **relativePath** that do not exist are created before the node is created. The container type is decided considering + **relativePath** that do not exist are created before the node is created. The container type is decided considering the type of the parent container and the type of the node to be created. You can set properties when creating a new fileplan component: @@ -324,7 +324,7 @@ paths: Any missing aspects are applied automatically. You can set aspects explicitly, if needed, using an **aspectNames** field. - **Note:** You can create more than one child by + **Note:** You can create more than one child by specifying a list of nodes in the JSON body. For example, the following JSON body creates two folders inside the specified **nodeId**, if the **nodeId** identifies a folder: @@ -341,7 +341,7 @@ paths: ] ``` If you specify a list as input, then a paginated list rather than an entry is returned in the response body. For example: - + ```JSON { "list": { @@ -599,11 +599,11 @@ paths: $ref: '#/definitions/Error' '/records/{recordId}/file': post: - tags: + tags: - records summary: File a record description: | - Files the record **recordId** in the target record folder. + Files the record **recordId** in the target record folder. You can specify the target record folder by providing its id **targetParentId** or by providing the id of a parent container **targetParentId** and a relative path **relativePath**. @@ -613,9 +613,9 @@ paths: The relativePath is made of record containers and a record folder as the last element. Containers that are missing from relativePath will be created before filing. - If the record is already filed, a link to the target record folder is created. + If the record is already filed, a link to the target record folder is created. operationId: fileRecord - parameters: + parameters: - $ref: '#/parameters/recordIdParam' - $ref: '#/parameters/IGNodeEntryIncludeParam' - $ref: '#/parameters/fieldsParam' @@ -654,12 +654,12 @@ paths: $ref: '#/definitions/Error' '/files/{fileId}/declare': post: - tags: + tags: - files summary: Declare as record description: Declares the file **fileId** in the unfiled record container. operationId: declareRecord - parameters: + parameters: - name: fileId in: path description: The identifier of a non-record file.