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)
126360 jkaabimofrad: Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2) 119711 jvonka: FileFolder API - consistently handle node aspects &/or properties (on create or update) - also allow specialise node type (when updating a node) - minor tweaks to javadoc/comments - RA-635, RA-636, RA-639 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@126706 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -549,8 +549,8 @@ public class NodesImpl implements Nodes
|
|||||||
|
|
||||||
if (! minimalInfo)
|
if (! minimalInfo)
|
||||||
{
|
{
|
||||||
node.setProperties(mapProperties(properties, selectParam, mapUserInfo));
|
node.setProperties(mapFromNodeProperties(properties, selectParam, mapUserInfo));
|
||||||
node.setAspectNames(mapAspects(nodeService.getAspects(nodeRef)));
|
node.setAspectNames(mapFromNodeAspects(nodeService.getAspects(nodeRef)));
|
||||||
}
|
}
|
||||||
|
|
||||||
node.setNodeType(typeQName.toPrefixString(namespaceService));
|
node.setNodeType(typeQName.toPrefixString(namespaceService));
|
||||||
@@ -661,7 +661,20 @@ public class NodesImpl implements Nodes
|
|||||||
return new PathInfo(pathStr, isComplete, pathElements);
|
return new PathInfo(pathStr, isComplete, pathElements);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<String, Object> mapProperties(Map<QName, Serializable> nodeProps, List<String> selectParam, Map<String,UserInfo> mapUserInfo)
|
protected Map<QName, Serializable> mapToNodeProperties(Map<String, Object> props)
|
||||||
|
{
|
||||||
|
Map<QName, Serializable> nodeProps = new HashMap<>(props.size());
|
||||||
|
|
||||||
|
for (Entry<String, Object> entry : props.entrySet())
|
||||||
|
{
|
||||||
|
QName propQName = QName.createQName(entry.getKey(), namespaceService);
|
||||||
|
nodeProps.put(propQName, (Serializable)entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodeProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<String, Object> mapFromNodeProperties(Map<QName, Serializable> nodeProps, List<String> selectParam, Map<String,UserInfo> mapUserInfo)
|
||||||
{
|
{
|
||||||
List<QName> selectedProperties;
|
List<QName> selectedProperties;
|
||||||
|
|
||||||
@@ -708,7 +721,7 @@ public class NodesImpl implements Nodes
|
|||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<String> mapAspects(Set<QName> nodeAspects)
|
protected List<String> mapFromNodeAspects(Set<QName> nodeAspects)
|
||||||
{
|
{
|
||||||
List<String> aspectNames = new ArrayList<>(nodeAspects.size());
|
List<String> aspectNames = new ArrayList<>(nodeAspects.size());
|
||||||
|
|
||||||
@@ -833,19 +846,20 @@ public class NodesImpl implements Nodes
|
|||||||
throw new InvalidArgumentException("NodeId of folder is expected: "+parentNodeRef);
|
throw new InvalidArgumentException("NodeId of folder is expected: "+parentNodeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// node name - mandatory
|
||||||
String nodeName = nodeInfo.getName();
|
String nodeName = nodeInfo.getName();
|
||||||
if ((nodeName == null) || nodeName.isEmpty())
|
if ((nodeName == null) || nodeName.isEmpty())
|
||||||
{
|
{
|
||||||
throw new InvalidArgumentException("Node name is expected: "+parentNodeRef);
|
throw new InvalidArgumentException("Node name is expected: "+parentNodeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// node type - check that requested type is a (sub-) type of folder or content
|
||||||
String nodeType = nodeInfo.getNodeType();
|
String nodeType = nodeInfo.getNodeType();
|
||||||
if ((nodeType == null) || nodeType.isEmpty())
|
if ((nodeType == null) || nodeType.isEmpty())
|
||||||
{
|
{
|
||||||
throw new InvalidArgumentException("Node type is expected: "+parentNodeRef+","+nodeName);
|
throw new InvalidArgumentException("Node type is expected: "+parentNodeRef+","+nodeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that requested type is a (sub-) type of folder or content
|
|
||||||
QName nodeTypeQName = createQName(nodeType);
|
QName nodeTypeQName = createQName(nodeType);
|
||||||
|
|
||||||
Set<QName> contentAndFolders = new HashSet<>(Arrays.asList(ContentModel.TYPE_FOLDER, ContentModel.TYPE_CONTENT));
|
Set<QName> contentAndFolders = new HashSet<>(Arrays.asList(ContentModel.TYPE_FOLDER, ContentModel.TYPE_CONTENT));
|
||||||
@@ -855,15 +869,12 @@ public class NodesImpl implements Nodes
|
|||||||
|
|
||||||
boolean isContent = typeMatches(nodeTypeQName, Collections.singleton(ContentModel.TYPE_CONTENT), null);
|
boolean isContent = typeMatches(nodeTypeQName, Collections.singleton(ContentModel.TYPE_CONTENT), null);
|
||||||
|
|
||||||
Map<QName, Serializable> props = new HashMap<>(10);
|
Map<QName, Serializable> props = new HashMap<>(1);
|
||||||
|
|
||||||
if (nodeInfo.getProperties() != null)
|
if (nodeInfo.getProperties() != null)
|
||||||
{
|
{
|
||||||
for (Entry<String, Object> entry : nodeInfo.getProperties().entrySet())
|
// node properties - set any additional properties
|
||||||
{
|
props = mapToNodeProperties(nodeInfo.getProperties());
|
||||||
QName propQName = QName.createQName(entry.getKey(), namespaceService);
|
|
||||||
props.put(propQName, (Serializable)entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
props.put(ContentModel.PROP_NAME, nodeName);
|
props.put(ContentModel.PROP_NAME, nodeName);
|
||||||
@@ -871,6 +882,22 @@ public class NodesImpl implements Nodes
|
|||||||
QName assocQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(nodeName));
|
QName assocQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(nodeName));
|
||||||
NodeRef nodeRef = nodeService.createNode(parentNodeRef, ContentModel.ASSOC_CONTAINS, assocQName, nodeTypeQName, props).getChildRef();
|
NodeRef nodeRef = nodeService.createNode(parentNodeRef, ContentModel.ASSOC_CONTAINS, assocQName, nodeTypeQName, props).getChildRef();
|
||||||
|
|
||||||
|
List<String> aspectNames = nodeInfo.getAspectNames();
|
||||||
|
if (aspectNames != null)
|
||||||
|
{
|
||||||
|
// node aspects - set any additional aspects
|
||||||
|
for (String aspectName : aspectNames)
|
||||||
|
{
|
||||||
|
QName aspectQName = QName.createQName(aspectName, namespaceService);
|
||||||
|
if (EXCLUDED_ASPECTS.contains(aspectQName) || aspectQName.equals(ContentModel.ASPECT_AUDITABLE))
|
||||||
|
{
|
||||||
|
continue; // ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeService.addAspect(nodeRef, aspectQName, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isContent) {
|
if (isContent) {
|
||||||
// add empty file
|
// add empty file
|
||||||
ContentWriter writer = sr.getContentService().getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
|
ContentWriter writer = sr.getContentService().getWriter(nodeRef, ContentModel.PROP_CONTENT, true);
|
||||||
@@ -886,34 +913,48 @@ public class NodesImpl implements Nodes
|
|||||||
{
|
{
|
||||||
final NodeRef nodeRef = validateNode(nodeId);
|
final NodeRef nodeRef = validateNode(nodeId);
|
||||||
|
|
||||||
|
QName nodeTypeQName = nodeService.getType(nodeRef);
|
||||||
|
|
||||||
final Set<QName> fileOrFolder = new HashSet<>(Arrays.asList(ContentModel.TYPE_FOLDER, ContentModel.TYPE_CONTENT));
|
final Set<QName> fileOrFolder = new HashSet<>(Arrays.asList(ContentModel.TYPE_FOLDER, ContentModel.TYPE_CONTENT));
|
||||||
if (! nodeMatches(nodeRef, fileOrFolder, null))
|
if (! typeMatches(nodeTypeQName, fileOrFolder, null))
|
||||||
{
|
{
|
||||||
throw new InvalidArgumentException("NodeId of file or folder is expected");
|
throw new InvalidArgumentException("NodeId of file or folder is expected");
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<QName, Serializable> props = new HashMap<>(10);
|
Map<QName, Serializable> props = new HashMap<>(0);
|
||||||
|
|
||||||
if (nodeInfo.getProperties() != null)
|
if (nodeInfo.getProperties() != null)
|
||||||
{
|
{
|
||||||
for (Entry<String, Object> entry : nodeInfo.getProperties().entrySet())
|
props = mapToNodeProperties(nodeInfo.getProperties());
|
||||||
{
|
|
||||||
QName propQName = QName.createQName(entry.getKey(), namespaceService);
|
|
||||||
props.put(propQName, (Serializable)entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String name = nodeInfo.getName();
|
String name = nodeInfo.getName();
|
||||||
if ((name != null) && (! name.isEmpty()))
|
if ((name != null) && (! name.isEmpty()))
|
||||||
{
|
{
|
||||||
// note: this is equivalent of a rename within target folder
|
// update node name if needed - note: if the name is different than existing then this is equivalent of a rename (within parent folder)
|
||||||
props.put(ContentModel.PROP_NAME, name);
|
props.put(ContentModel.PROP_NAME, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String nodeType = nodeInfo.getNodeType();
|
||||||
|
if ((nodeType != null) && (! nodeType.isEmpty()))
|
||||||
|
{
|
||||||
|
// update node type - ensure that we are performing a specialise (we do not support generalise)
|
||||||
|
QName destNodeTypeQName = QName.createQName(nodeType, namespaceService);
|
||||||
|
|
||||||
|
if ((! destNodeTypeQName.equals(nodeTypeQName)) && dictionaryService.isSubClass(destNodeTypeQName, nodeTypeQName))
|
||||||
|
{
|
||||||
|
nodeService.setType(nodeRef, destNodeTypeQName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Cannot generalise the node type (from "+nodeTypeQName+" to "+destNodeTypeQName+")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
List<String> aspectNames = nodeInfo.getAspectNames();
|
List<String> aspectNames = nodeInfo.getAspectNames();
|
||||||
if (aspectNames != null)
|
if (aspectNames != null)
|
||||||
{
|
{
|
||||||
// note: can be empty (eg. to remove existing aspects (+ aspect properties) ... apart from cm:auditable, sys:referencable, sys:localized)
|
// update aspects - note: can be empty (eg. to remove existing aspects+properties) but not cm:auditable, sys:referencable, sys:localized
|
||||||
Set<QName> aspectQNames = new HashSet<>(aspectNames.size());
|
Set<QName> aspectQNames = new HashSet<>(aspectNames.size());
|
||||||
for (String aspectName : aspectNames)
|
for (String aspectName : aspectNames)
|
||||||
{
|
{
|
||||||
@@ -967,6 +1008,7 @@ public class NodesImpl implements Nodes
|
|||||||
|
|
||||||
if (props.size() > 0)
|
if (props.size() > 0)
|
||||||
{
|
{
|
||||||
|
// update node properties - note: null will unset the specified property
|
||||||
nodeService.addProperties(nodeRef, props);
|
nodeService.addProperties(nodeRef, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,7 +35,11 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO ... work-in-progress
|
* Node Children
|
||||||
|
*
|
||||||
|
* - list folder children
|
||||||
|
* - create folder &/or empty file
|
||||||
|
* - create (ie. upload) file with content
|
||||||
*
|
*
|
||||||
* @author janv
|
* @author janv
|
||||||
* @author Jamal Kaabi-Mofrad
|
* @author Jamal Kaabi-Mofrad
|
||||||
@@ -59,17 +63,12 @@ public class NodeChildrenRelation implements RelationshipResourceAction.Read<Nod
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* List folder children - returns a filtered/sorted/paged list of nodes that are immediate children of the parent folder
|
* List folder children - returns a filtered/sorted/paged list of nodes that are immediate children of the parent folder
|
||||||
*
|
*
|
||||||
* TODO filtering, sorting, ...
|
* @param parentFolderNodeId String id of parent folder - will also accept well-known alias, eg. -root- or -my- or -shared-
|
||||||
* TODO metadata/properties & permissions etc ...
|
|
||||||
*
|
|
||||||
* @param parentFolderNodeId String id of parent folder - will also accept aliases "-root-" (Company Home) or "-my-" (current user's home folder)
|
|
||||||
*
|
*
|
||||||
* Optional query parameters:
|
* Optional query parameters:
|
||||||
*
|
*
|
||||||
* - incFiles
|
* - select
|
||||||
* - incFolders
|
|
||||||
*
|
|
||||||
* - properties
|
* - properties
|
||||||
* - where
|
* - where
|
||||||
* - orderBy
|
* - orderBy
|
||||||
@@ -90,7 +89,7 @@ public class NodeChildrenRelation implements RelationshipResourceAction.Read<Nod
|
|||||||
/**
|
/**
|
||||||
* Create one or more nodes (folder or empty file) below parent folder.
|
* Create one or more nodes (folder or empty file) below parent folder.
|
||||||
*
|
*
|
||||||
* Note: for parent folder nodeId, can also use well-known alias, eg. -root- or -my-
|
* Note: for parent folder nodeId, can also use well-known alias, eg. -root- or -my- or -shared-
|
||||||
*
|
*
|
||||||
* If parentFolderNodeId does not exist, EntityNotFoundException (status 404).
|
* If parentFolderNodeId does not exist, EntityNotFoundException (status 404).
|
||||||
* If parentFolderNodeId does not represent a folder, InvalidArgumentException (status 400).
|
* If parentFolderNodeId does not represent a folder, InvalidArgumentException (status 400).
|
||||||
|
Reference in New Issue
Block a user