diff --git a/config/alfresco/templates/webscripts/org/alfresco/paging.lib.atom.ftl b/config/alfresco/templates/webscripts/org/alfresco/paging.lib.atom.ftl new file mode 100644 index 0000000000..44ef1ec732 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/paging.lib.atom.ftl @@ -0,0 +1,34 @@ +<#macro cursor cursor pageArg="pageNo" skipArg="skipCount"> +<#-- NOTE: this macro requires the definition of xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/" in --> +<#-- the enclosing document --> +${cursor.totalRows} +${cursor.startRow} +${cursor.pageSize} +<#if cursor.pageType = "PAGE"> +<#if cursor.hasFirstPage> + + +<#if cursor.hasLastPage> + + +<#if cursor.hasPrevPage> + + +<#if cursor.hasNextPage> + + +<#else> +<#if cursor.hasFirstPage> + + +<#if cursor.hasLastPage> + + +<#if cursor.hasPrevPage> + + +<#if cursor.hasNextPage> + + + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/repository.get.atom.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/repository.get.atom.ftl index ce224cc936..c555684ae5 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/repository.get.atom.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/repository.get.atom.ftl @@ -19,7 +19,7 @@ <#-- TODO: cmis:id on collection elements - are they required by cmis? --> <#-- TODO: collection resources --> - + CMIS root folder diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.atom.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.atom.ftl new file mode 100644 index 0000000000..79aec1b987 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.atom.ftl @@ -0,0 +1,57 @@ + + + Alfresco (${server.edition}) + ${node.name} + ${xmldate(node.properties.modified)} + ${absurl(url.context)}/images/logo/AlfrescoLogo16.ico + + ${node.properties.creator!""} + + urn:uuid:${node.id} + + +<#if cursor.pageType = "WINDOW"> +<#if cursor.hasFirstPage> + + +<#if cursor.hasLastPage> + + +<#if cursor.hasPrevPage> + + +<#if cursor.hasNextPage> + + +<#else> +<#if cursor.hasFirstPage> + + +<#if cursor.hasLastPage> + + +<#if cursor.hasPrevPage> + + +<#if cursor.hasNextPage> + + + + +<#list results as child> + + ${child.name} + + ${absurl(url.context)}${child.icon16} <#comment>TODO: What's the standard for entry icons? + urn:uuid:${child.id} + ${xmldate(child.properties.modified)} + ${xmldate(child.properties.created)} + ${child.properties.description!""} + + ${child.properties.creator} + + ${child.nodeRef} + + + + \ 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 new file mode 100644 index 0000000000..1864bfc9e9 --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.atomfeed.ftl @@ -0,0 +1,27 @@ +<#import "/org/alfresco/paging.lib.atom.ftl" as pagingLib/> + + + Alfresco (${server.edition}) + ${node.name} + ${xmldate(node.properties.modified)} + ${absurl(url.context)}/images/logo/AlfrescoLogo16.ico + + ${node.properties.creator!""} + + urn:uuid:${node.id} + + <@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} + + + \ No newline at end of file diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.desc.xml b/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.desc.xml new file mode 100644 index 0000000000..d3c54a228f --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.desc.xml @@ -0,0 +1,8 @@ + + Retrieve list of children + Retrieve list of child folders and/or documents + /api/node/{store_type}/{store_id}/{id}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxChildren={maxChildren?} + /api/path/{store_type}/{store_id}/{id}/children?types={types}&filter={filter?}&skipCount={skipCount?}&maxChildren={maxChildren?} + guest + + \ 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 new file mode 100644 index 0000000000..4fafb37f7b --- /dev/null +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/store/children.get.js @@ -0,0 +1,31 @@ +script: +{ + // locate node + var pathSegments = url.match.split("/"); + var reference = [ url.templateArgs.store_type, url.templateArgs.store_id, url.templateArgs.id ]; + 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; + } + + // handle filters + model.types = cmis.findArg(args.types, headers["CMIS-types"]) === null ? cmis.defaultTypesFilter : cmis.findArg(args.types, headers["CMIS-types"]); + if (!cmis.isValidTypesFilter(model.types)) + { + status.code = 400; + status.message = "Types filter '" + model.types + "' unknown"; + status.redirect = true; + break script; + } + // TODO: property filters + + // retrieve children + var page = paging.createPageOrWindow(args.pageNo, args.pageSize, cmis.findArg(args.skipCount, headers["CMIS-skipCount"]), cmis.findArg(args.maxChildren, headers["CMIS-maxChildren"])); + var paged = cmis.queryChildren(model.node, model.types, page); + model.results = paged.results; + model.cursor = paged.cursor; +} diff --git a/config/alfresco/web-scripts-application-context.xml b/config/alfresco/web-scripts-application-context.xml index 1653837936..d58e5f2185 100644 --- a/config/alfresco/web-scripts-application-context.xml +++ b/config/alfresco/web-scripts-application-context.xml @@ -93,6 +93,13 @@ Repository + + + + + + + @@ -133,6 +140,32 @@ + + + + + + + + + + + + + + + + + + + + cmis + + + + + + diff --git a/source/java/org/alfresco/repo/cmis/CMISScript.java b/source/java/org/alfresco/repo/cmis/CMISScript.java new file mode 100644 index 0000000000..518774acc1 --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/CMISScript.java @@ -0,0 +1,218 @@ +/* + * 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 org.alfresco.repo.cmis.Navigation.TypesFilter; +import org.alfresco.repo.jscript.BaseScopableProcessorExtension; +import org.alfresco.repo.jscript.ScriptNode; +import org.alfresco.repo.web.scripts.Repository; +import org.alfresco.repo.web.util.paging.Cursor; +import org.alfresco.repo.web.util.paging.Page; +import org.alfresco.repo.web.util.paging.PagedResults; +import org.alfresco.repo.web.util.paging.Paging; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.repository.NodeRef; + + +/** + * CMIS Javascript API + * + * @author davic + */ +public class CMISScript extends BaseScopableProcessorExtension +{ + private static final TypesFilter defaultTypesFilter = TypesFilter.FoldersAndDocuments; + + + private ServiceRegistry services; + private Repository repository; + private Navigation navigation; + private Paging paging; + + /** + * Set the service registry + * + * @param services the service registry + */ + public void setServiceRegistry(ServiceRegistry services) + { + this.services = services; + } + + /** + * Set the repository + * + * @param repository + */ + public void setRepository(Repository repository) + { + this.repository = repository; + } + + /** + * Set the paging helper + * + * @param paging + */ + public void setPaging(Paging paging) + { + this.paging = paging; + } + + /** + * Set the CMIS Navigation helper + * + * @param navigation + */ + public void setNavigation(Navigation navigation) + { + this.navigation = navigation; + } + + + /** + * Finds the arg value from the specified url argument and header + * + * NOTE: Url argument takes precedence over header + * + * @param argVal url arg value + * @param headerVal header value + * @return value (or null) + */ + public String findArg(String argVal, String headerVal) + { + return (argVal == null) ? headerVal : argVal; + } + + /** + * Finds the arg value from the specified url argument and header + * + * NOTE: Url argument takes precedence over header + * + * @param argVal url arg value + * @param headerVal header value + * @return value (or null) + */ + public String[] findArgM(String[] argVal, String[] headerVal) + { + return (argVal == null) ? headerVal : argVal; + } + + /** + * Gets the default Types filter + * + * @return default types filter + */ + public String getDefaultTypesFilter() + { + return defaultTypesFilter.toString(); + } + + /** + * Is specified Types filter valid? + * + * @param typesFilter types filter + * @return true => valid + */ + public boolean isValidTypesFilter(String typesFilter) + { + try + { + TypesFilter.valueOf(typesFilter); + return true; + } + catch(IllegalArgumentException e) + { + return false; + } + catch(NullPointerException e) + { + return false; + } + } + + /** + * Finds a Node with the repository given a reference + * + * @param referenceType node, path + * @param reference node => id, path => path + * @return node (or null, if not found) + */ + public ScriptNode findNode(String referenceType, String[] reference) + { + ScriptNode node = null; + NodeRef nodeRef = repository.findNodeRef(referenceType, reference); + if (nodeRef != null) + { + node = new ScriptNode(nodeRef, services, getScope()); + } + return node; + } + + /** + * Query for node children + * + * @param parent node to query children for + * @param typesFilter types filter + * @param page page to query for + * @return paged result set of children + */ + public PagedResults queryChildren(ScriptNode parent, String typesFilter, Page page) + { + TypesFilter filter = resolveTypesFilter(typesFilter); + NodeRef[] children = navigation.getChildren(parent.getNodeRef(), filter); + + Cursor cursor = paging.createCursor(children.length, page); + ScriptNode[] nodes = new ScriptNode[cursor.getRowCount()]; + for (int i = cursor.getStartRow(); i <= cursor.getEndRow(); i++) + { + nodes[i - cursor.getStartRow()] = new ScriptNode(children[i], services, getScope()); + } + + PagedResults results = paging.createPagedResults(nodes, cursor); + return results; + } + + /** + * Resolve to a Types Filter + * + * NOTE: If specified types filter is not specified or invalid, the default types + * filter is returned + * + * @param typesFilter types filter + * @return resolved types filter + */ + private TypesFilter resolveTypesFilter(String typesFilter) + { + if (isValidTypesFilter(typesFilter)) + { + return TypesFilter.valueOf(typesFilter); + } + else + { + return defaultTypesFilter; + } + } +} diff --git a/source/java/org/alfresco/repo/cmis/Navigation.java b/source/java/org/alfresco/repo/cmis/Navigation.java new file mode 100644 index 0000000000..5cee9963bd --- /dev/null +++ b/source/java/org/alfresco/repo/cmis/Navigation.java @@ -0,0 +1,179 @@ +/* + * 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.util.List; + +import org.alfresco.model.ContentModel; +import org.alfresco.repo.search.QueryParameterDefImpl; +import org.alfresco.service.cmr.dictionary.DataTypeDefinition; +import org.alfresco.service.cmr.dictionary.DictionaryService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.search.QueryParameterDefinition; +import org.alfresco.service.cmr.search.ResultSet; +import org.alfresco.service.cmr.search.SearchParameters; +import org.alfresco.service.cmr.search.SearchService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; +import org.springframework.beans.factory.InitializingBean; + + +/** + * CMIS Navigation Service + * + * @author davidc + */ +public class Navigation implements InitializingBean +{ + /** + * Types Filter + * + * @author davidc + */ + public enum TypesFilter + { + Folders, + FoldersAndDocuments, + Documents + }; + + /** Query Parameters */ + private static final QName PARAM_PARENT = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "parent"); + + /** Shallow search for all files and folders */ + private static final String LUCENE_QUERY_SHALLOW_FOLDERS = + "+PARENT:\"${cm:parent}\" " + + "-TYPE:\"" + ContentModel.TYPE_SYSTEM_FOLDER + "\" " + + "+TYPE:\"" + ContentModel.TYPE_FOLDER + "\" "; + + /** Shallow search for all files and folders */ + private static final String LUCENE_QUERY_SHALLOW_FILES = + "+PARENT:\"${cm:parent}\" " + + "-TYPE:\"" + ContentModel.TYPE_SYSTEM_FOLDER + "\" " + + "+TYPE:\"" + ContentModel.TYPE_CONTENT + "\" "; + + // dependencies + private DictionaryService dictionaryService; + private SearchService searchService; + private DataTypeDefinition nodeRefDataType; + + + /** + * @param dictionaryService + */ + public void setDictionaryService(DictionaryService dictionaryService) + { + this.dictionaryService = dictionaryService; + } + + /** + * @param searchService + */ + public void setSearchService(SearchService searchService) + { + this.searchService = searchService; + } + + /** + * Initialisation + */ + public void afterPropertiesSet() throws Exception + { + nodeRefDataType = dictionaryService.getDataType(DataTypeDefinition.NODE_REF); + } + + + /** + * Query for node children + * + * @param parent node to query children for + * @param typesFilter types filter + * @return children of node + */ + public NodeRef[] getChildren(NodeRef parent, TypesFilter typesFilter) + { + if (typesFilter == TypesFilter.FoldersAndDocuments) + { + NodeRef[] folders = queryChildren(parent, TypesFilter.Folders); + NodeRef[] docs = queryChildren(parent, TypesFilter.Documents); + NodeRef[] foldersAndDocs = new NodeRef[folders.length + docs.length]; + System.arraycopy(folders, 0, foldersAndDocs, 0, folders.length); + System.arraycopy(docs, 0, foldersAndDocs, folders.length, docs.length); + return foldersAndDocs; + } + else if (typesFilter == TypesFilter.Folders) + { + NodeRef[] folders = queryChildren(parent, TypesFilter.Folders); + return folders; + } + else if (typesFilter == TypesFilter.Documents) + { + NodeRef[] docs = queryChildren(parent, TypesFilter.Documents); + return docs; + } + + return new NodeRef[0]; + } + + /** + * Query children helper + * + * NOTE: Queries for folders only or documents only + * + * @param parent node to query children for + * @param typesFilter folders or documents + * @return node children + */ + private NodeRef[] queryChildren(NodeRef parent, TypesFilter typesFilter) + { + SearchParameters params = new SearchParameters(); + params.setLanguage(SearchService.LANGUAGE_LUCENE); + params.addStore(parent.getStoreRef()); + QueryParameterDefinition parentDef = new QueryParameterDefImpl(PARAM_PARENT, nodeRefDataType, true, parent.toString()); + params.addQueryParameterDefinition(parentDef); + + if (typesFilter == TypesFilter.Folders) + { + params.setQuery(LUCENE_QUERY_SHALLOW_FOLDERS); + } + else if (typesFilter == TypesFilter.Documents) + { + params.setQuery(LUCENE_QUERY_SHALLOW_FILES); + } + + ResultSet resultSet = searchService.query(params); + try + { + List results = resultSet.getNodeRefs(); + NodeRef[] nodeRefs = new NodeRef[results.size()]; + return results.toArray(nodeRefs); + } + finally + { + resultSet.close(); + } + } + +} diff --git a/source/java/org/alfresco/repo/web/util/paging/Paging.java b/source/java/org/alfresco/repo/web/util/paging/Paging.java index a3bcaee02b..bc4f3255ab 100644 --- a/source/java/org/alfresco/repo/web/util/paging/Paging.java +++ b/source/java/org/alfresco/repo/web/util/paging/Paging.java @@ -135,6 +135,28 @@ public class Paging return zeroBasedRow; } + /** + * Create a Page or Window + * + * @param pageNumber page number (optional and paired with pageSize) + * @param pageSize page size (optional and paired with pageNumber) + * @param skipCount skipCount (optional and paired with maxItems) + * @param maxItems maxItems (optional and paired with skipCount) + * @return page (if pageNumber driven) or window (if skipCount driven) + */ + public Page createPageOrWindow(Integer pageNumber, Integer pageSize, Integer skipCount, Integer maxItems) + { + if (pageNumber != null) + { + return createPage(pageNumber, pageSize == null ? 0 : pageSize); + } + else if (skipCount != null) + { + return createWindow(skipCount, maxItems == null ? 0 : maxItems); + } + return createUnlimitedPage(); + } + /** * Create a Page * @@ -147,6 +169,16 @@ public class Paging return new Page(PageType.PAGE, zeroBasedPage, pageNumber, pageSize); } + /** + * Create an unlimited Page + * + * @return page (single Page starting at first page of unlimited page size) + */ + public Page createUnlimitedPage() + { + return new Page(PageType.PAGE, zeroBasedPage, zeroBasedPage ? 0 : 1, 0); + } + /** * Create a Window * @param skipRows number of rows to skip diff --git a/source/test/apptest/credentials.txt b/source/test/apptest/credentials.txt new file mode 100644 index 0000000000..295182ad9c --- /dev/null +++ b/source/test/apptest/credentials.txt @@ -0,0 +1,2 @@ +admin +admin \ No newline at end of file diff --git a/source/test/apptest/results.html b/source/test/apptest/results.html index b3ae33c040..d8ed6e260e 100644 --- a/source/test/apptest/results.html +++ b/source/test/apptest/results.html @@ -13,7 +13,7 @@

