Merged HEAD (5.2) to 5.2.N (5.2.1)

126410 jkaabimofrad: Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2)
      121557 jvonka: FileFolder API - experimental support for multi move/copy via post to target folder
      - please note: API (including uri endpoint) is subject to change
      RA-683, RA-684


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@126756 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Ancuta Morarasu
2016-05-11 11:10:51 +00:00
parent 3914ebcfcc
commit cb90942321
4 changed files with 137 additions and 37 deletions

View File

@@ -107,7 +107,7 @@ public interface Nodes
void deleteNode(String nodeId);
/**
* Create node(s) - folder or (empty) file.
* Create node - folder or (empty) file.
*
* @param parentFolderNodeId
* @param nodeInfo
@@ -116,6 +116,28 @@ public interface Nodes
*/
Node createNode(String parentFolderNodeId, Node nodeInfo, Parameters parameters);
/**
* Move node
*
* @param sourceNodeId
* @param parentFolderNodeId
* @param name
* @param parameters
* @return
*/
Node moveNode(String sourceNodeId, String parentFolderNodeId, String name, Parameters parameters);
/**
* Copy node
*
* @param sourceNodeId
* @param parentFolderNodeId
* @param name
* @param parameters
* @return
*/
Node copyNode(String sourceNodeId, String parentFolderNodeId, String name, Parameters parameters);
/**
* Update node meta-data.
*

View File

@@ -1091,8 +1091,18 @@ public class NodesImpl implements Nodes
NodeRef parentNodeRef = nodeInfo.getParentId();
if (parentNodeRef != null)
{
// move/rename - with exception mapping
move(nodeRef, parentNodeRef, name);
NodeRef currentParentNodeRef = getParentNodeRef(nodeRef);
if (currentParentNodeRef == null)
{
// implies root (Company Home) hence return 403 here
throw new PermissionDeniedException();
}
if (! currentParentNodeRef.equals(parentNodeRef))
{
// move/rename - with exception mapping
moveOrCopy(nodeRef, parentNodeRef, name, false);
}
}
List<String> aspectNames = nodeInfo.getAspectNames();
@@ -1178,47 +1188,62 @@ public class NodesImpl implements Nodes
return getFolderOrDocument(nodeRef.getId(), parameters);
}
private void move(NodeRef nodeRef, NodeRef parentNodeRef, String name)
public Node moveNode(String sourceNodeId, String parentFolderNodeId, String name, Parameters parameters)
{
NodeRef currentParentNodeRef = getParentNodeRef(nodeRef);
if (currentParentNodeRef == null)
{
// implies root (Company Home) hence return 403 here
throw new PermissionDeniedException();
}
final NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId, null);
final NodeRef sourceNodeRef = validateOrLookupNode(sourceNodeId, null);
if (! currentParentNodeRef.equals(parentNodeRef))
FileInfo fi = moveOrCopy(sourceNodeRef, parentNodeRef, name, false);
return getFolderOrDocument(fi.getNodeRef().getId(), parameters);
}
public Node copyNode(String sourceNodeId, String parentFolderNodeId, String name, Parameters parameters)
{
final NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId, null);
final NodeRef sourceNodeRef = validateOrLookupNode(sourceNodeId, null);
FileInfo fi = moveOrCopy(sourceNodeRef, parentNodeRef, name, true);
return getFolderOrDocument(fi.getNodeRef().getId(), parameters);
}
protected FileInfo moveOrCopy(NodeRef nodeRef, NodeRef parentNodeRef, String name, boolean isCopy)
{
try
{
try
if (isCopy)
{
return fileFolderService.copy(nodeRef, parentNodeRef, name);
}
else
{
// updating "parentId" means moving primary parent !
// note: in the future (as and when we support secondary parent/child assocs) we may also
// wish to select which parent to "move from" (in case where the node resides in multiple locations)
fileFolderService.move(nodeRef, parentNodeRef, name);
}
catch (InvalidNodeRefException inre)
{
throw new EntityNotFoundException(inre.getMessage()+" ["+nodeRef+","+parentNodeRef+"]");
}
catch (FileNotFoundException fnfe)
{
// convert checked exception
throw new EntityNotFoundException(fnfe.getMessage()+" ["+nodeRef+","+parentNodeRef+"]");
}
catch (FileExistsException fee)
{
// duplicate - name clash
throw new ConstraintViolatedException(fee.getMessage()+" ["+nodeRef+","+parentNodeRef+"]");
}
catch (FileFolderServiceImpl.InvalidTypeException ite)
{
throw new InvalidArgumentException(ite.getMessage()+" ["+nodeRef+","+parentNodeRef+"]");
}
catch (CyclicChildRelationshipException ccre)
{
throw new InvalidArgumentException(ccre.getMessage()+" ["+nodeRef+","+parentNodeRef+"]");
return fileFolderService.move(nodeRef, parentNodeRef, name);
}
}
catch (InvalidNodeRefException inre)
{
throw new EntityNotFoundException(inre.getMessage()+" ["+nodeRef+","+parentNodeRef+"]");
}
catch (FileNotFoundException fnfe)
{
// convert checked exception
throw new EntityNotFoundException(fnfe.getMessage()+" ["+nodeRef+","+parentNodeRef+"]");
}
catch (FileExistsException fee)
{
// duplicate - name clash
throw new ConstraintViolatedException(fee.getMessage()+" ["+nodeRef+","+parentNodeRef+"]");
}
catch (FileFolderServiceImpl.InvalidTypeException ite)
{
throw new InvalidArgumentException(ite.getMessage()+" ["+nodeRef+","+parentNodeRef+"]");
}
catch (CyclicChildRelationshipException ccre)
{
throw new InvalidArgumentException(ccre.getMessage() + " [" + nodeRef + "," + parentNodeRef + "]");
}
}
@Override

View File

@@ -34,7 +34,6 @@ import java.util.Map;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.rest.framework.resource.UniqueId;
import org.alfresco.rest.framework.resource.content.*;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.security.NoSuchPersonException;
@@ -68,7 +67,6 @@ public class Node implements Comparable<Node>
protected String prefixTypeQName;
protected List<String> aspectNames;
protected Map<String, Object> properties;
public Node(NodeRef nodeRef, NodeRef parentNodeRef, Map<QName, Serializable> nodeProps, Map<String, UserInfo> mapUserInfo, ServiceRegistry sr)
@@ -143,6 +141,8 @@ public class Node implements Comparable<Node>
return userInfo;
}
// note: nodeRef maps to json "id" (when serializing/deserializng)
@UniqueId
public NodeRef getNodeRef()
{
@@ -285,6 +285,7 @@ public class Node implements Comparable<Node>
}
// here to allow POST /nodes/{id}/children when creating empty file with specified content.mimeType
protected ContentInfo contentInfo;
public void setContent(ContentInfo contentInfo)
@@ -297,6 +298,21 @@ public class Node implements Comparable<Node>
return this.contentInfo;
}
// TODO experimental (API subject to change) - special property (request-only) to allow move/copy via POST /nodes/{id}/children
protected String action;
public String getAction()
{
return action;
}
public void setAction(String action)
{
this.action = action;
}
// TODO for backwards compat' - set explicitly when needed (ie. favourites) (note: we could choose to have separate old Node/NodeImpl etc)
protected String title;
@@ -383,4 +399,5 @@ public class Node implements Comparable<Node>
{
this.modifiedBy = modifiedBy;
}
}

View File

@@ -25,6 +25,7 @@ import org.alfresco.rest.api.Nodes;
import org.alfresco.rest.api.model.Node;
import org.alfresco.rest.framework.WebApiDescription;
import org.alfresco.rest.framework.WebApiParam;
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
import org.alfresco.rest.framework.resource.RelationshipResource;
import org.alfresco.rest.framework.resource.actions.interfaces.MultiPartRelationshipResourceAction;
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
@@ -100,10 +101,45 @@ public class NodeChildrenRelation implements RelationshipResourceAction.Read<Nod
{
List<Node> result = new ArrayList<>(nodeInfos.size());
// TODO experimental (API subject to change) - eg. this may move to a separate endpoint !
for (Node nodeInfo : nodeInfos)
{
String action = nodeInfo.getAction();
if (action != null)
{
String sourceNodeId = nodeInfo.getNodeRef().getId();
String optionalName = nodeInfo.getName();
if (action.equalsIgnoreCase("move"))
{
result.add(nodes.moveNode(sourceNodeId, parentFolderNodeId, optionalName, parameters));
}
else if (action.equalsIgnoreCase("copy"))
{
result.add(nodes.copyNode(sourceNodeId, parentFolderNodeId, optionalName, parameters));
}
else
{
throw new InvalidArgumentException("Unknown action: "+action);
}
}
else
{
if (nodeInfo.getNodeRef() != null)
{
throw new InvalidArgumentException("Unexpected id without action, eg. move/copy: "+nodeInfo.getNodeRef());
}
result.add(nodes.createNode(parentFolderNodeId, nodeInfo, parameters));
}
}
/*
for (Node nodeInfo : nodeInfos)
{
result.add(nodes.createNode(parentFolderNodeId, nodeInfo, parameters));
}
*/
return result;
}