You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fg...@apache.org on 2010/01/13 16:58:41 UTC

svn commit: r898816 - in /incubator/chemistry/trunk/chemistry: chemistry-api/src/main/java/org/apache/chemistry/ chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/ chemistry-atompub-client/src/test/java/org/apache/chemistry/ato...

Author: fguillaume
Date: Wed Jan 13 15:58:41 2010
New Revision: 898816

URL: http://svn.apache.org/viewvc?rev=898816&view=rev
Log:
CMIS-96: Updated TypeManager API, fixed AtomPub type descendants feed and service collection

Modified:
    incubator/chemistry/trunk/chemistry/chemistry-api/src/main/java/org/apache/chemistry/TypeManager.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPRepository.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/test/java/org/apache/chemistry/atompub/client/TypeFeedReaderTest.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISCollection.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISObjectsCollection.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISProvider.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISTypesCollection.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISWorkspaceManager.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/jaxrs/AbderaResource.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/test/java/org/apache/chemistry/atompub/server/AtomPubServerTestCase.java
    incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/base/BaseRepository.java
    incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleTypeManager.java
    incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/impl/simple/TestSimpleRepository.java
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrRepository.java
    incubator/chemistry/trunk/chemistry/chemistry-tests/src/main/java/org/apache/chemistry/test/BasicTestCase.java

Modified: incubator/chemistry/trunk/chemistry/chemistry-api/src/main/java/org/apache/chemistry/TypeManager.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-api/src/main/java/org/apache/chemistry/TypeManager.java?rev=898816&r1=898815&r2=898816&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-api/src/main/java/org/apache/chemistry/TypeManager.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-api/src/main/java/org/apache/chemistry/TypeManager.java Wed Jan 13 15:58:41 2010
@@ -42,21 +42,48 @@
     Type getType(String typeId);
 
     /**
-     * Gets the types.
+     * Gets all the types.
+     *
+     * @return all the types
+     */
+    Collection<Type> getTypes();
+
+    /**
+     * Gets a type and all its descendants.
      * <p>
-     * If typeId is provided, only the specific type and its descendants are
-     * returned, otherwise all types are returned.
+     * Note that contrary to {@link #getTypeDescendants(String, int, boolean)}
+     * the type itself is also returned.
      *
-     * @param typeId the base type ID, or {@code null}
-     * @return the types, or a subset of them
+     * @param typeId the type ID, or {@code null} for all types
+     * @return the type and its descendants, or {@code null} if not found
+     *
+     * @throws IllegalArgumentException if the type does not exist
      */
-    Collection<Type> getTypes(String typeId);
+    Collection<Type> getTypeDescendants(String typeId);
 
     /**
-     * Gets the types.
+     * Gets the children of a given type.
      * <p>
-     * If typeId is provided, only the specific type and its descendants are
-     * returned, otherwise all types are returned.
+     * If typeId is {@code null} then the supported base types are returned.
+     *
+     * @param typeId the type ID
+     * @param includePropertyDefinitions {@code false} to skip property
+     *            definitions
+     * @param paging paging information, or {@code null} for a
+     *            repository-specific default
+     * @return the children types
+     *
+     * @throws IllegalArgumentException if the type does not exist
+     */
+    ListPage<Type> getTypeChildren(String typeId,
+            boolean includePropertyDefinitions, Paging paging);
+
+    /**
+     * Gets the descendants of a given type.
+     * <p>
+     * If typeId is provided only its descendants are returned (up to the
+     * specified depth), otherwise if typeId is {@code null} all the types are
+     * returned (and depth is ignored).
      * <p>
      * The depth parameter controls the number of levels of the type hierarchy
      * to return:
@@ -67,17 +94,21 @@
      * </ul>
      * If includePropertyDefinitions is {@code false}, then the
      * {@link PropertyDefinition}s will not be returned in each {@link Type}.
+     * <p>
+     * Note that contrary to {@link #getTypeDescendants(String)} if a typeId is
+     * passed, the type itself is not returned.
      *
      * @param typeId the base type ID, or {@code null}
      * @param depth the number of levels of depth in the type hierarchy from
      *            which to return results
      * @param includePropertyDefinitions {@code false} to skip property
      *            definitions
-     * @return the types, or a subset of them
+     * @return the types, or a subset of them, or {@code null} if not found
      *
-     * @throws IllegalArgumentException if the depth is invalid
+     * @throws IllegalArgumentException if the depth is invalid or the type does
+     *             not exist
      */
