Merged CMIS063 to HEAD

15463: Fixed MOB-1100: Update Web Services to 0.62 final

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@17232 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
David Caruana
2009-10-29 16:31:49 +00:00
parent e90b63f20b
commit babca05012
168 changed files with 10960 additions and 6673 deletions

View File

@@ -44,7 +44,7 @@ public class PropertyFilter
private static final int MINIMAL_ALLOWED_STRUCTURE_SIZE = 1;
private static final String MATCH_ALL_FILTER = "*";
private static final Pattern PROPERTY_FILTER_REGEX = Pattern.compile("^(\\*)|([\\p{Alpha}\\p{Digit}_]+((,){1}( )*[\\p{Alpha}\\p{Digit}_]+)*)$");
private static final Pattern PROPERTY_FILTER_REGEX = Pattern.compile("^(\\*)|(((cmis\\:)?[\\p{Alpha}\\p{Digit}_]+)((,){1}( )*((cmis\\:)?[\\p{Alpha}\\p{Digit}_]+))*)$");
private Set<String> properties;

View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2005-2009 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have recieved a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.repo.cmis.ws;
import java.util.List;
import javax.xml.ws.Holder;
/**
* @author Dmitry Velichkevich
*/
@javax.jws.WebService(name = "ACLServicePort", serviceName = "ACLService", portName = "ACLServicePort", targetNamespace = "http://docs.oasis-open.org/ns/cmis/ws/200901", endpointInterface = "org.alfresco.repo.cmis.ws.ACLServicePort")
public class DMAclServicePort extends DMAbstractServicePort implements ACLServicePort
{
private static final String ACL_SERVICE_NOT_IMPLEMENTED_MESSAGE = "ACLService not implemented";
public DMAclServicePort()
{
}
public void applyACL(String repositoryId, String objectId, CmisAccessControlListType addACEs, CmisAccessControlListType removeACEs, EnumACLPropagation propogationType,
Holder<List<CmisAccessControlListType>> acl, Holder<Boolean> exact) throws CmisException
{
throw cmisObjectsUtils.createCmisException(ACL_SERVICE_NOT_IMPLEMENTED_MESSAGE, EnumServiceException.RUNTIME);
}
public CmisAccessControlListType getACL(String repositoryId, String objectId, boolean onlyBasicPermissions) throws CmisException
{
throw cmisObjectsUtils.createCmisException(ACL_SERVICE_NOT_IMPLEMENTED_MESSAGE, EnumServiceException.RUNTIME);
}
}

View File

@@ -44,7 +44,6 @@ import org.alfresco.cmis.CMISResultSetRow;
@javax.jws.WebService(name = "DiscoveryServicePort", serviceName = "DiscoveryService", portName = "DiscoveryServicePort", targetNamespace = "http://docs.oasis-open.org/ns/cmis/ws/200901", endpointInterface = "org.alfresco.repo.cmis.ws.DiscoveryServicePort")
public class DMDiscoveryServicePort extends DMAbstractServicePort implements DiscoveryServicePort
{
/**
* Queries the repository for queryable object based on properties or an optional full-text string. Relationship objects are not queryable. Content-streams are not returned as
* part of query
@@ -52,11 +51,11 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
* @param parameters query parameters
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME)
*/
public QueryResponse query(CmisQueryType parameters) throws CmisException
public QueryResponse query(Query parameters) throws CmisException
{
checkRepositoryId(parameters.getRepositoryId());
// TODO: searchAllVersions, returnAllowableActions
// TODO: searchAllVersions, includeRelationships, includeAllowableActions, includeRenditions
CMISQueryOptions options = new CMISQueryOptions(parameters.getStatement(), cmisService.getDefaultRootStoreRef());
if (parameters.getSkipCount() != null)
@@ -64,12 +63,14 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
options.setSkipCount(parameters.getSkipCount().intValue());
}
if (parameters.getPageSize() != null)
if (parameters.getMaxItems() != null)
{
options.setMaxItems(parameters.getPageSize().intValue());
options.setMaxItems(parameters.getMaxItems().intValue());
}
// execute query
// TODO: If the select clause includes properties from more than a single type reference, then the repository SHOULD throw an exception if includeRelationships or
// includeAllowableActions is specified as true.
CMISResultSet resultSet = cmisQueryService.query(options);
CMISResultSetColumn[] columns = resultSet.getMetaData().getColumns();
@@ -105,5 +106,6 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
Holder<List<CmisObjectType>> changedObject) throws CmisException
{
// TODO
throw cmisObjectsUtils.createCmisException("Not implemented", EnumServiceException.RUNTIME);
}
}

View File

@@ -62,7 +62,8 @@ public class DMMultiFilingServicePort extends DMAbstractServicePort implements M
if (!folderType.getAllowedTargetTypes().isEmpty() && !folderType.getAllowedTargetTypes().contains(objectType))
{
throw cmisObjectsUtils.createCmisException("The typeID of Object is not in the list of AllowedChildObjectTypeIds of the parent-folder specified by folderId", EnumServiceException.CONSTRAINT);
throw cmisObjectsUtils.createCmisException("The typeId of Object is not in the list of AllowedChildObjectTypeIds of the parent-folder specified by folderId",
EnumServiceException.CONSTRAINT);
}
cmisObjectsUtils.addObjectToFolder(objectNodeRef, parentFolderNodeRef);
}

View File

