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.acl.CMISAccessControlEntryImpl;
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.PropertyUtil;
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 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;
static
{
@@ -96,7 +97,7 @@ public class DMAbstractServicePort
INCLUDE_RELATIONSHIPS_ENUM_MAPPING.put(EnumIncludeRelationships.SOURCE, CMISRelationshipDirectionEnum.SOURCE);
INCLUDE_RELATIONSHIPS_ENUM_MAPPING.put(EnumIncludeRelationships.TARGET, CMISRelationshipDirectionEnum.TARGET);
INCLUDE_RELATIONSHIPS_ENUM_MAPPING.put(EnumIncludeRelationships.BOTH, CMISRelationshipDirectionEnum.BOTH);
try
{
ALLOWED_ACTION_ENUM_MAPPING = new HashMap<CMISAllowedActionEnum, PropertyDescriptor>(97);
@@ -215,73 +216,68 @@ public class DMAbstractServicePort
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
*
* @param filter properties filter value for filtering objects returning properties
* @param includeRelationships
* what relationships to include
* @param includeRelationships what relationships to include
* @param sourceList the list that contains all returning Node References
* @param resultList the list of <b>CmisObjectType</b> values for end response result collecting
* @throws CmisException
*/
protected void createCmisObjectList(PropertyFilter filter, CMISRelationshipDirectionEnum includeRelationships,
boolean includeAllowableActions, String renditionFilter, List<NodeRef> sourceList,
List<CmisObjectType> resultList) throws CmisException
protected void createCmisObjectList(PropertyFilter filter, CMISRelationshipDirectionEnum includeRelationships, boolean includeAllowableActions, String renditionFilter,
List<NodeRef> sourceList, List<CmisObjectType> resultList) throws CmisException
{
for (NodeRef objectNodeRef : sourceList)
{
resultList.add(createCmisObject(objectNodeRef, filter, includeRelationships, includeAllowableActions,
renditionFilter));
resultList.add(createCmisObject(objectNodeRef, filter, includeRelationships, includeAllowableActions, renditionFilter));
}
}
/**
* This method creates and configures CMIS object against appropriate Alfresco object (NodeRef or AssociationRef).
*
* @param object
* the Alfresco object
* @param filter
* accepted properties filter
* @param includeRelationships
* what relationships to include
* @param includeAllowableActions
* should we include allowable actions?
* @param renditionFilter
* the rendition filter
* @param object the Alfresco object
* @param filter accepted properties filter
* @param includeRelationships what relationships to include
* @param includeAllowableActions should we include allowable actions?
* @param renditionFilter the rendition filter
* @return the converted CMIS object
* @throws CmisException
* on error
* @throws CmisException on error
*/
protected CmisObjectType createCmisObject(Object object, PropertyFilter filter,
EnumIncludeRelationships includeRelationships, Boolean includeAllowableActions, String renditionFilter)
throws CmisException
protected CmisObjectType createCmisObject(Object object, PropertyFilter filter, EnumIncludeRelationships includeRelationships, Boolean includeAllowableActions,
String renditionFilter) throws CmisException
{
return createCmisObject(object, filter, includeRelationships == null ? null
: INCLUDE_RELATIONSHIPS_ENUM_MAPPING.get(includeRelationships), includeAllowableActions != null
return createCmisObject(object, filter, includeRelationships == null ? null : INCLUDE_RELATIONSHIPS_ENUM_MAPPING.get(includeRelationships), includeAllowableActions != null
&& includeAllowableActions, renditionFilter);
}
/**
* This method creates and configures CMIS object against appropriate Alfresco object (NodeRef or AssociationRef).
*
* @param object
* the Alfresco object
* @param filter
* accepted properties filter
* @param includeRelationships
* what relationships to include
* @param includeAllowableActions
* should we include allowable actions?
* @param renditionFilter
* the rendition filter
* @param object the Alfresco object
* @param filter accepted properties filter
* @param includeRelationships what relationships to include
* @param includeAllowableActions should we include allowable actions?
* @param renditionFilter the rendition filter
* @return the converted CMIS object
* @throws CmisException
* on error
* @throws CmisException on error
*/
protected CmisObjectType createCmisObject(Object object, PropertyFilter filter,
CMISRelationshipDirectionEnum includeRelationships, boolean includeAllowableActions, String renditionFilter)
throws CmisException
protected CmisObjectType createCmisObject(Object object, PropertyFilter filter, CMISRelationshipDirectionEnum includeRelationships, boolean includeAllowableActions,
String renditionFilter) throws CmisException
{
// Get a NodeRef if we can
if (object instanceof Version)
@@ -292,18 +288,7 @@ public class DMAbstractServicePort
result.setProperties(propertiesUtil.getProperties(object, filter));
if (object instanceof NodeRef && includeRelationships != null)
{
List<CmisObjectType> relationships = result.getRelationship();
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);
}
appendWithRelationships((NodeRef) object, filter, includeRelationships, includeAllowableActions, renditionFilter, result);
}
if (includeAllowableActions)
{
@@ -320,6 +305,23 @@ public class DMAbstractServicePort
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.
*
@@ -407,11 +409,11 @@ public class DMAbstractServicePort
throw ExceptionUtil.createCmisException(e);
}
}
}
}
}
protected CmisACLType applyAclCarefully(NodeRef object, CmisAccessControlListType addACEs, CmisAccessControlListType removeACEs, EnumACLPropagation aclPropagation, List<String> policies)
throws CmisException
protected CmisACLType applyAclCarefully(NodeRef object, CmisAccessControlListType addACEs, CmisAccessControlListType removeACEs, EnumACLPropagation aclPropagation,
List<String> policies) throws CmisException
{
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.CMISDictionaryModel;
import org.alfresco.cmis.CMISQueryOptions;
import org.alfresco.cmis.CMISRelationshipDirectionEnum;
import org.alfresco.cmis.CMISResultSet;
import org.alfresco.cmis.CMISResultSetColumn;
import org.alfresco.cmis.CMISResultSetRow;
@@ -95,6 +96,9 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
QueryResponse response = new QueryResponse();
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 (CMISResultSetRow row : resultSet)
{
@@ -114,9 +118,10 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
CmisObjectType object = new CmisObjectType();
object.setProperties(properties);
Object identifier;
NodeRef nodeRef;
try
{
NodeRef nodeRef = row.getNodeRef();
nodeRef = row.getNodeRef();
identifier = cmisService.getReadableObject((String) nodeRef.toString(), Object.class);
}
catch (CMISServiceException e)
@@ -127,6 +132,10 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
{
object.setAllowableActions(determineObjectAllowableActions(identifier));
}
if (null != includeRelationships)
{
appendWithRelationships(nodeRef, createPropertyFilter((String) null), includeRelationships, includeAllowableActions, renditionFilter, object);
}
if (renditionFilter != null)
{
List<CmisRenditionType> renditions = getRenditions(identifier, renditionFilter);
@@ -137,7 +146,7 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
}
response.getObjects().getObjects().add(object);
}
// TODO: response.getObjects().setNumItems(value);
response.getObjects().setNumItems(BigInteger.valueOf(response.getObjects().getObjects().size()));
response.getObjects().setHasMoreItems(resultSet.hasMore());
return response;
}
@@ -226,7 +235,7 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
if (nodeService.exists(event.getChangedNode()) && includeAce)
{
appendWithAce(event.getChangedNode(), object);
}
}
CmisChangeEventType changeInfo = new CmisChangeEventType();
XMLGregorianCalendar modificationDate = propertiesUtil.convert(event.getChangeTime());
changeInfo.setChangeType(changesTypeMapping.get(event.getChangeType()));
@@ -235,5 +244,4 @@ public class DMDiscoveryServicePort extends DMAbstractServicePort implements Dis
result.add(object);
}
}
}

View File

@@ -20,8 +20,11 @@ package org.alfresco.repo.cmis.ws;
import javax.xml.ws.Holder;
import org.alfresco.cmis.CMISDictionaryModel;
import org.alfresco.cmis.CMISServiceException;
import org.alfresco.cmis.CMISTypeDefinition;
import org.alfresco.repo.cmis.ws.utils.ExceptionUtil;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* 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
{
checkRepositoryId(repositoryId);
checkConstraints(objectId, folderId);
try
{
cmisService.removeObjectFromFolder(objectId, folderId);
@@ -72,5 +77,35 @@ public class DMMultiFilingServicePort extends DMAbstractServicePort implements M
{
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 (false)
if (!typeDef.isVersionable() && (null != versioningState))
{
throw ExceptionUtil.createCmisException(("Verioning for \"" + documentTypeId + "\" document type is not allowed"), EnumServiceException.CONSTRAINT);
}