-    Collection<Type> getTypes(String typeId, int depth,
+    Collection<Type> getTypeDescendants(String typeId, int depth,
             boolean includePropertyDefinitions);
 
 }

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPRepository.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPRepository.java?rev=898816&r1=898815&r2=898816&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPRepository.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPRepository.java Wed Jan 13 15:58:41 2010
@@ -24,24 +24,33 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.chemistry.BaseType;
 import org.apache.chemistry.Connection;
+import org.apache.chemistry.ListPage;
+import org.apache.chemistry.Paging;
 import org.apache.chemistry.Repository;
 import org.apache.chemistry.RepositoryInfo;
 import org.apache.chemistry.SPI;
 import org.apache.chemistry.Type;
 import org.apache.chemistry.TypeManager;
+import org.apache.chemistry.atompub.AtomPub;
 import org.apache.chemistry.atompub.AtomPubCMIS;
 import org.apache.chemistry.atompub.URITemplate;
 import org.apache.chemistry.atompub.client.connector.APPContentManager;
 import org.apache.chemistry.atompub.client.connector.Request;
 import org.apache.chemistry.atompub.client.connector.Response;
 import org.apache.chemistry.atompub.client.stax.ReadContext;
+import org.apache.chemistry.impl.simple.SimpleTypeManager;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 /**
  * An APP client repository proxy
  */
 public class APPRepository implements Repository {
 
+    private static final Log log = LogFactory.getLog(APPRepository.class);
+
     protected final APPContentManager cm;
 
     protected RepositoryInfo info;
@@ -117,15 +126,28 @@
         return typeManager.getType(typeId);
     }
 
-    public Collection<Type> getTypes(String typeId) {
+    public Collection<Type> getTypes() {
+        loadTypes();
+        return typeManager.getTypes();
+    }
+
+    public Collection<Type> getTypeDescendants(String typeId) {
+        loadTypes();
+        return typeManager.getTypeDescendants(typeId);
+    }
+
+    public ListPage<Type> getTypeChildren(String typeId,
+            boolean includePropertyDefinitions, Paging paging) {
         loadTypes();
-        return typeManager.getTypes(typeId);
+        return typeManager.getTypeChildren(typeId, includePropertyDefinitions,
+                paging);
     }
 
-    public Collection<Type> getTypes(String typeId, int depth,
+    public Collection<Type> getTypeDescendants(String typeId, int depth,
             boolean includePropertyDefinitions) {
         loadTypes();
-        return typeManager.getTypes(typeId, depth, includePropertyDefinitions);
+        return typeManager.getTypeDescendants(typeId, depth,
+                includePropertyDefinitions);
     }
 
     public String getCollectionHref(String type) {
@@ -147,25 +169,34 @@
             return;
         }
         try {
+            // the base types
             String href = getCollectionHref(AtomPubCMIS.COL_TYPES);
             if (href == null) {
                 throw new IllegalArgumentException(
                         "Invalid CMIS repository. No types children collection defined");
             }
-            // TODO lazy load property definition
-            Request req = new Request(href + "?includePropertyDefinitions=true");
-            Response resp = cm.getConnector().get(req);
-            if (!resp.isOk()) {
-                throw new ContentManagerException(
-                        "Remote server returned error code: "
-                                + resp.getStatusCode());
-            }
-            InputStream in = resp.getStream();
-            try {
-                typeManager = TypeFeedReader.INSTANCE.read(
-                        new ReadContext(this), in);
-            } finally {
-                in.close();
+            typeManager = new SimpleTypeManager();
+            // for each base type read all the descendants
+            Collection<Type> baseTypes = readTypes(href).getTypes();
+            for (Type type : baseTypes) {
+                if (!BaseType.ALL_IDS.contains(type.getId())) {
+                    // not a base type, shouldn't be there
+                    continue;
+                }
+                typeManager.addType(type);
+                href = ((APPType) type).getLink(AtomPub.LINK_DOWN,
+                        AtomPubCMIS.MEDIA_TYPE_CMIS_TREE);
+                if (href == null) {
+                    // missing descendants types link
+                    log.error("Type " + type.getId()
+                            + " is missing descendants link");
+                    continue;
+                }
+                TypeManager rr = readTypes(href);
+                Collection<Type> subTypes = rr.getTypes();
+                for (Type t : subTypes) {
+                    typeManager.addType(t);
+                }
             }
         } catch (Exception e) { // TODO how to handle exceptions?
             throw new RuntimeException("Failed to load repository types for "
@@ -173,6 +204,23 @@
         }
     }
 
+    protected TypeManager readTypes(String href) throws Exception {
+        // TODO lazy load property definition
+        Request req = new Request(href + "?includePropertyDefinitions=true");
+        Response resp = cm.getConnector().get(req);
+        if (!resp.isOk()) {
+            throw new ContentManagerException(
+                    "Remote server returned error code: "
+                            + resp.getStatusCode());
+        }
+        InputStream in = resp.getStream();
+        try {
+            return TypeFeedReader.INSTANCE.read(new ReadContext(this), in);
+        } finally {
+            in.close();
+        }
+    }
+
     /*
      * Subclasses should override this.
      */

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/test/java/org/apache/chemistry/atompub/client/TypeFeedReaderTest.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/test/java/org/apache/chemistry/atompub/client/TypeFeedReaderTest.java?rev=898816&r1=898815&r2=898816&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/test/java/org/apache/chemistry/atompub/client/TypeFeedReaderTest.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/test/java/org/apache/chemistry/atompub/client/TypeFeedReaderTest.java Wed Jan 13 15:58:41 2010
@@ -31,7 +31,7 @@
         InputStream is = getClass().getResourceAsStream("/types-feed.xml");
         TypeManager typeManager = TypeFeedReader.INSTANCE.read(new ReadContext(
                 (Repository) null), is);
-        assertEquals(5, typeManager.getTypes(null).size());
+        assertEquals(5, typeManager.getTypes().size());
     }
 
 }

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISCollection.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISCollection.java?rev=898816&r1=898815&r2=898816&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISCollection.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISCollection.java Wed Jan 13 15:58:41 2010
@@ -133,6 +133,20 @@
         return request.absoluteUrlFor(TargetType.TYPE_ENTRY, params);
     }
 