@@ -25,11 +25,14 @@
package org.alfresco.repo.cmis.ws;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
import javax.xml.ws.Holder;
import org.alfresco.cmis.CMISDictionaryModel;
import org.alfresco.cmis.CMISTypesFilterEnum;
import org.alfresco.repo.cmis.PropertyFilter;
@@ -55,7 +58,6 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
private static final BigInteger FULL_DESCENDANTS_HIERARCHY_CONDITION = BigInteger.valueOf(-1l);
private static final String FILTER_TOKENS_DELIMETER = ", ";
private static final String POLICIES_LISTING_UNSUPPORTED_EXCEPTION_MESSAGE = "Policies listing isn't supported";
private static final Pattern ORDER_BY_CLAUSE_MASK = Pattern.compile("^( )*([\\p{Alnum}_]+(( )+((ASC)|(DESC)))?){1}((,){1}( )*[\\p{Alnum}_]+(( )+((ASC)|(DESC)))?)*( )*$",
Pattern.CASE_INSENSITIVE);
@@ -67,43 +69,42 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
* skipCount: 0 = start at beginning
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME, FILTER_NOT_VALID)
*/
public GetCheckedoutDocsResponse getCheckedoutDocs(GetCheckedoutDocs parameters) throws CmisException
public void getCheckedOutDocs(String repositoryId, String folderId, String filter, String orderBy, Boolean includeAllowableActions,
EnumIncludeRelationships includeRelationships, BigInteger maxItems, BigInteger skipCount, Holder<List<CmisObjectType>> object, Holder<Boolean> hasMoreItems)
throws CmisException
{
checkRepositoryId(parameters.getRepositoryId());
PropertyFilter propertyFilter = createPropertyFilter(parameters.getFilter());
checkRepositoryId(repositoryId);
PropertyFilter propertyFilter = createPropertyFilter(filter);
NodeRef folderId = null;
String folderIdParam = parameters.getFolderId() == null ? null : parameters.getFolderId().getValue();
if ((folderIdParam != null) && !folderIdParam.equals(""))
NodeRef folderRef = null;
if ((folderId != null) && !folderId.equals(""))
{
folderId = cmisObjectsUtils.getIdentifierInstance(folderIdParam, AlfrescoObjectType.FOLDER_OBJECT);
folderRef = cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT);
}
@SuppressWarnings("unused")
List<Pair<String, Boolean>> orderingFields = null;
if ((parameters.getOrderBy() != null) && (parameters.getOrderBy().getValue() != null) && !parameters.getOrderBy().getValue().equals(""))
if ((orderBy != null) && !orderBy.equals(""))
{
orderingFields = checkAndParseOrderByClause(parameters.getOrderBy().getValue());
orderingFields = checkAndParseOrderByClause(orderBy);
}
// TODO: Ordering functionality SHOULD be moved to getChildren service method
NodeRef[] nodeRefs = cmisService.getCheckedOut(AuthenticationUtil.getFullyAuthenticatedUser(), folderId, (folderId == null));
Cursor cursor = createCursor(nodeRefs.length, parameters.getSkipCount() != null ? parameters.getSkipCount().getValue() : null,
parameters.getMaxItems() != null ? parameters.getMaxItems().getValue() : null);
NodeRef[] nodeRefs = cmisService.getCheckedOut(AuthenticationUtil.getFullyAuthenticatedUser(), folderRef, (folderRef == null));
Cursor cursor = createCursor(nodeRefs.length, skipCount, maxItems);
GetCheckedoutDocsResponse response = new GetCheckedoutDocsResponse();
List<CmisObjectType> resultListing = response.getObject();
object.value = new ArrayList<CmisObjectType>();
List<CmisObjectType> resultListing = object.value;
for (int index = cursor.getStartRow(); index <= cursor.getEndRow(); index++)
{
resultListing.add(createCmisObject(nodeRefs[index].toString(), propertyFilter));
}
response.setHasMoreItems(cursor.getEndRow() < (nodeRefs.length - 1));
hasMoreItems.value = new Boolean(cursor.getEndRow() < (nodeRefs.length - 1));
// TODO: includeAllowableActions, includeRelationships
return response;
}
/**
@@ -115,59 +116,39 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
* @return collection of CmisObjectType and boolean hasMoreItems
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME, FILTER_NOT_VALID)
*/
public GetChildrenResponse getChildren(GetChildren parameters) throws CmisException
public void getChildren(String repositoryId, String folderId, String filter, Boolean includeAllowableActions, EnumIncludeRelationships includeRelationships,
Boolean includeRenditions, Boolean includeACL, BigInteger maxItems, BigInteger skipCount, String orderBy, Holder<List<CmisObjectType>> object,
Holder<Boolean> hasMoreItems) throws CmisException
{
checkRepositoryId(parameters.getRepositoryId());
PropertyFilter propertyFilter = createPropertyFilter(parameters.getFilter());
checkRepositoryId(repositoryId);
PropertyFilter propertyFilter = createPropertyFilter(filter);
NodeRef folderNodeRef = cmisObjectsUtils.getIdentifierInstance(parameters.getFolderId(), AlfrescoObjectType.FOLDER_OBJECT);
EnumTypesOfFileableObjects types = EnumTypesOfFileableObjects.ANY;
if ((parameters.getType() != null) && ((parameters.getType().getValue() != null)))
{
types = parameters.getType().getValue();
}
NodeRef folderNodeRef = cmisObjectsUtils.getIdentifierInstance(folderId, AlfrescoObjectType.FOLDER_OBJECT);
@SuppressWarnings("unused")
List<Pair<String, Boolean>> orderingFields = null;
if ((parameters.getOrderBy() != null) && !parameters.getOrderBy().equals(""))
if ((orderBy != null) && !orderBy.equals(""))
{
orderingFields = checkAndParseOrderByClause(parameters.getOrderBy());
orderingFields = checkAndParseOrderByClause(orderBy);
}
// TODO: Ordering functionality SHOULD be moved to getChildren service method
NodeRef[] listing = null;
switch (types)
{
case DOCUMENTS:
listing = cmisService.getChildren(folderNodeRef, CMISTypesFilterEnum.DOCUMENTS);
break;
case FOLDERS:
listing = cmisService.getChildren(folderNodeRef, CMISTypesFilterEnum.FOLDERS);
break;
case POLICIES:
throw cmisObjectsUtils.createCmisException(POLICIES_LISTING_UNSUPPORTED_EXCEPTION_MESSAGE, EnumServiceException.NOT_SUPPORTED);
case ANY:
listing = cmisService.getChildren(folderNodeRef, CMISTypesFilterEnum.ANY);
break;
}
NodeRef[] listing = cmisService.getChildren(folderNodeRef, CMISTypesFilterEnum.ANY);
Cursor cursor = createCursor(listing.length, (parameters.getSkipCount() != null ? parameters.getSkipCount().getValue() : null),
(parameters.getMaxItems() != null ? parameters.getMaxItems().getValue() : null));
Cursor cursor = createCursor(listing.length, skipCount, maxItems);
GetChildrenResponse response = new GetChildrenResponse();
List<CmisObjectType> resultListing = response.getObject();
object.value = new ArrayList<CmisObjectType>();
List<CmisObjectType> resultListing = object.value;
for (int index = cursor.getStartRow(); index <= cursor.getEndRow(); index++)
{
resultListing.add(createCmisObject(listing[index].toString(), propertyFilter));
}
// TODO: includeAllowableActions, includeRelationships
hasMoreItems.value = new Boolean(cursor.getEndRow() < (listing.length - 1));
response.setHasMoreItems(cursor.getEndRow() < (listing.length - 1));
// TODO: Process includeAllowableActions, includeRelationships, includeRenditions, includeACL
return response;
}
// TODO: This method will create appropriate Ordering fields
@@ -202,37 +183,25 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
* @return collection of CmisObjectType
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME, FILTER_NOT_VALID)
*/
public GetDescendantsResponse getDescendants(GetDescendants parameters) throws CmisException
public List<CmisObjectType> getDescendants(String repositoryId, String folderId, BigInteger depth, String filter, Boolean includeAllowableActions,
EnumIncludeRelationships includeRelationships, Boolean includeRenditions, String orderBy) throws CmisException
{
checkRepositoryId(parameters.getRepositoryId());
PropertyFilter propertyFilter = createPropertyFilter(parameters.getFilter());
BigInteger depth = ((parameters.getDepth() != null) && (parameters.getDepth().getValue() != null)) ? (parameters.getDepth().getValue()) : (BigInteger.ONE);
checkDepthParameter(depth);
GetDescendantsResponse response = new GetDescendantsResponse();
HierarchyReceiverStrategy receiver = createHierarchyReceiver(parameters.getType() != null ? parameters.getType() : EnumTypesOfFileableObjects.ANY, depth);
List<Pair<String, Boolean>> orderingFields = null;
if ((parameters.getOrderBy() != null) && !parameters.getOrderBy().equals(""))
{
orderingFields = checkAndParseOrderByClause(parameters.getOrderBy());
}
// TODO: Ordering functionality SHOULD be moved to getChildren service method
createCmisObjectList(propertyFilter, receiver.receiveHierarchy(parameters.getFolderId(), orderingFields), response.getObject());
// TODO: includeAllowableActions, includeRelationships
return response;
return getDescendants(repositoryId, folderId, depth, filter, includeAllowableActions, includeRelationships, includeRenditions, orderBy, null);
}
private void checkDepthParameter(BigInteger depth) throws CmisException
/**
* Gets the list of descendant objects contained at one or more levels in the tree rooted at the specified folder. Only the filter-selected properties associated with each
* object are returned. The content-stream is not returned. For paging through the children (depth of 1) only use {@link #getChildren(GetChildren parameters)}.
*
* @param parameters repositoryId: repository Id; folderId: folder Id; depth: 1 this folder only (Default), N folders deep, -1 for all levels; filter: property filter;
* includeAllowableActions; includeRelationships;
* @return collection of CmisObjectType
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME, FILTER_NOT_VALID)
*/
public List<CmisObjectType> getFolderTree(String repositoryId, String folderId, String filter, BigInteger depth, Boolean includeAllowableActions,
EnumIncludeRelationships includeRelationships) throws CmisException
{
if (depth.equals(BigInteger.ZERO) || (depth.compareTo(FULL_DESCENDANTS_HIERARCHY_CONDITION) < EQUALS_CONDITION_VALUE))
{
throw cmisObjectsUtils.createCmisException("The specified descendants depth is not valid. Valid depth values are: -1 (full hierarchy), N > 0",
EnumServiceException.INVALID_ARGUMENT);
}
return getDescendants(repositoryId, folderId, depth, filter, includeAllowableActions, includeRelationships, null, null, CMISTypesFilterEnum.FOLDERS);
}
/**
@@ -243,11 +212,10 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
* @return collection of CmisObjectType
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME, FILTER_NOT_VALID)
*/
public GetFolderParentResponse getFolderParent(GetFolderParent parameters) throws CmisException
public CmisObjectType getFolderParent(String repositoryId, String folderId, String filter) throws CmisException
{
checkRepositoryId(parameters.getRepositoryId());
checkRepositoryId(repositoryId);
String filter = parameters.getFilter();
if ((filter != null) && !filter.equals("") && !filter.equals("*"))
{
if (!filter.contains(CMISDictionaryModel.PROP_PARENT_ID))
@@ -262,15 +230,11 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
}
PropertyFilter propertyFilter = createPropertyFilter(filter);
GetFolderParentResponse response = new GetFolderParentResponse();
boolean returnToRoot = ((parameters.getReturnToRoot() != null) && (parameters.getReturnToRoot().getValue() != null)) ? (parameters.getReturnToRoot().getValue()) : false;
List<NodeRef> parents = receiveParentList(parameters.getFolderId(), returnToRoot);
createCmisObjectList(propertyFilter, parents, response.getObject());
NodeRef parentRef = receiveParent(folderId);
CmisObjectType result = createCmisObject(parentRef, propertyFilter);
// TODO: includeAllowableActions, includeRelationships
return response;
return result;
}
/**
@@ -281,42 +245,58 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME, CONSTRAINT,
* FILTER_NOT_VALID)
*/
public GetObjectParentsResponse getObjectParents(GetObjectParents parameters) throws CmisException
public List<CmisObjectType> getObjectParents(String repositoryId, String objectId, String filter) throws CmisException
{
// TODO: Policy
checkRepositoryId(repositoryId);
PropertyFilter propertyFilter = createPropertyFilter(filter);
checkRepositoryId(parameters.getRepositoryId());
PropertyFilter propertyFilter = createPropertyFilter(parameters.getFilter());
GetObjectParentsResponse response = new GetObjectParentsResponse();
List<NodeRef> parents = receiveObjectParents((NodeRef) cmisObjectsUtils.getIdentifierInstance(parameters.getObjectId(), AlfrescoObjectType.DOCUMENT_OBJECT));
createCmisObjectList(propertyFilter, parents, response.getObject());
// TODO: includeAllowableActions, includeRelationships
return response;
List<NodeRef> parents = receiveObjectParents((NodeRef) cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OBJECT));
List<CmisObjectType> result = new ArrayList<CmisObjectType>();
createCmisObjectList(propertyFilter, parents, result);
return result;
}
private List<NodeRef> receiveParentList(String targetChildIdentifier, boolean fullParentsHierarchy) throws CmisException
private NodeRef receiveParent(String targetChildIdentifier) throws CmisException
{
List<NodeRef> result = new LinkedList<NodeRef>();
if (targetChildIdentifier.equals(cmisService.getDefaultRootNodeRef().toString()))
{
return result;
return null;
}
NodeRef currentParent = receiveNextParentNodeReference((NodeRef) cmisObjectsUtils.getIdentifierInstance(targetChildIdentifier, AlfrescoObjectType.FOLDER_OBJECT), result);
return (fullParentsHierarchy) ? (receiveFullAncestorsHierachy(currentParent, result)) : (result);
return receiveNextParentNodeReference((NodeRef) cmisObjectsUtils.getIdentifierInstance(targetChildIdentifier, AlfrescoObjectType.FOLDER_OBJECT), new ArrayList<NodeRef>());
}
private List<NodeRef> receiveFullAncestorsHierachy(NodeRef currentParent, List<NodeRef> parents)
private List<CmisObjectType> getDescendants(String repositoryId, String folderId, BigInteger depth, String filter, Boolean includeAllowableActions,
EnumIncludeRelationships includeRelationships, Boolean includeRenditions, String orderBy, CMISTypesFilterEnum type) throws CmisException
{
String lastAncestorIdentifier = cmisService.getDefaultRootNodeRef().toString();
while ((currentParent != null) && !currentParent.toString().equals(lastAncestorIdentifier))
checkRepositoryId(repositoryId);
PropertyFilter propertyFilter = createPropertyFilter(filter);
depth = (depth == null) ? (BigInteger.ONE) : depth;
checkDepthParameter(depth);
HierarchyReceiverStrategy receiver = createHierarchyReceiver(type, depth);
List<Pair<String, Boolean>> orderingFields = null;
if ((orderBy != null) && !orderBy.equals(""))
{
currentParent = receiveNextParentNodeReference(currentParent, parents);
orderingFields = checkAndParseOrderByClause(orderBy);
}
List<CmisObjectType> result = new ArrayList<CmisObjectType>();
// TODO: Ordering functionality SHOULD be moved to getChildren service method
createCmisObjectList(propertyFilter, receiver.receiveHierarchy(folderId, orderingFields), result);
// TODO: includeAllowableActions, includeRelationships, includeRenditions
return result;
}
private void checkDepthParameter(BigInteger depth) throws CmisException
{
if (depth.equals(BigInteger.ZERO) || (depth.compareTo(FULL_DESCENDANTS_HIERARCHY_CONDITION) < EQUALS_CONDITION_VALUE))
{
throw cmisObjectsUtils.createCmisException("The specified descendants depth is not valid. Valid depth values are: -1 (full hierarchy), N > 0",
EnumServiceException.INVALID_ARGUMENT);
}
return parents;
}
private NodeRef receiveNextParentNodeReference(NodeRef currentParent, List<NodeRef> parents)
@@ -339,20 +319,20 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
return parents;
}
private HierarchyReceiverStrategy createHierarchyReceiver(EnumTypesOfFileableObjects returnObjectsType, BigInteger finalDepth)
private HierarchyReceiverStrategy createHierarchyReceiver(CMISTypesFilterEnum type, BigInteger finalDepth)
{
if (finalDepth.equals(FULL_DESCENDANTS_HIERARCHY_CONDITION))
{
return new FullHierarchyReceiver(returnObjectsType);
return new FullHierarchyReceiver(type);
}
else
{
return new LayerConstrainedHierarchyReceiver(returnObjectsType, finalDepth);
return new LayerConstrainedHierarchyReceiver(type, finalDepth);
}
}
private void separateDescendantsObjects(EnumTypesOfFileableObjects returnObjectsType, List<NodeRef> descendantsFolders, List<NodeRef> currentLayerFolders,
List<NodeRef> currentLayerDocuments, List<Pair<String, Boolean>> orderingFields)
private void separateDescendantsObjects(List<NodeRef> descendantsFolders, List<NodeRef> currentLayerFolders, List<NodeRef> currentLayerDocuments,
List<Pair<String, Boolean>> orderingFields)
{
for (NodeRef element : descendantsFolders)
{
@@ -360,25 +340,22 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
currentLayerFolders.addAll(Arrays.asList(cmisService.getChildren(element, CMISTypesFilterEnum.FOLDERS)));
// TODO: Ordering functionality SHOULD be moved to getChildren service method
if ((returnObjectsType == EnumTypesOfFileableObjects.ANY) || (returnObjectsType == EnumTypesOfFileableObjects.DOCUMENTS))
{
currentLayerDocuments.addAll(Arrays.asList(cmisService.getChildren(element, CMISTypesFilterEnum.DOCUMENTS)));
}
currentLayerDocuments.addAll(Arrays.asList(cmisService.getChildren(element, CMISTypesFilterEnum.DOCUMENTS)));
}
}
private List<NodeRef> performDescendantsResultObjectsStoring(EnumTypesOfFileableObjects returnObjectsType, List<NodeRef> resultList, List<NodeRef> descendantsFolders,
List<NodeRef> currentLayerFolders, List<NodeRef> currentLayerDocuments, List<Pair<String, Boolean>> orderingFields)
private List<NodeRef> performDescendantsResultObjectsStoring(List<NodeRef> resultList, List<NodeRef> descendantsFolders, List<NodeRef> currentLayerFolders,
List<NodeRef> currentLayerDocuments, List<Pair<String, Boolean>> orderingFields, CMISTypesFilterEnum type)
{
separateDescendantsObjects(returnObjectsType, descendantsFolders, currentLayerFolders, currentLayerDocuments, orderingFields);
if ((returnObjectsType == EnumTypesOfFileableObjects.ANY) || (returnObjectsType == EnumTypesOfFileableObjects.FOLDERS))
separateDescendantsObjects(descendantsFolders, currentLayerFolders, currentLayerDocuments, orderingFields);
if (CMISTypesFilterEnum.ANY.equals(type) || CMISTypesFilterEnum.FOLDERS.equals(type))
{
resultList.addAll(currentLayerFolders);
}
resultList.addAll(currentLayerDocuments);
if (CMISTypesFilterEnum.ANY.equals(type) || CMISTypesFilterEnum.DOCUMENTS.equals(type))
{
resultList.addAll(currentLayerDocuments);
}
return currentLayerFolders;
}
@@ -400,16 +377,16 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
*/
private class FullHierarchyReceiver implements HierarchyReceiverStrategy
{
private EnumTypesOfFileableObjects returnObjectsType;
private List<NodeRef> descendantsFolders = new LinkedList<NodeRef>();
private List<NodeRef> resultList = new LinkedList<NodeRef>();
private CMISTypesFilterEnum type = CMISTypesFilterEnum.ANY;
/**
* @param returnObjectsType flag that specifies objects of which type are need to be returned
*/
public FullHierarchyReceiver(EnumTypesOfFileableObjects returnObjectsType)
public FullHierarchyReceiver(CMISTypesFilterEnum type)
{
this.returnObjectsType = returnObjectsType;
if (type != null)
{
this.type = type;
}
}
/**
@@ -420,8 +397,8 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
descendantsFolders.add((NodeRef) cmisObjectsUtils.getIdentifierInstance(rootFolderIdentifier, AlfrescoObjectType.FOLDER_OBJECT));
while (!descendantsFolders.isEmpty())
{
descendantsFolders = performDescendantsResultObjectsStoring(returnObjectsType, resultList, descendantsFolders, new LinkedList<NodeRef>(),
new LinkedList<NodeRef>(), orderingFields);
descendantsFolders = performDescendantsResultObjectsStoring(resultList, descendantsFolders, new LinkedList<NodeRef>(), new LinkedList<NodeRef>(), orderingFields,
type);
}
return resultList;
@@ -434,19 +411,22 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
private class LayerConstrainedHierarchyReceiver implements HierarchyReceiverStrategy
{
private List<NodeRef> descendantsFolders = new LinkedList<NodeRef>();
private EnumTypesOfFileableObjects returnObjectsType;
private BigInteger finalDepth;
private BigInteger currentDepth = BigInteger.ZERO;
private List<NodeRef> resultList = new LinkedList<NodeRef>();
private CMISTypesFilterEnum type = CMISTypesFilterEnum.ANY;
/**
* @param returnObjectsType flag that specifies objects of which type are need to be returned
* @param finalDepth the number of final Alfresco hierarchy layer: 1 - only children of specified folder; -1 - full descendants hierarchy
*/
public LayerConstrainedHierarchyReceiver(EnumTypesOfFileableObjects returnObjectsType, BigInteger finalDepth)
public LayerConstrainedHierarchyReceiver(CMISTypesFilterEnum type, BigInteger finalDepth)
{
this.returnObjectsType = returnObjectsType;
this.finalDepth = finalDepth;
if (type != null)
{
this.type = type;
}
}
/**
@@ -458,12 +438,13 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
do
{
descendantsFolders = performDescendantsResultObjectsStoring(this.returnObjectsType, this.resultList, this.descendantsFolders, new LinkedList<NodeRef>(),
new LinkedList<NodeRef>(), orderingFields);
descendantsFolders = performDescendantsResultObjectsStoring(this.resultList, this.descendantsFolders, new LinkedList<NodeRef>(), new LinkedList<NodeRef>(),
orderingFields, type);
currentDepth = currentDepth.add(BigInteger.ONE);
} while (!descendantsFolders.isEmpty() && (currentDepth.compareTo(this.finalDepth) < EQUALS_CONDITION_VALUE));
return this.resultList;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -24,11 +24,12 @@
*/
package org.alfresco.repo.cmis.ws;
import java.util.List;
@javax.jws.WebService(name = "PolicyServicePort", serviceName = "PolicyServicePort", portName = "PolicyServicePort", targetNamespace = "http://docs.oasis-open.org/ns/cmis/ws/200901", endpointInterface = "org.alfresco.repo.cmis.ws.PolicyServicePort")
public class DMPolicyServicePort extends DMAbstractServicePort implements PolicyServicePort
{
private static final String POLICY_NOT_SUPPORTED_MESSAGE = "PolicyService not supported";
private static final String POLICY_NOT_SUPPORTED_MESSAGE = "PolicyService not implemented";
/**
* Applies a policy object to a target object.
@@ -40,7 +41,7 @@ public class DMPolicyServicePort extends DMAbstractServicePort implements Policy
*/
public void applyPolicy(String repositoryId, String policyId, String objectId) throws CmisException
{
throw cmisObjectsUtils.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.NOT_SUPPORTED);
throw cmisObjectsUtils.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.RUNTIME);
}
/**
@@ -49,9 +50,9 @@ public class DMPolicyServicePort extends DMAbstractServicePort implements Policy
* @param parameters repositoryId: repository Id; objectId: target object Id; filter: filter specifying which properties to return
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME, FILTER_NOT_VALID)
*/
public GetAppliedPoliciesResponse getAppliedPolicies(GetAppliedPolicies parameters) throws CmisException
public List<CmisObjectType> getAppliedPolicies(String repositoryId, String objectId, String filter) throws CmisException
{
throw cmisObjectsUtils.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.NOT_SUPPORTED);
throw cmisObjectsUtils.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.RUNTIME);
}
/**
@@ -64,6 +65,6 @@ public class DMPolicyServicePort extends DMAbstractServicePort implements Policy
*/
public void removePolicy(String repositoryId, String policyId, String objectId) throws CmisException
{
throw cmisObjectsUtils.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.NOT_SUPPORTED);
throw cmisObjectsUtils.createCmisException(POLICY_NOT_SUPPORTED_MESSAGE, EnumServiceException.RUNTIME);
}
}

