Merging BRANCHES/DEV/BELARUS/HEAD-2010_03_09 to HEAD:

19261: CMIS-WS:

Bug fixing in WS Bindings and CMISServices

Bug related to DeleteTree with "unfile" flag was fixed.
- Removal of secondary parent associations was added to CMISServices.deleteObject method.
Objects state verification was added to MultifillingService.
- Verification of object and folder type was added. Verification of object presence in folder was added.
- Checking constraints for versioning typeDef was added.
DiscoveryService.query() problems were fixed.
- includeRelationships feature was added to DMDiscoveryServicePort.query().
- DMAbstractServicePort was refactored and extended to introduce functionality required for includeRelationships feature in other
binding port implementations.

TCK bug fixing
- Test cases in Java TCK tests for Query Ordering problem demonstration were developed
(CmisDiscoveryServiceClient.testQueryWithAscendingOrdering() and CmisDiscoveryServiceClient.testQueryWithDescendingOrdering()).
- CmisDiscoveryServiceClient.testQueryAllVersionsSearchable() was corrected. Using of invalid property "cmis:parentId" for none folder
object was removed.
- CmisDiscoveryServiceClient.testQueryRelationships() was fixed. Currently, this method correctly tests relationships receiving for
each EnumIncludeRelationships constant. Relationships supporting by repository checking was added. Test was redeveloped against new
functionality.
- Expected exceptions verification was corrected.
- Properties filter was corrected in concordance with CMIS Specification.
- RepositoryInfo and capabilities assertion was fixed and extended.
- Test for latest non-major version receiving was corrected.
- TCK Build file was corrected. WSI part was removed. Target "jar" that creates one executable jar was added.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@19270 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
David Caruana
2010-03-12 22:27:42 +00:00
parent f85d448070
commit 4860bf5ec6
4 changed files with 106 additions and 62 deletions

View File