+    public String getTypeChildrenLink(String tid, RequestContext request) {
+        Map<String, String> params = new HashMap<String, String>();
+        params.put("collection", "typechildren");
+        params.put("id", tid);
+        return request.absoluteUrlFor(TargetType.TYPE_COLLECTION, params);
+    }
+
+    public String getTypeDescendantsLink(String tid, RequestContext request) {
+        Map<String, String> params = new HashMap<String, String>();
+        params.put("collection", "typedescendants");
+        params.put("id", tid);
+        return request.absoluteUrlFor(TargetType.TYPE_COLLECTION, params);
+    }
+
     public String getChildrenLink(String fid, RequestContext request) {
         Map<String, String> params = new HashMap<String, String>();
         params.put("collection", "children");

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISObjectsCollection.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISObjectsCollection.java?rev=898816&r1=898815&r2=898816&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISObjectsCollection.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISObjectsCollection.java Wed Jan 13 15:58:41 2010
@@ -98,6 +98,8 @@
 
     public static final String COLTYPE_PATH = "path";
 
+    public static final String COLTYPE_CHILDREN = "children";
+
     public static final String COLTYPE_DESCENDANTS = "descendants";
 
     public static final String COLTYPE_FOLDER_TREE = "foldertree";

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISProvider.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISProvider.java?rev=898816&r1=898815&r2=898816&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISProvider.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISProvider.java Wed Jan 13 15:58:41 2010
@@ -90,7 +90,7 @@
         targetResolver.setPattern("/unfiled", TargetType.TYPE_COLLECTION);
         targetResolver.setPattern("/query(\\?.*)?",
                 CMISQueryFeed.TARGET_TYPE_CMIS_QUERY);
-        targetResolver.setPattern("/types(\\?.*)?", //
+        targetResolver.setPattern("/typechildren(\\?.*)?", //
                 TargetType.TYPE_COLLECTION);
         // per-object collections
         targetResolver.setPattern("/parents/([^/?]+)",
@@ -107,7 +107,9 @@
                 TargetType.TYPE_COLLECTION, "objectid");
         targetResolver.setPattern("/policies/([^/?]+)",
                 TargetType.TYPE_COLLECTION, "objectid");
-        targetResolver.setPattern("/types/([^/?]+)",
+        targetResolver.setPattern("/typechildren/([^/?]+)(\\?.*)?",
+                TargetType.TYPE_COLLECTION, "typeid");
+        targetResolver.setPattern("/typedescendants/([^/?]+)(\\?.*)?",
                 TargetType.TYPE_COLLECTION, "typeid");
 
         // CMIS workspaces available

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISTypesCollection.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISTypesCollection.java?rev=898816&r1=898815&r2=898816&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISTypesCollection.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISTypesCollection.java Wed Jan 13 15:58:41 2010
@@ -35,6 +35,7 @@
 import org.apache.abdera.protocol.server.ResponseContext;
 import org.apache.abdera.protocol.server.context.ResponseContextException;
 import org.apache.chemistry.CMIS;
+import org.apache.chemistry.Paging;
 import org.apache.chemistry.PropertyDefinition;
 import org.apache.chemistry.PropertyType;
 import org.apache.chemistry.Repository;
@@ -51,7 +52,7 @@
     protected boolean singleEntry;
 
     public CMISTypesCollection(String type, String id, Repository repository) {
-        super(type, "types", id, repository);
+        super(type, "typechildren", id, repository);
     }
 
     /*
@@ -104,6 +105,9 @@
                         AtomPubCMIS.PARAM_INCLUDE_PROPERTY_DEFINITIONS, false);
         Factory factory = request.getAbdera().getFactory();
 
+        String tid = type.getId();
+        String tpid = type.getParentId();
+
         entry.setId(getId(type));
         entry.setTitle(getTitle(type));
         entry.setUpdated(getUpdated(type));
@@ -119,15 +123,26 @@
         // alternate is mandated by Atom when there is no atom:content
         entry.addLink(link, AtomPub.LINK_ALTERNATE);
         // CMIS links
+        if (tpid != null) {
+            entry.addLink(getTypeLink(tpid, request), AtomPub.LINK_UP,
+                    AtomPub.MEDIA_TYPE_ATOM_ENTRY, null, null, -1);
+        }
+        entry.addLink(getTypeChildrenLink(tid, request), AtomPub.LINK_DOWN,
+                AtomPub.MEDIA_TYPE_ATOM_FEED, null, null, -1);
+        entry.addLink(getTypeDescendantsLink(tid, request), AtomPub.LINK_DOWN,
+                AtomPubCMIS.MEDIA_TYPE_CMIS_TREE, null, null, -1);
+        entry.addLink(getTypeLink(type.getBaseType().getId(), request),
+                AtomPub.LINK_DESCRIBED_BY, AtomPub.MEDIA_TYPE_ATOM_ENTRY, null,
+                null, -1);
 
         // CMIS-specific
         Element te = factory.newElement(AtomPubCMIS.TYPE, entry);
-        te.setAttributeValue(AtomPubCMIS.ID, type.getId());
+        te.setAttributeValue(AtomPubCMIS.ID, tid);
         Element el;
         // note: setText is called in a separate statement as JDK 5 has problems
         // compiling when it's on one line (compiler generics bug)
         el = factory.newElement(CMIS.ID, te);
-        el.setText(type.getId());
+        el.setText(tid);
         el = factory.newElement(CMIS.LOCAL_NAME, te);
         el.setText(type.getLocalName());
         URI localNamespace = type.getLocalNamespace();
@@ -142,7 +157,7 @@
         el = factory.newElement(CMIS.BASE_ID, te);
         el.setText(type.getBaseType().getId());
         el = factory.newElement(CMIS.PARENT_ID, te);
-        el.setText(type.getParentId());
+        el.setText(tpid == null ? "" : tpid);
         el = factory.newElement(CMIS.DESCRIPTION, te);
         el.setText(type.getDescription());
         el = factory.newElement(CMIS.CREATABLE, te);
@@ -271,10 +286,19 @@
     @Override
     public Iterable<Type> getEntries(RequestContext request)
             throws ResponseContextException {
-        int depth = getParameter(request, AtomPubCMIS.PARAM_DEPTH, -1);
         boolean includePropertyDefinitions = getParameter(request,
                 AtomPubCMIS.PARAM_INCLUDE_PROPERTY_DEFINITIONS, false);
-        return repository.getTypes(id, depth, includePropertyDefinitions);
+        if (CMISObjectsCollection.COLTYPE_DESCENDANTS.equals(getType())) {
+            int depth = getParameter(request, AtomPubCMIS.PARAM_DEPTH, -1);
+            return repository.getTypeDescendants(id, depth,
+                    includePropertyDefinitions);
+        } else { // children
+            int maxItems = getParameter(request, AtomPubCMIS.PARAM_MAX_ITEMS, 0);
+            int skipCount = getParameter(request, AtomPubCMIS.PARAM_SKIP_COUNT,
+                    0);
+            return repository.getTypeChildren(id, includePropertyDefinitions,
+                    new Paging(maxItems, skipCount));
+        }
     }
 
     @Override

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISWorkspaceManager.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISWorkspaceManager.java?rev=898816&r1=898815&r2=898816&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISWorkspaceManager.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISWorkspaceManager.java Wed Jan 13 15:58:41 2010
@@ -17,11 +17,11 @@
  */
 package org.apache.chemistry.atompub.server;
 
+import org.apache.abdera.i18n.text.UrlEncoding;
 import org.apache.abdera.protocol.server.CollectionAdapter;
 import org.apache.abdera.protocol.server.RequestContext;
 import org.apache.abdera.protocol.server.impl.AbstractWorkspaceManager;
 import org.apache.chemistry.Repository;
-import org.apache.chemistry.atompub.AtomPubCMIS;
 
 /**
  * Workspace manager that correctly finds the appropriate collection adapter by
@@ -45,29 +45,41 @@
         String path = spath == null ? uri : uri.substring(spath.length());
         String paths = path + '/';
 
-        if (paths.startsWith("/types/")) {
-            return new CMISTypesCollection(null, null, repository);
+        if (paths.startsWith("/typechildren/")) {
+            String param = request.getTarget().getParameter("typeid");
+            String tid = UrlEncoding.decode(param);
+            return new CMISTypesCollection(
+                    CMISObjectsCollection.COLTYPE_CHILDREN, tid, repository);
+        }
+        if (paths.startsWith("/typedescendants/")) {
+            String param = request.getTarget().getParameter("typeid");
+            String tid = UrlEncoding.decode(param);
+            return new CMISTypesCollection(
+                    CMISObjectsCollection.COLTYPE_DESCENDANTS, tid, repository);
         }
         if (paths.startsWith("/type/")) {
-            return new CMISTypesCollection(AtomPubCMIS.COL_TYPES, null,
-                    repository);
+            return new CMISTypesCollection(null, null, repository);
         }
         if (paths.startsWith("/children/")) {
-            String id = request.getTarget().getParameter("objectid");
+            String param = request.getTarget().getParameter("objectid");
+            String id = UrlEncoding.decode(param);
             return new CMISChildrenCollection(null, id, repository);
         }
         if (paths.startsWith("/descendants/")) {
-            String id = request.getTarget().getParameter("objectid");
+            String param = request.getTarget().getParameter("objectid");
+            String id = UrlEncoding.decode(param);
             return new CMISChildrenCollection(
                     CMISObjectsCollection.COLTYPE_DESCENDANTS, id, repository);
         }
         if (paths.startsWith("/foldertree/")) {
-            String id = request.getTarget().getParameter("objectid");
+            String param = request.getTarget().getParameter("objectid");
+            String id = UrlEncoding.decode(param);
             return new CMISChildrenCollection(
                     CMISObjectsCollection.COLTYPE_FOLDER_TREE, id, repository);
         }
         if (paths.startsWith("/parents/")) {
-            String id = request.getTarget().getParameter("objectid");
+            String param = request.getTarget().getParameter("objectid");
+            String id = UrlEncoding.decode(param);
             return new CMISParentsCollection(null, id, repository);
         }
         if (paths.startsWith("/object/")) {

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/jaxrs/AbderaResource.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/jaxrs/AbderaResource.java?rev=898816&r1=898815&r2=898816&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/jaxrs/AbderaResource.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/jaxrs/AbderaResource.java Wed Jan 13 15:58:41 2010
@@ -250,22 +250,23 @@
 
     @GET
     @Produces(AtomPub.MEDIA_TYPE_ATOM_FEED)
-    @Path("types")
-    public Response doGetTypes() {
+    @Path("typechildren")
+    public Response doGetTypeChildrenAll() {
         return getAbderaFeed(1);
     }
 
     @GET
     @Produces(AtomPub.MEDIA_TYPE_ATOM_FEED)
-    @Path("typesdescendants")
-    public Response doGetTypesDescendantsAll() {
-        return getAbderaFeed(1);
+    @Path("typechildren/{typeid}")
+    public Response doGetTypeChildren() {
+        return getAbderaFeed(2);
     }
 
     @GET
+    // TODO produces tree
     @Produces(AtomPub.MEDIA_TYPE_ATOM_FEED)
-    @Path("typesdescendants/{typeid}")
-    public Response doGetTypesDescendantsTyped() {
+    @Path("typedescendants/{typeid}")
+    public Response doGetTypeDescendants() {
         return getAbderaFeed(2);
     }
 

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/test/java/org/apache/chemistry/atompub/server/AtomPubServerTestCase.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/test/java/org/apache/chemistry/atompub/server/AtomPubServerTestCase.java?rev=898816&r1=898815&r2=898816&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/test/java/org/apache/chemistry/atompub/server/AtomPubServerTestCase.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/test/java/org/apache/chemistry/atompub/server/AtomPubServerTestCase.java Wed Jan 13 15:58:41 2010
@@ -200,15 +200,26 @@
     }
 
     public void testTypes() throws Exception {
-        ClientResponse resp = client.get(base + "/types");
+        ClientResponse resp = client.get(base + "/typechildren");
         assertEquals(HttpStatus.SC_OK, resp.getStatus());
         Element el = resp.getDocument().getRoot();
         assertNotNull(el);
         resp.release();
+
+        resp = client.get(base + "/typechildren/doc");
+        assertEquals(HttpStatus.SC_OK, resp.getStatus());
+        el = resp.getDocument().getRoot();
+        assertNotNull(el);
+        resp.release();
+        resp = client.get(base + "/typedescendants/doc");
+        assertEquals(HttpStatus.SC_OK, resp.getStatus());
+        el = resp.getDocument().getRoot();
+        assertNotNull(el);
+        resp.release();
     }
 
     public void testType() throws Exception {
-        ClientResponse resp = client.get(base + "/type/cmis:document");
+        ClientResponse resp = client.get(base + "/type/doc");
         assertEquals(HttpStatus.SC_OK, resp.getStatus());
         Element el = resp.getDocument().getRoot();
         assertNotNull(el);

Modified: incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/base/BaseRepository.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/base/BaseRepository.java?rev=898816&r1=898815&r2=898816&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/base/BaseRepository.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/base/BaseRepository.java Wed Jan 13 15:58:41 2010
@@ -22,6 +22,8 @@
 
 import org.apache.chemistry.BaseType;
 import org.apache.chemistry.ContentStreamPresence;
+import org.apache.chemistry.ListPage;
+import org.apache.chemistry.Paging;
 import org.apache.chemistry.PropertyDefinition;
 import org.apache.chemistry.Repository;
 import org.apache.chemistry.RepositoryCapabilities;
@@ -158,13 +160,24 @@
         return typeManager.getType(typeId);
     }
 
-    public Collection<Type> getTypes(String typeId) {
-        return typeManager.getTypes(typeId);
+    public Collection<Type> getTypes() {
+        return typeManager.getTypes();
     }
 
-    public Collection<Type> getTypes(String typeId, int depth,
+    public Collection<Type> getTypeDescendants(String typeId) {
+        return typeManager.getTypeDescendants(typeId);
+    }
+
+    public ListPage<Type> getTypeChildren(String typeId,
+            boolean includePropertyDefinitions, Paging paging) {
+        return typeManager.getTypeChildren(typeId, includePropertyDefinitions,
+                paging);
+    }
+
+    public Collection<Type> getTypeDescendants(String typeId, int depth,
             boolean includePropertyDefinitions) {
-        return typeManager.getTypes(typeId, depth, includePropertyDefinitions);
+        return typeManager.getTypeDescendants(typeId, depth,
+                includePropertyDefinitions);
     }
 
 }

Modified: incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleTypeManager.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleTypeManager.java?rev=898816&r1=898815&r2=898816&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleTypeManager.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleTypeManager.java Wed Jan 13 15:58:41 2010
@@ -16,6 +16,7 @@
  */
 package org.apache.chemistry.impl.simple;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -26,6 +27,8 @@
 import java.util.Set;
 
 import org.apache.chemistry.BaseType;
+import org.apache.chemistry.ListPage;
+import org.apache.chemistry.Paging;
 import org.apache.chemistry.Type;
 import org.apache.chemistry.TypeManager;
 
@@ -75,14 +78,46 @@
         return types.get(typeId);
     }
 
-    public Collection<Type> getTypes(String typeId) {
-        return getTypes(typeId, -1, true);
+    public Collection<Type> getTypes() {
+        return new ArrayList<Type>(types.values());
+    }
+
+    public Collection<Type> getTypeDescendants(String typeId) {
+        Collection<Type> list = getTypeDescendants(typeId, -1, true);
+        if (typeId != null) {
+            // add the type itself as first element
+            Type type = getType(typeId);
+            ((LinkedList<Type>) list).addFirst(type);
+        }
+        return list;
+    }
+
+    public ListPage<Type> getTypeChildren(String typeId,
+            boolean includePropertyDefinitions, Paging paging) {
+        // TODO includePropertyDefinitions, paging
+        List<Type> list;
+        if (typeId == null) {
+            list = new ArrayList<Type>(4);
+            for (String id : BaseType.ALL_IDS) {
+                Type type = types.get(id);
+                if (type != null) {
+                    list.add(type);
+                }
+            }
+        } else {
+            Collection<Type> children = typesChildren.get(typeId);
+            if (children == null) {
+                throw new IllegalArgumentException("No such type: " + typeId);
+            }
+            list = new ArrayList<Type>(children);
+        }
+        return new SimpleListPage<Type>(list);
     }
 
     /*
      * This implementation returns subtypes depth-first.
      */
-    public Collection<Type> getTypes(String typeId, int depth,
+    public Collection<Type> getTypeDescendants(String typeId, int depth,
             boolean returnPropertyDefinitions) {
         if (depth == 0) {
             throw new IllegalArgumentException("Depth 0 invalid");
@@ -90,7 +125,7 @@
         List<Type> list = new LinkedList<Type>();
         Set<String> done = new HashSet<String>();
         if (typeId == null) {
-            // ignore depth
+            // return all types
             for (String tid : BaseType.ALL_IDS) {
                 Type type = types.get(tid);
                 if (type == null) {
@@ -104,10 +139,6 @@
             if (!types.containsKey(typeId)) {
                 throw new IllegalArgumentException("No such type: " + typeId);
             }
-            // TODO spec unclear on depth 0
-            if (depth < 0) {
-                list.add(types.get(typeId));
-            }
             collectSubTypes(typeId, depth, returnPropertyDefinitions, list,
                     done);
         }

Modified: incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/impl/simple/TestSimpleRepository.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/impl/simple/TestSimpleRepository.java?rev=898816&r1=898815&r2=898816&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/impl/simple/TestSimpleRepository.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/impl/simple/TestSimpleRepository.java Wed Jan 13 15:58:41 2010
@@ -106,24 +106,42 @@
     }
 
     public void testTypes() {
-        Collection<Type> types = repo.getTypes(null);
+        Collection<Type> types = repo.getTypes();
         assertEquals(5 + 3, types.size()); // default types have been added
+        assertEquals(types.size(), repo.getTypeDescendants(null).size());
         assertNotNull(repo.getType("doc"));
         assertNotNull(repo.getType("subdoc"));
         assertNotNull(repo.getType("fold"));
         assertNull(repo.getType("no-such-type"));
-        assertEquals(3,
-                repo.getTypes(BaseType.DOCUMENT.getId(), -1, false).size());
-        assertEquals(1,
-                repo.getTypes(BaseType.DOCUMENT.getId(), 1, false).size());
-        assertEquals(2,
-                repo.getTypes(BaseType.DOCUMENT.getId(), 2, false).size());
-        assertEquals(2,
-                repo.getTypes(BaseType.DOCUMENT.getId(), 3, false).size());
-        assertEquals(2, repo.getTypes("doc", -1, false).size());
-        assertEquals(1, repo.getTypes("doc", 1, false).size());
-        assertEquals(1, repo.getTypes("doc", 2, false).size());
-        assertEquals(1, repo.getTypes("doc", 3, false).size());
+
+        assertEquals(1, repo.getTypeChildren(BaseType.DOCUMENT.getId(), true,
+                null).size());
+        assertEquals(1, repo.getTypeChildren("doc", true, null).size());
+        assertEquals(0, repo.getTypeChildren("subdoc", true, null).size());
+        // chemistry:root and fold
+        assertEquals(2, repo.getTypeChildren(BaseType.FOLDER.getId(), true,
+                null).size());
+        assertEquals(0, repo.getTypeChildren("fold", true, null).size());
+
+        assertEquals(2, repo.getTypeDescendants(BaseType.DOCUMENT.getId(), -1,
+                false).size());
+        assertEquals(1, repo.getTypeDescendants(BaseType.DOCUMENT.getId(), 1,
+                false).size());
+        assertEquals(2, repo.getTypeDescendants(BaseType.DOCUMENT.getId(), 2,
+                false).size());
+        assertEquals(2, repo.getTypeDescendants(BaseType.DOCUMENT.getId(), 3,
+                false).size());
+        assertEquals(1, repo.getTypeDescendants("doc", -1, false).size());
+        assertEquals(1, repo.getTypeDescendants("doc", 1, false).size());
+        assertEquals(1, repo.getTypeDescendants("doc", 2, false).size());
+        assertEquals(1, repo.getTypeDescendants("doc", 3, false).size());
+
+        try {
+            repo.getTypeDescendants("no-such-type");
+            fail();
+        } catch (IllegalArgumentException e) {
+            // ok
+        }
     }
 
     public void testRoot() throws Exception {

Modified: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrRepository.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrRepository.java?rev=898816&r1=898815&r2=898816&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrRepository.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrRepository.java Wed Jan 13 15:58:41 2010
@@ -22,10 +22,10 @@
 
 import java.io.Serializable;
 import java.net.URI;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -33,6 +33,7 @@
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.SimpleCredentials;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
 import javax.jcr.nodetype.NodeType;
 import javax.jcr.nodetype.NodeTypeIterator;
 import javax.jcr.nodetype.NodeTypeManager;
@@ -45,13 +46,16 @@
 import org.apache.chemistry.CapabilityQuery;
 import org.apache.chemistry.CapabilityRendition;
 import org.apache.chemistry.Connection;
+import org.apache.chemistry.ListPage;
 import org.apache.chemistry.ObjectId;
+import org.apache.chemistry.Paging;
 import org.apache.chemistry.Repository;
 import org.apache.chemistry.RepositoryCapabilities;
 import org.apache.chemistry.RepositoryEntry;
 import org.apache.chemistry.RepositoryInfo;
 import org.apache.chemistry.SPI;
 import org.apache.chemistry.Type;
+import org.apache.chemistry.impl.simple.SimpleListPage;
 import org.apache.chemistry.impl.simple.SimpleObjectId;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -124,6 +128,8 @@
                 baseType = BaseType.DOCUMENT;
             }
             return new JcrType(nt, baseType);
+        } catch (NoSuchNodeTypeException e) {
+            return null;
         } catch (RepositoryException e) {
             String msg = "Unable get type: " + typeId;
             log.error(msg, e);
@@ -131,21 +137,44 @@
         return null;
     }
 
-    public Collection<Type> getTypes(String typeId) {
-        return getTypes(typeId, -1, true);
+    public Collection<Type> getTypes() {
+        return getTypeDescendants(null, -1, true);
     }
 
-    public List<Type> getTypes(String typeId, int depth,
+    public Collection<Type> getTypeDescendants(String typeId) {
+        Collection<Type> list = getTypeDescendants(typeId, -1, true);
+        if (typeId != null) {
+            // add the type itself as first element
+            Type type = getType(typeId);
+            ((LinkedList<Type>) list).addFirst(type);
+        }
+        return list;
+    }
+
+    public ListPage<Type> getTypeChildren(String typeId,
+            boolean includePropertyDefinitions, Paging paging) {
+        // TODO proper children
+        List<Type> list = getTypeDescendants(typeId, -1, true);
+        return new SimpleListPage<Type>(list);
+    }
+
+    public List<Type> getTypeDescendants(String typeId, int depth,
             boolean includePropertyDefinitions) {
 
         // TODO depth, includePropertyDefinitions
 
         try {
-            List<Type> result = new ArrayList<Type>();
+            List<Type> result = new LinkedList<Type>();
 
             Session session = repository.login(creds, workspace);
 
-            NodeTypeIterator nodeTypes = session.getWorkspace().getNodeTypeManager().getAllNodeTypes();
+            NodeTypeManager ntmgr = session.getWorkspace().getNodeTypeManager();
+            if (typeId != null) {
+                // check existence
+                ntmgr.getNodeType(typeId);
+            }
+
+            NodeTypeIterator nodeTypes = ntmgr.getAllNodeTypes();
             while (nodeTypes.hasNext()) {
                 NodeType nodeType = nodeTypes.nextNodeType();
                 if (nodeType.isMixin()) {
@@ -156,14 +185,17 @@
                 if (JcrCmisMap.isBaseTypeDocument(nodeType.getName())) {
                     baseType = BaseType.DOCUMENT;
                 }
-                // If typeId is provided, only the specific type and its
-                // descendants are returned, otherwise all types are returned.
-                if (typeId == null || typeId.equals(baseType.getId())) {
+                // If typeId is provided, only the descendants are returned,
+                // otherwise all types are returned.
+                // TODO proper hierarchy of types
+                if (typeId == null) {
                     result.add(new JcrType(nodeType, baseType));
                 }
             }
 
             return result;
+        } catch (NoSuchNodeTypeException e) {
+            throw new IllegalArgumentException("No such type: " + typeId);
         } catch (RepositoryException e) {
             String msg = "Unable to retrieve node types.";
             log.error(msg, e);

Modified: incubator/chemistry/trunk/chemistry/chemistry-tests/src/main/java/org/apache/chemistry/test/BasicTestCase.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-tests/src/main/java/org/apache/chemistry/test/BasicTestCase.java?rev=898816&r1=898815&r2=898816&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-tests/src/main/java/org/apache/chemistry/test/BasicTestCase.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-tests/src/main/java/org/apache/chemistry/test/BasicTestCase.java Wed Jan 13 15:58:41 2010
@@ -202,6 +202,11 @@
         assertEquals(root.getId(), fold.getId());
     }
 
+    public void testTypes() {
+        Collection<Type> types = repository.getTypes();
+        assertEquals(7, types.size());
+    }
+
     public void testDefaultValues() {
         Folder root = conn.getRootFolder();
         Folder f1 = (Folder) root.getChildren().get(0);