diff --git a/source/java/org/alfresco/repo/cmis/rest/CMISAssocsMethod.java b/source/java/org/alfresco/repo/cmis/rest/CMISAssocsMethod.java
new file mode 100644
index 0000000000..fbcab08c25
--- /dev/null
+++ b/source/java/org/alfresco/repo/cmis/rest/CMISAssocsMethod.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2005-2010 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 received 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.rest;
+
+import java.util.List;
+
+import org.alfresco.cmis.CMISRelationshipDirectionEnum;
+import org.alfresco.cmis.CMISServiceException;
+import org.alfresco.cmis.CMISServices;
+import org.alfresco.repo.template.TemplateNode;
+import org.alfresco.repo.web.scripts.RepositoryImageResolver;
+import org.alfresco.service.cmr.repository.AssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.TemplateImageResolver;
+import org.alfresco.service.cmr.repository.TemplateValueConverter;
+import org.springframework.extensions.webscripts.WebScriptException;
+
+import freemarker.ext.beans.BeanModel;
+import freemarker.template.TemplateMethodModelEx;
+import freemarker.template.TemplateModelException;
+import freemarker.template.TemplateScalarModel;
+
+/**
+ * Custom FreeMarker Template language method.
+ *
+ * Gets the associations of a TemplateNode
+ *
+ * Usage: cmisassocs(TemplateNode node, String direction)
+ *
+ * @author dward
+ */
+public class CMISAssocsMethod implements TemplateMethodModelEx
+{
+ private CMISServices cmisService;
+ private TemplateImageResolver imageResolver;
+ private TemplateValueConverter templateValueConverter;
+
+ /**
+ * Construct
+ */
+ public CMISAssocsMethod(CMISServices cmisService, RepositoryImageResolver imageResolver,
+ TemplateValueConverter templateValueConverter)
+ {
+ this.cmisService = cmisService;
+ this.imageResolver = imageResolver.getImageResolver();
+ this.templateValueConverter = templateValueConverter;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object exec(List args) throws TemplateModelException
+ {
+ NodeRef nodeRef = null;
+ CMISRelationshipDirectionEnum direction = CMISRelationshipDirectionEnum.SOURCE;
+ try
+ {
+ int i = 0;
+ // extract node ref
+ Object arg = args.get(i++);
+ if (arg instanceof BeanModel)
+ {
+ Object wrapped = ((BeanModel) arg).getWrappedObject();
+ if (wrapped != null)
+ {
+ if (wrapped instanceof TemplateNode)
+ {
+ nodeRef = ((TemplateNode) wrapped).getNodeRef();
+ }
+ }
+ }
+ // extract direction, if specified
+ arg = args.get(i++);
+ if (arg instanceof TemplateScalarModel)
+ {
+ direction = CMISRelationshipDirectionEnum.valueOf(((TemplateScalarModel) arg).getAsString());
+ }
+ }
+ catch (IndexOutOfBoundsException e)
+ {
+ // Ignore optional arguments
+ }
+
+ // query relationships
+ if (nodeRef != null)
+ {
+ AssociationRef[] assocs;
+ try
+ {
+ assocs = cmisService.getRelationships(nodeRef, null, true, direction);
+ }
+ catch (CMISServiceException e)
+ {
+ throw new WebScriptException(e.getStatusCode(), e.getMessage(), e);
+ }
+ return templateValueConverter.convertValue(assocs, imageResolver);
+ }
+
+ return null;
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/cmis/ws/DMAbstractServicePort.java b/source/java/org/alfresco/repo/cmis/ws/DMAbstractServicePort.java
index 27e5c859e1..f814bbb791 100644
--- a/source/java/org/alfresco/repo/cmis/ws/DMAbstractServicePort.java
+++ b/source/java/org/alfresco/repo/cmis/ws/DMAbstractServicePort.java
@@ -50,6 +50,7 @@ import org.alfresco.cmis.CMISConstraintException;
import org.alfresco.cmis.CMISFilterNotValidException;
import org.alfresco.cmis.CMISInvalidArgumentException;
import org.alfresco.cmis.CMISQueryService;
+import org.alfresco.cmis.CMISRelationshipDirectionEnum;
import org.alfresco.cmis.CMISRendition;
import org.alfresco.cmis.CMISRenditionService;
import org.alfresco.cmis.CMISServices;
@@ -87,14 +88,20 @@ public class DMAbstractServicePort
private static final String INVALID_REPOSITORY_ID_MESSAGE = "Invalid repository id";
private static final Map ACL_PROPAGATION_ENUM_MAPPGIN;
+ private static final Map INCLUDE_RELATIONSHIPS_ENUM_MAPPING;
private static final Map ALLOWED_ACTION_ENUM_MAPPING;
static
{
- ACL_PROPAGATION_ENUM_MAPPGIN = new HashMap();
+ ACL_PROPAGATION_ENUM_MAPPGIN = new HashMap(5);
ACL_PROPAGATION_ENUM_MAPPGIN.put(EnumACLPropagation.OBJECTONLY, CMISAclPropagationEnum.OBJECT_ONLY);
ACL_PROPAGATION_ENUM_MAPPGIN.put(EnumACLPropagation.PROPAGATE, CMISAclPropagationEnum.PROPAGATE);
ACL_PROPAGATION_ENUM_MAPPGIN.put(EnumACLPropagation.REPOSITORYDETERMINED, CMISAclPropagationEnum.REPOSITORY_DETERMINED);
+ INCLUDE_RELATIONSHIPS_ENUM_MAPPING = new HashMap(5);
+ 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(97);
@@ -210,37 +217,99 @@ public class DMAbstractServicePort
* This method converts Alfresco's NodeRef's to CMIS objects those will be stored in resultList-parameter. Properties for returning filtering also performs
*
* @param filter properties filter value for filtering objects returning properties
+ * @param includeRelationships
+ * what relationships to include
* @param sourceList the list that contains all returning Node References
* @param resultList the list of CmisObjectType values for end response result collecting
* @throws CmisException
*/
- protected void createCmisObjectList(PropertyFilter filter, boolean includeAllowableActions, String renditionFilter, List sourceList, List resultList)
- throws CmisException
+ protected void createCmisObjectList(PropertyFilter filter, CMISRelationshipDirectionEnum includeRelationships,
+ boolean includeAllowableActions, String renditionFilter, List sourceList,
+ List resultList) throws CmisException
{
for (NodeRef objectNodeRef : sourceList)
{
- resultList.add(createCmisObject(objectNodeRef, filter, includeAllowableActions, renditionFilter));
+ resultList.add(createCmisObject(objectNodeRef, filter, includeRelationships, 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 objectNodeRef the Alfresco object against those conversion must to be done
- * @param filter accepted properties filter
- * @return converted to CMIS object Alfresco object
+ * @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
*/
- protected CmisObjectType createCmisObject(Object identifier, PropertyFilter filter, 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
+ && 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
+ * @return the converted CMIS object
+ * @throws CmisException
+ * on error
+ */
+ 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)
+ {
+ object = ((Version) object).getFrozenStateNodeRef();
+ }
CmisObjectType result = new CmisObjectType();
- result.setProperties(propertiesUtil.getProperties(identifier, filter));
+ result.setProperties(propertiesUtil.getProperties(object, filter));
+ if (object instanceof NodeRef && includeRelationships != null)
+ {
+ List 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);
+ }
+ }
if (includeAllowableActions)
{
- result.setAllowableActions(determineObjectAllowableActions(identifier));
+ result.setAllowableActions(determineObjectAllowableActions(object));
}
if (renditionFilter != null)
{
- List renditions = getRenditions(identifier, renditionFilter);
+ List renditions = getRenditions(object, renditionFilter);
if (renditions != null && !renditions.isEmpty())
{
result.getRendition().addAll(renditions);
diff --git a/source/java/org/alfresco/repo/cmis/ws/DMNavigationServicePort.java b/source/java/org/alfresco/repo/cmis/ws/DMNavigationServicePort.java
index 6a0b9f4a2e..2a5bb4f5eb 100644
--- a/source/java/org/alfresco/repo/cmis/ws/DMNavigationServicePort.java
+++ b/source/java/org/alfresco/repo/cmis/ws/DMNavigationServicePort.java
@@ -84,13 +84,10 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
for (int index = cursor.getStartRow(); index <= cursor.getEndRow(); index++)
{
- resultListing.add(createCmisObject(nodeRefs[index], propertyFilter, includeAllowableActions,
- renditionFilter));
+ resultListing.add(createCmisObject(nodeRefs[index], propertyFilter, includeRelationships,
+ includeAllowableActions, renditionFilter));
}
result.setHasMoreItems(new Boolean(cursor.getEndRow() < (nodeRefs.length - 1)));
-
- // TODO: includeAllowableActions, includeRelationships, renditions
-
return result;
}
catch (CMISServiceException e)
@@ -128,8 +125,8 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
for (int index = cursor.getStartRow(); index <= cursor.getEndRow(); index++)
{
- CmisObjectType cmisObject = createCmisObject(listing[index], propertyFilter, includeAllowableActions,
- renditionFilter);
+ CmisObjectType cmisObject = createCmisObject(listing[index], propertyFilter, includeRelationships,
+ includeAllowableActions, renditionFilter);
CmisObjectInFolderType cmisObjectInFolder = new CmisObjectInFolderType();
cmisObjectInFolder.setObject(cmisObject);
if (includePathSegments != null && includePathSegments)
@@ -220,7 +217,7 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
throw ExceptionUtil.createCmisException(e);
}
- CmisObjectType result = createCmisObject(parentRef, propertyFilter, false, null);
+ CmisObjectType result = createCmisObject(parentRef, propertyFilter, null, false, null);
return result;
}
@@ -253,8 +250,8 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
String relativePathSegment = propertiesUtil.getProperty(childNode, CMISDictionaryModel.PROP_NAME, "");
for (NodeRef objectNodeRef : parents)
{
- CmisObjectType cmisObject = createCmisObject(objectNodeRef, propertyFilter, includeAllowableActions, renditionFilter);
- // TODO: includeRelationship, renditions
+ CmisObjectType cmisObject = createCmisObject(objectNodeRef, propertyFilter, includeRelationships,
+ includeAllowableActions, renditionFilter);
CmisObjectParentsType cmisObjectParentsType = new CmisObjectParentsType();
cmisObjectParentsType.setObject(cmisObject);
if (includeRelativePathSegment != null && includeRelativePathSegment)
@@ -262,7 +259,6 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
cmisObjectParentsType.setRelativePathSegment(relativePathSegment);
}
result.add(cmisObjectParentsType);
-
}
return result;
}
@@ -319,9 +315,8 @@ public class DMNavigationServicePort extends DMAbstractServicePort implements Na
private CmisObjectInFolderContainerType createObjectInFolderContainer(NodeRef nodeRef, PropertyFilter filter, Boolean includeAllowableActions,
EnumIncludeRelationships includeRelationships, String renditionFilter, Boolean includePathSegments) throws CmisException
{
- includeAllowableActions = includeAllowableActions == null ? Boolean.FALSE : includeAllowableActions;
- CmisObjectType cmisObject = createCmisObject(nodeRef, filter, includeAllowableActions, renditionFilter);
- // TODO: add relationships and renditions
+ CmisObjectType cmisObject = createCmisObject(nodeRef, filter, includeRelationships, includeAllowableActions,
+ renditionFilter);
CmisObjectInFolderType objectInFolderType = new CmisObjectInFolderType();
objectInFolderType.setObject(cmisObject);
diff --git a/source/java/org/alfresco/repo/cmis/ws/DMObjectServicePort.java b/source/java/org/alfresco/repo/cmis/ws/DMObjectServicePort.java
index d9e56943e5..99868e721e 100644
--- a/source/java/org/alfresco/repo/cmis/ws/DMObjectServicePort.java
+++ b/source/java/org/alfresco/repo/cmis/ws/DMObjectServicePort.java
@@ -431,8 +431,8 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
{
NodeRef object = cmisService.getReadableObject(objectId, NodeRef.class);
PropertyFilter propertyFilter = createPropertyFilter(filter);
- boolean includeActions = (null != includeAllowableActions) ? (includeAllowableActions.booleanValue()) : (false);
- CmisObjectType cmisObject = createCmisObject(object, propertyFilter, includeActions, renditionFilter);
+ CmisObjectType cmisObject = createCmisObject(object, propertyFilter, includeRelationships,
+ includeAllowableActions, renditionFilter);
// TODO: process relationships
// TODO: process policyIds
@@ -471,7 +471,8 @@ public class DMObjectServicePort extends DMAbstractServicePort implements Object
throw ExceptionUtil.createCmisException("Path to Folder was not specified or Folder Path is invalid", EnumServiceException.INVALID_ARGUMENT);
}
PropertyFilter propertyFilter = createPropertyFilter(filter);
- CmisObjectType object = createCmisObject(objectNodeRef, propertyFilter, includeAllowableActions, renditionFilter);
+ CmisObjectType object = createCmisObject(objectNodeRef, propertyFilter, includeRelationships,
+ includeAllowableActions, renditionFilter);
boolean includeAcl = (null != includeACL) ? (includeACL.booleanValue()) : (false);
if (includeAcl)
{
diff --git a/source/java/org/alfresco/repo/cmis/ws/DMRelationshipServicePort.java b/source/java/org/alfresco/repo/cmis/ws/DMRelationshipServicePort.java
index 1bc9fa9f9d..e50f402087 100755
--- a/source/java/org/alfresco/repo/cmis/ws/DMRelationshipServicePort.java
+++ b/source/java/org/alfresco/repo/cmis/ws/DMRelationshipServicePort.java
@@ -88,14 +88,14 @@ public class DMRelationshipServicePort extends DMAbstractServicePort implements
}
}
- private CmisObjectListType createResult(PropertyFilter filter, boolean includeAllowableActions, Object[] sourceArray, BigInteger skipCount, BigInteger maxItems)
+ private CmisObjectListType createResult(PropertyFilter filter, Boolean includeAllowableActions, Object[] sourceArray, BigInteger skipCount, BigInteger maxItems)
throws CmisException
{
Cursor cursor = createCursor(sourceArray.length, skipCount, maxItems);
CmisObjectListType result = new CmisObjectListType();
for (int i = cursor.getStartRow(); i <= cursor.getEndRow(); i++)
{
- result.getObjects().add(createCmisObject(sourceArray[i], filter, includeAllowableActions, null));
+ result.getObjects().add(createCmisObject(sourceArray[i], filter, null, includeAllowableActions, null));
}
result.setHasMoreItems(cursor.getEndRow() < sourceArray.length);
result.setNumItems(BigInteger.valueOf(cursor.getPageSize()));
diff --git a/source/java/org/alfresco/repo/cmis/ws/DMVersioningServicePort.java b/source/java/org/alfresco/repo/cmis/ws/DMVersioningServicePort.java
index 1b404d64ca..488d264da6 100755
--- a/source/java/org/alfresco/repo/cmis/ws/DMVersioningServicePort.java
+++ b/source/java/org/alfresco/repo/cmis/ws/DMVersioningServicePort.java
@@ -162,15 +162,11 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
checkRepositoryId(repositoryId);
PropertyFilter propertyFilter = createPropertyFilter(filter);
List objects = new LinkedList();
- if (includeAllowableActions == null)
- {
- includeAllowableActions = false;
- }
try
{
for (NodeRef nodeRef : cmisService.getAllVersions(objectId))
{
- objects.add(createCmisObject(nodeRef, propertyFilter, includeAllowableActions, null));
+ objects.add(createCmisObject(nodeRef, propertyFilter, null, includeAllowableActions, null));
}
}
catch (CMISServiceException e)
@@ -215,10 +211,10 @@ public class DMVersioningServicePort extends DMAbstractServicePort implements Ve
try
{
NodeRef latestVersionNodeRef = cmisService.getLatestVersion(objectId, major != null && major);
- // TODO: includeRelationships
// TODO: includePolicyIds
PropertyFilter propertyFilter = createPropertyFilter(filter);
- CmisObjectType result = createCmisObject(latestVersionNodeRef, propertyFilter, includeAllowableActions, renditionFilter);
+ CmisObjectType result = createCmisObject(latestVersionNodeRef, propertyFilter, includeRelationships,
+ includeAllowableActions, renditionFilter);
if (includeACL)
{
appendWithAce(cmisService.getVersionSeries(objectId, NodeRef.class, false), result);