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 2009/08/02 15:08:25 UTC

svn commit: r800062 - 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/main/java/org/apache/chemistry/ato...

Author: fguillaume
Date: Sun Aug  2 13:08:24 2009
New Revision: 800062

URL: http://svn.apache.org/viewvc?rev=800062&view=rev
Log:
CMIS-44: added getFolderTree. cleaned up cmis vs cmisra namespaces

Modified:
    incubator/chemistry/trunk/chemistry/chemistry-api/src/main/java/org/apache/chemistry/RepositoryCapabilities.java
    incubator/chemistry/trunk/chemistry/chemistry-api/src/main/java/org/apache/chemistry/SPI.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPConnection.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPObjectEntry.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPRepositoryCapabilities.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/AbstractEntryReader.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/AbstractObjectReader.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/ObjectEntryWriter.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/QueryWriter.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/ServiceDocumentReader.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/XmlProperty.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/test/resources/feedentry.xml
    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/CMISServiceResponse.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-atompub/src/main/java/org/apache/chemistry/atompub/CMIS.java
    incubator/chemistry/trunk/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/abdera/ObjectElement.java
    incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java
    incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleRepository.java
    incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/util/GregorianCalendar.java
    incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/util/TestGregorianCalendar.java
    incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrConnection.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/RepositoryCapabilities.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-api/src/main/java/org/apache/chemistry/RepositoryCapabilities.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-api/src/main/java/org/apache/chemistry/RepositoryCapabilities.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-api/src/main/java/org/apache/chemistry/RepositoryCapabilities.java Sun Aug  2 13:08:24 2009
@@ -57,6 +57,12 @@
     boolean isAllVersionsSearchable();
 
     /**
+     * Ability to enumerate the descendants of a folder via
+     * {@link SPI#getDescendants} and {@link SPI#getFolderTree}.
+     */
+    boolean hasGetDescendants();
+
+    /**
      * Support for query on full-text or metadata.
      */
     QueryCapability getQueryCapability();

Modified: incubator/chemistry/trunk/chemistry/chemistry-api/src/main/java/org/apache/chemistry/SPI.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-api/src/main/java/org/apache/chemistry/SPI.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-api/src/main/java/org/apache/chemistry/SPI.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-api/src/main/java/org/apache/chemistry/SPI.java Sun Aug  2 13:08:24 2009
@@ -66,6 +66,17 @@
      */
 
     /**
+     * Gets the set of descendant folders contained in the specified folder.
+     *
+     * @param folder the folder
+     * @param depth the depth, or {@code -1} for all levels
+     * @param filter the properties filter, or {@code null} for all properties
+     * @param includeAllowableActions {@code true} to include allowable actions
+     */
+    List<ObjectEntry> getFolderTree(ObjectId folder, int depth, String filter,
+            boolean includeAllowableActions);
+
+    /**
      * Gets the descendants of a folder.
      * <p>
      * Returns the descendant objects contained at one or more levels in the

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPConnection.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPConnection.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPConnection.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPConnection.java Sun Aug  2 13:08:24 2009
@@ -130,12 +130,12 @@
 
     public Folder newFolder(String typeId, Folder folder) {
         Type type = repository.getType(typeId);
-        if (type == null || type.getBaseType() != BaseType.DOCUMENT) {
+        if (type == null || type.getBaseType() != BaseType.FOLDER) {
             throw new IllegalArgumentException(typeId);
         }
         APPObjectEntry entry = newObjectEntry(typeId);
         if (folder != null) {
-            entry.setValue(Property.PARENT_ID, folder.getId());
+            entry._setValue(Property.PARENT_ID, folder.getId());
             entry.addLink(Atom.LINK_UP,
                     ((APPFolder) folder).entry.getEditLink());
         }
@@ -171,6 +171,34 @@
      */
 
     /**
+     * Accumulates the descendant folders into a list recursively.
+     */
+    protected void accumulateFolders(ObjectId folder, int depth, String filter,
+            boolean includeAllowableActions, List<ObjectEntry> list) {
+        List<ObjectEntry> children = getChildren(folder, filter,
+                includeAllowableActions, false, Integer.MAX_VALUE, 0, null,
+                new boolean[1]);
+        for (ObjectEntry child : children) {
+            if (child.getBaseType() != BaseType.FOLDER) {
+                continue;
+            }
+            list.add(child);
+            if (depth > 1) {
+                accumulateFolders(child, depth - 1, filter,
+                        includeAllowableActions, list);
+            }
+        }
+    }
+
+    // TODO use foldertree feed
+    public List<ObjectEntry> getFolderTree(ObjectId folder, int depth,
+            String filter, boolean includeAllowableActions) {
+        List<ObjectEntry> list = new ArrayList<ObjectEntry>();
+        accumulateFolders(folder, depth, filter, includeAllowableActions, list);
+        return list;
+    }
+
+    /**
      * Accumulates the descendants into a list recursively.
      */
     protected void accumulateDescendants(ObjectId folder, int depth,
@@ -190,6 +218,7 @@
         }
     }
 
+    // TODO use descendants feed
     public List<ObjectEntry> getDescendants(ObjectId folder, int depth,
             String filter, boolean includeAllowableActions,
             boolean includeRelationships, String orderBy) {

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPObjectEntry.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPObjectEntry.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPObjectEntry.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPObjectEntry.java Sun Aug  2 13:08:24 2009
@@ -152,6 +152,22 @@
         }
     }
 