Test Report

Date
-
Thu May 1 16:48:30 2008
+
Mon May 12 15:38:50 2008

Legend

@@ -48,7 +48,7 @@ transfer-encoding: chunked server: Apache-Coyote/1.1 pragma: no-cache cache-control: no-cache -date: Thu, 01 May 2008 15:48:26 GMT +date: Mon, 12 May 2008 14:38:47 GMT content-type: application/atom+xml;charset=UTF-8 @@ -71,7 +71,7 @@ content-type: application/atom+xml;charset=UTF-8 </cmis:repository_info> - <collection cmis:collectionType="root" href="http://example.org/cmis/main"> + <collection cmis:collectionType="root" href="http://localhost:8080/alfresco/service/api/path/workspace/SpacesStore//children"> <atom:title>CMIS root folder</atom:title> </collection> <collection cmis:collectionType="checkedout" href="http://example.org/cmis/main?checkedout"> @@ -91,9 +91,9 @@ content-type: application/atom+xml;charset=UTF-8

Basic Entry Manipulation

Add and remove three entries to the collection

    -
  1. Service Document: http://example.org/cmis/main
  2. +
  3. Service Document: http://localhost:8080/alfresco/service/api/path/workspace/SpacesStore//children
  4. Request
    
    -GET http://example.org/cmis/main
    +GET http://localhost:8080/alfresco/service/api/path/workspace/SpacesStore//children
     
     
     
    @@ -101,26 +101,193 @@ GET http://example.org/cmis/main
     
  5. Response
    
     
    -status: 404
    -content-length: 283
    -server: Apache/2.2.3 (CentOS)
    -connection: close
    -date: Thu, 01 May 2008 15:48:30 GMT
    -content-type: text/html; charset=iso-8859-1
    +status: 200
    +content-location: http://localhost:8080/alfresco/service/api/path/workspace/SpacesStore//children
    +transfer-encoding: chunked
    +server: Apache-Coyote/1.1
    +pragma: no-cache
    +cache-control: no-cache
    +date: Mon, 12 May 2008 14:38:50 GMT
    +content-type: application/atom+xml;type=feed;charset=UTF-8
     
     
     
    -
    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    -<html><head>
    -<title>404 Not Found</title>
    -</head><body>
    -<h1>Not Found</h1>
    -<p>The requested URL /cmis/main was not found on this server.</p>
    -<hr>
    -<address>Apache/2.2.3 (CentOS) Server at example.org Port 80</address>
    -</body></html>
    +
    <?xml version="1.0" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:alf="http://www.alfresco.org" xmlns:cmis="http://www.cmis.org/CMIS/1.0">
    +  <generator version="3.0.0 (dev @build-number@)">Alfresco (Community Network)</generator>
    +  <title>Company Home</title> 
    +  <updated>2008-04-24T18:33:35.511+01:00</updated>
    +  <icon>http://localhost:8080/alfresco/images/logo/AlfrescoLogo16.ico</icon>
    +  <author> 
    +    <name>System</name>
    +  </author> 
    +  <id>urn:uuid:6413e19d-1224-11dd-bee8-852083ea779d</id>
    +  <link href="http://localhost:8080/alfresco/service/api/path/workspace/SpacesStore//children" rel="self" type="application/atom+xml;type=feed"/>
    +
    +  <link href="http://localhost:8080/alfresco/service/api/path/workspace/SpacesStore//children?skipCount=0&amp;guest=" rel="first" type="application/atom+xml;type=feed"/>
    +  
    +  <entry>
    +    <title>Data Dictionary</title>
    +    <link href="http://localhost:8080/alfresco/service/n/browse/workspace/SpacesStore/642ce7e4-1224-11dd-bee8-852083ea779d" rel="alternate"/>
    +    <icon>http://localhost:8080/alfresco/images/icons/space-icon-default-16.gif</icon>       
    +    <id>urn:uuid:642ce7e4-1224-11dd-bee8-852083ea779d</id>
    +    <updated>2008-04-24T18:33:35.708+01:00</updated>
    +    <published>2008-04-24T18:32:20.013+01:00</published>
    +    <summary>User managed definitions</summary>
    +    <author> 
    +      <name>System</name>
    +    </author> 
    +    <alf:noderef>workspace://SpacesStore/642ce7e4-1224-11dd-bee8-852083ea779d</alf:noderef>
    +  </entry>
    +  <entry>
    +    <title>Guest Home</title>
    +    <link href="http://localhost:8080/alfresco/service/n/browse/workspace/SpacesStore/648715e5-1224-11dd-bee8-852083ea779d" rel="alternate"/>
    +    <icon>http://localhost:8080/alfresco/images/icons/space-icon-default-16.gif</icon>       
    +    <id>urn:uuid:648715e5-1224-11dd-bee8-852083ea779d</id>
    +    <updated>2008-04-24T18:33:36.941+01:00</updated>
    +    <published>2008-04-24T18:32:20.608+01:00</published>
    +    <summary>The guest root space</summary>
    +    <author> 
    +      <name>System</name>
    +    </author> 
    +    <alf:noderef>workspace://SpacesStore/648715e5-1224-11dd-bee8-852083ea779d</alf:noderef>
    +  </entry>
    +  <entry>
    +    <title>User Homes</title>
    +    <link href="http://localhost:8080/alfresco/service/n/browse/workspace/SpacesStore/64963118-1224-11dd-bee8-852083ea779d" rel="alternate"/>
    +    <icon>http://localhost:8080/alfresco/images/icons/space-icon-default-16.gif</icon>       
    +    <id>urn:uuid:64963118-1224-11dd-bee8-852083ea779d</id>
    +    <updated>2008-04-24T18:33:37.110+01:00</updated>
    +    <published>2008-04-24T18:32:20.699+01:00</published>
    +    <summary>User Homes</summary>
    +    <author> 
    +      <name>System</name>
    +    </author> 
    +    <alf:noderef>workspace://SpacesStore/64963118-1224-11dd-bee8-852083ea779d</alf:noderef>
    +  </entry>
    +  <entry>
    +    <title>Projects</title>
    +    <link href="http://localhost:8080/alfresco/service/n/browse/workspace/SpacesStore/90df9f8b-1224-11dd-bee8-852083ea779d" rel="alternate"/>
    +    <icon>http://localhost:8080/alfresco/images/icons/space-icon-default-16.gif</icon>       
    +    <id>urn:uuid:90df9f8b-1224-11dd-bee8-852083ea779d</id>
    +    <updated>2008-04-24T18:33:47.401+01:00</updated>
    +    <published>2008-04-24T18:33:35.091+01:00</published>
    +    <summary>Project Collaboration Spaces</summary>
    +    <author> 
    +      <name>System</name>
    +    </author> 
    +    <alf:noderef>workspace://SpacesStore/90df9f8b-1224-11dd-bee8-852083ea779d</alf:noderef>
    +  </entry>
    +  <entry>
    +    <title>Web Projects</title>
    +    <link href="http://localhost:8080/alfresco/service/n/browse/workspace/SpacesStore/a3beb60b-1224-11dd-bee8-852083ea779d" rel="alternate"/>
    +    <icon>http://localhost:8080/alfresco/images/icons/space-icon-default-16.gif</icon>       
    +    <id>urn:uuid:a3beb60b-1224-11dd-bee8-852083ea779d</id>
    +    <updated>2008-04-24T18:34:06.711+01:00</updated>
    +    <published>2008-04-24T18:34:06.649+01:00</published>
    +    <summary>Web Content Management Spaces</summary>
    +    <author> 
    +      <name>System</name>
    +    </author> 
    +    <alf:noderef>workspace://SpacesStore/a3beb60b-1224-11dd-bee8-852083ea779d</alf:noderef>
    +  </entry>
    +
    +</feed>
  6. +
  7. [RFC2616] Section 13.3.4 No ETag: header was sent with the response.
  8. +
  9. [RFC2616] Section 13.3.4 No Last-Modified: header was sent with the response.
  10. +
  11. [RFC4287] line 18, column 4: Undefined entry element: icon (5 occurrences)
  12. +
  13. [RFC4287] line 2, column 0: Use of unknown namespace: http://www.cmis.org/CMIS/1.0 +line 2, column 0: Use of unknown namespace: http://www.alfresco.org +line 11, column 145: "self" link references a non-Atom representation
  14. +
  15. line 4, column 2: title should contain a xml:lang element (6 occurrences) +line 22, column 4: summary should contain a xml:lang element (5 occurrences)
  16. +
  17. Create new entry #1
  18. +
  19. Request
    
    +POST http://localhost:8080/alfresco/service/api/path/workspace/SpacesStore//children
    +content-type: application/atom+xml
    +slug: ddabfdegge
    +
    +
    +
    +
    <?xml version="1.0" ?><entry xmlns="http://www.w3.org/2005/Atom">
    +<title>Iñtërnâtiônàlizætiøn - 1</title>
    +<id>tag:bitworking.org,2008-02-26:1210603130.5665419</id>
    +<updated>2005-07-10T12:29:29Z</updated>
    +<author>
    +<name>Joe Gregorio</name>
    +</author>
    +<content type="xhtml">
    +<div xmlns="http://www.w3.org/1999/xhtml">
    +<p><i>A test of utf-8</i></p>
    +</div>
    +</content>
    +</entry>
  20. +
  21. Response
    
    +
    +status: 405
    +transfer-encoding: chunked
    +server: Apache-Coyote/1.1
    +pragma: no-cache
    +cache-control: no-cache
    +date: Mon, 12 May 2008 14:38:50 GMT
    +content-type: text/html;charset=UTF-8
    +
    +
    +
    +
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    +<html xmlns="http://www.w3.org/1999/xhtml">
    +   <head>
    +      <title>Web Script Status 405 - Method Not Allowed</title>
    +      <link rel="stylesheet" href="/alfresco/css/base.css" TYPE="text/css">
    +   </head>
    +   <body>
    +      <table>
    +         <tr>
    +            <td><img src="/alfresco/images/logo/AlfrescoLogo32.png" alt="Alfresco" /></td>
    +            <td><span class="title">Web Script Status 405 - Method Not Allowed</span></td>
    +         </tr>
    +      </table>
    +      <br/>
    +      <table>
    +         <tr><td>The Web Script <a href="/alfresco/service/api/path/workspace/SpacesStore//children">/alfresco/service/api/path/workspace/SpacesStore//children</a> has responded with a status of 405 - Method Not Allowed.</td></tr>
    +      </table>
    +      <br/>
    +      <table>
    +         <tr><td><b>405 Description:</b></td><td> The method specified in the Request-Line is not allowed for the resource identified by the Request-URI.</td></tr>
    +         <tr><td>&nbsp;</td></tr>
    +         <tr><td><b>Message:</b></td><td>Script url /api/path/workspace/SpacesStore//children does not support the method POST</td></tr>
    +         <tr><td></td><td>&nbsp;</td></tr>
    +   <tr><td><b>Exception:</b></td><td>org.alfresco.web.scripts.WebScriptException - Script url /api/path/workspace/SpacesStore//children does not support the method POST</td></tr>
    +   <tr><td></td><td>&nbsp;</td></tr>
    +         <tr><td></td><td>org.alfresco.web.scripts.AbstractRuntime.executeScript(AbstractRuntime.java:113)</td></tr>
    +         <tr><td></td><td>org.alfresco.web.scripts.servlet.WebScriptServlet.service(WebScriptServlet.java:116)</td></tr>
    +         <tr><td></td><td>javax.servlet.http.HttpServlet.service(HttpServlet.java:803)</td></tr>
    +         <tr><td></td><td>org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)</td></tr>
    +         <tr><td></td><td>org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)</td></tr>
    +         <tr><td></td><td>org.alfresco.web.app.servlet.MTWebScriptAuthenticationFilter.doFilter(MTWebScriptAuthenticationFilter.java:102)</td></tr>
    +         <tr><td></td><td>org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)</td></tr>
    +         <tr><td></td><td>org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)</td></tr>
    +         <tr><td></td><td>org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)</td></tr>
    +         <tr><td></td><td>org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:174)</td></tr>
    +         <tr><td></td><td>org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)</td></tr>
    +         <tr><td></td><td>org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)</td></tr>
    +         <tr><td></td><td>org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)</td></tr>
    +         <tr><td></td><td>org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:151)</td></tr>
    +         <tr><td></td><td>org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:874)</td></tr>
    +         <tr><td></td><td>org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)</td></tr>
    +         <tr><td></td><td>org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)</td></tr>
    +         <tr><td></td><td>org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)</td></tr>
    +         <tr><td></td><td>org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)</td></tr>
    +         <tr><td></td><td>java.lang.Thread.run(Thread.java:613)</td></tr>
    +   <tr><td></td><td>&nbsp;</td></tr>
    +         <tr><td><b>Server</b>:</td><td>Alfresco Community Network v3.0.0 (dev @build-number@) schema 124</td></tr>
    +         <tr><td><b>Time</b>:</td><td>May 12, 2008 3:38:50 PM</td></tr>
    +         <tr><td></td><td>&nbsp;</td></tr>
    +      </table>
    +   </body>
    +</html>
    +
     
  22. -
  23. [RFC2616] Section 10.2.1 Could not successfully retrieve the document. Got a status code of: 404
  24. +
  25. [RFC5023] Section 9.2 Entry creation failed with status: 405 Method Not Allowed
  26. Didn't find any Media Collections that would accept GIF images
diff --git a/source/test/apptest/test.sh b/source/test/apptest/test.sh index d09371151f..bb9e5fcd91 100755 --- a/source/test/apptest/test.sh +++ b/source/test/apptest/test.sh @@ -1,6 +1,4 @@ # ! /bin/sh -# TODO: change url to Alfresco root service document - -python validator/appclienttest.py --html --verbose --output=results.html "http://localhost:8080/alfresco/service/api/repository" +python validator/appclienttest.py --html --credentials=credentials.txt --verbose --output=results.html "http://localhost:8080/alfresco/service/api/repository" open results.html