View File

@@ -25,8 +25,11 @@
package org.alfresco.repo.cmis.ws;
import java.math.BigInteger;
import java.util.LinkedList;
import java.util.List;
import javax.xml.ws.Holder;
import org.alfresco.cmis.CMISScope;
import org.alfresco.cmis.CMISTypeDefinition;
import org.alfresco.repo.cmis.PropertyFilter;
@@ -62,48 +65,60 @@ public class DMRelationshipServicePort extends DMAbstractServicePort implements
* @return collection of CmisObjectType and boolean hasMoreItems
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME, FILTER_NOT_VALID)
*/
public GetRelationshipsResponse getRelationships(GetRelationships parameters) throws CmisException
public void getRelationships(String repositoryId, String objectId, EnumRelationshipDirection direction, String typeId, Boolean includeSubRelationshipTypes, String filter,
Boolean includeAllowableActions, EnumIncludeRelationships includeRelationships, BigInteger maxItems, BigInteger skipCount, Holder<List<CmisObjectType>> object,
Holder<Boolean> hasMoreItems) throws CmisException
{
checkRepositoryId(parameters.getRepositoryId());
checkRepositoryId(repositoryId);
EnumRelationshipDirection direction = ((parameters.getDirection() != null) && (parameters.getDirection().getValue() != null)) ? parameters.getDirection().getValue()
: EnumRelationshipDirection.SOURCE;
Boolean includingSubtypes = ((parameters.getIncludeSubRelationshipTypes() != null) && (parameters.getIncludeSubRelationshipTypes().getValue() != null)) ? parameters
.getIncludeSubRelationshipTypes().getValue() : false;
String typeId = ((parameters.getTypeId() != null) && (parameters.getTypeId().getValue() != null)) ? parameters.getTypeId().getValue() : null;
BigInteger skipCount = ((parameters.getSkipCount() != null) && (parameters.getSkipCount().getValue() != null)) ? parameters.getSkipCount().getValue() : BigInteger.ZERO;
BigInteger maxItems = ((parameters.getMaxItems() != null) && (parameters.getMaxItems().getValue() != null)) ? parameters.getMaxItems().getValue() : BigInteger.ZERO;
direction = (null != direction) ? direction : EnumRelationshipDirection.SOURCE;
if (null == includeSubRelationshipTypes)
{
throw cmisObjectsUtils.createCmisException("includeSubRelationshipTypes input parameter is required", EnumServiceException.INVALID_ARGUMENT);
}
skipCount = (null != skipCount) ? skipCount : BigInteger.ZERO;
maxItems = (null != maxItems) ? maxItems : BigInteger.ZERO;
QName associationType = null;
if ((parameters.getTypeId() != null) && (parameters.getTypeId().getValue() != null) && !parameters.getTypeId().getValue().equals(""))
if ((null != typeId) && !typeId.equals(""))
{
CMISTypeDefinition cmisTypeDef = cmisDictionaryService.findType(typeId);
associationType = cmisTypeDef.getTypeId().getQName();
}
// TODO: process 'includeAllowableActions' param, see DMObjectServicePort->determineObjectAllowableActions
PropertyFilter propertyFilter = createPropertyFilter(parameters.getFilter());
NodeRef objectNodeRef = cmisObjectsUtils.getIdentifierInstance(parameters.getObjectId(), AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT);
PropertyFilter propertyFilter = createPropertyFilter(filter);
NodeRef objectNodeRef = cmisObjectsUtils.getIdentifierInstance(objectId, AlfrescoObjectType.DOCUMENT_OR_FOLDER_OBJECT);
List<AssociationRef> assocs = null;
try
{
assocs = cmisObjectsUtils.receiveAssociations(objectNodeRef, new RelationshipTypeFilter(associationType, includingSubtypes), direction);
assocs = cmisObjectsUtils.receiveAssociations(objectNodeRef, new RelationshipTypeFilter(associationType, includeSubRelationshipTypes), direction);
}
catch (Exception e)
{
throw cmisObjectsUtils.createCmisException("Can't receive associations", e);
}
return formatResponse(propertyFilter, assocs.toArray(), new GetRelationshipsResponse(), skipCount, maxItems);
if (null == object)
{
object = new Holder<List<CmisObjectType>>();
}
object.value = formatResponse(propertyFilter, assocs.toArray(), skipCount, maxItems, hasMoreItems);
}
private GetRelationshipsResponse formatResponse(PropertyFilter filter, Object[] sourceArray, GetRelationshipsResponse result, BigInteger skipCount, BigInteger maxItems)
private List<CmisObjectType> formatResponse(PropertyFilter filter, Object[] sourceArray, BigInteger skipCount, BigInteger maxItems, Holder<Boolean> hasMoreItems)
throws CmisException
{
Cursor cursor = createCursor(sourceArray.length, skipCount, maxItems);
List<CmisObjectType> result = new LinkedList<CmisObjectType>();
for (int i = cursor.getStartRow(); i < cursor.getEndRow(); i++)
{
result.getObject().add(createCmisObject(sourceArray[i].toString(), filter));
result.add(createCmisObject(sourceArray[i].toString(), filter));
}
if (null == hasMoreItems)
{
hasMoreItems = new Holder<Boolean>();
}
hasMoreItems.value = cursor.getEndRow() < sourceArray.length;
return result;
}
@@ -126,6 +141,7 @@ public class DMRelationshipServicePort extends DMAbstractServicePort implements
}
else if (includeSubtypes)
{
// TODO: it is necessary introduce checking on descendants
return dictionaryService.getAssociation(qname) != null;
}
else