+    protected void _setValue(String id, Serializable value) {
+        XmlProperty p = properties.get(id);
+        if (p != null) {
+            p._setValue(value);
+        } else {
+            PropertyDefinition pd = connection.getRepository().getType(
+                    getTypeId()).getPropertyDefinition(id);
+            if (pd == null) {
+                throw new IllegalArgumentException("No such property: " + id);
+            }
+            p = new XmlProperty(pd);
+            p._setValue(value);
+            properties.put(id, p);
+        }
+    }
+
     public void setValues(Map<String, Serializable> values) {
         for (Map.Entry<String, Serializable> entry : values.entrySet()) {
             setValue(entry.getKey(), entry.getValue());
@@ -186,7 +202,7 @@
     }
 
     public void writeObjectTo(XMLWriter xw) throws IOException {
-        xw.element(CMIS.OBJECT);
+        xw.element(CMIS.RESTATOM_OBJECT);
         xw.start();
         xw.element(CMIS.PROPERTIES);
         xw.start();

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPRepositoryCapabilities.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPRepositoryCapabilities.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPRepositoryCapabilities.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/APPRepositoryCapabilities.java Sun Aug  2 13:08:24 2009
@@ -40,6 +40,8 @@
 
     protected boolean isAllVersionsSearchable;
 
+    protected boolean hasGetDescendants;
+
     protected boolean isPWCSearchable;
 
     protected boolean isPWCUpdatable;
@@ -72,6 +74,10 @@
         return isAllVersionsSearchable;
     }
 
+    public boolean hasGetDescendants() {
+        return hasGetDescendants;
+    }
+
     public boolean isPWCSearchable() {
         return isPWCSearchable;
     }
@@ -84,6 +90,10 @@
         this.isAllVersionsSearchable = isAllVersionsSearchable;
     }
 