@@ -53,6 +53,7 @@ import org.alfresco.cmis.CMISTypeDefinition;
import org.alfresco.cmis.PropertyFilter; import org.alfresco.cmis.PropertyFilter;
import org.alfresco.cmis.acl.CMISAccessControlEntryImpl; import org.alfresco.cmis.acl.CMISAccessControlEntryImpl;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil; import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
import org.alfresco.repo.cmis.ws.utils.PropertyUtil; import org.alfresco.repo.cmis.ws.utils.PropertyUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
@@ -83,7 +84,7 @@ public class DMAbstractServicePort
private static final String INVALID_REPOSITORY_ID_MESSAGE = "Invalid repository id"; private static final String INVALID_REPOSITORY_ID_MESSAGE = "Invalid repository id";
private static final Map<EnumACLPropagation, CMISAclPropagationEnum> ACL_PROPAGATION_ENUM_MAPPGIN; private static final Map<EnumACLPropagation, CMISAclPropagationEnum> ACL_PROPAGATION_ENUM_MAPPGIN;
private static final Map<EnumIncludeRelationships, CMISRelationshipDirectionEnum> INCLUDE_RELATIONSHIPS_ENUM_MAPPING; protected static final Map<EnumIncludeRelationships, CMISRelationshipDirectionEnum> INCLUDE_RELATIONSHIPS_ENUM_MAPPING;
private static final Map<CMISAllowedActionEnum, PropertyDescriptor> ALLOWED_ACTION_ENUM_MAPPING; private static final Map<CMISAllowedActionEnum, PropertyDescriptor> ALLOWED_ACTION_ENUM_MAPPING;
static static
{ {
@@ -215,73 +216,68 @@ public class DMAbstractServicePort
return paging.createCursor(totalRows, window); return paging.createCursor(totalRows, window);
} }
/**
* Returns true if folder contains object
*
* @param object object NodeRef
* @param folder folder NodeRef
* @return returns true if folder contains object
*/
protected boolean isObjectInFolder(NodeRef object, NodeRef folder)
{
NodeRef searchedObjectNodeRef = fileFolderService.searchSimple(folder, (String) nodeService.getProperty(object, ContentModel.PROP_NAME));
return (null != searchedObjectNodeRef) && (searchedObjectNodeRef.equals(object));
}
/** /**
* This method converts Alfresco's <b>NodeRef</b>'s to CMIS objects those will be stored in <b>resultList</b>-parameter. Properties for returning filtering also performs * This method converts Alfresco's <b>NodeRef</b>'s to CMIS objects those will be stored in <b>resultList</b>-parameter. Properties for returning filtering also performs
* *
* @param filter properties filter value for filtering objects returning properties * @param filter properties filter value for filtering objects returning properties
* @param includeRelationships * @param includeRelationships what relationships to include
* what relationships to include
* @param sourceList the list that contains all returning Node References * @param sourceList the list that contains all returning Node References
* @param resultList the list of <b>CmisObjectType</b> values for end response result collecting * @param resultList the list of <b>CmisObjectType</b> values for end response result collecting
* @throws CmisException * @throws CmisException
*/ */
protected void createCmisObjectList(PropertyFilter filter, CMISRelationshipDirectionEnum includeRelationships, protected void createCmisObjectList(PropertyFilter filter, CMISRelationshipDirectionEnum includeRelationships, boolean includeAllowableActions, String renditionFilter,
boolean includeAllowableActions, String renditionFilter, List<NodeRef> sourceList, List<NodeRef> sourceList, List<CmisObjectType> resultList) throws CmisException
List<CmisObjectType> resultList) throws CmisException
{ {
for (NodeRef objectNodeRef : sourceList) for (NodeRef objectNodeRef : sourceList)
{ {
resultList.add(createCmisObject(objectNodeRef, filter, includeRelationships, includeAllowableActions, resultList.add(createCmisObject(objectNodeRef, filter, includeRelationships, includeAllowableActions, renditionFilter));
renditionFilter));
} }
} }
/** /**
* This method creates and configures CMIS object against appropriate Alfresco object (NodeRef or AssociationRef). * This method creates and configures CMIS object against appropriate Alfresco object (NodeRef or AssociationRef).
* *
* @param object * @param object the Alfresco object
* the Alfresco object * @param filter accepted properties filter
* @param filter * @param includeRelationships what relationships to include
* accepted properties filter * @param includeAllowableActions should we include allowable actions?
* @param includeRelationships * @param renditionFilter the rendition filter
* what relationships to include
* @param includeAllowableActions
* should we include allowable actions?
* @param renditionFilter
* the rendition filter
* @return the converted CMIS object * @return the converted CMIS object
* @throws CmisException * @throws CmisException on error
* on error
*/ */
protected CmisObjectType createCmisObject(Object object, PropertyFilter filter, protected CmisObjectType createCmisObject(Object object, PropertyFilter filter, EnumIncludeRelationships includeRelationships, Boolean includeAllowableActions,
EnumIncludeRelationships includeRelationships, Boolean includeAllowableActions, String renditionFilter) String renditionFilter) throws CmisException
throws CmisException
{ {
return createCmisObject(object, filter, includeRelationships == null ? null return createCmisObject(object, filter, includeRelationships == null ? null : INCLUDE_RELATIONSHIPS_ENUM_MAPPING.get(includeRelationships), includeAllowableActions != null
: INCLUDE_RELATIONSHIPS_ENUM_MAPPING.get(includeRelationships), includeAllowableActions != null
&& includeAllowableActions, renditionFilter); && includeAllowableActions, renditionFilter);
} }
/** /**
* This method creates and configures CMIS object against appropriate Alfresco object (NodeRef or AssociationRef). * This method creates and configures CMIS object against appropriate Alfresco object (NodeRef or AssociationRef).
* *
* @param object * @param object the Alfresco object
* the Alfresco object * @param filter accepted properties filter
* @param filter * @param includeRelationships what relationships to include
* accepted properties filter * @param includeAllowableActions should we include allowable actions?
* @param includeRelationships * @param renditionFilter the rendition filter
* what relationships to include
* @param includeAllowableActions
* should we include allowable actions?
* @param renditionFilter
* the rendition filter
* @return the converted CMIS object * @return the converted CMIS object
* @throws CmisException * @throws CmisException on error
* on error
*/ */
protected CmisObjectType createCmisObject(Object object, PropertyFilter filter, protected CmisObjectType createCmisObject(Object object, PropertyFilter filter, CMISRelationshipDirectionEnum includeRelationships, boolean includeAllowableActions,
CMISRelationshipDirectionEnum includeRelationships, boolean includeAllowableActions, String renditionFilter) String renditionFilter) throws CmisException
throws CmisException
{ {
// Get a NodeRef if we can // Get a NodeRef if we can
if (object instanceof Version) if (object instanceof Version)
@@ -292,18 +288,7 @@ public class DMAbstractServicePort
result.setProperties(propertiesUtil.getProperties(object, filter)); result.setProperties(propertiesUtil.getProperties(object, filter));
if (object instanceof NodeRef && includeRelationships != null) if (object instanceof NodeRef && includeRelationships != null)
{ {
List<CmisObjectType> relationships = result.getRelationship(); appendWithRelationships((NodeRef) object, filter, includeRelationships, includeAllowableActions, renditionFilter, result);
try
{
for (AssociationRef assoc : cmisService.getRelationships((NodeRef)object, null, true, includeRelationships))
{
relationships.add(createCmisObject(assoc, filter, includeRelationships, includeAllowableActions, renditionFilter));
}
}
catch (CMISInvalidArgumentException e)
{
throw ExceptionUtil.createCmisException(e);
}
} }
if (includeAllowableActions) if (includeAllowableActions)
{ {
@@ -320,6 +305,23 @@ public class DMAbstractServicePort
return result; return result;
} }
protected void appendWithRelationships(NodeRef object, PropertyFilter filter, CMISRelationshipDirectionEnum includeRelationships, boolean includeAllowableActions,
String renditionFilter, CmisObjectType result) throws CmisException
{
List<CmisObjectType> relationships = result.getRelationship();
try
{
for (AssociationRef assoc : cmisService.getRelationships(object, null, true, includeRelationships))
{
relationships.add(createCmisObject(assoc, filter, includeRelationships, includeAllowableActions, renditionFilter));
}
}
catch (CMISInvalidArgumentException e)
{
throw ExceptionUtil.createCmisException(e);
}
}
/** /**
* Checks specified in CMIS request parameters repository Id. * Checks specified in CMIS request parameters repository Id.
* *
@@ -410,8 +412,8 @@ public class DMAbstractServicePort
} }
} }
protected CmisACLType applyAclCarefully(NodeRef object, CmisAccessControlListType addACEs, CmisAccessControlListType removeACEs, EnumACLPropagation aclPropagation, List<String> policies) protected CmisACLType applyAclCarefully(NodeRef object, CmisAccessControlListType addACEs, CmisAccessControlListType removeACEs, EnumACLPropagation aclPropagation,
throws CmisException List<String> policies) throws CmisException
{ {
if (addACEs == null && removeACEs == null) if (addACEs == null && removeACEs == null)
{ {

View File

@@ -33,6 +33,7 @@ import org.alfresco.cmis.CMISChangeType;
import org.alfresco.cmis.CMISDataTypeEnum; import org.alfresco.cmis.CMISDataTypeEnum;
import org.alfresco.cmis.CMISDictionaryModel; import org.alfresco.cmis.CMISDictionaryModel;
import org.alfresco.cmis.CMISQueryOptions; import org.alfresco.cmis.CMISQueryOptions;
import org.alfresco.cmis.CMISRelationshipDirectionEnum;
import org.alfresco.cmis.CMISResultSet; import org.alfresco.cmis.CMISResultSet;
import org.alfresco.cmis.CMISResultSetColumn; import org.alfresco.cmis.CMISResultSetColumn;
import org.alfresco.cmis.CMISResultSetRow; import org.alfresco.cmis.CMISResultSetRow;
@@ -95,6 +96,9 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
QueryResponse response = new QueryResponse(); QueryResponse response = new QueryResponse();
response.setObjects(new CmisObjectListType()); response.setObjects(new CmisObjectListType());
EnumIncludeRelationships cmisDirection = (null != parameters.getIncludeRelationships()) ? (parameters.getIncludeRelationships().getValue()) : (null);
CMISRelationshipDirectionEnum includeRelationships = INCLUDE_RELATIONSHIPS_ENUM_MAPPING.get(cmisDirection);
// for each row... // for each row...
for (CMISResultSetRow row : resultSet) for (CMISResultSetRow row : resultSet)
{ {
@@ -114,9 +118,10 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
CmisObjectType object = new CmisObjectType(); CmisObjectType object = new CmisObjectType();
object.setProperties(properties); object.setProperties(properties);
Object identifier; Object identifier;
NodeRef nodeRef;
try try
{ {
NodeRef nodeRef = row.getNodeRef(); nodeRef = row.getNodeRef();
identifier = cmisService.getReadableObject((String) nodeRef.toString(), Object.class); identifier = cmisService.getReadableObject((String) nodeRef.toString(), Object.class);
} }
catch (CMISServiceException e) catch (CMISServiceException e)
@@ -127,6 +132,10 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
{ {
object.setAllowableActions(determineObjectAllowableActions(identifier)); object.setAllowableActions(determineObjectAllowableActions(identifier));
} }
if (null != includeRelationships)
{
appendWithRelationships(nodeRef, createPropertyFilter((String) null), includeRelationships, includeAllowableActions, renditionFilter, object);
}
if (renditionFilter != null) if (renditionFilter != null)
{ {
List<CmisRenditionType> renditions = getRenditions(identifier, renditionFilter); List<CmisRenditionType> renditions = getRenditions(identifier, renditionFilter);
@@ -137,7 +146,7 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
} }
response.getObjects().getObjects().add(object); response.getObjects().getObjects().add(object);
} }
// TODO: response.getObjects().setNumItems(value); response.getObjects().setNumItems(BigInteger.valueOf(response.getObjects().getObjects().size()));
response.getObjects().setHasMoreItems(resultSet.hasMore()); response.getObjects().setHasMoreItems(resultSet.hasMore());
return response; return response;
} }
@@ -235,5 +244,4 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
result.add(object); result.add(object);
} }
} }
} }

View File

@@ -20,8 +20,11 @@ package org.alfresco.repo.cmis.ws;
import javax.xml.ws.Holder; import javax.xml.ws.Holder;
import org.alfresco.cmis.CMISDictionaryModel;
import org.alfresco.cmis.CMISServiceException; import org.alfresco.cmis.CMISServiceException;
import org.alfresco.cmis.CMISTypeDefinition;
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil; import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
import org.alfresco.service.cmr.repository.NodeRef;
/** /**
* Port for Multi-Filing service. * Port for Multi-Filing service.
@@ -64,6 +67,8 @@ public class DMMultiFilingServicePort extends DMAbstractServicePort implements M
public void removeObjectFromFolder(String repositoryId, String objectId, String folderId, Holder<CmisExtensionType> extension) throws CmisException public void removeObjectFromFolder(String repositoryId, String objectId, String folderId, Holder<CmisExtensionType> extension) throws CmisException
{ {
checkRepositoryId(repositoryId); checkRepositoryId(repositoryId);
checkConstraints(objectId, folderId);
try try
{ {
cmisService.removeObjectFromFolder(objectId, folderId); cmisService.removeObjectFromFolder(objectId, folderId);
@@ -72,5 +77,35 @@ public class DMMultiFilingServicePort extends DMAbstractServicePort implements M
{ {
throw ExceptionUtil.createCmisException(e); throw ExceptionUtil.createCmisException(e);
} }
} }
private void checkConstraints(String objectId, String folderId) throws CmisException
{
NodeRef objectNodeRef = null;
NodeRef folderNodeRef = null;
CMISTypeDefinition objectTypeDef = null;
try
{
objectNodeRef = cmisService.getObject(objectId, NodeRef.class, true, false, false);
folderNodeRef = cmisService.getFolder(folderId);
objectTypeDef = cmisService.getTypeDefinition(objectNodeRef);
}
catch (CMISServiceException e)
{
throw ExceptionUtil.createCmisException(e.getMessage(), EnumServiceException.INVALID_ARGUMENT);
}
if (!objectTypeDef.getTypeId().getBaseTypeId().equals(CMISDictionaryModel.DOCUMENT_TYPE_ID))
{
throw ExceptionUtil.createCmisException("Object " + objectId + " is not a document", EnumServiceException.INVALID_ARGUMENT);
}
if (!isObjectInFolder(objectNodeRef, folderNodeRef))
{
throw ExceptionUtil.createCmisException("Folder doesn't contain specified object", EnumServiceException.OBJECT_NOT_FOUND);
}
}
} }

View File

@@ -813,8 +813,7 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
} }
} }
// FIXME: change condition below to "!typeDef.isVersionable() && (null != versioningState)" when dictionary problem will be fixed if (!typeDef.isVersionable() && (null != versioningState))
if (false)
{ {
throw ExceptionUtil.createCmisException(("Verioning for \"" + documentTypeId + "\" document type is not allowed"), EnumServiceException.CONSTRAINT); throw ExceptionUtil.createCmisException(("Verioning for \"" + documentTypeId + "\" document type is not allowed"), EnumServiceException.CONSTRAINT);
} }