From 7d41c0b8bbffdc9b69721e74fd5d370dadb12809 Mon Sep 17 00:00:00 2001 From: Dave Ward Date: Sat, 27 Feb 2010 13:24:10 +0000 Subject: [PATCH] Merged DEV/CMIS_10 to HEAD 18731: SAIL-169: CMIS REST versioning compliance - Rendering of "via" link for working copy and "current-version" and "working-copy" links for documents - Added ability to dereference object IDs in cmisproperty() template function - Fixed broken CMIS index page git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18896 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../alfresco/cmis/checkedout.get.atomfeed.ftl | 2 +- .../cmis/checkedout.post.atomentry.201.ftl | 2 +- .../org/alfresco/cmis/index.get.desc.xml | 1 + .../alfresco/cmis/lib/atomentry.lib.atom.ftl | 38 +----- .../org/alfresco/cmis/lib/links.lib.atom.ftl | 15 ++- .../org/alfresco/cmis/pwc.get.atomentry.ftl | 4 +- .../org/alfresco/cmis/pwc.get.desc.xml | 32 ++++- .../webscripts/org/alfresco/cmis/pwc.get.js | 25 +++- .../web-scripts-application-context.xml | 2 + .../cmis/rest/CMISPropertyValueMethod.java | 123 +++++++++++------- 10 files changed, 154 insertions(+), 90 deletions(-) diff --git a/config/alfresco/templates/webscripts/org/alfresco/cmis/checkedout.get.atomfeed.ftl b/config/alfresco/templates/webscripts/org/alfresco/cmis/checkedout.get.atomfeed.ftl index 0d197e3bc3..f7f19cb6df 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/cmis/checkedout.get.atomfeed.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/cmis/checkedout.get.atomfeed.ftl @@ -17,7 +17,7 @@ [#list results as child] [#if child.isDocument] - [@entryLib.pwc node=child renditionfilter=renditionFilter propfilter=filter includeallowableactions=includeAllowableActions includerelationships="none"/] + [@entryLib.document node=child renditionfilter=renditionFilter propfilter=filter includeallowableactions=includeAllowableActions includerelationships="none"/] [/#if] [/#list] diff --git a/config/alfresco/templates/webscripts/org/alfresco/cmis/checkedout.post.atomentry.201.ftl b/config/alfresco/templates/webscripts/org/alfresco/cmis/checkedout.post.atomentry.201.ftl index 251d9cafcf..a11cbba6c9 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/cmis/checkedout.post.atomentry.201.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/cmis/checkedout.post.atomentry.201.ftl @@ -6,6 +6,6 @@ [#assign namespace][@nsLib.entryNS/][/#assign] -[@entryLib.pwc node=pwc includeallowableactions=true includerelationships="none" ns=namespace/] +[@entryLib.document node=pwc includeallowableactions=true includerelationships="none" ns=namespace/] [/#compress] \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/cmis/index.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/cmis/index.get.desc.xml index 1bf5a42d7e..b271b1e3bc 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/cmis/index.get.desc.xml +++ b/config/alfresco/templates/webscripts/org/alfresco/cmis/index.get.desc.xml @@ -8,5 +8,6 @@ none + required CMIS diff --git a/config/alfresco/templates/webscripts/org/alfresco/cmis/lib/atomentry.lib.atom.ftl b/config/alfresco/templates/webscripts/org/alfresco/cmis/lib/atomentry.lib.atom.ftl index 9cd98ab443..8a964a9ded 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/cmis/lib/atomentry.lib.atom.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/cmis/lib/atomentry.lib.atom.ftl @@ -56,6 +56,13 @@ [@linksLib.linkacl node/] [@linksLib.linkparents node/] [@linksLib.linkversions node/] +[#if node.isWorkingCopy] + [#local nodeuri][@linksLib.nodeuri cmisproperty(node, cmisconstants.PROP_VERSION_SERIES_ID, true)/][/#local] + [@linksLib.linkvia href="${nodeuri}"/] +[#else] + [@linksLib.linkcurrentversion node/] + [#if cmisproperty(node, cmisconstants.PROP_IS_VERSION_SERIES_CHECKED_OUT)][@linksLib.linkpwc cmisproperty(node, cmisconstants.PROP_VERSION_SERIES_CHECKED_OUT_ID, true)/][/#if] +[/#if] [@linksLib.linktype node/] [@linksLib.linkservice/] [#local nodeMap=cmisrenditions(node, renditionfilter)/] @@ -89,37 +96,6 @@ [/@entry] [/#macro] - -[#-- --] -[#-- ATOM Entry for Private Working Copy --] -[#-- --] - -[#macro pwc node renditionfilter="cmis:none" propfilter="*" includeallowableactions=false includerelationships="none" ns=""] -[@entry ns] -${node.properties.creator!""} -[@contentstream node/] -urn:uuid:${node.id} -[#assign pwcuri]/cmis/pwc/[@linksLib.noderef node/][/#assign] -[@linksLib.linkself href="${pwcuri}"/] -[@linksLib.linkstream node "enclosure"/] -[@linksLib.linknodeedit node/] -[@linksLib.linkstream node "edit-media"/] -[@documentCMISLinks node=node renditionfilter=renditionfilter/] -${xmldate(node.properties.created)} -[@contentsummary node/] -${node.name?xml} -${xmldate(node.properties.modified)} -${xmldate(node.properties.modified)} -${absurl(url.context)}${node.icon16} - -[@objectCMISProps node propfilter/] -[#if includeallowableactions][@allowableactions node/][/#if] - -${node.name?xml} -[/@entry] -[/#macro] - - [#-- --] [#-- ATOM Entry for Folder --] [#-- --] diff --git a/config/alfresco/templates/webscripts/org/alfresco/cmis/lib/links.lib.atom.ftl b/config/alfresco/templates/webscripts/org/alfresco/cmis/lib/links.lib.atom.ftl index 57e3f68bc9..0a915157b1 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/cmis/lib/links.lib.atom.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/cmis/lib/links.lib.atom.ftl @@ -54,6 +54,16 @@ [/#macro] +[#-- Link to current node version --] +[#macro linkcurrentversion node] + +[/#macro] + +[#-- Link to working copy node --] +[#macro linkpwc pwc] + +[/#macro] + [#-- Link to source node --] [#macro linktosource node] @@ -95,7 +105,7 @@ [/#macro] [#macro linknodeself node] - + [/#macro] [#macro linkassocself assoc] @@ -157,6 +167,9 @@ [#-- Helper to render Alfresco Node uri --] [#macro nodeuri node]/cmis/[@noderef node/][/#macro] +[#-- Helper to render Alfresco PWC uri --] +[#macro pwcuri node]/cmis/pwc/[@noderef node/][/#macro] + [#-- Helper to render Alfresco Assoc uri --] [#macro assocuri assoc]/cmis/rel/${assoc.associationRef.id}[/#macro] diff --git a/config/alfresco/templates/webscripts/org/alfresco/cmis/pwc.get.atomentry.ftl b/config/alfresco/templates/webscripts/org/alfresco/cmis/pwc.get.atomentry.ftl index 5d34804b2e..f89e065be1 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/cmis/pwc.get.atomentry.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/cmis/pwc.get.atomentry.ftl @@ -7,6 +7,6 @@ [#assign namespace][@nsLib.entryNS/][/#assign] -[@entryLib.pwc node=node renditionfilter=renditionFilter includeallowableactions=false includerelationships="none" ns=namespace/] +[@entryLib.document node=node renditionfilter=renditionFilter propfilter=filter includeallowableactions=includeAllowableActions includerelationships="none" includeacl=includeACL ns=namespace/] -[/#compress] +[/#compress] \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/cmis/pwc.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/cmis/pwc.get.desc.xml index a00b8406cc..4935e5eabc 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/cmis/pwc.get.desc.xml +++ b/config/alfresco/templates/webscripts/org/alfresco/cmis/pwc.get.desc.xml @@ -1,9 +1,33 @@ - Retrieve properties of PWC - Retrieves the properties of a private working copy + Retrieve properties of PWC (getProperties) + + +
+Inputs:
+
+ID objectId
+(Optional) Enum returnVersion: This (Default), Latest, LatestMajor
+(Optional) String filter: Filter for properties to be returned
+(Optional) Boolean includeAllowableActions: False (default)
+(Optional) Enum includeRelationships: none (default), source, target, both
+
+Outputs:
+
+Collection propertyCollection
+Collection allowableActionCollection
+
+Notes:
+
+If “includeAllowableActions” is TRUE, the repository will return the allowable actions for the current user for the object as part of the output.
+"IncludeRelationships" indicates whether relationships are also returned for the object. If it is set to "source" or "target", relationships for which the returned object is a source, or respectively a target, will also be returned. If it is set to "both", relationships for which the returned object is either a source or a target will be returned. If it is set to "none", relationships are not returned.
+Does not return the content-stream of a document
+PropertyCollection includes changeToken (if applicable to repository)
+]]> +
- /cmis/pwc/i/{id}?filter={filter?}&renditionFilter={renditionFilter?} - /cmis/pwc/s/{store}/i/{id}?filter={filter?}&renditionFilter={renditionFilter?} + /cmis/pwc/i/{id}?filter={filter?}&returnVersion={returnVersion?}&includeAllowableActions={includeAllowableActions?}&includeACL={includeACL?}&renditionFilter={renditionFilter?} + /cmis/pwc/s/{store}/i/{id}?filter={filter?}&returnVersion={returnVersion?}&includeAllowableActions={includeAllowableActions?}&includeACL={includeACL?}&renditionFilter={renditionFilter?} user diff --git a/config/alfresco/templates/webscripts/org/alfresco/cmis/pwc.get.js b/config/alfresco/templates/webscripts/org/alfresco/cmis/pwc.get.js index 62c24c845a..8054613ab9 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/cmis/pwc.get.js +++ b/config/alfresco/templates/webscripts/org/alfresco/cmis/pwc.get.js @@ -2,14 +2,31 @@ script: { - // locate node var object = getObjectFromUrl(); - if (object.node == null) + if (object.node === null) { break script; } model.node = object.node; + + // return version + var returnVersion = args[cmis.ARG_RETURN_VERSION]; + if (returnVersion === null || returnVersion.length == 0) + { + returnVersion = "this"; + } + model.node = cmis.getReturnVersion(model.node, returnVersion); + // property filter + model.filter = args[cmis.ARG_FILTER]; + if (model.filter === null || model.filter == "") + { + model.filter = "*"; + } + + // ACL + model.includeACL = args[cmis.ARG_INCLUDE_ACL] == "true"; + // rendition filter model.renditionFilter = args[cmis.ARG_RENDITION_FILTER]; if (model.renditionFilter === null || model.renditionFilter.length == 0) @@ -17,6 +34,6 @@ script: model.renditionFilter = "cmis:none"; } - // TODO: property filters - + // include allowable actions + model.includeAllowableActions = args[cmis.ARG_INCLUDE_ALLOWABLE_ACTIONS] == "true"; } diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index 0bee3de048..c8fd95e3a5 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -138,6 +138,8 @@ + + diff --git a/source/java/org/alfresco/repo/cmis/rest/CMISPropertyValueMethod.java b/source/java/org/alfresco/repo/cmis/rest/CMISPropertyValueMethod.java index 8e39aeed03..eed762e6e6 100644 --- a/source/java/org/alfresco/repo/cmis/rest/CMISPropertyValueMethod.java +++ b/source/java/org/alfresco/repo/cmis/rest/CMISPropertyValueMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * 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 @@ -18,7 +18,7 @@ * 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 + * 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" */ @@ -26,14 +26,18 @@ package org.alfresco.repo.cmis.rest; import java.util.List; -import org.alfresco.cmis.CMISInvalidArgumentException; +import org.alfresco.cmis.CMISServiceException; import org.alfresco.cmis.CMISServices; import org.alfresco.repo.template.TemplateAssociation; import org.alfresco.repo.template.TemplateNode; +import org.alfresco.repo.web.scripts.RepositoryImageResolver; +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.ext.beans.BeansWrapper; +import freemarker.template.TemplateBooleanModel; import freemarker.template.TemplateMethodModelEx; import freemarker.template.TemplateModel; import freemarker.template.TemplateModelException; @@ -42,73 +46,100 @@ import freemarker.template.TemplateScalarModel; /** * Custom FreeMarker Template language method. *

- * Retrieve the CMIS property value for an Alfresco node + * Retrieve the CMIS property value for an Alfresco node and optionally dereferences it as an objectId. *

* Usage: cmisproperty(TemplateNode node, String propertyName) - * + * cmisproperty(TemplateNode node, String propertyName, Boolean asObject) * @author davidc + * @author dward */ -public final class CMISPropertyValueMethod implements TemplateMethodModelEx +public class CMISPropertyValueMethod implements TemplateMethodModelEx { /** * NULL value marker */ - public static class NULL {}; + public static class NULL + { + }; + public static TemplateModel IS_NULL = new BeanModel(new NULL(), BeansWrapper.getDefaultInstance()); - + private CMISServices cmisService; + private TemplateImageResolver imageResolver; + private TemplateValueConverter templateValueConverter; /** * Construct */ - public CMISPropertyValueMethod(CMISServices cmisService) + public CMISPropertyValueMethod(CMISServices cmisService, RepositoryImageResolver imageResolver, + TemplateValueConverter templateValueConverter) { this.cmisService = cmisService; + this.imageResolver = imageResolver.getImageResolver(); + this.templateValueConverter = templateValueConverter; } - - /** - * @see freemarker.template.TemplateMethodModel#exec(java.util.List) - */ + @SuppressWarnings("unchecked") public Object exec(List args) throws TemplateModelException { - Object result = null; - - if (args.size() == 2) + Object wrapped = null; + String propertyName = null; + boolean asObject = false; + try { - Object arg0 = args.get(0); - if (arg0 instanceof BeanModel) - { - // extract property name - String propertyName = null; - Object arg1 = args.get(1); - if (arg1 instanceof TemplateScalarModel) - { - propertyName = ((TemplateScalarModel)arg1).getAsString(); - } + int i = 0; - // extract node - Object wrapped = ((BeanModel)arg0).getWrappedObject(); - if (wrapped != null && wrapped instanceof TemplateNode) - { - // retrieve property value from node - try - { - result = cmisService.getProperty(((TemplateNode)wrapped).getNodeRef(), propertyName); - } - catch (CMISInvalidArgumentException e) - { - throw new WebScriptException(e.getStatusCode(), e.getMessage(), e); - } - } - else if (wrapped != null && wrapped instanceof TemplateAssociation) - { - // retrieve property value from node - result = cmisService.getProperty(((TemplateAssociation)wrapped).getAssociationRef(), propertyName); - } + // extract object + Object arg = args.get(i++); + if (arg instanceof BeanModel) + { + wrapped = ((BeanModel) arg).getWrappedObject(); + } + + // extract property name + arg = args.get(i++); + if (arg instanceof TemplateScalarModel) + { + propertyName = ((TemplateScalarModel) arg).getAsString(); + } + + // extract asObject flag + arg = args.get(i++); + if (arg instanceof TemplateBooleanModel) + { + asObject = ((TemplateBooleanModel) arg).getAsBoolean(); } } + catch (IndexOutOfBoundsException e) + { + // Ignore optional arguments + } + + try + { + Object result = null; + if (wrapped != null && wrapped instanceof TemplateNode) + { + // retrieve property value from node + result = cmisService.getProperty(((TemplateNode) wrapped).getNodeRef(), propertyName); + } + else if (wrapped != null && wrapped instanceof TemplateAssociation) + { + // retrieve property value from association + result = cmisService.getProperty(((TemplateAssociation) wrapped).getAssociationRef(), propertyName); + } + if (asObject && result instanceof String) + { + // convert result to an object if required + result = cmisService.getReadableObject((String) result, Object.class); + } + return result == null ? IS_NULL : templateValueConverter.convertValue(result, imageResolver); + } + catch (CMISServiceException e) + { + throw new WebScriptException(e.getStatusCode(), e.getMessage(), e); + } - return result == null ? IS_NULL : result; } + }