+    public void setHasGetDescendants(boolean hasGetDescendants) {
+        this.hasGetDescendants = hasGetDescendants;
+    }
+
     public void setHasMultifiling(boolean hasMultifiling) {
         this.hasMultifiling = hasMultifiling;
     }

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/AbstractEntryReader.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/AbstractEntryReader.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/AbstractEntryReader.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/AbstractEntryReader.java Sun Aug  2 13:08:24 2009
@@ -49,7 +49,9 @@
         T object = createObject(ctx);
         ChildrenNavigator children = reader.getChildren();
         while (children.next()) {
-            if (reader.getNamespaceURI().equals(CMIS.CMIS_NS)) {
+            String nsuri = reader.getNamespaceURI();
+            if (nsuri.equals(CMIS.CMIS_NS)
+                    || nsuri.equals(CMIS.CMISRA_NS)) {
                 readCmisElement(ctx, reader, object);
             } else {
                 readEntryElement(ctx, reader, object);

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/AbstractObjectReader.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/AbstractObjectReader.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/AbstractObjectReader.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/AbstractObjectReader.java Sun Aug  2 13:08:24 2009
@@ -42,7 +42,7 @@
     @Override
     protected void readCmisElement(ReadContext ctx, StaxReader reader, T object)
             throws XMLStreamException {
-        if (reader.getLocalName().equals(CMIS.OBJECT.getLocalPart())) {
+        if (reader.getLocalName().equals(CMIS.RESTATOM_OBJECT.getLocalPart())) {
             readCmisObject(ctx, reader, object);
         }
     }
@@ -57,7 +57,7 @@
 
     protected void readObjectChildElement(ReadContext ctx, StaxReader reader,
             T object) throws XMLStreamException {
-        if (reader.getNamespaceURI().equals(CMIS.OBJECT.getNamespaceURI())) {
+        if (reader.getNamespaceURI().equals(CMIS.CMIS_NS)) {
             if (reader.getLocalName().equals(CMIS.PROPERTIES.getLocalPart())) {
                 readProperties(ctx, reader, object);
             } else if (reader.getLocalName().equals(

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/ObjectEntryWriter.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/ObjectEntryWriter.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/ObjectEntryWriter.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/ObjectEntryWriter.java Sun Aug  2 13:08:24 2009
@@ -40,12 +40,22 @@
     public void write(ObjectEntry object, XMLWriter xw) throws IOException {
         try {
             xw.start();
-            xw.element("entry").xmlns(Atom.ATOM_NS).xmlns(CMIS.CMIS_PREFIX,
-                    CMIS.CMIS_NS);
+            xw.element("entry");
+            xw.xmlns(Atom.ATOM_NS);
+            xw.xmlns(CMIS.CMIS_PREFIX, CMIS.CMIS_NS);
+            xw.xmlns(CMIS.CMISRA_PREFIX, CMIS.CMISRA_NS);
             xw.start();
             // atom requires an ID to be set even on new created entries ..
             xw.element("id").content("urn:uuid:" + object.getId());
-            xw.element("title").content((String) object.getValue(Property.NAME));
+            // TODO hardcoded title properties...
+            String title = (String) object.getValue("title");
+            if (title == null) {
+                title = (String) object.getValue("dc:title");
+            }
+            if (title == null) {
+                title = (String) object.getValue(Property.NAME);
+            }
+            xw.element("title").content(title);
             xw.element("updated").content(new Date());
             xw.element("content").content(""); // TODO fake content for now
             writeCmisObject(object, xw);

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/QueryWriter.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/QueryWriter.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/QueryWriter.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/QueryWriter.java Sun Aug  2 13:08:24 2009
@@ -67,7 +67,7 @@
 
     @Override
     public String getContentType() {
-        return "application/cmisquery+xml";
+        return CMIS.MEDIA_TYPE_CMIS_QUERY;
     }
 
     @Override

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/ServiceDocumentReader.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/ServiceDocumentReader.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/ServiceDocumentReader.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/ServiceDocumentReader.java Sun Aug  2 13:08:24 2009
@@ -70,7 +70,7 @@
                         String href = reader.getAttributeValue("href");
                         String type = reader.getAttributeValue(CMIS.RESTATOM_COLLECTION_TYPE.getLocalPart());
                         addCollection(repo, href, type);
-                    } else if (name.equals(CMIS.REPOSITORY_INFO)) {
+                    } else if (name.equals(CMIS.RESTATOM_REPOSITORY_INFO)) {
                         RepositoryInfo info = readRepositoryInfo(context,
                                 reader);
                         setInfo(repo, info);
@@ -104,6 +104,8 @@
                     localName = reader.getLocalName();
                     if (localName.equals(CMIS.CAPABILITY_ALL_VERSIONS_SEARCHABLE.getLocalPart())) {
                         caps.setAllVersionsSearchable(Boolean.parseBoolean(reader.getElementText()));
+                    } else if (localName.equals(CMIS.CAPABILITY_CAN_GET_DESCENDANTS.getLocalPart())) {
+                        caps.setHasGetDescendants(Boolean.parseBoolean(reader.getElementText()));
                     } else if (localName.equals(CMIS.CAPABILITY_MULTIFILING.getLocalPart())) {
                         caps.setHasMultifiling(Boolean.parseBoolean(reader.getElementText()));
                     } else if (localName.equals(CMIS.CAPABILITY_PWC_SEARCHABLE.getLocalPart())) {

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/XmlProperty.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/XmlProperty.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/XmlProperty.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/main/java/org/apache/chemistry/atompub/client/stax/XmlProperty.java Sun Aug  2 13:08:24 2009
@@ -168,6 +168,10 @@
         this.value = value;
     }
 
+    public void _setValue(Serializable value) {
+        this.value = value;
+    }
+
     public Object getXmlValue() {
         return xmlValue;
     }

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/test/resources/feedentry.xml
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/test/resources/feedentry.xml?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/test/resources/feedentry.xml (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-client/src/test/resources/feedentry.xml Sun Aug  2 13:08:24 2009
@@ -2,19 +2,19 @@
 <entry xmlns="http://www.w3.org/2005/Atom" xmlns:cmis="http://docs.oasis-open.org/ns/cmis/core/200901">
   <cmis:object>
     <cmis:properties>
-      <cmis:propertyString cmis:pdid="string_null" />
-      <cmis:propertyString cmis:pdid="string">
+      <cmis:propertyString pdid="string_null" />
+      <cmis:propertyString pdid="string">
         <cmis:value>string1</cmis:value>
       </cmis:propertyString>
-      <cmis:propertyDateTime cmis:pdid="date">
+      <cmis:propertyDateTime pdid="date">
         <cmis:value>2009-03-17T17:55:08+01:00
         </cmis:value>
       </cmis:propertyDateTime>
-      <cmis:propertyString cmis:pdid="string_array">
+      <cmis:propertyString pdid="string_array">
         <cmis:value>string1</cmis:value>
         <cmis:value>string2</cmis:value>
       </cmis:propertyString>
-      <cmis:propertyDateTime cmis:pdid="date_array">
+      <cmis:propertyDateTime pdid="date_array">
         <cmis:value>2009-03-17T17:55:08+01:00
         </cmis:value>
         <cmis:value>2009-03-18T17:55:08+01:00

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=800062&r1=800061&r2=800062&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 Sun Aug  2 13:08:24 2009
@@ -105,7 +105,7 @@
         return request.absoluteUrlFor(TargetType.TYPE_ENTRY, params);
     }
 
-    public String getDownLink(String fid, RequestContext request) {
+    public String getChildrenLink(String fid, RequestContext request) {
         Map<String, String> params = new HashMap<String, String>();
         params.put("entrytype", "children");
         params.put("id", fid);

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=800062&r1=800061&r2=800062&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 Sun Aug  2 13:08:24 2009
@@ -29,6 +29,7 @@
 import org.apache.abdera.i18n.iri.IRI;
 import org.apache.abdera.model.AtomDate;
 import org.apache.abdera.model.Content;
+import org.apache.abdera.model.DateTime;
 import org.apache.abdera.model.Document;
 import org.apache.abdera.model.Element;
 import org.apache.abdera.model.Entry;
@@ -48,6 +49,7 @@
 import org.apache.chemistry.ObjectEntry;
 import org.apache.chemistry.ObjectId;
 import org.apache.chemistry.Property;
+import org.apache.chemistry.PropertyDefinition;
 import org.apache.chemistry.Repository;
 import org.apache.chemistry.SPI;
 import org.apache.chemistry.Type;
@@ -56,6 +58,7 @@
 import org.apache.chemistry.atompub.CMIS;
 import org.apache.chemistry.atompub.abdera.ObjectElement;
 import org.apache.chemistry.impl.simple.SimpleObjectId;
+import org.apache.chemistry.util.GregorianCalendar;
 
 /**
  * CMIS Collection for object entries.
@@ -81,7 +84,7 @@
         feed.addAuthor(getAuthor(request));
         feed.setUpdated(new Date()); // XXX
 
-        feed.addLink(getDownLink(id, request), "self");
+        feed.addLink(getChildrenLink(id, request), "self");
         feed.addLink(getObjectLink(id, request), CMIS.LINK_SOURCE);
 
         // RFC 5005 paging
@@ -148,14 +151,24 @@
         entry.addLink(link, "edit");
         // alternate is mandated by Atom when there is no atom:content
         entry.addLink(link, "alternate");
+
         // CMIS links
         String oid = object.getId();
-        // TODO for folder's up, link to an entry and not a feed
-        entry.addLink(getParentsLink(oid, request), Atom.LINK_UP,
-                Atom.MEDIA_TYPE_ATOM_FEED, null, null, 0);
-        if (object.getBaseType() == BaseType.FOLDER) {
-            entry.addLink(getDownLink(oid, request), Atom.LINK_DOWN,
-                    Atom.MEDIA_TYPE_ATOM_FEED, null, null, 0);
+        BaseType baseType = object.getBaseType();
+        if (baseType == BaseType.FOLDER) {
+            String pid = (String) object.getValue(Property.PARENT_ID);
+            if (pid != null) {
+                entry.addLink(getObjectLink(pid, request), Atom.LINK_UP,
+                        Atom.MEDIA_TYPE_ATOM_ENTRY, null, null, -1);
+            }
+            // TODO don't add links if no children/decendants
+            entry.addLink(getChildrenLink(oid, request), Atom.LINK_DOWN,
+                    Atom.MEDIA_TYPE_ATOM_FEED, null, null, -1);
+            // TODO children descendants and folder tree
+        } else if (baseType == BaseType.DOCUMENT) {
+            // TODO don't add link if no parents
+            entry.addLink(getParentsLink(oid, request), Atom.LINK_UP,
+                    Atom.MEDIA_TYPE_ATOM_FEED, null, null, -1);
         }
         // entry.addLink("XXX", CMIS.LINK_ALLOWABLE_ACTIONS);
         // entry.addLink("XXX", CMIS.LINK_RELATIONSHIPS);
@@ -182,10 +195,11 @@
         } catch (ResponseContextException e) {
             return createErrorResponse(e);
         }
-        if (entry == null || !ProviderHelper.isValidEntry(entry)) {
+        if (entry == null /* || !ProviderHelper.isValidEntry(entry) TODO XXX TCK */) {
             return new EmptyResponseContext(400);
         }
-        Element obb = entry.getFirstChild(CMIS.OBJECT);
+
+        Element obb = entry.getFirstChild(CMIS.RESTATOM_OBJECT);
         ObjectElement objectElement = new ObjectElement(obb, repository);
         Map<String, Serializable> properties;
         try {
@@ -193,14 +207,56 @@
         } catch (Exception e) { // TODO proper exception
             return createErrorResponse(new ResponseContextException(500, e));
         }
-        ContentStream contentStream = null;
-        VersioningState versioningState = null;
+
         String typeId = (String) properties.get(Property.TYPE_ID);
-        // not null, already checked in getProperties
+        Type type = repository.getType(typeId);
+        if (type == null) {
+            return createErrorResponse(new ResponseContextException(
+                    "Unknown type: " + typeId, 500));
+        }
+
+        // set Atom-defined properties into entry
+        // TODO hardcoded title properties...
+        PropertyDefinition pdt = type.getPropertyDefinition("title");
+        if (pdt == null) {
+            pdt = type.getPropertyDefinition("dc:title");
+        }
+        if (pdt == null) {
+            pdt = type.getPropertyDefinition(Property.NAME);
+        }
+        if (pdt != null) {
+            String title = entry.getTitle(); // Atom MUST
+            properties.put(pdt.getId(), title);
+        }
+        // TODO summary
+        // parse the date ourselves, as Abdera's AtomDate loses the timezone
+        Calendar updated;
+        DateTime updatedElement = entry.getUpdatedElement(); // Atom MUST
+        if (updatedElement == null) { // TODO XXX TCK
+            updated = null;
+        } else {
+            updated = GregorianCalendar.fromAtomPub(updatedElement.getText());
+            properties.put(Property.LAST_MODIFICATION_DATE, updated);
+        }
 
         SPI spi = repository.getSPI(); // TODO XXX connection leak
-        ObjectId objectId = spi.createDocument(typeId, properties,
-                new SimpleObjectId(id), contentStream, versioningState);
+        ObjectId folderId = new SimpleObjectId(id);
+        ObjectId objectId;
+        switch (type.getBaseType()) {
+        case DOCUMENT:
+            ContentStream contentStream = null; // TODO
+            VersioningState versioningState = null; // TODO
+            objectId = spi.createDocument(typeId, properties, folderId,
+                    contentStream, versioningState);
+            break;
+        case FOLDER:
+            objectId = spi.createFolder(typeId, properties, folderId);
+            break;
+        default:
+            throw new UnsupportedOperationException("not implemented: "
+                    + type.getBaseType());
+        }
+
         ObjectEntry object = spi.getProperties(objectId, null, false, false);
 
         // prepare the updated entry to return in the response
@@ -264,7 +320,8 @@
             throws ResponseContextException {
         String mediaLink = getMediaLink(object.getId(), request);
         entry.setContent(new IRI(mediaLink), getContentType(object));
-        entry.addLink(mediaLink, Atom.LINK_EDIT_MEDIA);
+        entry.addLink(mediaLink, Atom.LINK_EDIT_MEDIA, getContentType(object),
+                null, null, getContentSize(object));
         return mediaLink;
     }
 

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISServiceResponse.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISServiceResponse.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISServiceResponse.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub-server/src/main/java/org/apache/chemistry/atompub/server/CMISServiceResponse.java Sun Aug  2 13:08:24 2009
@@ -56,8 +56,8 @@
         sw.startDocument();
         sw.startService();
         ((StaxStreamWriter) sw).writeNamespace(CMIS.CMIS_PREFIX, CMIS.CMIS_NS);
-        ((StaxStreamWriter) sw).writeNamespace(CMIS.CMIS_RESTATOM_PREFIX,
-                CMIS.CMIS_RESTATOM_NS);
+        ((StaxStreamWriter) sw).writeNamespace(CMIS.CMISRA_PREFIX,
+                CMIS.CMISRA_NS);
         for (WorkspaceInfo wi : provider.getWorkspaceManager(request).getWorkspaces(
                 request)) {
             sw.startWorkspace();
@@ -113,7 +113,7 @@
             RepositoryInfo info = repository.getInfo();
             RepositoryCapabilities cap = info.getCapabilities();
 
-            sw.startElement(CMIS.REPOSITORY_INFO);
+            sw.startElement(CMIS.RESTATOM_REPOSITORY_INFO);
             write(CMIS.REPOSITORY_ID, repository.getId());
             write(CMIS.REPOSITORY_NAME, repository.getName());
             write(CMIS.REPOSITORY_RELATIONSHIP, "self");

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=800062&r1=800061&r2=800062&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 Sun Aug  2 13:08:24 2009
@@ -37,6 +37,7 @@
 import org.apache.abdera.protocol.server.servlet.ServletRequestContext;
 import org.apache.chemistry.Repository;
 import org.apache.chemistry.atompub.Atom;
+import org.apache.chemistry.atompub.CMIS;
 import org.apache.chemistry.atompub.server.CMISProvider;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -182,7 +183,7 @@
     }
 
     @POST
-    @Consumes("application/cmisquery+xml")
+    @Consumes(CMIS.MEDIA_TYPE_CMIS_QUERY)
     @Produces(Atom.MEDIA_TYPE_ATOM_FEED)
     @Path("query")
     public Response doPostQuery() {

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=800062&r1=800061&r2=800062&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 Sun Aug  2 13:08:24 2009
@@ -161,7 +161,7 @@
         Service root = (Service) resp.getDocument().getRoot();
         Workspace workspace = root.getWorkspaces().get(0);
         assertNotNull(root);
-        Element info = workspace.getFirstChild(CMIS.REPOSITORY_INFO);
+        Element info = workspace.getFirstChild(CMIS.RESTATOM_REPOSITORY_INFO);
         assertNotNull(info);
 
         resp = client.get(base + "/types");
@@ -208,7 +208,7 @@
 
         @Override
         public String getContentType() {
-            return "application/cmisquery+xml";
+            return CMIS.MEDIA_TYPE_CMIS_QUERY;
         }
 
         public boolean isRepeatable() {

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/CMIS.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/CMIS.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/CMIS.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/CMIS.java Sun Aug  2 13:08:24 2009
@@ -27,28 +27,28 @@
     private CMIS() {
     }
 
-    public static final String CMIS_NS = "http://docs.oasis-open.org/ns/cmis/core/200901";
+    public static final String CMIS_NS_BASE = "http://docs.oasis-open.org/ns/cmis/";
+
+    public static final String CMIS_NS = CMIS_NS_BASE + "core/200901";
 
     public static final String CMIS_PREFIX = "cmis";
 
-    public static final String CMIS_RESTATOM_NS = "http://docs.oasis-open.org/ns/cmis/restatom/200901";
+    public static final String CMISRA_NS = CMIS_NS_BASE + "restatom/200901";
 
-    public static final String CMIS_RESTATOM_PREFIX = "cmisra";
+    public static final String CMISRA_PREFIX = "cmisra";
 
     public static QName CMISName(String localPart) {
         return new QName(CMIS_NS, localPart, CMIS_PREFIX);
     }
 
     public static QName CMISRAName(String localPart) {
-        return new QName(CMIS_RESTATOM_NS, localPart, CMIS_RESTATOM_PREFIX);
+        return new QName(CMISRA_NS, localPart, CMISRA_PREFIX);
     }
 
     /*
      * ----- XML Qualified Names -----
      */
 
-    public static final QName REPOSITORY_INFO = CMISName("repositoryInfo");
-
     public static final QName REPOSITORY_ID = CMISName("repositoryId");
 
     public static final QName REPOSITORY_NAME = CMISName("repositoryName");
@@ -79,6 +79,8 @@
 
     public static final QName CAPABILITY_ALL_VERSIONS_SEARCHABLE = CMISName("capabilityAllVersionsSearchable");
 
+    public static final QName CAPABILITY_CAN_GET_DESCENDANTS = CMISName("capabilityGetDescendants");
+
     public static final QName CAPABILITY_QUERY = CMISName("capabilityQuery");
 
     public static final QName CAPABILITY_JOIN = CMISName("capabilityJoin");
@@ -159,8 +161,6 @@
 
     public static final QName DEFAULT_VALUE = CMISName("defaultValue");
 
-    public static final QName OBJECT = CMISName("object");
-
     public static final QName PROPERTIES = CMISName("properties");
 
     public static final QName PROPERTY_STRING = CMISName("propertyString");
@@ -183,12 +183,6 @@
 
     public static final QName PROPERTY_XHTML = CMISName("propertyXhtml");
 
-    public static final QName PDID = CMISName("pdid");
-
-    public static final QName LOCALNAME = CMISName("localname");
-
-    public static final QName DISPLAYNAME = CMISName("displayname");
-
     public static final QName VALUE = CMISName("value");
 
     public static final QName ALLOWABLE_ACTIONS = CMISName("allowableActions");
@@ -205,10 +199,20 @@
 
     public static final QName INCLUDE_ALLOWABLE_ACTIONS = CMISName("includeAllowableActions");
 
+    // no namespace for attributes
+
+    public static final QName PDID = new QName("pdid");
+
+    public static final QName LOCALNAME = new QName("localname");
+
+    public static final QName DISPLAYNAME = new QName("displayname");
+
     /*
      * ----- CMIS REST Atom Qualified Names-----
      */
 
+    public static final QName RESTATOM_REPOSITORY_INFO = CMISRAName("repositoryInfo");
+
     public static final QName RESTATOM_COLLECTION_TYPE = CMISRAName("collectionType");
 
     public static final QName RESTATOM_URI_TEMPLATE = CMISRAName("uritemplate");
@@ -219,21 +223,23 @@
 
     public static final QName RESTATOM_MEDIA_TYPE = CMISRAName("mediatype");
 
+    public static final QName RESTATOM_OBJECT = CMISRAName("object");
+
     /*
      * ----- CMIS Collection Types -----
      */
 
-    public static final String COL_ROOT_CHILDREN = "rootchildren";
+    public static final String COL_ROOT_CHILDREN = "root";
 
-    public static final String COL_ROOT_DESCENDANTS = "rootdescendants";
+    public static final String COL_ROOT_DESCENDANTS = "rootdescendants"; // TODO
 
     public static final String COL_UNFILED = "unfiled";
 
     public static final String COL_CHECKED_OUT = "checkedout";
 
-    public static final String COL_TYPES_CHILDREN = "typeschildren";
+    public static final String COL_TYPES_CHILDREN = "types";
 
-    public static final String COL_TYPES_DESCENDANTS = "typesdescendants";
+    public static final String COL_TYPES_DESCENDANTS = "typesdescendants"; // TODO
 
     public static final String COL_QUERY = "query";
 
@@ -241,23 +247,33 @@
      * ----- CMIS Link Types -----
      */
 
-    public static final String LINK_SOURCE = "source";
+    public static final String CMIS_LINK_NS_BASE = CMIS_NS_BASE
+            + "link/200901/";
+
+    public static final String LINK_SOURCE = CMIS_LINK_NS_BASE + "source";
 
-    public static final String LINK_TARGET = "target";
+    public static final String LINK_TARGET = CMIS_LINK_NS_BASE + "target";
 
-    public static final String LINK_ALLOWABLE_ACTIONS = "allowableactions";
+    public static final String LINK_ALLOWABLE_ACTIONS = CMIS_LINK_NS_BASE
+            + "allowableactions";
 
-    public static final String LINK_RELATIONSHIPS = "relationships";
+    public static final String LINK_RELATIONSHIPS = CMIS_LINK_NS_BASE
+            + "relationships";
 
-    public static final String LINK_POLICIES = "policies";
+    public static final String LINK_POLICIES = CMIS_LINK_NS_BASE + "policies";
 
-    public static final String LINK_ACL = "acl";
+    public static final String LINK_ACL = CMIS_LINK_NS_BASE + "acl";
 
-    public static final String LINK_CHANGES = "changes";
+    public static final String LINK_CHANGES = CMIS_LINK_NS_BASE + "changes";
 
-    public static final String LINK_TYPES_DESCENDANTS = "typesdescendants";
+    public static final String LINK_FOLDER_TREE = CMIS_LINK_NS_BASE
+            + "foldertree";
 
-    public static final String LINK_ROOT_DESCENDANTS = "rootdescendants";
+    public static final String LINK_TYPES_DESCENDANTS = CMIS_LINK_NS_BASE
+            + "typesdescendants";
+
+    public static final String LINK_ROOT_DESCENDANTS = CMIS_LINK_NS_BASE
+            + "rootdescendants";
 
     /*
      * ----- CMIS URI Template Types -----
@@ -269,4 +285,14 @@
 
     public static final String URITMPL_QUERY = "query";
 
+    /*
+     * ----- CMIS Media Types -----
+     */
+
+    public static final String MEDIA_TYPE_CMIS_QUERY = "application/cmisquery+xml";
+
+    public static final String MEDIA_TYPE_CMIS_ALLOWABLE_ACTIONS = "application/cmisallowableactions+xml";
+
+    public static final String MEDIA_TYPE_CMIS_TREE = "application/cmistree+xml";
+
 }

Modified: incubator/chemistry/trunk/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/abdera/ObjectElement.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/abdera/ObjectElement.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/abdera/ObjectElement.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-atompub/src/main/java/org/apache/chemistry/atompub/abdera/ObjectElement.java Sun Aug  2 13:08:24 2009
@@ -51,7 +51,7 @@
      * Constructor used when generating XML.
      */
     public ObjectElement(Factory factory, ObjectEntry object, Type type) {
-        super(factory, CMIS.OBJECT);
+        super(factory, CMIS.RESTATOM_OBJECT);
         properties = new PropertiesElement(getFactory());
         addExtension(properties);
         setProperties(object.getValues(), type);

Modified: incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleConnection.java Sun Aug  2 13:08:24 2009
@@ -153,6 +153,33 @@
      */
 
     /**
+     * Accumulates the descendant folders into a list recursively.
+     */
+    protected void accumulateFolders(ObjectId folder, int depth, String filter,
+            boolean includeAllowableActions, List<ObjectEntry> list) {
+        List<ObjectEntry> children = getChildren(folder, filter,
+                includeAllowableActions, false, Integer.MAX_VALUE, 0, null,
+                new boolean[1]);
+        for (ObjectEntry child : children) {
+            if (child.getBaseType() != BaseType.FOLDER) {
+                continue;
+            }
+            list.add(child);
+            if (depth > 1) {
+                accumulateFolders(child, depth - 1, filter,
+                        includeAllowableActions, list);
+            }
+        }
+    }
+
+    public List<ObjectEntry> getFolderTree(ObjectId folder, int depth,
+            String filter, boolean includeAllowableActions) {
+        List<ObjectEntry> list = new ArrayList<ObjectEntry>();
+        accumulateFolders(folder, depth, filter, includeAllowableActions, list);
+        return list;
+    }
+
+    /**
      * Accumulates the descendants into a list recursively.
      */
     protected void accumulateDescendants(ObjectId folder, int depth,
@@ -175,7 +202,6 @@
     public List<ObjectEntry> getDescendants(ObjectId folder, int depth,
             String filter, boolean includeAllowableActions,
             boolean includeRelationships, String orderBy) {
-        // TODO includeRelationship, includeAllowableActions, orderBy
         List<ObjectEntry> list = new ArrayList<ObjectEntry>();
         accumulateDescendants(folder, depth, filter, includeAllowableActions,
                 includeRelationships, orderBy, list);
@@ -373,12 +399,12 @@
     public ObjectId createDocument(String typeId,
             Map<String, Serializable> properties, ObjectId folder,
             ContentStream contentStream, VersioningState versioningState) {
+        // TODO contentStream, versioningState
         Type type = repository.getType(typeId);
-        BaseType baseType = type.getBaseType();
-        if (type == null || baseType != BaseType.DOCUMENT) {
+        if (type == null || type.getBaseType() != BaseType.DOCUMENT) {
             throw new IllegalArgumentException(typeId);
         }
-        SimpleData data = new SimpleData(typeId, baseType);
+        SimpleData data = new SimpleData(typeId, type.getBaseType());
         data.putAll(properties);
         if (folder != null) {
             data.put(Property.PARENT_ID, folder.getId());
@@ -389,8 +415,17 @@
 
     public ObjectId createFolder(String typeId,
             Map<String, Serializable> properties, ObjectId folder) {
-        // TODO Auto-generated method stub
-        throw new UnsupportedOperationException();
+        Type type = repository.getType(typeId);
+        if (type == null || type.getBaseType() != BaseType.FOLDER) {
+            throw new IllegalArgumentException(typeId);
+        }
+        SimpleData data = new SimpleData(typeId, type.getBaseType());
+        data.putAll(properties);
+        if (folder != null) {
+            data.put(Property.PARENT_ID, folder.getId());
+        }
+        saveData(data, typeId);
+        return new SimpleObjectId((String) data.get(Property.ID));
     }
 
     public ObjectId createRelationship(String typeId,

Modified: incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleRepository.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleRepository.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleRepository.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/impl/simple/SimpleRepository.java Sun Aug  2 13:08:24 2009
@@ -166,6 +166,10 @@
         return false;
     }
 
+    public boolean hasGetDescendants() {
+        return true;
+    }
+
     public JoinCapability getJoinCapability() {
         return JoinCapability.NONE;
     }

Modified: incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/util/GregorianCalendar.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/util/GregorianCalendar.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/util/GregorianCalendar.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-commons/src/main/java/org/apache/chemistry/util/GregorianCalendar.java Sun Aug  2 13:08:24 2009
@@ -42,7 +42,7 @@
 
     private static final Pattern ATOMPUB_PATTERN = Pattern.compile( //
     "(\\d{4})-(\\d{2})-(\\d{2})[Tt]"
-            + "(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d{3}))?"
+            + "(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?"
             + "(?:[Zz]|([+-]\\d{2}:\\d{2}))");
 
     /**
@@ -68,8 +68,10 @@
         cal.set(HOUR_OF_DAY, Integer.parseInt(m.group(4)));
         cal.set(MINUTE, Integer.parseInt(m.group(5)));
         cal.set(SECOND, Integer.parseInt(m.group(6)));
-        String ms = m.group(7);
-        cal.set(MILLISECOND, ms == null ? 0 : Integer.parseInt(ms));
+        String decimals = m.group(7);
+        int ms = decimals == null ? 0
+                : Integer.parseInt((decimals + "00").substring(0, 3));
+        cal.set(MILLISECOND, ms);
         return cal;
     }
 

Modified: incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/util/TestGregorianCalendar.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/util/TestGregorianCalendar.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/util/TestGregorianCalendar.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-commons/src/test/java/org/apache/chemistry/util/TestGregorianCalendar.java Sun Aug  2 13:08:24 2009
@@ -63,15 +63,22 @@
     }
 
     public void testFromAtomPub1() {
-        Calendar cal = GregorianCalendar.fromAtomPub("2009-07-14T12:00:00.123-06:30");
+        Calendar cal;
+        cal = GregorianCalendar.fromAtomPub("2009-07-14T12:00:00.123-06:30");
         assertEquals("GregorianCalendar(2009-07-14T12:00:00.123-06:30)",
                 cal.toString());
-    }
-
-    public void testFromAtomPub2() {
-        Calendar cal = GregorianCalendar.fromAtomPub("2009-07-14T12:00:00Z");
+        cal = GregorianCalendar.fromAtomPub("2009-07-14T12:00:00Z");
         assertEquals("GregorianCalendar(2009-07-14T12:00:00.000Z)",
                 cal.toString());
+        cal = GregorianCalendar.fromAtomPub("2009-07-14T12:00:00.5Z");
+        assertEquals("GregorianCalendar(2009-07-14T12:00:00.500Z)",
+                cal.toString());
+        cal = GregorianCalendar.fromAtomPub("2009-07-14T12:00:00.44Z");
+        assertEquals("GregorianCalendar(2009-07-14T12:00:00.440Z)",
+                cal.toString());
+        cal = GregorianCalendar.fromAtomPub("2009-07-14T12:00:00.333Z");
+        assertEquals("GregorianCalendar(2009-07-14T12:00:00.333Z)",
+                cal.toString());
     }
 
 }

Modified: incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrConnection.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrConnection.java?rev=800062&r1=800061&r2=800062&view=diff
==============================================================================
--- incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrConnection.java (original)
+++ incubator/chemistry/trunk/chemistry/chemistry-jcr/src/main/java/org/apache/chemistry/jcr/JcrConnection.java Sun Aug  2 13:08:24 2009
@@ -311,25 +311,31 @@
         return null;
     }
 
+    public List<ObjectEntry> getFolderTree(ObjectId folderId, int depth,
+            String filter, boolean includeAllowableActions) {
+        // TODO Auto-generated method stub
+        throw new UnsupportedOperationException();
+    }
+
     public List<ObjectEntry> getDescendants(ObjectId folderId, int depth,
             String filter, boolean includeAllowableActions,
             boolean includeRelationships, String orderBy) {
         // TODO Auto-generated method stub
-        return null;
+        throw new UnsupportedOperationException();
     }
 
     public List<ObjectEntry> getFolderParent(ObjectId folderId, String filter,
             boolean includeAllowableActions, boolean includeRelationships,
             boolean returnToRoot) {
         // TODO Auto-generated method stub
-        return null;
+        throw new UnsupportedOperationException();
     }
 
     public Collection<ObjectEntry> getObjectParents(ObjectId objectId,
             String filter, boolean includeAllowableActions,
             boolean includeRelationships) {
         // TODO Auto-generated method stub
-        return null;
+        throw new UnsupportedOperationException();
     }
 
     public ObjectEntry getProperties(ObjectId objectId, String filter,
@@ -358,7 +364,7 @@
     public Map<String, Serializable> getPropertiesOfLatestVersion(
             String versionSeriesId, boolean major, String filter) {
         // TODO Auto-generated method stub
-        return null;
+        throw new UnsupportedOperationException();
     }
 
     public List<ObjectEntry> getRelationships(ObjectId objectId,

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=800062&r1=800061&r2=800062&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 Sun Aug  2 13:08:24 2009
@@ -238,6 +238,10 @@
         return false;
     }
 
+    public boolean hasGetDescendants() {
+        return false;
+    }
+
     public boolean isPWCSearchable() {
         return false;
     }

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=800062&r1=800061&r2=800062&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 Sun Aug  2 13:08:24 2009
@@ -181,6 +181,12 @@
         assertTrue(hasMoreItems[0]);
     }
 
+    public void testGetFolderTree() {
+        Folder root = conn.getRootFolder();
+        List<ObjectEntry> desc = spi.getFolderTree(root, 4, null, false);
+        assertEquals(2, desc.size());
+    }
+
     public void testGetDescendants() {
         Folder root = conn.getRootFolder();
         List<ObjectEntry> desc = spi.getDescendants(root, 4, null, false,
@@ -271,4 +277,33 @@
         assertEquals(cal.toString(), cal2.toString());
     }
 
+    @SuppressWarnings("null")
+    public void testNewFolder() {
+        Folder root = conn.getRootFolder();
+        assertNull(getDocumentChild(root));
+        Folder fold = root.newFolder("fold");
+        fold.setName("myfold");
+        fold.setValue("title", "mytitle");
+        assertNull(fold.getId()); // not yet saved
+        fold.save();
+        String id = fold.getId();
+        assertNotNull(id);
+
+        // new connection
+        closeConn();
+        openConn();
+        root = conn.getRootFolder();
+        fold = null;
+        for (CMISObject child : root.getChildren()) {
+            if (child.getName().equals("myfold")) {
+                fold = (Folder) child;
+                break;
+            }
+        }
+        assertNotNull(fold);
+        assertEquals(id, fold.getId());
+        assertEquals("myfold", fold.getName());
+        assertEquals("mytitle", fold.getString("title"));
+    }
+
 }