View File

@@ -34,7 +34,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXBElement;
import javax.xml.ws.Holder;
import org.alfresco.cmis.CMISCardinalityEnum;
@@ -118,11 +117,12 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
{
CmisRepositoryEntryType repositoryEntryType = new CmisRepositoryEntryType();
Descriptor serverDescriptor = descriptorService.getCurrentRepositoryDescriptor();
repositoryEntryType.setRepositoryId(serverDescriptor.getId());
repositoryEntryType.setRepositoryName(serverDescriptor.getName());
repositoryEntryType.setId(serverDescriptor.getId());
repositoryEntryType.setName(serverDescriptor.getName());
repositoryEntryType.setRelationship(serverDescriptor.getName());
// TODO: Hardcoded! repositoryUri should be retrieved using standard mechanism
repositoryEntryType.setRepositoryURI(repositoryUri);
repositoryEntryType.setThinClientURI(repositoryUri);
List<CmisRepositoryEntryType> result = new LinkedList<CmisRepositoryEntryType>();
result.add(repositoryEntryType);
return result;
@@ -158,11 +158,140 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
capabilities.setCapabilityAllVersionsSearchable(cmisQueryService.getAllVersionsSearchable());
capabilities.setCapabilityQuery(queryTypeEnumMapping.get(cmisQueryService.getQuerySupport()));
capabilities.setCapabilityJoin(joinEnumMapping.get(cmisQueryService.getJoinSupport()));
capabilities.setCapabilityACL(EnumCapabilityACL.NONE);
capabilities.setCapabilityChanges(EnumCapabilityChanges.NONE);
capabilities.setCapabilityContentStreamUpdatability(EnumCapabilityContentStreamUpdates.ANYTIME);
capabilities.setCapabilityGetDescendants(true);
capabilities.setCapabilityRenditions(EnumCapabilityRendition.NONE);
repositoryInfoType.setCapabilities(capabilities);
repositoryInfoType.setCmisVersionSupported(cmisService.getCMISVersion());
repositoryInfoType.setCmisVersionSupported(BigDecimal.valueOf(0.62));
// TODO: cmisVersionSupported is different in stubs and specification
// repositoryInfoType.setCmisVersionSupported(cmisService.getCMISVersion());
return repositoryInfoType;
}
/**
* Gets the definition for specified object type
*
* @param parameters repositoryId: repository Id; typeId: type Id;
* @return CMIS type definition
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME)
*/
public CmisTypeDefinitionType getTypeDefinition(String repositoryId, String typeId) throws CmisException
{
checkRepositoryId(repositoryId);
CMISTypeDefinition typeDef = cmisDictionaryService.findType(typeId);
return getCmisTypeDefinition(typeDef, true);
}
/**
* Returns the set of descendant Object-Types defined for the Repository under the specified Type.
*
* @param parameters srepositoryId: repository Id; typeId: type Id; includePropertyDefinitions: false (default); depth: The number of levels of depth in the type hierarchy from
* which to return results;
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME)
*/
public List<CmisTypeContainer> getTypeDescendants(String repositoryId, String typeId, BigInteger depth, Boolean includePropertyDefinitions) throws CmisException
{
checkRepositoryId(repositoryId);
Collection<CMISTypeDefinition> typeDefs = new LinkedList<CMISTypeDefinition>();
if ((typeId == null) || typeId.equals(""))
{
typeDefs = cmisDictionaryService.getBaseTypes();
}
else
{
CMISTypeDefinition typeDef = cmisDictionaryService.findType(typeId);
if (null == typeDef)
{
throw cmisObjectsUtils.createCmisException(("Invalid type id: \"" + typeId + "\""), EnumServiceException.INVALID_ARGUMENT);
}
typeDefs.add(typeDef);
}
long depthLong = depth == null || depth.equals(BigInteger.valueOf(-1)) ? Long.MAX_VALUE : depth.longValue();
boolean includePropertyDefsBool = includePropertyDefinitions == null ? false : includePropertyDefinitions;
List<CmisTypeContainer> result = new LinkedList<CmisTypeContainer>();
for (CMISTypeDefinition typeDef : typeDefs)
{
result.add(getTypeDescedants(typeDef, depthLong, includePropertyDefsBool));
}
return result;
}
/**
* Returns the list of Object-Types defined for the Repository under the specified Type.
*
* @param parameters repositoryId: repository Id; typeId: type Id; returnPropertyDefinitions: false (default); maxItems: 0 = Repository-default number of items(Default);
* skipCount: 0 = start;
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME)
*/
public void getTypeChildren(String repositoryId, String typeId, Boolean returnPropertyDefinitions, BigInteger maxItems, BigInteger skipCount,
Holder<List<CmisTypeDefinitionType>> type, Holder<Boolean> hasMoreItems) throws CmisException
{
checkRepositoryId(repositoryId);
Collection<CMISTypeDefinition> typeDefs = new LinkedList<CMISTypeDefinition>();
if ((typeId == null) || typeId.equals(""))
{
typeDefs = cmisDictionaryService.getBaseTypes();
}
else
{
CMISTypeDefinition typeDef = null;
try
{
typeDef = cmisDictionaryService.findType(typeId);
}
catch (RuntimeException exception)
{
throw cmisObjectsUtils.createCmisException(exception.toString(), EnumServiceException.INVALID_ARGUMENT);
}
if (null == typeDef)
{
throw cmisObjectsUtils.createCmisException(("Invalid type id: \"" + typeId + "\""), EnumServiceException.INVALID_ARGUMENT);
}
typeDefs.add(typeDef);
Collection<CMISTypeDefinition> subTypes = typeDef.getSubTypes(true);
if (null != subTypes)
{
typeDefs.addAll(subTypes);
}
}
// skip
Cursor cursor = createCursor(typeDefs.size(), skipCount, maxItems);
Iterator<CMISTypeDefinition> iterTypeDefs = typeDefs.iterator();
for (int i = 0; i < cursor.getStartRow(); i++)
{
iterTypeDefs.next();
}
boolean returnPropertyDefinitionsVal = returnPropertyDefinitions == null ? false : returnPropertyDefinitions.booleanValue();
type.value = new LinkedList<CmisTypeDefinitionType>();
for (int i = cursor.getStartRow(); i <= cursor.getEndRow(); i++)
{
CmisTypeDefinitionType element = getCmisTypeDefinition(iterTypeDefs.next(), returnPropertyDefinitionsVal);
if (element != null)
{
type.value.add(element);
}
else
{
throw cmisObjectsUtils.createCmisException(("Subtypes collection is corrupted. Type id: " + typeId), EnumServiceException.STORAGE);
}
}
hasMoreItems.value = ((maxItems == null) || (maxItems.intValue() == 0)) ? (false) : ((cursor.getEndRow() < (typeDefs.size() - 1)));
}
/**
* Create web service choice object from repository choice object
*
@@ -170,80 +299,58 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
* @param propertyType type of property
* @return web service choice
*/
private JAXBElement<? extends CmisChoiceType> getCmisChoiceType(CMISChoice choice, CMISDataTypeEnum propertyType)
private CmisChoice getCmisChoiceType(CMISChoice choice, CMISDataTypeEnum propertyType)
{
JAXBElement<? extends CmisChoiceType> result = null;
CmisChoice result = null;
switch (propertyType)
{
case BOOLEAN:
CmisChoiceBooleanType choiceBooleanType = new CmisChoiceBooleanType();
choiceBooleanType.setKey(choice.getName());
CmisChoiceBoolean choiceBooleanType = new CmisChoiceBoolean();
choiceBooleanType.setDisplayName(choice.getName());
choiceBooleanType.getValue().add(Boolean.parseBoolean(choice.getValue().toString()));
result = cmisObjectFactory.createChoiceBoolean(choiceBooleanType);
result = choiceBooleanType;
break;
case DATETIME:
CmisChoiceDateTimeType choiceDateTimeType = new CmisChoiceDateTimeType();
choiceDateTimeType.setKey(choice.getName());
CmisChoiceDateTime choiceDateTimeType = new CmisChoiceDateTime();
choiceDateTimeType.setDisplayName(choice.getName());
choiceDateTimeType.getValue().add(propertiesUtil.convert((Date) choice.getValue()));
result = cmisObjectFactory.createChoiceDateTime(choiceDateTimeType);
result = choiceDateTimeType;
break;
case DECIMAL:
CmisChoiceDecimalType choiceDecimalType = new CmisChoiceDecimalType();
choiceDecimalType.setKey(choice.getName());
CmisChoiceDecimal choiceDecimalType = new CmisChoiceDecimal();
choiceDecimalType.setDisplayName(choice.getName());
choiceDecimalType.getValue().add(BigDecimal.valueOf(Double.parseDouble(choice.getValue().toString())));
result = cmisObjectFactory.createChoiceDecimal(choiceDecimalType);
result = choiceDecimalType;
break;
case HTML:
break;
case ID:
CmisChoiceIdType choiceIdType = new CmisChoiceIdType();
choiceIdType.setKey(choice.getName());
CmisChoiceId choiceIdType = new CmisChoiceId();
choiceIdType.setDisplayName(choice.getName());
choiceIdType.getValue().add(choice.getValue().toString());
result = cmisObjectFactory.createChoiceId(choiceIdType);
result = choiceIdType;
break;
case INTEGER:
CmisChoiceIntegerType choiceIntegerType = new CmisChoiceIntegerType();
choiceIntegerType.setKey(choice.getName());
CmisChoiceInteger choiceIntegerType = new CmisChoiceInteger();
choiceIntegerType.setDisplayName(choice.getName());
choiceIntegerType.getValue().add(BigInteger.valueOf(Integer.parseInt(choice.getValue().toString())));
result = cmisObjectFactory.createChoiceInteger(choiceIntegerType);
result = choiceIntegerType;
break;
case STRING:
CmisChoiceStringType choiceStringType = new CmisChoiceStringType();
choiceStringType.setKey(choice.getName());
CmisChoiceString choiceStringType = new CmisChoiceString();
choiceStringType.setDisplayName(choice.getName());
choiceStringType.getValue().add(choice.getValue().toString());
result = cmisObjectFactory.createChoiceString(choiceStringType);
result = choiceStringType;
break;
case URI:
break;
case XML:
break;
}
return result;
}
/**
* Add choices childrens to list of JAXBElements
*
* @param propertyType type of property
* @param choices repository choice object
* @param cmisChoices web service choice object
*/
private void addChoiceChildrens(CMISDataTypeEnum propertyType, Collection<CMISChoice> choices, List<JAXBElement<? extends CmisChoiceType>> cmisChoices)
{
for (CMISChoice choice : choices)
{
JAXBElement<? extends CmisChoiceType> cmisChoiceType = getCmisChoiceType(choice, propertyType);
cmisChoices.add(cmisChoiceType);
if (choice.getChildren().isEmpty() == false)
{
addChoiceChildrens(propertyType, choice.getChildren(), cmisChoiceType.getValue().getChoice());
}
}
}
/**
* Add root choices to list of choices
*
@@ -251,16 +358,36 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
* @param choices repository choice object
* @param cmisChoices web service choice object
*/
private void addChoices(CMISDataTypeEnum propertyType, Collection<CMISChoice> choices, List<CmisChoiceType> cmisChoices)
private void addChoices(CMISDataTypeEnum propertyType, Collection<CMISChoice> choices, List<CmisChoice> cmisChoices)
{
for (CMISChoice choice : choices)
{
JAXBElement<? extends CmisChoiceType> cmisChoiceType = getCmisChoiceType(choice, propertyType);
cmisChoices.add(cmisChoiceType.getValue());
CmisChoice cmisChoiceType = getCmisChoiceType(choice, propertyType);
cmisChoices.add(cmisChoiceType);
if (choice.getChildren().isEmpty() == false)
{
addChoiceChildrens(propertyType, choice.getChildren(), cmisChoices);
}
}
}
/**
* Add choices childrens to list of JAXBElements
*
* @param propertyType type of property
* @param choices repository choice object
* @param cmisChoices web service choice object
*/
private void addChoiceChildrens(CMISDataTypeEnum propertyType, Collection<CMISChoice> choices, List<CmisChoice> cmisChoices)
{
for (CMISChoice choice : choices)
{
CmisChoice cmisChoiceType = getCmisChoiceType(choice, propertyType);
cmisChoices.add(cmisChoiceType);
if (choice.getChildren().isEmpty() == false)
{
addChoiceChildrens(propertyType, choice.getChildren(), cmisChoiceType.getValue().getChoice());
addChoiceChildrens(propertyType, choice.getChildren(), cmisChoices);
}
}
}
@@ -275,6 +402,7 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
throws CmisException
{
CmisPropertyDefinitionType wsPropertyDef = createPropertyDefinitionType(propertyDefinition.getDataType());
wsPropertyDef.setLocalName(propertyDefinition.getPropertyId().getLocalName());
wsPropertyDef.setId(propertyDefinition.getPropertyId().getId());
wsPropertyDef.setDisplayName(propertyDefinition.getDisplayName());
wsPropertyDef.setDescription(propertyDefinition.getDescription());
@@ -285,12 +413,59 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
wsPropertyDef.setRequired(propertyDefinition.isRequired());
wsPropertyDef.setQueryable(propertyDefinition.isQueryable());
wsPropertyDef.setOrderable(propertyDefinition.isOrderable());
addChoices(propertyDefinition.getDataType(), propertyDefinition.getChoices(), wsPropertyDef.getChoice());
addChoices(propertyDefinition.getDataType(), propertyDefinition.getChoices(), getChoices(wsPropertyDef));
wsPropertyDef.setOpenChoice(propertyDefinition.isOpenChoice());
wsPropertyDefs.add(wsPropertyDef);
}
private CmisTypeContainer getTypeDescedants(CMISTypeDefinition typeDef, long depth, boolean includePropertyDefs) throws CmisException
{
if (depth < 0)
{
return null;
}
CmisTypeContainer container = new CmisTypeContainer();
CmisTypeDefinitionType targetTypeDef = getCmisTypeDefinition(typeDef, includePropertyDefs);
if (targetTypeDef != null)
{
container.setType(targetTypeDef);
Collection<CMISTypeDefinition> subTypes = typeDef.getSubTypes(false);
if (subTypes != null)
{
for (CMISTypeDefinition subType : subTypes)
{
CmisTypeContainer child = getTypeDescedants(subType, depth - 1, includePropertyDefs);
if (child != null)
{
container.getChildren().add(child);
}
}
}
}
else
{
throw cmisObjectsUtils.createCmisException(("Subtypes collection is corrupted. Type id: " + targetTypeDef), EnumServiceException.STORAGE);
}
return container;
}
@SuppressWarnings("unchecked")
private static List<CmisChoice> getChoices(CmisPropertyDefinitionType propertyDef)
{
List<CmisChoice> result = null;
if (propertyDef != null)
{
try
{
result = (List<CmisChoice>) propertyDef.getClass().getMethod("getChoice").invoke(propertyDef);
}
catch (Exception e)
{
}
}
return result;
}
private CmisPropertyDefinitionType createPropertyDefinitionType(CMISDataTypeEnum type) throws CmisException
{
switch (type)
@@ -347,17 +522,23 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
*/
private void setCmisTypeDefinitionProperties(CmisTypeDefinitionType cmisTypeDefinition, CMISTypeDefinition typeDefinition, boolean includeProperties) throws CmisException
{
cmisTypeDefinition.setTypeId(typeDefinition.getTypeId().getId());
cmisTypeDefinition.setId(typeDefinition.getTypeId().getId());
cmisTypeDefinition.setQueryName(typeDefinition.getQueryName());
cmisTypeDefinition.setDisplayName(typeDefinition.getDisplayName());
cmisTypeDefinition.setBaseType(EnumBaseObjectType.fromValue(typeDefinition.getBaseType().getTypeId().getId()));
cmisTypeDefinition.setParentId(typeDefinition.getParentType().getTypeId().getId());
cmisTypeDefinition.setBaseTypeQueryName(typeDefinition.getBaseType().getQueryName());
cmisTypeDefinition.setBaseTypeId(EnumBaseObjectTypeIds.fromValue(typeDefinition.getBaseType().getTypeId().getId()));
if ((null != typeDefinition.getParentType()) && (null != typeDefinition.getParentType().getTypeId()))
{
cmisTypeDefinition.setParentId(typeDefinition.getParentType().getTypeId().getId());
}
cmisTypeDefinition.setQueryName(typeDefinition.getBaseType().getQueryName());
cmisTypeDefinition.setDescription(typeDefinition.getDescription());
cmisTypeDefinition.setCreatable(typeDefinition.isCreatable());
cmisTypeDefinition.setFileable(typeDefinition.isFileable());
cmisTypeDefinition.setQueryable(typeDefinition.isQueryable());
cmisTypeDefinition.setControllable(typeDefinition.isControllablePolicy());
cmisTypeDefinition.setControllableACL(typeDefinition.isControllableACL());
cmisTypeDefinition.setControllablePolicy(typeDefinition.isControllablePolicy());
cmisTypeDefinition.setIncludedInSupertypeQuery(typeDefinition.isIncludeInSuperTypeQuery());
if (includeProperties)
@@ -380,17 +561,12 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
*/
private CmisTypeDefinitionType getCmisTypeDefinition(CMISTypeDefinition typeDef, boolean includeProperties) throws CmisException
{
if (typeDef.getParentType() == null)
{
return null;
}
if (typeDef == null)
{
throw cmisObjectsUtils.createCmisException("Type not found", EnumServiceException.OBJECT_NOT_FOUND);
}
JAXBElement<? extends CmisTypeDefinitionType> result = null;
CmisTypeDefinitionType result = null;
switch (typeDef.getTypeId().getScope())
{
@@ -399,87 +575,27 @@ public class DMRepositoryServicePort extends DMAbstractServicePort implements Re
setCmisTypeDefinitionProperties(documentDefinitionType, typeDef, includeProperties);
documentDefinitionType.setVersionable(typeDef.isVersionable());
documentDefinitionType.setContentStreamAllowed(contentStreamAllowedEnumMapping.get(typeDef.getContentStreamAllowed()));
result = cmisObjectFactory.createDocumentType(documentDefinitionType);
result = documentDefinitionType;
break;
case FOLDER:
CmisTypeFolderDefinitionType folderDefinitionType = new CmisTypeFolderDefinitionType();
setCmisTypeDefinitionProperties(folderDefinitionType, typeDef, includeProperties);
result = cmisObjectFactory.createFolderType(folderDefinitionType);
result = folderDefinitionType;
break;
case POLICY:
CmisTypePolicyDefinitionType policyDefinitionType = new CmisTypePolicyDefinitionType();
setCmisTypeDefinitionProperties(policyDefinitionType, typeDef, includeProperties);
result = cmisObjectFactory.createPolicyType(policyDefinitionType);
result = policyDefinitionType;
break;
case RELATIONSHIP:
CmisTypeRelationshipDefinitionType relationshipDefinitionType = new CmisTypeRelationshipDefinitionType();
setCmisTypeDefinitionProperties(relationshipDefinitionType, typeDef, includeProperties);
result = cmisObjectFactory.createRelationshipType(relationshipDefinitionType);
result = relationshipDefinitionType;
break;
case UNKNOWN:
throw cmisObjectsUtils.createCmisException("Unknown CMIS Type", EnumServiceException.INVALID_ARGUMENT);
}
return result.getValue();
}
/**
* Gets the list of all types in the repository.
*
* @param parameters repositoryId: repository Id; typeId: type Id; returnPropertyDefinitions: false (default); maxItems: 0 = Repository-default number of items(Default);
* skipCount: 0 = start;
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME)
*/
public void getTypes(String repositoryId, String typeId, Boolean returnPropertyDefinitions, BigInteger maxItems, BigInteger skipCount,
Holder<List<CmisTypeDefinitionType>> type, Holder<Boolean> hasMoreItems) throws CmisException
{
checkRepositoryId(repositoryId);
Collection<CMISTypeDefinition> typeDefs;
if ((typeId == null) || typeId.equals(""))
{
typeDefs = cmisDictionaryService.getAllTypes();
}
else
{
CMISTypeDefinition typeDef = cmisDictionaryService.findType(typeId);
typeDefs = typeDef.getSubTypes(true);
}
// skip
Cursor cursor = createCursor(typeDefs.size(), skipCount, maxItems);
Iterator<CMISTypeDefinition> iterTypeDefs = typeDefs.iterator();
for (int i = 0; i < cursor.getStartRow(); i++)
{
iterTypeDefs.next();
}
boolean returnPropertyDefinitionsVal = returnPropertyDefinitions == null ? false : returnPropertyDefinitions.booleanValue();
type.value = new LinkedList<CmisTypeDefinitionType>();
for (int i = cursor.getStartRow(); i <= cursor.getEndRow(); i++)
{
CmisTypeDefinitionType element = getCmisTypeDefinition(iterTypeDefs.next(), returnPropertyDefinitionsVal);
if (element != null)
{
type.value.add(element);
}
}
hasMoreItems.value = ((skipCount == null) || (maxItems == null)) ? (false) : ((cursor.getEndRow() < typeDefs.size()));
}
/**
* Gets the definition for specified object type
*
* @param parameters repositoryId: repository Id; typeId: type Id;
* @return CMIS type definition
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME)
*/
public CmisTypeDefinitionType getTypeDefinition(String repositoryId, String typeId) throws CmisException
{
checkRepositoryId(repositoryId);
CMISTypeDefinition typeDef = cmisDictionaryService.findType(typeId);
return getCmisTypeDefinition(typeDef, true);
return result;
}
}

View File

@@ -24,14 +24,18 @@
*/
package org.alfresco.repo.cmis.ws;
import java.util.LinkedList;
import java.util.List;
import javax.xml.ws.Holder;
import org.alfresco.cmis.CMISContentStreamAllowedEnum;
import org.alfresco.cmis.CMISDictionaryModel;
import org.alfresco.cmis.CMISTypeDefinition;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.cmis.PropertyFilter;
import org.alfresco.repo.cmis.ws.utils.AlfrescoObjectType;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockStatus;
import org.alfresco.service.cmr.repository.ContentWriter;
@@ -69,10 +73,31 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
{
checkRepositoryId(repositoryId);
NodeRef workingCopyNodeRef = cmisObjectsUtils.getIdentifierInstance(documentId, AlfrescoObjectType.DOCUMENT_OBJECT);
assertWorkingCopy(workingCopyNodeRef);
assertVersionableIsTrue(workingCopyNodeRef);
assertLatestVersion(workingCopyNodeRef, true);
checkOutCheckInService.cancelCheckout(workingCopyNodeRef);
}
private void assertVersionableIsTrue(NodeRef workingCopyNodeRef) throws CmisException
{
if (!getTypeDefinition(workingCopyNodeRef).isVersionable())
{
// TODO: uncomment this when CMIS dictionary model will be corrected
// throw cmisObjectsUtils.createCmisException("Document that was specified is not versionable", EnumServiceException.CONSTRAINT);
}
}
private CMISTypeDefinition getTypeDefinition(NodeRef nodeRef) throws CmisException
{
String typeId = propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_OBJECT_TYPE_ID, null);
CMISTypeDefinition typeDefinition = (null != typeId) ? (cmisDictionaryService.findType(typeId)) : (null);
if (null == typeDefinition)
{
throw cmisObjectsUtils.createCmisException(("Object type property is invalid"), EnumServiceException.RUNTIME);
}
return typeDefinition;
}
/**
* Makes the private working copy the current version of the document.
*
@@ -85,12 +110,21 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME, CONSTRAINT, STORAGE,
* STREAM_NOT_SUPPORTED, UPDATE_CONFLICT, VERSIONING)
*/
public void checkIn(String repositoryId, Holder<String> documentId, Boolean major, CmisPropertiesType properties, CmisContentStreamType contentStream, String checkinComment)
throws CmisException
public void checkIn(String repositoryId, Holder<String> documentId, Boolean major, CmisPropertiesType properties, CmisContentStreamType contentStream, String checkinComment,
List<String> applyPolicies, CmisAccessControlListType addACEs, CmisAccessControlListType removeACEs) throws CmisException
{
checkRepositoryId(repositoryId);
NodeRef workingCopyNodeRef = cmisObjectsUtils.getIdentifierInstance(documentId.value, AlfrescoObjectType.DOCUMENT_OBJECT);
assertWorkingCopy(workingCopyNodeRef);
assertVersionableIsTrue(workingCopyNodeRef);
assertLatestVersion(workingCopyNodeRef, true);
String versionSeriesId = propertiesUtil.getProperty(workingCopyNodeRef, CMISDictionaryModel.PROP_VERSION_SERIES_ID, null);
CMISTypeDefinition seriesObjectTypeDefinition = getTypeDefinition((NodeRef) cmisObjectsUtils.getIdentifierInstance(versionSeriesId, AlfrescoObjectType.DOCUMENT_OBJECT));
if ((null != contentStream) && (CMISContentStreamAllowedEnum.NOT_ALLOWED == seriesObjectTypeDefinition.getContentStreamAllowed()))
{
throw cmisObjectsUtils.createCmisException("Content stream is not allowed", EnumServiceException.STREAM_NOT_SUPPORTED);
}
if (contentStream != null)
{
@@ -106,10 +140,19 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
}
}
NodeRef nodeRef = checkOutCheckInService.checkin(workingCopyNodeRef,
createVersionProperties(checkinComment, major != null && major ? VersionType.MAJOR : VersionType.MINOR));
NodeRef nodeRef;
try
{
nodeRef = checkOutCheckInService.checkin(workingCopyNodeRef, createVersionProperties(checkinComment, ((null == major) || major) ? (VersionType.MAJOR)
: (VersionType.MINOR)));
propertiesUtil.setProperties(nodeRef, properties, createPropertyFilter(propertiesUtil.createStandardNotUpdatablePropertiesFilter()));
propertiesUtil.setProperties(nodeRef, properties, null);
}
catch (Exception e)
{
throw cmisObjectsUtils.createCmisException("Unable to check in Private Working Copy object that was specified", EnumServiceException.STORAGE, e);
}
// TODO: applyPolicies, addACEs, removeACEs
documentId.value = propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_OBJECT_ID, documentId.value);
}
@@ -126,18 +169,26 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
public void checkOut(String repositoryId, Holder<String> documentId, Holder<Boolean> contentCopied) throws CmisException
{
checkRepositoryId(repositoryId);
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(documentId.value, AlfrescoObjectType.DOCUMENT_OBJECT);
LockStatus lockStatus = lockService.getLockStatus(documentNodeRef);
assertVersionableIsTrue(documentNodeRef);
assertLatestVersion(documentNodeRef, false);
LockStatus lockStatus = lockService.getLockStatus(documentNodeRef);
if (lockStatus.equals(LockStatus.LOCKED) || lockStatus.equals(LockStatus.LOCK_OWNER) || nodeService.hasAspect(documentNodeRef, ContentModel.ASPECT_WORKING_COPY))
{
throw cmisObjectsUtils.createCmisException("Object is already checked out", EnumServiceException.NOT_SUPPORTED);
throw cmisObjectsUtils.createCmisException("Object is already checked out", EnumServiceException.UPDATE_CONFLICT);
}
NodeRef pwcNodeRef = checkoutNode(documentNodeRef);
documentId.value = propertiesUtil.getProperty(pwcNodeRef, CMISDictionaryModel.PROP_OBJECT_ID, documentId.value);
contentCopied.value = true;
try
{
NodeRef pwcNodeRef = checkoutNode(documentNodeRef);
documentId.value = propertiesUtil.getProperty(pwcNodeRef, CMISDictionaryModel.PROP_OBJECT_ID, documentId.value);
contentCopied.value = null != nodeService.getProperty(pwcNodeRef, ContentModel.PROP_CONTENT);
}
catch (Exception e)
{
throw cmisObjectsUtils.createCmisException(("Unable to execute Check Out services. Cause message: " + e.toString()), EnumServiceException.STORAGE);
}
}
/**
@@ -151,6 +202,12 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
{
checkRepositoryId(repositoryId);
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(versionSeriesId, AlfrescoObjectType.DOCUMENT_OBJECT);
NodeRef workingCopyRef = (cmisObjectsUtils.isWorkingCopy(documentNodeRef)) ? (documentNodeRef) : (checkOutCheckInService.getWorkingCopy(documentNodeRef));
if ((null != workingCopyRef) && cmisObjectsUtils.isWorkingCopy(workingCopyRef))
{
documentNodeRef = checkOutCheckInService.cancelCheckout(workingCopyRef);
}
versionService.deleteVersionHistory(documentNodeRef);
}
@@ -161,35 +218,44 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
* @return list of CmisObjectType
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME, FILTER_NOT_VALID)
*/
public GetAllVersionsResponse getAllVersions(GetAllVersions parameters) throws CmisException
public List<CmisObjectType> getAllVersions(String repositoryId, String versionSeriesId, String filter, Boolean includeAllowableActions,
EnumIncludeRelationships includeRelationships) throws CmisException
{
checkRepositoryId(parameters.getRepositoryId());
checkRepositoryId(repositoryId);
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(parameters.getVersionSeriesId(), AlfrescoObjectType.DOCUMENT_OBJECT);
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(versionSeriesId, AlfrescoObjectType.DOCUMENT_OBJECT);
documentNodeRef = cmisObjectsUtils.getLatestNode(documentNodeRef, false);
PropertyFilter propertyFilter = createPropertyFilter(parameters.getFilter());
PropertyFilter propertyFilter = createPropertyFilter(filter);
GetAllVersionsResponse response = new GetAllVersionsResponse();
List<CmisObjectType> objects = response.getObject();
List<CmisObjectType> objects = new LinkedList<CmisObjectType>();
searchWorkingCopy(documentNodeRef, propertyFilter, objects);
objects.add(createCmisObject(documentNodeRef, propertyFilter));
try
{
NodeRef workingCopyNodeReference = cmisObjectsUtils.isWorkingCopy(documentNodeRef) ? documentNodeRef : checkOutCheckInService.getWorkingCopy(documentNodeRef);
if (null != workingCopyNodeReference)
{
objects.add(createCmisObject(workingCopyNodeReference, propertyFilter));
}
}
catch (Exception e)
{
if (!(e instanceof AccessDeniedException))
{
throw cmisObjectsUtils.createCmisException(e.toString(), EnumServiceException.RUNTIME);
}
}
VersionHistory versionHistory = versionService.getVersionHistory(documentNodeRef);
if (versionHistory == null)
if (null != versionHistory)
{
return response;
for (Version version = versionService.getCurrentVersion(documentNodeRef); null != version; version = versionHistory.getPredecessor(version))
{
objects.add(createCmisObject(version.getFrozenStateNodeRef(), propertyFilter));
}
}
// TODO: includeAllowableActions, includeRelationships
Version version = versionService.getCurrentVersion(documentNodeRef);
while (version != null)
{
objects.add(createCmisObject(version.getFrozenStateNodeRef(), propertyFilter));
version = versionHistory.getPredecessor(version);
}
return response;
return objects;
}
/**
@@ -200,41 +266,43 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
* @return CmisObjectType with properties
* @throws CmisException (with following {@link EnumServiceException} : INVALID_ARGUMENT, OBJECT_NOT_FOUND, NOT_SUPPORTED, PERMISSION_DENIED, RUNTIME, FILTER_NOT_VALID)
*/
public GetPropertiesOfLatestVersionResponse getPropertiesOfLatestVersion(GetPropertiesOfLatestVersion parameters) throws CmisException
public CmisObjectType getPropertiesOfLatestVersion(String repositoryId, String versionSeriesId, boolean major, String filter, Boolean includeACL) throws CmisException
{
checkRepositoryId(parameters.getRepositoryId());
PropertyFilter propertyFilter = createPropertyFilter(parameters.getFilter());
checkRepositoryId(repositoryId);
PropertyFilter propertyFilter = createPropertyFilter(filter);
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(parameters.getVersionSeriesId(), AlfrescoObjectType.DOCUMENT_OBJECT);
NodeRef latestVersionNodeRef = cmisObjectsUtils.getLatestNode(documentNodeRef, parameters.isMajorVersion());
NodeRef documentNodeRef = cmisObjectsUtils.getIdentifierInstance(versionSeriesId, AlfrescoObjectType.DOCUMENT_OBJECT);
NodeRef latestVersionNodeRef = cmisObjectsUtils.getLatestNode(documentNodeRef, major);
Boolean majorVersionProperty = propertiesUtil.getProperty(latestVersionNodeRef, CMISDictionaryModel.PROP_IS_MAJOR_VERSION, false);
if (parameters.isMajorVersion() && !majorVersionProperty)
if (major && !majorVersionProperty)
{
throw cmisObjectsUtils.createCmisException("Object that was specified has no latest major version", EnumServiceException.OBJECT_NOT_FOUND);
}
GetPropertiesOfLatestVersionResponse response = new GetPropertiesOfLatestVersionResponse();
response.setObject(new CmisObjectType());
response.getObject().setProperties(propertiesUtil.getPropertiesType(latestVersionNodeRef.toString(), propertyFilter));
CmisObjectType result = new CmisObjectType();
result.setProperties(propertiesUtil.getPropertiesType(latestVersionNodeRef.toString(), propertyFilter));
// TODO: includeACL
return response;
return result;
}
private void searchWorkingCopy(NodeRef documentNodeRef, PropertyFilter propertyFilter, List<CmisObjectType> resultList) throws CmisException
private void assertLatestVersion(NodeRef nodeRef, boolean shouldBePwc) throws CmisException
{
NodeRef workingCopyNodeReference = cmisObjectsUtils.isWorkingCopy(documentNodeRef) ? documentNodeRef : checkOutCheckInService.getWorkingCopy(documentNodeRef);
if (workingCopyNodeReference != null)
if (shouldBePwc)
{
resultList.add(createCmisObject(workingCopyNodeReference, propertyFilter));
if (!cmisObjectsUtils.isWorkingCopy(nodeRef))
{
throw cmisObjectsUtils.createCmisException("Object isn't checked out", EnumServiceException.UPDATE_CONFLICT);
}
}
}
private void assertWorkingCopy(NodeRef nodeRef) throws CmisException
{
if (!cmisObjectsUtils.isWorkingCopy(nodeRef))
else
{
throw cmisObjectsUtils.createCmisException("Object isn't checked out", EnumServiceException.NOT_SUPPORTED);
Boolean latestVersion = propertiesUtil.getProperty(nodeRef, CMISDictionaryModel.PROP_IS_LATEST_VERSION, false);
if (!latestVersion && !cmisObjectsUtils.isWorkingCopy(nodeRef))
{
throw cmisObjectsUtils.createCmisException("Operation can be executed only on the latest document version", EnumServiceException.VERSIONING);
}
}
}
}

