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)
126366 jkaabimofrad: Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2) 119787 jvonka: FileFolder API - handle file/folder link & also prevent create/upload of unknown (~residual) props RA-638, RA-639 (and related) git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/DEV/5.2.N/root@126711 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.rest.api.impl;
|
package org.alfresco.rest.api.impl;
|
||||||
|
|
||||||
|
import org.alfresco.model.ApplicationModel;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.query.PagingRequest;
|
import org.alfresco.query.PagingRequest;
|
||||||
import org.alfresco.query.PagingResults;
|
import org.alfresco.query.PagingResults;
|
||||||
@@ -44,6 +45,7 @@ import org.alfresco.rest.framework.core.exceptions.ApiException;
|
|||||||
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
|
import org.alfresco.rest.framework.core.exceptions.ConstraintViolatedException;
|
||||||
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
|
||||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
|
||||||
|
import org.alfresco.rest.framework.core.exceptions.NotFoundException;
|
||||||
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
|
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
|
||||||
import org.alfresco.rest.framework.core.exceptions.RequestEntityTooLargeException;
|
import org.alfresco.rest.framework.core.exceptions.RequestEntityTooLargeException;
|
||||||
import org.alfresco.rest.framework.resource.content.BasicContentInfo;
|
import org.alfresco.rest.framework.resource.content.BasicContentInfo;
|
||||||
@@ -60,7 +62,9 @@ import org.alfresco.service.ServiceRegistry;
|
|||||||
import org.alfresco.service.cmr.action.Action;
|
import org.alfresco.service.cmr.action.Action;
|
||||||
import org.alfresco.service.cmr.action.ActionDefinition;
|
import org.alfresco.service.cmr.action.ActionDefinition;
|
||||||
import org.alfresco.service.cmr.action.ActionService;
|
import org.alfresco.service.cmr.action.ActionService;
|
||||||
|
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
|
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||||
import org.alfresco.service.cmr.model.FileFolderService;
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
import org.alfresco.service.cmr.model.FileInfo;
|
import org.alfresco.service.cmr.model.FileInfo;
|
||||||
import org.alfresco.service.cmr.model.FileNotFoundException;
|
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||||
@@ -129,7 +133,7 @@ public class NodesImpl implements Nodes
|
|||||||
private final static String PARAM_SELECT_PROPERTIES = "properties";
|
private final static String PARAM_SELECT_PROPERTIES = "properties";
|
||||||
private final static String PARAM_SELECT_PATH = "path";
|
private final static String PARAM_SELECT_PATH = "path";
|
||||||
private final static String PARAM_SELECT_ASPECTNAMES = "aspectNames";
|
private final static String PARAM_SELECT_ASPECTNAMES = "aspectNames";
|
||||||
private final static String PARAM_SELECT_ISLINK = "isLink"; // TODO ...
|
private final static String PARAM_SELECT_ISLINK = "isLink";
|
||||||
|
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
private DictionaryService dictionaryService;
|
private DictionaryService dictionaryService;
|
||||||
@@ -335,13 +339,42 @@ public class NodesImpl implements Nodes
|
|||||||
|
|
||||||
private Type getType(NodeRef nodeRef)
|
private Type getType(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
return getType(nodeService.getType(nodeRef));
|
return getType(nodeService.getType(nodeRef), nodeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type getType(QName type)
|
private Type getType(QName typeQName, NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
boolean isContainer = Boolean.valueOf((dictionaryService.isSubClass(type, ContentModel.TYPE_FOLDER) == true
|
if (dictionaryService.isSubClass(typeQName, ContentModel.TYPE_LINK))
|
||||||
&& !dictionaryService.isSubClass(type, ContentModel.TYPE_SYSTEM_FOLDER)));
|
{
|
||||||
|
// handle file/folder link type (we do not explicitly validate that the destination type matches)
|
||||||
|
if (dictionaryService.isSubClass(typeQName, ApplicationModel.TYPE_FOLDERLINK))
|
||||||
|
{
|
||||||
|
return Type.FOLDER;
|
||||||
|
}
|
||||||
|
else if (dictionaryService.isSubClass(typeQName, ApplicationModel.TYPE_FILELINK))
|
||||||
|
{
|
||||||
|
return Type.DOCUMENT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// cm:link (or other subclass)
|
||||||
|
NodeRef linkNodeRef = (NodeRef)nodeService.getProperty(nodeRef, ContentModel.PROP_LINK_DESTINATION);
|
||||||
|
if (linkNodeRef != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
typeQName = nodeService.getType(linkNodeRef);
|
||||||
|
}
|
||||||
|
catch (InvalidNodeRefException inre)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isContainer = (dictionaryService.isSubClass(typeQName, ContentModel.TYPE_FOLDER) &&
|
||||||
|
(! dictionaryService.isSubClass(typeQName, ContentModel.TYPE_SYSTEM_FOLDER)));
|
||||||
return isContainer ? Type.FOLDER : Type.DOCUMENT;
|
return isContainer ? Type.FOLDER : Type.DOCUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,7 +554,7 @@ public class NodesImpl implements Nodes
|
|||||||
return getFolderOrDocument(nodeRef, getParentNodeRef(nodeRef), typeQName, selectParam, null);
|
return getFolderOrDocument(nodeRef, getParentNodeRef(nodeRef), typeQName, selectParam, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node getFolderOrDocument(final NodeRef nodeRef, NodeRef parentNodeRef, QName typeQName, List<String> selectParam, Map<String,UserInfo> mapUserInfo)
|
private Node getFolderOrDocument(final NodeRef nodeRef, NodeRef parentNodeRef, QName nodeTypeQName, List<String> selectParam, Map<String,UserInfo> mapUserInfo)
|
||||||
{
|
{
|
||||||
if (mapUserInfo == null) {
|
if (mapUserInfo == null) {
|
||||||
mapUserInfo = new HashMap<>(2);
|
mapUserInfo = new HashMap<>(2);
|
||||||
@@ -533,7 +566,7 @@ public class NodesImpl implements Nodes
|
|||||||
pathInfo = lookupPathInfo(nodeRef);
|
pathInfo = lookupPathInfo(nodeRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type type = getType(typeQName);
|
Type type = getType(nodeTypeQName, nodeRef);
|
||||||
|
|
||||||
Node node;
|
Node node;
|
||||||
Map<QName, Serializable> properties = nodeService.getProperties(nodeRef);
|
Map<QName, Serializable> properties = nodeService.getProperties(nodeRef);
|
||||||
@@ -562,7 +595,13 @@ public class NodesImpl implements Nodes
|
|||||||
node.setAspectNames(mapFromNodeAspects(nodeService.getAspects(nodeRef)));
|
node.setAspectNames(mapFromNodeAspects(nodeService.getAspects(nodeRef)));
|
||||||
}
|
}
|
||||||
|
|
||||||
node.setNodeType(typeQName.toPrefixString(namespaceService));
|
if (selectParam.contains(PARAM_SELECT_ISLINK))
|
||||||
|
{
|
||||||
|
boolean isLink = typeMatches(nodeTypeQName, Collections.singleton(ContentModel.TYPE_LINK), null);
|
||||||
|
node.setIsLink(isLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
node.setNodeType(nodeTypeQName.toPrefixString(namespaceService));
|
||||||
node.setPath(pathInfo);
|
node.setPath(pathInfo);
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
@@ -677,7 +716,29 @@ 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 = QName.createQName(entry.getKey(), namespaceService);
|
||||||
nodeProps.put(propQName, (Serializable)entry.getValue());
|
|
||||||
|
PropertyDefinition pd = dictionaryService.getProperty(propQName);
|
||||||
|
if (pd != null)
|
||||||
|
{
|
||||||
|
Serializable value;
|
||||||
|
if (pd.getDataType().getName().equals(DataTypeDefinition.NODE_REF))
|
||||||
|
{
|
||||||
|
String nodeRefString = (String) entry.getValue();
|
||||||
|
if (! NodeRef.isNodeRef(nodeRefString))
|
||||||
|
{
|
||||||
|
value = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, nodeRefString);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = new NodeRef(nodeRefString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = (Serializable)entry.getValue();
|
||||||
|
}
|
||||||
|
nodeProps.put(propQName, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodeProps;
|
return nodeProps;
|
||||||
@@ -870,9 +931,12 @@ public class NodesImpl implements Nodes
|
|||||||
|
|
||||||
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<>(
|
||||||
if (! typeMatches(nodeTypeQName, contentAndFolders, null)) {
|
Arrays.asList(ContentModel.TYPE_FOLDER, ContentModel.TYPE_CONTENT, ContentModel.TYPE_LINK));
|
||||||
throw new InvalidArgumentException("Type of folder or content is expected: "+ nodeType);
|
|
||||||
|
if (! typeMatches(nodeTypeQName, contentAndFolders, null))
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException("Type of cm:folder cm:content or cm:link is expected: "+ nodeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isContent = typeMatches(nodeTypeQName, Collections.singleton(ContentModel.TYPE_CONTENT), null);
|
boolean isContent = typeMatches(nodeTypeQName, Collections.singleton(ContentModel.TYPE_CONTENT), null);
|
||||||
@@ -955,7 +1019,7 @@ public class NodesImpl implements Nodes
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("Cannot generalise the node type (from "+nodeTypeQName+" to "+destNodeTypeQName+")");
|
throw new IllegalArgumentException("Failed to change (specialise) the node type - from "+nodeTypeQName+" to "+destNodeTypeQName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -60,6 +60,7 @@ public class Node implements Comparable<Node>
|
|||||||
protected UserInfo modifiedByUser;
|
protected UserInfo modifiedByUser;
|
||||||
|
|
||||||
protected Boolean isFolder;
|
protected Boolean isFolder;
|
||||||
|
protected Boolean isLink;
|
||||||
|
|
||||||
protected NodeRef parentNodeRef;
|
protected NodeRef parentNodeRef;
|
||||||
protected PathInfo pathInfo;
|
protected PathInfo pathInfo;
|
||||||
@@ -238,7 +239,17 @@ public class Node implements Comparable<Node>
|
|||||||
|
|
||||||
public void setIsFolder(Boolean isFolder)
|
public void setIsFolder(Boolean isFolder)
|
||||||
{
|
{
|
||||||
this.isFolder=isFolder;
|
this.isFolder = isFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getIsLink()
|
||||||
|
{
|
||||||
|
return isLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsLink(Boolean isLink)
|
||||||
|
{
|
||||||
|
this.isLink = isLink;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean equals(Object other)
|
public boolean equals(Object other)
|
||||||
|
Reference in New Issue
Block a user