RM-4568: extended upload method to support relativePath creation and

minor change in specification
This commit is contained in:
Silviu Dinuta
2017-01-19 16:53:19 +02:00
parent a7b698750b
commit 397730876b
2 changed files with 49 additions and 17 deletions

View File

@@ -64,6 +64,8 @@ import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.util.Pair; import org.alfresco.util.Pair;
import org.alfresco.util.ParameterCheck; import org.alfresco.util.ParameterCheck;
import org.apache.commons.lang.StringUtils;
import org.springframework.extensions.webscripts.servlet.FormData;
import net.sf.acegisecurity.vote.AccessDecisionVoter; import net.sf.acegisecurity.vote.AccessDecisionVoter;
@@ -205,14 +207,14 @@ public class RMNodesImpl extends NodesImpl implements RMNodes
boolean isSpecialContainer = isFilePlan || isTransferContainer || isUnfiledContainer || isHoldsContainer; boolean isSpecialContainer = isFilePlan || isTransferContainer || isUnfiledContainer || isHoldsContainer;
// DELETE // DELETE
if(!isSpecialContainer && if(!isSpecialContainer &&
capabilityService.getCapability("Delete").evaluate(nodeRef) == AccessDecisionVoter.ACCESS_GRANTED) capabilityService.getCapability("Delete").evaluate(nodeRef) == AccessDecisionVoter.ACCESS_GRANTED)
{ {
allowableOperations.add(OP_DELETE); allowableOperations.add(OP_DELETE);
} }
// CREATE // CREATE
if(type != RMNodeType.FILE && if(type != RMNodeType.FILE &&
!isTransferContainer && !isTransferContainer &&
capabilityService.getCapability("FillingPermissionOnly").evaluate(nodeRef) == AccessDecisionVoter.ACCESS_GRANTED) 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); NodeRef parentNodeRef = getOrCreatePath(parentFolderNodeId, relativePath, nodeTypeQName);
// Set relative path to null as we pass the last element from the path // 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); 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 @Override
public NodeRef getOrCreatePath(String parentFolderNodeId, String relativePath, QName nodeTypeQName) 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 * Starting from the latest existing element create the rest of the elements
*/ */
QName parentNodeType = nodeService.getType(parentNodeRef); 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)) dictionaryService.isSubClass(parentNodeType, RecordsManagementModel.TYPE_UNFILED_RECORD_CONTAINER))
{ {
for (String pathElement : pathElements) 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(); 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 * except the last element which is a record folder if the created node is of type content
*/ */
Iterator<String> iterator = pathElements.iterator(); Iterator<String> iterator = pathElements.iterator();

View File

@@ -229,7 +229,7 @@ paths:
This API method also supports node creation using application/json. 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: You can create a category like this:
```JSON ```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 ```JSON
{ {
"name":"My Electronic Record", "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 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. 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: 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. 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 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 body creates two folders inside the specified **nodeId**, if the **nodeId** identifies
a folder: 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: If you specify a list as input, then a paginated list rather than an entry is returned in the response body. For example:
```JSON ```JSON
{ {
"list": { "list": {
@@ -599,11 +599,11 @@ paths:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
'/records/{recordId}/file': '/records/{recordId}/file':
post: post:
tags: tags:
- records - records
summary: File a record summary: File a record
description: | 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** 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**. 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. 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. 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 operationId: fileRecord
parameters: parameters:
- $ref: '#/parameters/recordIdParam' - $ref: '#/parameters/recordIdParam'
- $ref: '#/parameters/IGNodeEntryIncludeParam' - $ref: '#/parameters/IGNodeEntryIncludeParam'
- $ref: '#/parameters/fieldsParam' - $ref: '#/parameters/fieldsParam'
@@ -654,12 +654,12 @@ paths:
$ref: '#/definitions/Error' $ref: '#/definitions/Error'
'/files/{fileId}/declare': '/files/{fileId}/declare':
post: post:
tags: tags:
- files - files
summary: Declare as record summary: Declare as record
description: Declares the file **fileId** in the unfiled record container. description: Declares the file **fileId** in the unfiled record container.
operationId: declareRecord operationId: declareRecord
parameters: parameters:
- name: fileId - name: fileId
in: path in: path
description: The identifier of a non-record file. description: The identifier of a non-record file.