View File

@@ -37,7 +37,7 @@ import org.alfresco.cmis.CMISTypeDefinition;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.cmis.ws.CmisException;
import org.alfresco.repo.cmis.ws.CmisFaultType;
import org.alfresco.repo.cmis.ws.EnumObjectType;
import org.alfresco.repo.cmis.ws.EnumBaseObjectTypeIds;
import org.alfresco.repo.cmis.ws.EnumRelationshipDirection;
import org.alfresco.repo.cmis.ws.EnumServiceException;
import org.alfresco.repo.cmis.ws.utils.DescendantsQueueManager.DescendantElement;
@@ -344,25 +344,25 @@ public class CmisObjectsUtils
return false;
}
public EnumObjectType determineObjectType(String identifier)
public EnumBaseObjectTypeIds determineObjectType(String identifier)
{
if (isRelationship(identifier))
{
return EnumObjectType.RELATIONSHIP;
return EnumBaseObjectTypeIds.CMIS_RELATIONSHIP;
}
NodeRef objectNodeReference = new NodeRef(identifier);
if (isFolder(objectNodeReference))
{
return EnumObjectType.FOLDER;
return EnumBaseObjectTypeIds.CMIS_FOLDER;
}
if (isDocument(objectNodeReference))
{
return EnumObjectType.DOCUMENT;
return EnumBaseObjectTypeIds.CMIS_DOCUMENT;
}
return EnumObjectType.POLICY;
return EnumBaseObjectTypeIds.CMIS_POLICY;
}
public boolean isChildOfThisFolder(NodeRef objectNodeReference, NodeRef folderNodeReference)
@@ -422,13 +422,12 @@ public class CmisObjectsUtils
if ((null != latestVersion) && (VersionType.MAJOR != latestVersion.getVersionType()))
{
VersionHistory versionHistory = versionService.getVersionHistory(latestVersion.getFrozenStateNodeRef());
if (null != versionHistory)
{
do
for (latestVersion = versionHistory.getPredecessor(latestVersion); (null != latestVersion) && (VersionType.MAJOR != latestVersion.getVersionType()); latestVersion = versionHistory
.getPredecessor(latestVersion))
{
latestVersion = versionHistory.getPredecessor(latestVersion);
} while ((null != latestVersion) && (VersionType.MAJOR != latestVersion.getVersionType()));
}
}
if ((null != latestVersion) && (null != latestVersion.getFrozenStateNodeRef()))
@@ -527,12 +526,12 @@ public class CmisObjectsUtils
{
result = getNodeRefFromVersion(result, nodeRefAndVersionLabel.getSecond());
if ((null != result) || !nodeService.exists(result))
if ((null != result) && nodeService.exists(result))
{
return result;
return result;
}
}
}
}
throw createCmisException(INVALID_OBJECT_IDENTIFIER_MESSAGE, EnumServiceException.OBJECT_NOT_FOUND);
}
@@ -575,7 +574,7 @@ public class CmisObjectsUtils
}
result = version.getFrozenStateNodeRef();
}
}
}
return result;
@@ -616,6 +615,7 @@ public class CmisObjectsUtils
this.children = children;
}
@SuppressWarnings("unused")
protected UnlinkOperationStatus()
{
}

