mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Merged FILE-FOLDER-API (5.2.0) to HEAD (5.2)
118663 jvonka: Merge from DEV/SABRE_JANV1 (part 1) File Folder API (PoC - experimental WIP) - relates to RA-613 - initial file folder CRUD including - * list folder children (minimal info by default) with sorting, paging & optional isFolder=true/false - * create folders or (empty) files - * get node info with id, name, nodeType, auditable props, properties (not sys:referencable), aspectNames, ... - * put node info - * put content (upload file) - * get content (download file) - * delete node (cascade for folder) - * support for well-known folder alias, -root-, -my-, -shared- - TODO add tests git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@126348 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -433,6 +433,10 @@
|
|||||||
<property name="nodeService" ref="NodeService" />
|
<property name="nodeService" ref="NodeService" />
|
||||||
<property name="dictionaryService" ref="DictionaryService" />
|
<property name="dictionaryService" ref="DictionaryService" />
|
||||||
<property name="cmisConnector" ref="CMISConnector" />
|
<property name="cmisConnector" ref="CMISConnector" />
|
||||||
|
<property name="fileFolderService" ref="FileFolderService" />
|
||||||
|
<property name="repositoryHelper" ref="repositoryHelper" />
|
||||||
|
<property name="namespaceService" ref="NamespaceService" />
|
||||||
|
<property name="permissionService" ref="PermissionService" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="Nodes" class="org.springframework.aop.framework.ProxyFactoryBean">
|
<bean id="Nodes" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||||
@@ -660,6 +664,10 @@
|
|||||||
<property name="nodeRatings" ref="NodeRatings" />
|
<property name="nodeRatings" ref="NodeRatings" />
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean class="org.alfresco.rest.api.nodes.NodeChildrenRelation">
|
||||||
|
<property name="nodes" ref="Nodes" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean class="org.alfresco.rest.api.nodes.NodeTagsRelation">
|
<bean class="org.alfresco.rest.api.nodes.NodeTagsRelation">
|
||||||
<property name="tags" ref="Tags" />
|
<property name="tags" ref="Tags" />
|
||||||
</bean>
|
</bean>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2012 Alfresco Software Limited.
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This file is part of Alfresco
|
* This file is part of Alfresco
|
||||||
*
|
*
|
||||||
@@ -23,10 +23,16 @@ import java.util.Set;
|
|||||||
import org.alfresco.rest.api.model.Document;
|
import org.alfresco.rest.api.model.Document;
|
||||||
import org.alfresco.rest.api.model.Folder;
|
import org.alfresco.rest.api.model.Folder;
|
||||||
import org.alfresco.rest.api.model.Node;
|
import org.alfresco.rest.api.model.Node;
|
||||||
|
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||||
|
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author steveglover
|
||||||
|
* @author janv
|
||||||
|
*/
|
||||||
public interface Nodes
|
public interface Nodes
|
||||||
{
|
{
|
||||||
NodeRef validateNode(StoreRef storeRef, String nodeId);
|
NodeRef validateNode(StoreRef storeRef, String nodeId);
|
||||||
@@ -54,4 +60,49 @@ public interface Nodes
|
|||||||
* @return Folder
|
* @return Folder
|
||||||
*/
|
*/
|
||||||
Folder getFolder(NodeRef nodeRef);
|
Folder getFolder(NodeRef nodeRef);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the folder or document representation (as appropriate) for the given node.
|
||||||
|
* @param nodeId String nodeId or well-known alias, eg. "-root-" or "-my-"
|
||||||
|
* @param parameters the {@link Parameters} object to get the parameters passed into the request
|
||||||
|
* including:
|
||||||
|
* - incPrimaryParent
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Node getFolderOrDocument(String nodeId, Parameters parameters);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of children of a parent folder.
|
||||||
|
* @param parentFolderNodeId String id of parent folder node or well-known alias, eg. "-root-" or "-my-"
|
||||||
|
* @param parameters the {@link Parameters} object to get the parameters passed into the request
|
||||||
|
* including:
|
||||||
|
* - filter, sort & paging params (where, orderBy, skipCount, maxItems)
|
||||||
|
* - incFiles, incFolders (both true by default)
|
||||||
|
* @return a paged list of {@code org.alfresco.rest.api.model.Node} objects
|
||||||
|
*/
|
||||||
|
CollectionWithPagingInfo<Node> getChildren(String parentFolderNodeId, Parameters parameters);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the given node. Note: will cascade delete for a folder.
|
||||||
|
* @param nodeId String id of node (folder or document)
|
||||||
|
*/
|
||||||
|
void deleteNode(String nodeId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param parentFolderNodeId
|
||||||
|
* @param folderInfo
|
||||||
|
* @param parameters
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Folder createFolder(String parentFolderNodeId, Folder folderInfo, Parameters parameters);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param nodeId
|
||||||
|
* @param entity
|
||||||
|
* @param parameters
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Node updateNode(String nodeId, Node entity, Parameters parameters);
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2012 Alfresco Software Limited.
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This file is part of Alfresco
|
* This file is part of Alfresco
|
||||||
*
|
*
|
||||||
@@ -36,7 +36,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.rest.api.impl;
|
package org.alfresco.rest.api.impl;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.io.Serializable;
|
||||||
|
import java.util.AbstractList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -45,27 +47,35 @@ import java.util.Set;
|
|||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.opencmis.CMISConnector;
|
import org.alfresco.opencmis.CMISConnector;
|
||||||
import org.alfresco.opencmis.CMISNodeInfoImpl;
|
import org.alfresco.query.PagingRequest;
|
||||||
|
import org.alfresco.query.PagingResults;
|
||||||
|
import org.alfresco.repo.model.Repository;
|
||||||
import org.alfresco.rest.api.Nodes;
|
import org.alfresco.rest.api.Nodes;
|
||||||
import org.alfresco.rest.api.model.Document;
|
import org.alfresco.rest.api.model.Document;
|
||||||
import org.alfresco.rest.api.model.Folder;
|
import org.alfresco.rest.api.model.Folder;
|
||||||
import org.alfresco.rest.api.model.Node;
|
import org.alfresco.rest.api.model.Node;
|
||||||
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.resource.parameters.CollectionWithPagingInfo;
|
||||||
|
import org.alfresco.rest.framework.resource.parameters.Paging;
|
||||||
|
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
|
import org.alfresco.service.cmr.model.FileInfo;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.repository.Path.Element;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
|
|
||||||
import org.apache.chemistry.opencmis.commons.data.Properties;
|
|
||||||
import org.apache.chemistry.opencmis.commons.data.PropertyData;
|
|
||||||
import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyStringImpl;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Centralises access to node services and maps between representations.
|
* Centralises access to file/folder/node services and maps between representations.
|
||||||
*
|
*
|
||||||
* @author steveglover
|
* @author steveglover
|
||||||
|
* @author janv
|
||||||
|
*
|
||||||
* @since publicapi1.0
|
* @since publicapi1.0
|
||||||
*/
|
*/
|
||||||
public class NodesImpl implements Nodes
|
public class NodesImpl implements Nodes
|
||||||
@@ -76,9 +86,16 @@ public class NodesImpl implements Nodes
|
|||||||
DOCUMENT, FOLDER;
|
DOCUMENT, FOLDER;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final static String PATH_ROOT = "-root-";
|
||||||
|
private final static String PATH_MY = "-my-";
|
||||||
|
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
private DictionaryService dictionaryService;
|
private DictionaryService dictionaryService;
|
||||||
private CMISConnector cmisConnector;
|
private CMISConnector cmisConnector;
|
||||||
|
private FileFolderService fileFolderService;
|
||||||
|
private Repository repositoryHelper;
|
||||||
|
private NamespaceService namespaceService;
|
||||||
|
private PermissionService permissionService;
|
||||||
|
|
||||||
public void setDictionaryService(DictionaryService dictionaryService)
|
public void setDictionaryService(DictionaryService dictionaryService)
|
||||||
{
|
{
|
||||||
@@ -95,6 +112,26 @@ public class NodesImpl implements Nodes
|
|||||||
this.cmisConnector = cmisConnector;
|
this.cmisConnector = cmisConnector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setFileFolderService(FileFolderService fileFolderService)
|
||||||
|
{
|
||||||
|
this.fileFolderService = fileFolderService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRepositoryHelper(Repository repositoryHelper)
|
||||||
|
{
|
||||||
|
this.repositoryHelper = repositoryHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNamespaceService(NamespaceService namespaceService)
|
||||||
|
{
|
||||||
|
this.namespaceService = namespaceService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPermissionService(PermissionService permissionService)
|
||||||
|
{
|
||||||
|
this.permissionService = permissionService;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Note: assumes workspace://SpacesStore
|
* Note: assumes workspace://SpacesStore
|
||||||
@@ -170,23 +207,29 @@ public class NodesImpl implements Nodes
|
|||||||
{
|
{
|
||||||
NodeRef nodeRef = validateNode(nodeId);
|
NodeRef nodeRef = validateNode(nodeId);
|
||||||
|
|
||||||
return new Node(nodeRef, nodeService.getProperties(nodeRef));
|
return new Node(nodeRef, nodeService.getProperties(nodeRef), namespaceService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Node getNode(NodeRef nodeRef)
|
public Node getNode(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
return new Node(nodeRef, nodeService.getProperties(nodeRef));
|
return new Node(nodeRef, nodeService.getProperties(nodeRef), namespaceService);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type getType(NodeRef nodeRef)
|
private Type getType(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
QName type = nodeService.getType(nodeRef);
|
return getType(nodeService.getType(nodeRef));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Type getType(QName type)
|
||||||
|
{
|
||||||
boolean isContainer = Boolean.valueOf((dictionaryService.isSubClass(type, ContentModel.TYPE_FOLDER) == true &&
|
boolean isContainer = Boolean.valueOf((dictionaryService.isSubClass(type, ContentModel.TYPE_FOLDER) == true &&
|
||||||
!dictionaryService.isSubClass(type, ContentModel.TYPE_SYSTEM_FOLDER)));
|
!dictionaryService.isSubClass(type, ContentModel.TYPE_SYSTEM_FOLDER)));
|
||||||
return isContainer ? Type.FOLDER : Type.DOCUMENT;
|
return isContainer ? Type.FOLDER : Type.DOCUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
// TODO filter CMIS properties
|
// TODO filter CMIS properties
|
||||||
|
// TODO review & optimise - do we really need to go via CMIS properties !?
|
||||||
private Properties getCMISProperties(NodeRef nodeRef)
|
private Properties getCMISProperties(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
CMISNodeInfoImpl nodeInfo = cmisConnector.createNodeInfo(nodeRef);
|
CMISNodeInfoImpl nodeInfo = cmisConnector.createNodeInfo(nodeRef);
|
||||||
@@ -228,6 +271,7 @@ public class NodesImpl implements Nodes
|
|||||||
|
|
||||||
return wrapProperties;
|
return wrapProperties;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the public api representation of a document.
|
* Returns the public api representation of a document.
|
||||||
@@ -237,10 +281,11 @@ public class NodesImpl implements Nodes
|
|||||||
public Document getDocument(NodeRef nodeRef)
|
public Document getDocument(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
Type type = getType(nodeRef);
|
Type type = getType(nodeRef);
|
||||||
if(type.equals(Type.DOCUMENT))
|
if (type.equals(Type.DOCUMENT))
|
||||||
{
|
{
|
||||||
Properties properties = getCMISProperties(nodeRef);
|
//Properties properties = getCMISProperties(nodeRef);
|
||||||
Document doc = new Document(nodeRef, properties);
|
Map<QName, Serializable> properties = nodeService.getProperties(nodeRef);
|
||||||
|
Document doc = new Document(nodeRef, properties, namespaceService);
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -257,10 +302,11 @@ public class NodesImpl implements Nodes
|
|||||||
public Folder getFolder(NodeRef nodeRef)
|
public Folder getFolder(NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
Type type = getType(nodeRef);
|
Type type = getType(nodeRef);
|
||||||
if(type.equals(Type.FOLDER))
|
if (type.equals(Type.FOLDER))
|
||||||
{
|
{
|
||||||
Properties properties = getCMISProperties(nodeRef);
|
//Properties properties = getCMISProperties(nodeRef);
|
||||||
Folder folder = new Folder(nodeRef, properties);
|
Map<QName, Serializable> properties = nodeService.getProperties(nodeRef);
|
||||||
|
Folder folder = new Folder(nodeRef, properties, namespaceService);
|
||||||
return folder;
|
return folder;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -268,4 +314,223 @@ public class NodesImpl implements Nodes
|
|||||||
throw new InvalidArgumentException("Node is not a folder");
|
throw new InvalidArgumentException("Node is not a folder");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NodeRef validateOrLookupNode(String nodeId, String path) {
|
||||||
|
final NodeRef parentNodeRef;
|
||||||
|
if (nodeId.equals(PATH_ROOT))
|
||||||
|
{
|
||||||
|
parentNodeRef = repositoryHelper.getCompanyHome();
|
||||||
|
}
|
||||||
|
else if (nodeId.equals(PATH_MY))
|
||||||
|
{
|
||||||
|
NodeRef person = repositoryHelper.getPerson();
|
||||||
|
if (person == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Unexpected: cannot use "+PATH_MY);
|
||||||
|
}
|
||||||
|
parentNodeRef = repositoryHelper.getUserHome(person);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parentNodeRef = validateNode(nodeId);
|
||||||
|
}
|
||||||
|
return parentNodeRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node getFolderOrDocument(String nodeId, Parameters parameters)
|
||||||
|
{
|
||||||
|
String path = parameters.getParameter("path");
|
||||||
|
|
||||||
|
boolean incPrimaryPath = false;
|
||||||
|
String str = parameters.getParameter("incPrimaryPath");
|
||||||
|
if (str != null) {
|
||||||
|
incPrimaryPath = new Boolean(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeRef nodeRef = validateOrLookupNode(nodeId, path);
|
||||||
|
QName typeQName = nodeService.getType(nodeRef);
|
||||||
|
return getFolderOrDocument(nodeRef, typeQName, incPrimaryPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node getFolderOrDocument(NodeRef nodeRef, QName typeQName,boolean incPrimaryPath)
|
||||||
|
{
|
||||||
|
String primaryPath = null;
|
||||||
|
if (incPrimaryPath)
|
||||||
|
{
|
||||||
|
org.alfresco.service.cmr.repository.Path pp = nodeService.getPath(nodeRef);
|
||||||
|
|
||||||
|
// Remove "app:company_home" (2nd element)
|
||||||
|
int ppSize = pp.size();
|
||||||
|
if (ppSize > 1) {
|
||||||
|
if (ppSize == 2) {
|
||||||
|
pp = pp.subPath(0, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Element rootElement = pp.get(0);
|
||||||
|
pp = pp.subPath(2, ppSize-1).prepend(rootElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
primaryPath = pp.toDisplayPath(nodeService, permissionService); // note: slower (hence optional when getting node info)
|
||||||
|
}
|
||||||
|
|
||||||
|
Node node = null;
|
||||||
|
Type type = getType(typeQName);
|
||||||
|
|
||||||
|
Map<QName, Serializable> properties = nodeService.getProperties(nodeRef);
|
||||||
|
|
||||||
|
if (type.equals(Type.DOCUMENT))
|
||||||
|
{
|
||||||
|
//Properties properties = getCMISProperties(nodeRef);
|
||||||
|
node = new Document(nodeRef, properties, namespaceService);
|
||||||
|
}
|
||||||
|
else if (type.equals(Type.FOLDER))
|
||||||
|
{
|
||||||
|
// container/folder
|
||||||
|
//Properties properties = getCMISProperties(nodeRef);
|
||||||
|
node = new Folder(nodeRef, properties, namespaceService);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException("Node is not a folder or file");
|
||||||
|
}
|
||||||
|
|
||||||
|
node.setType(typeQName.toPrefixString(namespaceService));
|
||||||
|
node.setPrimaryPath(primaryPath); // optional - can be null
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CollectionWithPagingInfo<Node> getChildren(String parentFolderNodeId, Parameters parameters)
|
||||||
|
{
|
||||||
|
// TODO consider using: where=(exists(target/file)) / where=(exists(target/file))
|
||||||
|
// instead of: includeFiles=true / includeFolders=true
|
||||||
|
|
||||||
|
boolean includeFolders = true;
|
||||||
|
String str = parameters.getParameter("includeFolders");
|
||||||
|
if (str != null) {
|
||||||
|
includeFolders = new Boolean(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean includeFiles = true;
|
||||||
|
str = parameters.getParameter("includeFiles");
|
||||||
|
if (str != null) {
|
||||||
|
includeFiles = new Boolean(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
String path = parameters.getParameter("path");
|
||||||
|
|
||||||
|
Paging paging = parameters.getPaging();
|
||||||
|
final NodeRef parentNodeRef = validateOrLookupNode(parentFolderNodeId, path);
|
||||||
|
|
||||||
|
final Set<QName> folders = new HashSet<>(Arrays.asList(ContentModel.TYPE_FOLDER));
|
||||||
|
if (! nodeMatches(parentNodeRef, folders, null))
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException("NodeId of folder is expected");
|
||||||
|
}
|
||||||
|
|
||||||
|
PagingRequest pagingRequest = Util.getPagingRequest(paging);
|
||||||
|
|
||||||
|
final PagingResults<FileInfo> pagingResults = fileFolderService.list(parentNodeRef, includeFiles, includeFolders, null, null, pagingRequest);
|
||||||
|
|
||||||
|
final List<FileInfo> page = pagingResults.getPage();
|
||||||
|
List<Node> nodes = new AbstractList<Node>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Node get(int index)
|
||||||
|
{
|
||||||
|
FileInfo fInfo = page.get(index);
|
||||||
|
return getFolderOrDocument(fInfo.getNodeRef(), fInfo.getType(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return page.size();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return CollectionWithPagingInfo.asPaged(paging, nodes, pagingResults.hasMoreItems(), pagingResults.getTotalResultCount().getFirst());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteNode(String nodeId)
|
||||||
|
{
|
||||||
|
NodeRef nodeRef = validateNode(nodeId);
|
||||||
|
fileFolderService.delete(nodeRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Folder createFolder(String parentFolderNodeId, Folder folderInfo, Parameters parameters)
|
||||||
|
{
|
||||||
|
final NodeRef parentNodeRef = validateNode(parentFolderNodeId);
|
||||||
|
|
||||||
|
final Set<QName> folders = new HashSet<>(Arrays.asList(ContentModel.TYPE_FOLDER));
|
||||||
|
if (! nodeMatches(parentNodeRef, folders, null))
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException("NodeId of folder is expected");
|
||||||
|
}
|
||||||
|
|
||||||
|
String folderName = folderInfo.getName();
|
||||||
|
String folderType = folderInfo.getType();
|
||||||
|
if (folderType == null) {
|
||||||
|
folderType = "cm:folder";
|
||||||
|
}
|
||||||
|
|
||||||
|
QName folderTypeQName = QName.resolveToQName(namespaceService, folderType);
|
||||||
|
|
||||||
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>(10);
|
||||||
|
|
||||||
|
props.put(ContentModel.PROP_NAME, folderName);
|
||||||
|
|
||||||
|
String title = folderInfo.getTitle();
|
||||||
|
if ((title != null) && (! title.isEmpty())) {
|
||||||
|
props.put(ContentModel.PROP_TITLE, title);
|
||||||
|
}
|
||||||
|
|
||||||
|
String description = folderInfo.getDescription();
|
||||||
|
if ((description != null) && (! description.isEmpty())) {
|
||||||
|
props.put(ContentModel.PROP_DESCRIPTION, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO other custom properties !!
|
||||||
|
|
||||||
|
QName assocQName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, QName.createValidLocalName(folderName));
|
||||||
|
|
||||||
|
NodeRef nodeRef = nodeService.createNode(parentNodeRef, ContentModel.ASSOC_CONTAINS, assocQName, folderTypeQName, props).getChildRef();
|
||||||
|
|
||||||
|
return (Folder) getFolderOrDocument(nodeRef.getId(), parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Node updateNode(String nodeId, Node nodeInfo, Parameters parameters) {
|
||||||
|
|
||||||
|
final NodeRef nodeRef = validateNode(nodeId);
|
||||||
|
|
||||||
|
final Set<QName> fileOrFolder = new HashSet<>(Arrays.asList(ContentModel.TYPE_FOLDER, ContentModel.TYPE_CONTENT));
|
||||||
|
if (! nodeMatches(nodeRef, fileOrFolder, null))
|
||||||
|
{
|
||||||
|
throw new InvalidArgumentException("NodeId of file or folder is expected");
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<QName, Serializable> props = new HashMap<>(10);
|
||||||
|
|
||||||
|
String name = nodeInfo.getName();
|
||||||
|
if ((name != null) && (! name.isEmpty())) {
|
||||||
|
// note: this is equivalent of a rename within target folder
|
||||||
|
props.put(ContentModel.PROP_NAME, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
String title = nodeInfo.getTitle();
|
||||||
|
if ((title != null) && (! title.isEmpty())) {
|
||||||
|
props.put(ContentModel.PROP_TITLE, title);
|
||||||
|
}
|
||||||
|
|
||||||
|
String description = nodeInfo.getDescription();
|
||||||
|
if ((description != null) && (! description.isEmpty())) {
|
||||||
|
props.put(ContentModel.PROP_DESCRIPTION, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.size() > 0) {
|
||||||
|
nodeService.addProperties(nodeRef, props);
|
||||||
|
}
|
||||||
|
|
||||||
|
return getFolderOrDocument(nodeRef.getId(), parameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,6 +5,7 @@ import java.math.BigInteger;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.apache.chemistry.opencmis.commons.PropertyIds;
|
import org.apache.chemistry.opencmis.commons.PropertyIds;
|
||||||
import org.apache.chemistry.opencmis.commons.data.Properties;
|
import org.apache.chemistry.opencmis.commons.data.Properties;
|
||||||
@@ -14,6 +15,7 @@ import org.apache.chemistry.opencmis.commons.data.PropertyData;
|
|||||||
* Representation of a document node.
|
* Representation of a document node.
|
||||||
*
|
*
|
||||||
* @author steveglover
|
* @author steveglover
|
||||||
|
* @author janv
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Document extends Node
|
public class Document extends Node
|
||||||
@@ -27,6 +29,7 @@ public class Document extends Node
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
public Document(NodeRef nodeRef, Properties properties)
|
public Document(NodeRef nodeRef, Properties properties)
|
||||||
{
|
{
|
||||||
super(nodeRef, properties);
|
super(nodeRef, properties);
|
||||||
@@ -36,10 +39,11 @@ public class Document extends Node
|
|||||||
this.sizeInBytes = (BigInteger)getValue(props, PropertyIds.CONTENT_STREAM_LENGTH);
|
this.sizeInBytes = (BigInteger)getValue(props, PropertyIds.CONTENT_STREAM_LENGTH);
|
||||||
this.versionLabel = (String)getValue(props, PropertyIds.VERSION_LABEL);
|
this.versionLabel = (String)getValue(props, PropertyIds.VERSION_LABEL);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
public Document(NodeRef nodeRef, Map<QName, Serializable> nodeProps)
|
public Document(NodeRef nodeRef, Map<QName, Serializable> nodeProps, NamespaceService namespaceService)
|
||||||
{
|
{
|
||||||
super(nodeRef, nodeProps);
|
super(nodeRef, nodeProps, namespaceService);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMimeType()
|
public String getMimeType()
|
||||||
@@ -57,6 +61,11 @@ public class Document extends Node
|
|||||||
return versionLabel;
|
return versionLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean getIsFolder()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
|
@@ -4,6 +4,7 @@ import java.io.Serializable;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.apache.chemistry.opencmis.commons.data.Properties;
|
import org.apache.chemistry.opencmis.commons.data.Properties;
|
||||||
|
|
||||||
@@ -11,6 +12,7 @@ import org.apache.chemistry.opencmis.commons.data.Properties;
|
|||||||
* Representation of a folder node.
|
* Representation of a folder node.
|
||||||
*
|
*
|
||||||
* @author steveglover
|
* @author steveglover
|
||||||
|
* @author janv
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class Folder extends Node
|
public class Folder extends Node
|
||||||
@@ -20,14 +22,21 @@ public class Folder extends Node
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
public Folder(NodeRef nodeRef, Properties properties)
|
public Folder(NodeRef nodeRef, Properties properties)
|
||||||
{
|
{
|
||||||
super(nodeRef, properties);
|
super(nodeRef, properties);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
public Folder(NodeRef nodeRef, Map<QName, Serializable> nodeProps)
|
public Folder(NodeRef nodeRef, Map<QName, Serializable> nodeProps, NamespaceService namespaceService)
|
||||||
{
|
{
|
||||||
super(nodeRef, nodeProps);
|
super(nodeRef, nodeProps, namespaceService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getIsFolder()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2012 Alfresco Software Limited.
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This file is part of Alfresco
|
* This file is part of Alfresco
|
||||||
*
|
*
|
||||||
@@ -19,13 +19,19 @@
|
|||||||
package org.alfresco.rest.api.model;
|
package org.alfresco.rest.api.model;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.rest.framework.resource.UniqueId;
|
import org.alfresco.rest.framework.resource.UniqueId;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.util.EqualsHelper;
|
import org.alfresco.util.EqualsHelper;
|
||||||
import org.apache.chemistry.opencmis.commons.PropertyIds;
|
import org.apache.chemistry.opencmis.commons.PropertyIds;
|
||||||
@@ -37,20 +43,45 @@ import org.apache.chemistry.opencmis.commons.data.PropertyData;
|
|||||||
*
|
*
|
||||||
* @author steveglover
|
* @author steveglover
|
||||||
* @author Gethin James
|
* @author Gethin James
|
||||||
|
* @author janv
|
||||||
*/
|
*/
|
||||||
public class Node implements Comparable<Node>
|
public class Node implements Comparable<Node>
|
||||||
{
|
{
|
||||||
protected NodeRef nodeRef;
|
protected NodeRef nodeRef;
|
||||||
protected String name;
|
protected String name;
|
||||||
protected String title;
|
protected String title;
|
||||||
protected NodeRef guid;
|
protected NodeRef guid; // TODO review - do we need for favorites (backwards compat') ?
|
||||||
protected String description;
|
protected String description;
|
||||||
protected Date createdAt;
|
protected Date createdAt;
|
||||||
protected Date modifiedAt;
|
protected Date modifiedAt;
|
||||||
protected String createdBy;
|
protected String createdBy;
|
||||||
protected String modifiedBy;
|
protected String modifiedBy;
|
||||||
|
|
||||||
public Node(NodeRef nodeRef, Map<QName, Serializable> nodeProps)
|
protected String primaryPath;
|
||||||
|
protected String prefixTypeQName;
|
||||||
|
|
||||||
|
protected Map<String, Serializable> props;
|
||||||
|
|
||||||
|
private static final List<QName> EXCLUDED_PROPS = Arrays.asList(
|
||||||
|
ContentModel.PROP_NAME,
|
||||||
|
ContentModel.PROP_TITLE,
|
||||||
|
ContentModel.PROP_DESCRIPTION,
|
||||||
|
ContentModel.PROP_MODIFIER,
|
||||||
|
ContentModel.PROP_MODIFIED,
|
||||||
|
ContentModel.PROP_CREATOR,
|
||||||
|
ContentModel.PROP_CREATED,
|
||||||
|
ContentModel.PROP_CONTENT,
|
||||||
|
ContentModel.PROP_LOCALE,
|
||||||
|
ContentModel.PROP_NODE_UUID,
|
||||||
|
ContentModel.PROP_STORE_IDENTIFIER,
|
||||||
|
ContentModel.PROP_STORE_PROTOCOL,
|
||||||
|
ContentModel.PROP_NODE_DBID,
|
||||||
|
ContentModel.PROP_INITIAL_VERSION,
|
||||||
|
ContentModel.PROP_AUTO_VERSION_PROPS,
|
||||||
|
ContentModel.PROP_AUTO_VERSION);
|
||||||
|
|
||||||
|
// TODO fixme !
|
||||||
|
public Node(NodeRef nodeRef, Map<QName, Serializable> nodeProps, NamespaceService namespaceService)
|
||||||
{
|
{
|
||||||
if(nodeRef == null)
|
if(nodeRef == null)
|
||||||
{
|
{
|
||||||
@@ -58,7 +89,7 @@ public class Node implements Comparable<Node>
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.nodeRef = nodeRef;
|
this.nodeRef = nodeRef;
|
||||||
mapProperties(nodeProps);
|
mapProperties(nodeProps, namespaceService);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Object getValue(Map<String, PropertyData<?>> props, String name)
|
protected Object getValue(Map<String, PropertyData<?>> props, String name)
|
||||||
@@ -68,14 +99,19 @@ public class Node implements Comparable<Node>
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
public Node(NodeRef nodeRef, Properties properties)
|
public Node(NodeRef nodeRef, Properties properties)
|
||||||
{
|
{
|
||||||
this.nodeRef = nodeRef;
|
this.nodeRef = nodeRef;
|
||||||
|
|
||||||
Map<String, PropertyData<?>> props = properties.getProperties();
|
Map<String, PropertyData<?>> props = properties.getProperties();
|
||||||
|
|
||||||
|
this.guid = nodeRef;
|
||||||
|
|
||||||
this.name = (String)getValue(props, PropertyIds.NAME);
|
this.name = (String)getValue(props, PropertyIds.NAME);
|
||||||
this.title = (String)getValue(props, ContentModel.PROP_TITLE.toString());
|
this.title = (String)getValue(props, ContentModel.PROP_TITLE.toString());
|
||||||
this.guid = nodeRef;
|
this.description = (String)getValue(props, PropertyIds.DESCRIPTION);
|
||||||
|
|
||||||
GregorianCalendar cal = (GregorianCalendar)getValue(props, PropertyIds.CREATION_DATE);
|
GregorianCalendar cal = (GregorianCalendar)getValue(props, PropertyIds.CREATION_DATE);
|
||||||
this.createdAt = cal.getTime();
|
this.createdAt = cal.getTime();
|
||||||
cal = (GregorianCalendar)getValue(props, PropertyIds.LAST_MODIFICATION_DATE);
|
cal = (GregorianCalendar)getValue(props, PropertyIds.LAST_MODIFICATION_DATE);
|
||||||
@@ -83,21 +119,34 @@ public class Node implements Comparable<Node>
|
|||||||
this.createdBy = (String)getValue(props, PropertyIds.CREATED_BY);
|
this.createdBy = (String)getValue(props, PropertyIds.CREATED_BY);
|
||||||
this.modifiedBy = (String)getValue(props, PropertyIds.LAST_MODIFIED_BY);
|
this.modifiedBy = (String)getValue(props, PropertyIds.LAST_MODIFIED_BY);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
public Node()
|
public Node()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void mapProperties(Map<QName, Serializable> nodeProps)
|
protected void mapProperties(Map<QName, Serializable> nodeProps, NamespaceService namespaceService)
|
||||||
{
|
{
|
||||||
|
// TODO review backwards compat' for favorites & others (eg. set guid explicitly where still needed)
|
||||||
|
//this.guid = nodeRef;
|
||||||
|
|
||||||
this.name = (String)nodeProps.get(ContentModel.PROP_NAME);
|
this.name = (String)nodeProps.get(ContentModel.PROP_NAME);
|
||||||
this.guid = nodeRef;
|
|
||||||
this.title = (String)nodeProps.get(ContentModel.PROP_TITLE);
|
this.title = (String)nodeProps.get(ContentModel.PROP_TITLE);
|
||||||
|
this.description = (String)nodeProps.get(ContentModel.PROP_DESCRIPTION);
|
||||||
|
|
||||||
this.createdAt = (Date)nodeProps.get(ContentModel.PROP_CREATED);
|
this.createdAt = (Date)nodeProps.get(ContentModel.PROP_CREATED);
|
||||||
this.createdBy = (String)nodeProps.get(ContentModel.PROP_CREATOR);
|
this.createdBy = (String)nodeProps.get(ContentModel.PROP_CREATOR);
|
||||||
this.modifiedAt = (Date)nodeProps.get(ContentModel.PROP_MODIFIED);
|
this.modifiedAt = (Date)nodeProps.get(ContentModel.PROP_MODIFIED);
|
||||||
this.modifiedBy = (String)nodeProps.get(ContentModel.PROP_MODIFIER);
|
this.modifiedBy = (String)nodeProps.get(ContentModel.PROP_MODIFIER);
|
||||||
this.description = (String)nodeProps.get(ContentModel.PROP_DESCRIPTION);
|
|
||||||
|
this.props = new HashMap<>(nodeProps.size());
|
||||||
|
|
||||||
|
for (Map.Entry<QName, Serializable> entry : nodeProps.entrySet()) {
|
||||||
|
QName propQName = entry.getKey();
|
||||||
|
if (! EXCLUDED_PROPS.contains(propQName)) {
|
||||||
|
props.put(entry.getKey().toPrefixString(namespaceService), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGuid(NodeRef guid)
|
public void setGuid(NodeRef guid)
|
||||||
@@ -175,6 +224,30 @@ public class Node implements Comparable<Node>
|
|||||||
this.createdBy = createdBy;
|
this.createdBy = createdBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getPrimaryPath()
|
||||||
|
{
|
||||||
|
return primaryPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrimaryPath(String primaryPath)
|
||||||
|
{
|
||||||
|
this.primaryPath = primaryPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType()
|
||||||
|
{
|
||||||
|
return prefixTypeQName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String prefixType)
|
||||||
|
{
|
||||||
|
this.prefixTypeQName = prefixType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map getProperties() {
|
||||||
|
return this.props;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean equals(Object other)
|
public boolean equals(Object other)
|
||||||
{
|
{
|
||||||
if(this == other)
|
if(this == other)
|
||||||
@@ -200,9 +273,9 @@ public class Node implements Comparable<Node>
|
|||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "Node [nodeRef=" + nodeRef + ", name=" + name + ", title="
|
return "Node [nodeRef=" + nodeRef + ", type=" + prefixTypeQName + ", name=" + name + ", title="
|
||||||
+ title + ", description=" + description + ", createdAt="
|
+ title + ", description=" + description + ", createdAt="
|
||||||
+ createdAt + ", modifiedAt=" + modifiedAt + ", createdBy=" + createdBy + ", modifiedBy="
|
+ createdAt + ", modifiedAt=" + modifiedAt + ", createdBy=" + createdBy + ", modifiedBy="
|
||||||
+ modifiedBy + "]";
|
+ modifiedBy + ", primaryPath =" + primaryPath +"]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
|
*
|
||||||
|
* This file is part of Alfresco
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package org.alfresco.rest.api.nodes;
|
||||||
|
|
||||||
|
import org.alfresco.rest.api.Nodes;
|
||||||
|
import org.alfresco.rest.api.model.Folder;
|
||||||
|
import org.alfresco.rest.api.model.Node;
|
||||||
|
import org.alfresco.rest.framework.WebApiDescription;
|
||||||
|
import org.alfresco.rest.framework.resource.RelationshipResource;
|
||||||
|
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
|
||||||
|
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
|
||||||
|
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||||
|
import org.alfresco.util.ParameterCheck;
|
||||||
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO ... work-in-progress
|
||||||
|
*
|
||||||
|
* @author janv
|
||||||
|
*/
|
||||||
|
@RelationshipResource(name = "children", entityResource = NodesEntityResource.class, title = "Folder children")
|
||||||
|
public class NodeChildrenRelation implements RelationshipResourceAction.Read<Node>, RelationshipResourceAction.Create<Folder>, InitializingBean
|
||||||
|
{
|
||||||
|
private Nodes nodes;
|
||||||
|
|
||||||
|
public void setNodes(Nodes nodes)
|
||||||
|
{
|
||||||
|
this.nodes = nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet()
|
||||||
|
{
|
||||||
|
ParameterCheck.mandatory("nodes", this.nodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List folder children - returns a filtered/sorted/paged list of nodes that are immediate children of the parent folder
|
||||||
|
*
|
||||||
|
* TODO filtering, sorting, ...
|
||||||
|
* 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:
|
||||||
|
*
|
||||||
|
* - incFiles
|
||||||
|
* - incFolders
|
||||||
|
*
|
||||||
|
* - properties
|
||||||
|
* - where
|
||||||
|
* - orderBy
|
||||||
|
*
|
||||||
|
* - skipCount
|
||||||
|
* - maxItems
|
||||||
|
*
|
||||||
|
* If parentFolderNodeId does not exist, EntityNotFoundException (status 404).
|
||||||
|
* If parentFolderNodeId does not represent a folder, InvalidArgumentException (status 400).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@WebApiDescription(title = "Return a paged list of nodes for the document/folder identified by parentFolderNodeId")
|
||||||
|
public CollectionWithPagingInfo<Node> readAll(String parentFolderNodeId, Parameters parameters)
|
||||||
|
{
|
||||||
|
return nodes.getChildren(parentFolderNodeId, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create one or more sub-folders below parent folder. Note: can also use well-known alias, eg. -root- or -my-
|
||||||
|
*
|
||||||
|
* TODO also consider option to create path - eg. by passing name path in name (see Sparta API as an example) ... or should this be a separate API ?
|
||||||
|
*
|
||||||
|
* If parentFolderNodeId does not exist, EntityNotFoundException (status 404).
|
||||||
|
* If parentFolderNodeId does not represent a folder, InvalidArgumentException (status 400).
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@WebApiDescription(title="Create one (or more) folder(s) as a child of folder identified by parentFolderNodeId")
|
||||||
|
public List<Folder> create(String parentFolderNodeId, List<Folder> folderInfos, Parameters parameters)
|
||||||
|
{
|
||||||
|
List<Folder> result = new ArrayList<>(folderInfos.size());
|
||||||
|
|
||||||
|
for (Folder folderInfo : folderInfos)
|
||||||
|
{
|
||||||
|
result.add(nodes.createFolder(parentFolderNodeId, folderInfo, parameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2005-2012 Alfresco Software Limited.
|
* Copyright (C) 2005-2015 Alfresco Software Limited.
|
||||||
*
|
*
|
||||||
* This file is part of Alfresco
|
* This file is part of Alfresco
|
||||||
*
|
*
|
||||||
@@ -19,7 +19,12 @@
|
|||||||
package org.alfresco.rest.api.nodes;
|
package org.alfresco.rest.api.nodes;
|
||||||
|
|
||||||
import org.alfresco.rest.api.Nodes;
|
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.resource.EntityResource;
|
import org.alfresco.rest.framework.resource.EntityResource;
|
||||||
|
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
|
||||||
|
import org.alfresco.rest.framework.resource.parameters.Parameters;
|
||||||
import org.alfresco.util.ParameterCheck;
|
import org.alfresco.util.ParameterCheck;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
@@ -28,9 +33,10 @@ import org.springframework.beans.factory.InitializingBean;
|
|||||||
*
|
*
|
||||||
* @author sglover
|
* @author sglover
|
||||||
* @author Gethin James
|
* @author Gethin James
|
||||||
|
* @author janv
|
||||||
*/
|
*/
|
||||||
@EntityResource(name="nodes", title = "Nodes")
|
@EntityResource(name="nodes", title = "Nodes")
|
||||||
public class NodesEntityResource implements InitializingBean
|
public class NodesEntityResource implements EntityResourceAction.ReadById<Node>, EntityResourceAction.Delete, EntityResourceAction.Update<Node>, InitializingBean
|
||||||
{
|
{
|
||||||
private Nodes nodes;
|
private Nodes nodes;
|
||||||
|
|
||||||
@@ -44,4 +50,53 @@ public class NodesEntityResource implements InitializingBean
|
|||||||
{
|
{
|
||||||
ParameterCheck.mandatory("nodes", this.nodes);
|
ParameterCheck.mandatory("nodes", this.nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns information regarding the node 'nodeId' - folder or document
|
||||||
|
*
|
||||||
|
* TODO other metadata/properties & permissions etc ...
|
||||||
|
*
|
||||||
|
* @param nodeId String id of node (folder or document) - will also accept well-known aliases, eg. "-root-" or "-my-"
|
||||||
|
*
|
||||||
|
* Optional parameters:
|
||||||
|
* - path
|
||||||
|
* - incPrimaryPath
|
||||||
|
*/
|
||||||
|
@WebApiDescription(title = "Get Node Information", description = "Get information for the node with id 'nodeId'")
|
||||||
|
@WebApiParam(name = "nodeId", title = "The node id")
|
||||||
|
public Node readById(String nodeId, Parameters parameters)
|
||||||
|
{
|
||||||
|
return nodes.getFolderOrDocument(nodeId, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update info on the node 'nodeId' - folder or document
|
||||||
|
*
|
||||||
|
* Initially, name, title &/or description. Note: changing name is a "rename" (and must be unique within the current parent folder).
|
||||||
|
*
|
||||||
|
* TODO other metadata/properties & permissions etc ...
|
||||||
|
*
|
||||||
|
* @param nodeId String nodeId of node (folder or document)
|
||||||
|
* @param nodeInfo node entity with info to update (eg. name, title, description ...)
|
||||||
|
* @param parameters
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@WebApiDescription(title="Updates a node (file or folder) with id 'nodeId'")
|
||||||
|
public Node update(String nodeId, Node nodeInfo, Parameters parameters)
|
||||||
|
{
|
||||||
|
return nodes.updateNode(nodeId, nodeInfo, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the given node. Note: will cascade delete for a folder.
|
||||||
|
*
|
||||||
|
* @param nodeId String id of node (folder or document)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@WebApiDescription(title = "Delete Node", description="Delete the file or folder with id 'nodeId'. Folder will cascade delete")
|
||||||
|
public void delete(String nodeId, Parameters parameters)
|
||||||
|
{
|
||||||
|
nodes.deleteNode(nodeId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -138,7 +138,11 @@ public class ResourceDictionaryBuilder
|
|||||||
ResourceDictionary rd = new ResourceDictionary();
|
ResourceDictionary rd = new ResourceDictionary();
|
||||||
processResources(rd,apiMap,null);
|
processResources(rd,apiMap,null);
|
||||||
processTopLevelApis(rd);
|
processTopLevelApis(rd);
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug(rd.prettyPrint());
|
logger.debug(rd.prettyPrint());
|
||||||
|
}
|
||||||
|
|
||||||
return rd;
|
return rd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user