diff --git a/config/alfresco/templates/webscripts/org/alfresco/cmis/entries.lib.atom.ftl b/config/alfresco/templates/webscripts/org/alfresco/cmis/entries.lib.atom.ftl new file mode 100644 index 0000000000..02a767909b --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/cmis/entries.lib.atom.ftl @@ -0,0 +1,39 @@ +<#macro document node> + <#-- TODO: link elements (both APP and CMIS) --> + + ${node.name} + + urn:uuid:${node.id} + ${xmldate(node.properties.modified)} + ${xmldate(node.properties.created)} + ${node.properties.description!""} + ${node.properties.creator} + ${node.nodeRef} + ${absurl(url.context)}${node.icon16} + <#-- TODO: full cmis schema --> + + ${node.id} + document + + + + +<#macro folder node> + <#-- TODO: link elements (both APP and CMIS) --> + + ${node.name} + + urn:uuid:${node.id} + ${xmldate(node.properties.modified)} + ${xmldate(node.properties.created)} + ${node.properties.description!""} + ${node.properties.creator!""} + ${node.nodeRef} + ${absurl(url.context)}${node.icon16} + <#-- TODO: full cmis schema --> + + ${node.id} + folder + + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/repository.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/repository.get.desc.xml index 12cbe3638c..94138e82b3 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/repository.get.desc.xml +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/repository.get.desc.xml @@ -4,4 +4,5 @@ /api/repository none + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.atomfeed.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.atomfeed.ftl index 1864bfc9e9..2a0a2d7ee4 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.atomfeed.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.atomfeed.ftl @@ -1,4 +1,5 @@ <#import "/org/alfresco/paging.lib.atom.ftl" as pagingLib/> +<#import "/org/alfresco/cmis/entries.lib.atom.ftl" as entriesLib/> Alfresco (${server.edition}) @@ -12,16 +13,10 @@ <@pagingLib.cursor cursor=cursor/> <#list results as child> - - ${child.name} - - urn:uuid:${child.id} - ${xmldate(child.properties.modified)} - ${xmldate(child.properties.created)} - ${child.properties.description!""} - ${child.properties.creator} - ${child.nodeRef} - ${absurl(url.context)}${child.icon16} - +<#if child.isDocument> + <@entriesLib.document node=child/> +<#else> + <@entriesLib.folder node=child/> + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.js b/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.js index 4fafb37f7b..ee85e3058d 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.js +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.js @@ -2,7 +2,7 @@ script: { // locate node var pathSegments = url.match.split("/"); - var reference = [ url.templateArgs.store_type, url.templateArgs.store_id, url.templateArgs.id ]; + var reference = [ url.templateArgs.store_type, url.templateArgs.store_id ].concat(url.templateArgs.id.split("/")); model.node = cmis.findNode(pathSegments[2], reference); if (model.node === null) { diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/parent.get.atomfeed.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parent.get.atomfeed.ftl new file mode 100644 index 0000000000..f79d53f12d --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parent.get.atomfeed.ftl @@ -0,0 +1,23 @@ +<#import "/org/alfresco/cmis/entries.lib.atom.ftl" as entriesLib/> + + + Alfresco (${server.edition}) + ${node.name} + ${xmldate(node.properties.modified)} + ${absurl(url.context)}/images/logo/AlfrescoLogo16.ico + + ${node.properties.creator!""} + + urn:uuid:${node.id} + + <@parent node=node.parent recurse=returnToRoot/> + + +<#macro parent node recurse=false> + <#if node?exists && node.isContainer> + <@entriesLib.folder node=node/> + <#if recurse> + <@parent node=node.parent recurse=true/> + + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/parent.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parent.get.desc.xml new file mode 100644 index 0000000000..aa8e8e03eb --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parent.get.desc.xml @@ -0,0 +1,8 @@ + + Retrieve Parent Folder + Retrieve parent folder + /api/node/{store_type}/{store_id}/{id}/parent?returnToRoot={returnToRoot} + /api/path/{store_type}/{store_id}/{id}/parent?returnToRoot={returnToRoot} + guest + argument + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/parent.get.js b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parent.get.js new file mode 100644 index 0000000000..553d520fce --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parent.get.js @@ -0,0 +1,20 @@ +script: +{ + // locate node + var pathSegments = url.match.split("/"); + var reference = [ url.templateArgs.store_type, url.templateArgs.store_id ].concat(url.templateArgs.id.split("/")); + model.node = cmis.findNode(pathSegments[2], reference); + if (model.node === null) + { + status.code = 404; + status.message = "Repository " + pathSegments[2] + " " + reference.join("/") + " not found"; + status.redirect = true; + break script; + } + + // TODO: property filters + + // retrieve parent + var returnToRoot = cmis.findArg(args.returnToRoot, headers["CMIS-returnToRoot"]); + model.returnToRoot = returnToRoot == "true" ? true : false; +} diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/parents.get.atomfeed.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parents.get.atomfeed.ftl new file mode 100644 index 0000000000..c790833014 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parents.get.atomfeed.ftl @@ -0,0 +1,24 @@ +<#import "/org/alfresco/cmis/entries.lib.atom.ftl" as entriesLib/> + + + Alfresco (${server.edition}) + ${node.name} + ${xmldate(node.properties.modified)} + ${absurl(url.context)}/images/logo/AlfrescoLogo16.ico + + ${node.properties.creator!""} + + urn:uuid:${node.id} + + <@parent node=node.parent recurse=returnToRoot/> + <#-- TODO: secondary parents loop --> + + +<#macro parent node recurse=false> + <#if node?exists && node.isContainer> + <@entriesLib.folder node=node/> + <#if recurse> + <@parent node=node.parent recurse=true/> + + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/parents.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parents.get.desc.xml new file mode 100644 index 0000000000..669ad14305 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parents.get.desc.xml @@ -0,0 +1,9 @@ + + Retrieve Parent Folders + Retrieve parent folders (primary and secondary) + + /api/node/{store_type}/{store_id}/{id}/parents + /api/path/{store_type}/{store_id}/{id}/parents + guest + argument + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/parents.get.js b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parents.get.js new file mode 100644 index 0000000000..924644527e --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/parents.get.js @@ -0,0 +1,21 @@ +script: +{ + // locate node + var pathSegments = url.match.split("/"); + var reference = [ url.templateArgs.store_type, url.templateArgs.store_id ].concat(url.templateArgs.id.split("/")); + model.node = cmis.findNode(pathSegments[2], reference); + if (model.node === null) + { + status.code = 404; + status.message = "Repository " + pathSegments[2] + " " + reference.join("/") + " not found"; + status.redirect = true; + break script; + } + + // TODO: property filters + + // TODO: check returnToRoot is required for getDocumentParents + // retrieve parent + var returnToRoot = cmis.findArg(args.returnToRoot, headers["CMIS-returnToRoot"]); + model.returnToRoot = returnToRoot == "true" ? true : false; +} diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/unfiled.get.atomfeed.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/store/unfiled.get.atomfeed.ftl new file mode 100644 index 0000000000..3a2bdce3ed --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/unfiled.get.atomfeed.ftl @@ -0,0 +1,13 @@ + + + Alfresco (${server.edition}) + Unfiled Documents + ${xmldate(date)} + ${absurl(url.context)}/images/logo/AlfrescoLogo16.ico + + System + + urn:uuid:unfiled + + <#-- NOTE: Alfresco does not yet support unfiled documents --> + diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/unfiled.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/unfiled.get.desc.xml new file mode 100644 index 0000000000..43c1637069 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/unfiled.get.desc.xml @@ -0,0 +1,7 @@ + + Unfiled Documents + Retrieve list of documents that are not in any folder + /api/unfiled + guest + + \ No newline at end of file diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index d58e5f2185..f08f170509 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -149,6 +149,8 @@ + + @@ -403,5 +405,14 @@ + + + + + + + + + diff --git a/source/java/org/alfresco/repo/cmis/CMISDescription.java b/source/java/org/alfresco/repo/cmis/CMISDescription.java new file mode 100644 index 0000000000..c011123e6e --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/CMISDescription.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2005-2008 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; + +import java.io.InputStream; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.alfresco.web.scripts.DescriptionExtension; +import org.alfresco.web.scripts.WebScriptException; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; + + +/** + * Web Script Descriptor Extension + * + * + * + * @author davidc + */ +public class CMISDescription implements DescriptionExtension +{ + + /* (non-Javadoc) + * @see org.alfresco.web.scripts.DescriptionExtension#parseExtensions(java.lang.String, java.io.InputStream) + */ + public Map parseExtensions(String serviceDescPath, InputStream serviceDesc) + { + SAXReader reader = new SAXReader(); + try + { + Map extensions = null; + Document document = reader.read(serviceDesc); + Element rootElement = document.getRootElement(); + Element cmisElement = rootElement.element("cmis"); + if (cmisElement != null) + { + extensions = new HashMap(); + String version = cmisElement.attributeValue("version"); + if (version == null || version.length() == 0) + { + throw new WebScriptException("Expected 'version' attribute on element"); + } + extensions.put("cmis_version", version); + } + return extensions; + } + catch(DocumentException e) + { + throw new WebScriptException("Failed to parse web script description document " + serviceDescPath, e); + } + } + +}