View File

@@ -135,26 +135,6 @@ public class PropertyUtil
this.cmisObjectsUtils = cmisObjectsUtils;
}
/**
* @return <b>String</b> value that contains standard not updatable properties filter token
*/
public String createStandardNotUpdatablePropertiesFilter()
{
StringBuilder filter = new StringBuilder(CMISDictionaryModel.PROP_OBJECT_ID);
filter.append(PropertyFilter.PROPERTY_NAME_TOKENS_DELIMETER);
filter.append(CMISDictionaryModel.PROP_OBJECT_TYPE_ID);
filter.append(PropertyFilter.PROPERTY_NAME_TOKENS_DELIMETER);
filter.append(CMISDictionaryModel.PROP_ALLOWED_CHILD_OBJECT_TYPE_IDS);
filter.append(PropertyFilter.PROPERTY_NAME_TOKENS_DELIMETER);
filter.append(CMISDictionaryModel.PROP_PARENT_ID);
filter.append(PropertyFilter.PROPERTY_NAME_TOKENS_DELIMETER);
filter.append(CMISDictionaryModel.PROP_VERSION_SERIES_CHECKED_OUT_ID);
filter.append(PropertyFilter.PROPERTY_NAME_TOKENS_DELIMETER);
filter.append(CMISDictionaryModel.PROP_VERSION_SERIES_ID);
return filter.toString();
}
/**
* Gets property value by its name from Node Reference object
*
@@ -190,7 +170,7 @@ public class PropertyUtil
* @return value instance of the appropriate type if specified <i>cmisProperties</i> contains specified properties and <i>defaultValue</i> if requested property value or
* <i>cmisProperties</i> or <i>property</i> are <b>null</b> or if some exception occurred during property searching and receiving
*/
public <ResultType> ResultType getCmisPropertyValue(CmisPropertiesType cmisProperties, String property, ResultType defaultValue)
public <ResultType> ResultType getCmisPropertyValue(CmisPropertiesType cmisProperties, String property, ResultType defaultValue) throws CmisException
{
if ((null == property) || (null == cmisProperties))
{
@@ -199,7 +179,7 @@ public class PropertyUtil
for (CmisProperty cmisProperty : cmisProperties.getProperty())
{
if ((null != cmisProperty) && property.equals(cmisProperty.getName()))
if ((null != cmisProperty) && property.equals(getPropertyName(cmisProperty)))
{
return convertPropertyValue(getValue(cmisProperty), defaultValue);
}
@@ -226,185 +206,132 @@ public class PropertyUtil
}
}
private Object getValue(CmisProperty cmisProperty)
private Object getValue(CmisProperty cmisProperty) throws CmisException
{
Object value = null;
String propertyName = getPropertyName(cmisProperty);
if ((null == cmisProperty) || (null == propertyName))
{
return value;
}
PropertyMultiValueStateEnum multivaluedState = getPropertyMultiValuedState(null, propertyName);
Collection<?> convertedValue = null;
if (cmisProperty instanceof CmisPropertyBoolean)
{
Collection<Boolean> convertedValue = ((CmisPropertyBoolean) cmisProperty).getValue();
if (null != convertedValue)
{
if (1 == convertedValue.size())
{
value = convertedValue.iterator().next();
}
else
{
if (convertedValue.size() > 1)
{
value = convertedValue;
}
}
}
convertedValue = ((CmisPropertyBoolean) cmisProperty).getValue();
}
else if (cmisProperty instanceof CmisPropertyDateTime)
{
Collection<XMLGregorianCalendar> convertedValue = ((CmisPropertyDateTime) cmisProperty).getValue();
if (null != convertedValue)
{
if (1 == convertedValue.size())
{
value = convertedValue.iterator().next();
}
else
{
if (convertedValue.size() > 1)
{
value = convertedValue;
}
}
}
convertedValue = ((CmisPropertyDateTime) cmisProperty).getValue();
}
else if (cmisProperty instanceof CmisPropertyDecimal)
{
Collection<BigDecimal> convertedValue = ((CmisPropertyDecimal) cmisProperty).getValue();
if (null != convertedValue)
{
if (1 == convertedValue.size())
{
value = convertedValue.iterator().next();
}
else
{
if (convertedValue.size() > 1)
{
value = convertedValue;
}
}
}
convertedValue = ((CmisPropertyDecimal) cmisProperty).getValue();
}
else if (cmisProperty instanceof CmisPropertyHtml)
{
Collection<CmisPropertyHtml.Value> convertedValue = ((CmisPropertyHtml) cmisProperty).getValue();
if (null != convertedValue)
{
if (1 == convertedValue.size())
{
value = convertedValue.iterator().next();
}
else
{
if (convertedValue.size() > 1)
{
value = convertedValue;
}
}
}
convertedValue = ((CmisPropertyHtml) cmisProperty).getValue();
}
else if (cmisProperty instanceof CmisPropertyId)
{
Collection<String> convertedValue = ((CmisPropertyId) cmisProperty).getValue();
if (null != convertedValue)
{
if (1 == convertedValue.size())
{
value = convertedValue.iterator().next();
}
else
{
if (convertedValue.size() > 1)
{
value = convertedValue;
}
}
}
convertedValue = ((CmisPropertyId) cmisProperty).getValue();
}
else if (cmisProperty instanceof CmisPropertyInteger)
{
Collection<BigInteger> convertedValue = ((CmisPropertyInteger) cmisProperty).getValue();
if (null != convertedValue)
{
if (1 == convertedValue.size())
{
value = convertedValue.iterator().next();
}
else
{
if (convertedValue.size() > 1)
{
value = convertedValue;
}
}
}
convertedValue = ((CmisPropertyInteger) cmisProperty).getValue();
}
else if (cmisProperty instanceof CmisPropertyString)
{
Collection<String> convertedValue = ((CmisPropertyString) cmisProperty).getValue();
if (null != convertedValue)
{
if (1 == convertedValue.size())
{
value = convertedValue.iterator().next();
}
else
{
if (convertedValue.size() > 1)
{
value = convertedValue;
}
}
}
convertedValue = ((CmisPropertyString) cmisProperty).getValue();
}
else if (cmisProperty instanceof CmisPropertyUri)
{
Collection<String> convertedValue = ((CmisPropertyUri) cmisProperty).getValue();
if (null != convertedValue)
{
if (1 == convertedValue.size())
{
value = convertedValue.iterator().next();
}
else
{
if (convertedValue.size() > 1)
{
value = convertedValue;
}
}
}
convertedValue = ((CmisPropertyUri) cmisProperty).getValue();
}
else if (cmisProperty instanceof CmisPropertyXml)
{
Collection<CmisPropertyXml.Value> convertedValue = ((CmisPropertyXml) cmisProperty).getValue();
convertedValue = ((CmisPropertyXml) cmisProperty).getValue();
}
if (null != convertedValue)
if (null != convertedValue)
{
if (isMultiValued(propertyName, multivaluedState, convertedValue))
{
if (1 == convertedValue.size())
{
value = convertedValue.iterator().next();
}
else
{
if (convertedValue.size() > 1)
{
value = convertedValue;
}
}
value = (convertedValue.size() > 0) ? (convertedValue) : (null);
}
else
{
value = convertedValue.iterator().next();
}
}
return value;
}
private boolean isMultiValued(String propertyName, PropertyMultiValueStateEnum state, Collection<?> values) throws CmisException
{
// TODO: WARNING!!! This is invalid behavior! Multi valued property state can't be identified in this way!!!
if (PropertyMultiValueStateEnum.PROPERTY_NOT_FOUND == state)
{
return (values.size() > 0) ? (values.size() > 1) : (true);
}
if ((PropertyMultiValueStateEnum.PROPERTY_NOT_MULTIVALUED == state) && (values.size() > 1))
{
throw cmisObjectsUtils.createCmisException("\"" + propertyName + "\" property is not Multi Valued", EnumServiceException.INVALID_ARGUMENT);
}
return PropertyMultiValueStateEnum.PROPERTY_MULTIVALUED == state;
}
private PropertyMultiValueStateEnum getPropertyMultiValuedState(String typeId, String cmisPropertyName)
{
if ((null == cmisPropertyName) || cmisPropertyName.equals(""))
{
return PropertyMultiValueStateEnum.PROPERTY_NOT_FOUND;
}
CMISTypeDefinition typeDefinition = ((null != typeId) && !typeId.equals("")) ? (cmisDictionaryService.findType(typeId)) : (null);
CMISPropertyDefinition propertyDefinition = null;
if ((null != typeDefinition) && (null != typeDefinition.getOwnedPropertyDefinitions()))
{
propertyDefinition = typeDefinition.getOwnedPropertyDefinitions().get(cmisPropertyName);
}
else
{
propertyDefinition = cmisDictionaryService.findProperty(cmisPropertyName, null);
}
if ((null == propertyDefinition) || (null == propertyDefinition.getPropertyAccessor()))
{
return PropertyMultiValueStateEnum.PROPERTY_NOT_FOUND;
}
PropertyDefinition nativePropertyDefinition = null;
if (null != propertyDefinition.getPropertyAccessor().getMappedProperty())
{
nativePropertyDefinition = dictionaryService.getProperty(propertyDefinition.getPropertyAccessor().getMappedProperty());
}
else
{
nativePropertyDefinition = dictionaryService.getProperty(createQName(cmisPropertyName));
}
if (null == nativePropertyDefinition)
{
return PropertyMultiValueStateEnum.PROPERTY_NOT_FOUND;
}
return (nativePropertyDefinition.isMultiValued()) ? (PropertyMultiValueStateEnum.PROPERTY_MULTIVALUED) : (PropertyMultiValueStateEnum.PROPERTY_NOT_MULTIVALUED);
}
private enum PropertyMultiValueStateEnum
{
PROPERTY_MULTIVALUED, PROPERTY_NOT_MULTIVALUED, PROPERTY_NOT_FOUND;
}
/**
* Converts <b>CmisPropertiesType</b> properties representation to rapidly accessible form
*
@@ -425,8 +352,8 @@ public class PropertyUtil
{
if (null != cmisProperty)
{
String name = cmisProperty.getName();
properties.put(name, getValue(cmisProperty));
String pdid = getPropertyName(cmisProperty);
properties.put(pdid, getValue(cmisProperty));
}
}
@@ -438,11 +365,12 @@ public class PropertyUtil
*
* @param nodeRef - <b>NodeRef</b> for node for those properties must be setted
* @param properties - <b>CmisPropertiesType</b> instance that contains all the necessary properties' fields
* @param updateOptional - <b>boolean</b> value. If <b>true</b> - optionally updatable properties will be updated and will be ignored in other case
* @param ignoringPropertiesFilter - <b>PropertyFilter</b> instance. This filter determines which properties should be ignored and not setted without exception. If this
* parameter is <b>null</b> all properties will be processed in common flow
*/
public void setProperties(NodeRef nodeRef, CmisPropertiesType properties, PropertyFilter notUpdatablePropertiesFilter) throws CmisException
public void setProperties(NodeRef nodeRef, CmisPropertiesType properties, PropertyFilter ignoringPropertiesFilter) throws CmisException
{
// TODO: WARINING!!! This is WRONG behavior!!! Each CMIS object type and each property MUST be described in appropriate CMIS manner
// TODO: WARINING!!! This is WRONG behavior!!! Each CMIS object type and each property MUST be described in appropriate to CMIS manner
if ((null == nodeRef) || (null == properties) || (null == properties.getProperty()))
{
return;
@@ -461,31 +389,48 @@ public class PropertyUtil
for (CmisProperty property : properties.getProperty())
{
String propertyName = (null != property) ? (property.getName()) : (null);
if ((null != propertyName) && !notUpdatablePropertiesFilter.allow(propertyName))
String propertyName = getPropertyName(property);
if ((null == propertyName) || ((null != ignoringPropertiesFilter) && ignoringPropertiesFilter.allow(propertyName)))
{
Object value = getValue(property);
QName alfrescoPropertyName = null;
switch (checkProperty(nativeObjectType, cmisObjectType, propertyName, value, checkedOut))
{
case PROPERTY_CHECKED:
{
alfrescoPropertyName = cmisDictionaryService.findProperty(propertyName, cmisObjectType).getPropertyAccessor().getMappedProperty();
break;
}
case PROPERTY_NATIVE:
{
alfrescoPropertyName = createQName(propertyName);
break;
}
case PROPERTY_NOT_UPDATABLE:
{
continue;
}
}
nodeService.setProperty(nodeRef, alfrescoPropertyName, (Serializable) value);
continue;
}
Object value = getValue(property);
QName alfrescoPropertyName = null;
switch (checkProperty(nativeObjectType, cmisObjectType, propertyName, value, checkedOut))
{
case PROPERTY_CHECKED:
{
alfrescoPropertyName = cmisDictionaryService.findProperty(propertyName, cmisObjectType).getPropertyAccessor().getMappedProperty();
break;
}
case PROPERTY_NATIVE:
{
alfrescoPropertyName = createQName(propertyName);
break;
}
case PROPERTY_NOT_UPDATABLE:
{
throw cmisObjectsUtils.createCmisException(("\"" + propertyName + "\" property is not updatable by repository for specified Object id"),
EnumServiceException.CONSTRAINT);
}
}
nodeService.setProperty(nodeRef, alfrescoPropertyName, (Serializable) value);
}
}
public String getPropertyName(CmisProperty property)
{
String propertyName = (null != property) ? (property.getPdid()) : (null);
if (null == propertyName)
{
propertyName = property.getLocalname();
if (null == propertyName)
{
propertyName = property.getDisplayname();
}
}
return propertyName;
}
private QName createQName(String s)
@@ -516,7 +461,7 @@ public class PropertyUtil
{
CMISPropertyDefinition propertyDefinition = cmisDictionaryService.findProperty(propertyName, cmisObjectType);
if ((null == propertyDefinition) || ((null != propertyDefinition) && (null == propertyDefinition.getPropertyAccessor().getMappedProperty())))
if (null == propertyDefinition)
{
// TODO: WARINING!!! This is WRONG behavior!!! Each CMIS object type and each property MUST be described in appropriate CMIS manner
QName qualifiedName = createQName(propertyName);
@@ -531,7 +476,12 @@ public class PropertyUtil
boolean updatable = ((checkedOut) ? (CMISUpdatabilityEnum.READ_AND_WRITE_WHEN_CHECKED_OUT == propertyDefinition.getUpdatability())
: (CMISUpdatabilityEnum.READ_AND_WRITE == propertyDefinition.getUpdatability()));
if (updatable && propertyDefinition.isRequired() && (value == null))
if (!updatable)
{
return PropertyCheckingStateEnum.PROPERTY_NOT_UPDATABLE;
}
if (propertyDefinition.isRequired() && (value == null))
{
throw cmisObjectsUtils.createCmisException((propertyName + " property required"), EnumServiceException.CONSTRAINT);
}
@@ -637,20 +587,20 @@ public class PropertyUtil
/**
* Creates and initializes appropriate <b>CmisProperty</b> instance by name and data type
*
* @param name - <b>String</b> value that represents CMIS property name
* @param pdid - <b>String</b> value that represents CMIS property name
* @param dataType - <b>CMISDataTypeEnum</b> value that specifies real type of the property
* @param value - some instance of appropriate type or some <b>Collection</b> that contains several values of the type
* @return appropriate <b>CmisProperty</b> instance
*/
@SuppressWarnings("unchecked")
public CmisProperty createProperty(String name, CMISDataTypeEnum dataType, Serializable value)
public CmisProperty createProperty(String pdid, CMISDataTypeEnum dataType, Serializable value)
{
switch (dataType)
{
case BOOLEAN:
{
CmisPropertyBoolean property = new CmisPropertyBoolean();
property.setName(name);
property.setPdid(pdid);
if (value instanceof Collection)
{
@@ -669,7 +619,7 @@ public class PropertyUtil
case STRING:
{
CmisPropertyString property = new CmisPropertyString();
property.setName(name);
property.setPdid(pdid);
if (value instanceof Collection)
{
@@ -688,7 +638,7 @@ public class PropertyUtil
case INTEGER:
{
CmisPropertyInteger property = new CmisPropertyInteger();
property.setName(name);
property.setPdid(pdid);
if (value instanceof Collection)
{
@@ -707,7 +657,7 @@ public class PropertyUtil
case DATETIME:
{
CmisPropertyDateTime property = new CmisPropertyDateTime();
property.setName(name);
property.setPdid(pdid);
if (value instanceof Collection)
{
@@ -734,7 +684,7 @@ public class PropertyUtil
case ID:
{
CmisPropertyId property = new CmisPropertyId();
property.setName(name);
property.setPdid(pdid);
if (value instanceof Collection)
{
@@ -753,7 +703,7 @@ public class PropertyUtil
case URI:
{
CmisPropertyUri property = new CmisPropertyUri();
property.setName(name);
property.setPdid(pdid);
if (value instanceof Collection)
{
@@ -772,7 +722,7 @@ public class PropertyUtil
case DECIMAL:
{
CmisPropertyDecimal property = new CmisPropertyDecimal();
property.setName(name);
property.setPdid(pdid);
if (value instanceof Collection)
{
@@ -791,7 +741,7 @@ public class PropertyUtil
case XML:
{
CmisPropertyXml property = new CmisPropertyXml();
property.setName(name);
property.setPdid(pdid);
if (value instanceof Collection)
{
@@ -810,7 +760,7 @@ public class PropertyUtil
case HTML:
{
CmisPropertyHtml property = new CmisPropertyHtml();
property.setName(name);
property.setPdid(pdid);
if (value instanceof Collection)
{