You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@chemistry.apache.org by fm...@apache.org on 2010/09/14 14:04:31 UTC

svn commit: r996858 - in /incubator/chemistry/opencmis/trunk: chemistry-opencmis-client/chemistry-opencmis-client-api/src/main/java/org/apache/chemistry/opencmis/client/api/ chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apa...

Author: fmui
Date: Tue Sep 14 12:04:30 2010
New Revision: 996858

URL: http://svn.apache.org/viewvc?rev=996858&view=rev
Log:
CMIS-251: new CMIS extensions handling

Added:
    incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/data/CmisExtensionElement.java   (with props)
    incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/CmisExtensionElementImpl.java   (with props)
Modified:
    incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-api/src/main/java/org/apache/chemistry/opencmis/client/api/CmisObject.java
    incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/AbstractPersistentCmisObject.java
    incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/CmisObjectMock.java
    incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/data/ExtensionsData.java
    incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/Converter.java
    incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/AbstractExtensionData.java
    incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryObjectServiceImpl.java
    incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/ContentStreamDataImpl.java
    incubator/chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-fit/src/test/java/org/apache/chemistry/opencmis/fit/runtime/extensions/AbstractExtensionTestIT.java

Modified: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-api/src/main/java/org/apache/chemistry/opencmis/client/api/CmisObject.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-api/src/main/java/org/apache/chemistry/opencmis/client/api/CmisObject.java?rev=996858&r1=996857&r2=996858&view=diff
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-api/src/main/java/org/apache/chemistry/opencmis/client/api/CmisObject.java (original)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-api/src/main/java/org/apache/chemistry/opencmis/client/api/CmisObject.java Tue Sep 14 12:04:30 2010
@@ -25,6 +25,7 @@ import java.util.Map;
 import org.apache.chemistry.opencmis.commons.data.Ace;
 import org.apache.chemistry.opencmis.commons.data.Acl;
 import org.apache.chemistry.opencmis.commons.data.AllowableActions;
+import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
 import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
 import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
 import org.apache.chemistry.opencmis.commons.enums.ExtensionLevel;
@@ -75,8 +76,8 @@ public interface CmisObject extends Obje
     GregorianCalendar getLastModificationDate();
 
     /**
-     * Get the object's base type (maintained by the repository). {@code
-     * Property<String> 'cmis:baseTypeId'}
+     * Get the object's base type (maintained by the repository).
+     * {@code Property<String> 'cmis:baseTypeId'}
      */
     ObjectType getBaseType();
 
@@ -261,7 +262,7 @@ public interface CmisObject extends Obje
 
     // extensions
 
-    List<Object> getExtensions(ExtensionLevel level);
+    List<CmisExtensionElement> getExtensions(ExtensionLevel level);
 
     // session handling
 

Modified: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/AbstractPersistentCmisObject.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/AbstractPersistentCmisObject.java?rev=996858&r1=996857&r2=996858&view=diff
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/AbstractPersistentCmisObject.java (original)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/runtime/AbstractPersistentCmisObject.java Tue Sep 14 12:04:30 2010
@@ -46,6 +46,7 @@ import org.apache.chemistry.opencmis.com
 import org.apache.chemistry.opencmis.commons.data.Ace;
 import org.apache.chemistry.opencmis.commons.data.Acl;
 import org.apache.chemistry.opencmis.commons.data.AllowableActions;
+import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
 import org.apache.chemistry.opencmis.commons.data.ObjectData;
 import org.apache.chemistry.opencmis.commons.data.ObjectList;
 import org.apache.chemistry.opencmis.commons.data.RenditionData;
@@ -73,7 +74,7 @@ public abstract class AbstractPersistent
     private Acl acl;
     private List<Policy> policies;
     private List<Relationship> relationships;
-    private Map<ExtensionLevel, List<Object>> extensions;
+    private Map<ExtensionLevel, List<CmisExtensionElement>> extensions;
     private OperationContext creationContext;
     private boolean isChanged = false;
     private long refreshTimestamp;
@@ -101,7 +102,7 @@ public abstract class AbstractPersistent
 
         this.session = session;
         this.objectType = objectType;
-        this.extensions = new HashMap<ExtensionLevel, List<Object>>();
+        this.extensions = new HashMap<ExtensionLevel, List<CmisExtensionElement>>();
         this.creationContext = new OperationContextImpl(context);
         this.refreshTimestamp = System.currentTimeMillis();
 
@@ -588,9 +589,9 @@ public abstract class AbstractPersistent
 
                 // fetch the relationships
                 ObjectList relList = relationshipService.getObjectRelationships(getRepositoryId(), objectId,
-                        includeSubRelationshipTypes, relationshipDirection, typeId, ctxt.getFilterString(), ctxt
-                                .isIncludeAllowableActions(), BigInteger.valueOf(this.maxNumItems), BigInteger
-                                .valueOf(skipCount), null);
+                        includeSubRelationshipTypes, relationshipDirection, typeId, ctxt.getFilterString(),
+                        ctxt.isIncludeAllowableActions(), BigInteger.valueOf(this.maxNumItems),
+                        BigInteger.valueOf(skipCount), null);
 
                 // convert relationship objects
                 List<Relationship> page = new ArrayList<Relationship>();
@@ -603,16 +604,16 @@ public abstract class AbstractPersistent
                     }
                 }
 
-                return new AbstractPageFetch.PageFetchResult<Relationship>(page, relList.getNumItems(), relList
-                        .hasMoreItems());
+                return new AbstractPageFetch.PageFetchResult<Relationship>(page, relList.getNumItems(),
+                        relList.hasMoreItems());
             }
         });
     }
 
     // --- extensions ---
 
-    public List<Object> getExtensions(ExtensionLevel level) {
-        List<Object> ext = extensions.get(level);
+    public List<CmisExtensionElement> getExtensions(ExtensionLevel level) {
+        List<CmisExtensionElement> ext = extensions.get(level);
         if (ext == null) {
             return null;
         }
@@ -658,10 +659,13 @@ public abstract class AbstractPersistent
             String objectId = getObjectId();
 
             // get the latest data from the repository
-            ObjectData objectData = getSession().getBinding().getObjectService().getObject(getRepositoryId(), objectId,
-                    creationContext.getFilterString(), creationContext.isIncludeAllowableActions(),
-                    creationContext.getIncludeRelationships(), creationContext.getRenditionFilterString(),
-                    creationContext.isIncludePolicies(), creationContext.isIncludeAcls(), null);
+            ObjectData objectData = getSession()
+                    .getBinding()
+                    .getObjectService()
+                    .getObject(getRepositoryId(), objectId, creationContext.getFilterString(),
+                            creationContext.isIncludeAllowableActions(), creationContext.getIncludeRelationships(),
+                            creationContext.getRenditionFilterString(), creationContext.isIncludePolicies(),
+                            creationContext.isIncludeAcls(), null);
 
             // reset this object
             initialize(getSession(), getObjectType(), objectData, this.creationContext);

Modified: incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/CmisObjectMock.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/CmisObjectMock.java?rev=996858&r1=996857&r2=996858&view=diff
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/CmisObjectMock.java (original)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/test/java/org/apache/chemistry/opencmis/client/runtime/CmisObjectMock.java Tue Sep 14 12:04:30 2010
@@ -35,6 +35,7 @@ import org.apache.chemistry.opencmis.cli
 import org.apache.chemistry.opencmis.commons.data.Ace;
 import org.apache.chemistry.opencmis.commons.data.Acl;
 import org.apache.chemistry.opencmis.commons.data.AllowableActions;
+import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
 import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
 import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
 import org.apache.chemistry.opencmis.commons.enums.ExtensionLevel;
@@ -48,11 +49,11 @@ public class CmisObjectMock implements C
     private static final long serialVersionUID = 1L;
 
     private String id;
-    
+
     public CmisObjectMock(String id) {
         this.id = id;
     }
-    
+
     public void addAcl(List<Ace> addAces, AclPropagation aclPropagation) {
     }
 
@@ -151,39 +152,39 @@ public class CmisObjectMock implements C
         return null;
     }
 
-    public List<Object> getExtensions(ExtensionLevel level) {
+    public List<CmisExtensionElement> getExtensions(ExtensionLevel level) {
         return null;
     }
-    
+
     public boolean isChanged() {
         return false;
     }
 
     public void refresh() {
-        
+
     }
 
     public void refreshIfOld(long durationInMillis) {
-        
+
     }
 
     public void removeAcl(List<Ace> removeAces, AclPropagation aclPropagation) {
-        
+
     }
 
     public void removePolicy(ObjectId policyId) {
-        
+
     }
 
     public void setName(String name) {
-        
+
     }
 
     public <T> void setProperty(String id, T value) {
     }
 
     public <T> void setPropertyMultivalue(String id, List<T> value) {
-        
+
     }
 
     public ObjectId updateProperties() {
@@ -197,5 +198,5 @@ public class CmisObjectMock implements C
     public String getId() {
         return this.id;
     }
-    
+
 };

Added: incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/data/CmisExtensionElement.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/data/CmisExtensionElement.java?rev=996858&view=auto
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/data/CmisExtensionElement.java (added)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/data/CmisExtensionElement.java Tue Sep 14 12:04:30 2010
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.commons.data;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class represents one node in the extension tree.
+ */
+public interface CmisExtensionElement {
+
+    /**
+     * Returns the name of the extension. The name is never <code>null</code>.
+     */
+    String getName();
+
+    /**
+     * Returns the namespace of the extension. If the binding doesn't support
+     * namespaces this method will return <code>null</code>.
+     * 
+     * Don't rely on namespaces because they are binding specific!
+     */
+    String getNamespace();
+
+    /**
+     * Returns the value of the extension as a String. If this extension has
+     * children than this method returns <code>null</code>.
+     */
+    String getValue();
+
+    /**
+     * Returns the attributes of the extension. If the binding doesn't support
+     * attributes this method will return <code>null</code>.
+     * 
+     * Try to avoid attributes because they are binding specific!
+     */
+    Map<String, String> getAttributes();
+
+    /**
+     * Returns the children of this extension.
+     */
+    List<CmisExtensionElement> getChildren();
+}

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/data/CmisExtensionElement.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/data/ExtensionsData.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/data/ExtensionsData.java?rev=996858&r1=996857&r2=996858&view=diff
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/data/ExtensionsData.java (original)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-api/src/main/java/org/apache/chemistry/opencmis/commons/data/ExtensionsData.java Tue Sep 14 12:04:30 2010
@@ -22,13 +22,10 @@ import java.util.List;
 
 /**
  * Holds extension data either set by the CMIS repository or the client.
- * 
- * @author <a href="mailto:fmueller@opentext.com">Florian M&uuml;ller</a>
- * 
  */
 public interface ExtensionsData {
 
-    List<Object> getExtensions();
+    List<CmisExtensionElement> getExtensions();
 
-    void setExtensions(List<Object> extensions);
+    void setExtensions(List<CmisExtensionElement> extensions);
 }

Modified: incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/Converter.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/Converter.java?rev=996858&r1=996857&r2=996858&view=diff
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/Converter.java (original)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/Converter.java Tue Sep 14 12:04:30 2010
@@ -27,6 +27,7 @@ import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.GregorianCalendar;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -37,11 +38,14 @@ import javax.activation.DataSource;
 import javax.xml.datatype.DatatypeConfigurationException;
 import javax.xml.datatype.DatatypeFactory;
 import javax.xml.datatype.XMLGregorianCalendar;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.apache.chemistry.opencmis.commons.data.Ace;
 import org.apache.chemistry.opencmis.commons.data.Acl;
 import org.apache.chemistry.opencmis.commons.data.AclCapabilities;
 import org.apache.chemistry.opencmis.commons.data.AllowableActions;
+import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
 import org.apache.chemistry.opencmis.commons.data.ContentStream;
 import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
 import org.apache.chemistry.opencmis.commons.data.FailedToDeleteData;
@@ -111,6 +115,7 @@ import org.apache.chemistry.opencmis.com
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.AllowableActionsImpl;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.ChangeEventInfoDataImpl;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.ChoiceImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.CmisExtensionElementImpl;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.DocumentTypeDefinitionImpl;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.ExtensionDataImpl;
@@ -222,17 +227,20 @@ import org.apache.chemistry.opencmis.com
 import org.apache.chemistry.opencmis.commons.impl.jaxb.EnumTypeOfChanges;
 import org.apache.chemistry.opencmis.commons.impl.jaxb.EnumUpdatability;
 import org.apache.chemistry.opencmis.commons.spi.Holder;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 
 import com.sun.xml.ws.developer.StreamingDataHandler;
 
 /**
  * Contains converter methods.
- * 
- * @author <a href="mailto:fmueller@opentext.com">Florian M&uuml;ller</a>
- * 
  */
 public final class Converter {
 
+    private static final String DEFAULT_EXTENSION_NS = "http://apache.org/chemistry/opencmis";
+
     /**
      * Private constructor.
      */
@@ -293,8 +301,8 @@ public final class Converter {
         result.setAllVersionsSearchable(capabilities.isCapabilityAllVersionsSearchable());
         result.setCapabilityAcl(convert(CapabilityAcl.class, capabilities.getCapabilityACL()));
         result.setCapabilityChanges(convert(CapabilityChanges.class, capabilities.getCapabilityChanges()));
-        result.setCapabilityContentStreamUpdates(convert(CapabilityContentStreamUpdates.class, capabilities
-                .getCapabilityContentStreamUpdatability()));
+        result.setCapabilityContentStreamUpdates(convert(CapabilityContentStreamUpdates.class,
+                capabilities.getCapabilityContentStreamUpdatability()));
         result.setCapabilityJoin(convert(CapabilityJoin.class, capabilities.getCapabilityJoin()));
         result.setCapabilityQuery(convert(CapabilityQuery.class, capabilities.getCapabilityQuery()));
         result.setCapabilityRendition(convert(CapabilityRenditions.class, capabilities.getCapabilityRenditions()));
@@ -407,8 +415,8 @@ public final class Converter {
         result.setCapabilityACL(convert(EnumCapabilityACL.class, capabilities.getAclCapability()));
         result.setCapabilityAllVersionsSearchable(capabilities.isAllVersionsSearchableSupported());
         result.setCapabilityChanges(convert(EnumCapabilityChanges.class, capabilities.getChangesCapability()));
-        result.setCapabilityContentStreamUpdatability(convert(EnumCapabilityContentStreamUpdates.class, capabilities
-                .getContentStreamUpdatesCapability()));
+        result.setCapabilityContentStreamUpdatability(convert(EnumCapabilityContentStreamUpdates.class,
+                capabilities.getContentStreamUpdatesCapability()));
         result.setCapabilityGetDescendants(capabilities.isGetDescendantsSupported());
         result.setCapabilityGetFolderTree(capabilities.isGetFolderTreeSupported());
         result.setCapabilityJoin(convert(EnumCapabilityJoin.class, capabilities.getJoinCapability()));
@@ -436,8 +444,8 @@ public final class Converter {
 
         CmisACLCapabilityType result = new CmisACLCapabilityType();
 
-        result.setSupportedPermissions(convert(EnumSupportedPermissions.class, aclCapabilities
-                .getSupportedPermissions()));
+        result.setSupportedPermissions(convert(EnumSupportedPermissions.class,
+                aclCapabilities.getSupportedPermissions()));
 
         result.setPropagation(convert(EnumACLPropagation.class, aclCapabilities.getAclPropagation()));
 
@@ -1388,19 +1396,19 @@ public final class Converter {
         PropertyData<?> result = null;
 
         if (property instanceof CmisPropertyString) {
-            result = new PropertyStringImpl(property.getPropertyDefinitionId(), ((CmisPropertyString) property)
-                    .getValue());
+            result = new PropertyStringImpl(property.getPropertyDefinitionId(),
+                    ((CmisPropertyString) property).getValue());
         } else if (property instanceof CmisPropertyId) {
             result = new PropertyIdImpl(property.getPropertyDefinitionId(), ((CmisPropertyId) property).getValue());
         } else if (property instanceof CmisPropertyInteger) {
-            result = new PropertyIntegerImpl(property.getPropertyDefinitionId(), ((CmisPropertyInteger) property)
-                    .getValue());
+            result = new PropertyIntegerImpl(property.getPropertyDefinitionId(),
+                    ((CmisPropertyInteger) property).getValue());
         } else if (property instanceof CmisPropertyDecimal) {
-            result = new PropertyDecimalImpl(property.getPropertyDefinitionId(), ((CmisPropertyDecimal) property)
-                    .getValue());
+            result = new PropertyDecimalImpl(property.getPropertyDefinitionId(),
+                    ((CmisPropertyDecimal) property).getValue());
         } else if (property instanceof CmisPropertyBoolean) {
-            result = new PropertyBooleanImpl(property.getPropertyDefinitionId(), ((CmisPropertyBoolean) property)
-                    .getValue());
+            result = new PropertyBooleanImpl(property.getPropertyDefinitionId(),
+                    ((CmisPropertyBoolean) property).getValue());
         } else if (property instanceof CmisPropertyDateTime) {
             result = new PropertyDateTimeImpl(property.getPropertyDefinitionId(),
                     convertXMLCalendar(((CmisPropertyDateTime) property).getValue()));
@@ -2400,8 +2408,8 @@ public final class Converter {
         CmisExtensionType result = new CmisExtensionType();
 
         if (extension.getExtensions() != null) {
-            for (Object obj : extension.getExtensions()) {
-                result.getAny().add(obj);
+            for (CmisExtensionElement ext : extension.getExtensions()) {
+                result.getAny().add(convertCmisExtensionElementToNode(ext));
             }
         }
 
@@ -2435,12 +2443,12 @@ public final class Converter {
             return;
         }
 
-        List<Object> list = new ArrayList<Object>();
+        List<CmisExtensionElement> list = new ArrayList<CmisExtensionElement>();
         target.setExtensions(list);
 
         if (!source.value.getAny().isEmpty()) {
             for (Object obj : source.value.getAny()) {
-                list.add(obj);
+                list.add(convertDomToCmisExtensionElement(obj));
             }
         }
     }
@@ -2470,8 +2478,8 @@ public final class Converter {
         }
 
         if (source.getExtensions() != null) {
-            for (Object ext : source.getExtensions()) {
-                target.value.getAny().add(ext);
+            for (CmisExtensionElement ext : source.getExtensions()) {
+                target.value.getAny().add(convertCmisExtensionElementToNode(ext));
             }
         }
     }
@@ -2537,7 +2545,12 @@ public final class Converter {
             List<Object> list = (List<Object>) m.invoke(source, new Object[0]);
 
             if (!list.isEmpty()) {
-                target.setExtensions(list);
+                List<CmisExtensionElement> extensions = new ArrayList<CmisExtensionElement>();
+                for (Object obj : list) {
+                    extensions.add(convertDomToCmisExtensionElement(obj));
+                }
+
+                target.setExtensions(extensions);
             } else {
                 target.setExtensions(null);
             }
@@ -2559,7 +2572,9 @@ public final class Converter {
 
             list.clear();
             if (source.getExtensions() != null) {
-                list.addAll(source.getExtensions());
+                for (CmisExtensionElement ext : source.getExtensions()) {
+                    list.add(convertCmisExtensionElementToNode(ext));
+                }
             }
         } catch (NoSuchMethodException e) {
         } catch (Exception e) {
@@ -2576,11 +2591,141 @@ public final class Converter {
         }
 
         ExtensionDataImpl result = new ExtensionDataImpl();
-        result.setExtensions(extension.getAny());
+        List<CmisExtensionElement> extensions = new ArrayList<CmisExtensionElement>();
+        result.setExtensions(extensions);
+
+        for (Object obj : extension.getAny()) {
+            extensions.add(convertDomToCmisExtensionElement(obj));
+        }
+
+        return result;
+    }
+
+    /**
+     * Converts a DOM node to a CMIS extension element
+     */
+    private static CmisExtensionElement convertDomToCmisExtensionElement(Object source) {
+        // if it's not a Node, skip it
+        if (!(source instanceof Node)) {
+            return null;
+        }
+
+        Node node = (Node) source;
+        if (node.getNodeType() != Node.ELEMENT_NODE) {
+            return null;
+        }
+
+        String name = node.getLocalName();
+        String namespace = node.getNamespaceURI();
+
+        CmisExtensionElement result = null;
+        List<CmisExtensionElement> cmisChildren = new ArrayList<CmisExtensionElement>();
+        StringBuilder value = new StringBuilder();
+
+        NodeList children = node.getChildNodes();
+
+        for (int i = 0; i < children.getLength(); i++) {
+            Node child = children.item(i);
+
+            if (child.getNodeType() == Node.ELEMENT_NODE) {
+                CmisExtensionElement cimsChild = convertDomToCmisExtensionElement(child);
+                if (cimsChild != null) {
+                    cmisChildren.add(cimsChild);
+                }
+            } else if (child.getNodeType() == Node.TEXT_NODE) {
+                value.append(child.getNodeValue());
+            }
+        }
+
+        Map<String, String> attributes = null;
+        if (node.getAttributes() != null) {
+            attributes = new HashMap<String, String>();
+            for (int i = 0; i < node.getAttributes().getLength(); i++) {
+                Node attrNode = node.getAttributes().item(i);
+                attributes.put(attrNode.getLocalName(), attrNode.getNodeValue());
+            }
+        }
+
+        if (cmisChildren.isEmpty()) {
+            result = new CmisExtensionElementImpl(namespace, name, attributes, value.toString());
+        } else {
+            result = new CmisExtensionElementImpl(namespace, name, attributes, cmisChildren);
+        }
 
         return result;
     }
 
+    /**
+     * Converts a CMIS extension element to a DOM node.
+     */
+    private static Node convertCmisExtensionElementToNode(CmisExtensionElement source) {
+        if (source == null) {
+            return null;
+        }
+
+        Document doc = null;
+
+        try {
+            DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
+            DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
+            doc = docBuilder.newDocument();
+        } catch (Exception e) {
+            throw new CmisRuntimeException("Unable to convert extensions!", e);
+        }
+
+        Element root = doc.createElementNS(
+                (source.getNamespace() == null ? DEFAULT_EXTENSION_NS : source.getNamespace()), source.getName());
+        doc.appendChild(root);
+
+        if (source.getValue() != null) {
+            root.appendChild(doc.createTextNode(source.getValue()));
+        } else {
+            for (CmisExtensionElement child : source.getChildren()) {
+                root.appendChild(convertCmisExtensionElementToNode(child, root, doc));
+            }
+        }
+
+        // set attributes
+        if (source.getAttributes() != null) {
+            for (Map.Entry<String, String> e : source.getAttributes().entrySet()) {
+                root.setAttributeNS((source.getNamespace() == null ? DEFAULT_EXTENSION_NS : source.getNamespace()),
+                        e.getKey(), e.getValue());
+            }
+        }
+
+        return root;
+    }
+
+    /**
+     * Converts a CMIS extension element to a DOM node.
+     */
+    private static Node convertCmisExtensionElementToNode(CmisExtensionElement source, Element parent, Document doc) {
+        if (source == null) {
+            return null;
+        }
+
+        Element element = doc.createElementNS(
+                (source.getNamespace() == null ? DEFAULT_EXTENSION_NS : source.getNamespace()), source.getName());
+
+        if (source.getValue() != null) {
+            element.appendChild(doc.createTextNode(source.getValue()));
+        } else {
+            for (CmisExtensionElement child : source.getChildren()) {
+                element.appendChild(convertCmisExtensionElementToNode(child, element, doc));
+            }
+        }
+
+        // set attributes
+        if (source.getAttributes() != null) {
+            for (Map.Entry<String, String> e : source.getAttributes().entrySet()) {
+                element.setAttributeNS((source.getNamespace() == null ? DEFAULT_EXTENSION_NS : source.getNamespace()),
+                        e.getKey(), e.getValue());
+            }
+        }
+
+        return element;
+    }
+
     private static boolean convertBoolean(Boolean value, boolean def) {
         return (value == null ? def : value.booleanValue());
     }

Modified: incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/AbstractExtensionData.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/AbstractExtensionData.java?rev=996858&r1=996857&r2=996858&view=diff
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/AbstractExtensionData.java (original)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/AbstractExtensionData.java Tue Sep 14 12:04:30 2010
@@ -20,40 +20,26 @@ package org.apache.chemistry.opencmis.co
 
 import java.util.List;
 
+import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
 import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
 
 /**
  * Abstract extension data implementation.
- * 
- * @author <a href="mailto:fmueller@opentext.com">Florian M&uuml;ller</a>
- * 
  */
 public abstract class AbstractExtensionData implements ExtensionsData {
 
-    private List<Object> fExtensions;
+    private List<CmisExtensionElement> extensions;
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.apache.opencmis.client.provider.ExtensionsData#getExtensions()
-     */
-    public List<Object> getExtensions() {
-        return fExtensions;
+    public List<CmisExtensionElement> getExtensions() {
+        return extensions;
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * org.apache.opencmis.client.provider.ExtensionsData#setExtensions(java
-     * .util.List)
-     */
-    public void setExtensions(List<Object> extensions) {
-        fExtensions = extensions;
+    public void setExtensions(List<CmisExtensionElement> extensions) {
+        this.extensions = extensions;
     }
 
     @Override
     public String toString() {
-        return "[extensions=" + fExtensions + "]";
+        return "[extensions=" + extensions + "]";
     }
 }

Added: incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/CmisExtensionElementImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/CmisExtensionElementImpl.java?rev=996858&view=auto
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/CmisExtensionElementImpl.java (added)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/CmisExtensionElementImpl.java Tue Sep 14 12:04:30 2010
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.chemistry.opencmis.commons.impl.dataobjects;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
+
+public class CmisExtensionElementImpl implements CmisExtensionElement {
+
+    private String name;
+    private String namespace;
+    private String value;
+    private Map<String, String> attributes;
+    private List<CmisExtensionElement> children;
+
+    /**
+     * Constructor for a leaf.
+     */
+    public CmisExtensionElementImpl(String namespace, String name, Map<String, String> attributes, String value) {
+        if (name == null) {
+            throw new IllegalArgumentException("Name must set!");
+        }
+
+        this.name = name;
+        this.namespace = namespace;
+        this.value = value;
+        children = Collections.emptyList();
+
+        if (attributes != null) {
+            this.attributes = Collections.unmodifiableMap(new HashMap<String, String>(attributes));
+        } else {
+            this.attributes = Collections.emptyMap();
+        }
+    }
+
+    /**
+     * Constructor for a node.
+     */
+    public CmisExtensionElementImpl(String namespace, String name, Map<String, String> attributes,
+            List<CmisExtensionElement> children) {
+        if (name == null) {
+            throw new IllegalArgumentException("Name must set!");
+        }
+
+        this.name = name;
+        this.namespace = namespace;
+        this.value = null;
+
+        if (children != null) {
+            this.children = Collections.unmodifiableList(new ArrayList<CmisExtensionElement>(children));
+        } else {
+            this.children = Collections.emptyList();
+        }
+
+        if (attributes != null) {
+            this.attributes = Collections.unmodifiableMap(new HashMap<String, String>(attributes));
+        } else {
+            this.attributes = Collections.emptyMap();
+        }
+    }
+
+    /**
+     * Copy constructor.
+     */
+    public CmisExtensionElementImpl(CmisExtensionElement element) {
+        if (element == null) {
+            throw new IllegalArgumentException("Element must set!");
+        }
+        if (element.getName() == null) {
+            throw new IllegalArgumentException("Name must set!");
+        }
+
+        this.name = element.getName();
+        this.namespace = element.getNamespace();
+        this.value = element.getValue();
+        this.children = element.getChildren();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getNamespace() {
+        return namespace;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public List<CmisExtensionElement> getChildren() {
+        return children;
+    }
+
+    public Map<String, String> getAttributes() {
+        return attributes;
+    }
+
+    @Override
+    public String toString() {
+        return (namespace == null ? "" : "{" + namespace + "}") + name + " " + attributes + ": "
+                + (children.isEmpty() ? value : children.toString());
+    }
+}

Propchange: incubator/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/CmisExtensionElementImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryObjectServiceImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryObjectServiceImpl.java?rev=996858&r1=996857&r2=996858&view=diff
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryObjectServiceImpl.java (original)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/server/InMemoryObjectServiceImpl.java Tue Sep 14 12:04:30 2010
@@ -21,6 +21,7 @@ package org.apache.chemistry.opencmis.in
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.GregorianCalendar;
 import java.util.HashMap;
 import java.util.List;
@@ -29,6 +30,7 @@ import java.util.Map;
 import org.apache.chemistry.opencmis.commons.PropertyIds;
 import org.apache.chemistry.opencmis.commons.data.Acl;
 import org.apache.chemistry.opencmis.commons.data.AllowableActions;
+import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
 import org.apache.chemistry.opencmis.commons.data.ContentStream;
 import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
 import org.apache.chemistry.opencmis.commons.data.FailedToDeleteData;
@@ -52,6 +54,7 @@ import org.apache.chemistry.opencmis.com
 import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
 import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
 import org.apache.chemistry.opencmis.commons.exceptions.CmisUpdateConflictException;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.CmisExtensionElementImpl;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.ContentStreamImpl;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.FailedToDeleteDataImpl;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertiesImpl;
@@ -378,6 +381,17 @@ public class InMemoryObjectServiceImpl e
 //        myExtensions.add(new JAXBElement<ExtensionSample>(new QName("http://apache.org/chemistry/opencmis/extensions", "MyExtension"), ExtensionSample.class, new ExtensionSample()));
 //        od.setExtensions(myExtensions);
 
+        String ns = "http://apache.org/opencmis/inmemory";
+        List<CmisExtensionElement> extElements = new ArrayList<CmisExtensionElement>();
+        
+        Map<String, String> attr = new HashMap<String, String>();
+        attr.put("type", so.getTypeId());
+        
+        extElements.add(new CmisExtensionElementImpl(ns, "objectId", attr, objectId));
+        extElements.add(new CmisExtensionElementImpl(ns, "name", null, so.getName()));
+        od.setExtensions(Collections.singletonList(
+                (CmisExtensionElement) new CmisExtensionElementImpl(ns, "exampleExtension",null,  extElements)));
+        
         LOG.debug("stop getObject()");
 
         return od;

Modified: incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/ContentStreamDataImpl.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/ContentStreamDataImpl.java?rev=996858&r1=996857&r2=996858&view=diff
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/ContentStreamDataImpl.java (original)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-inmemory/src/main/java/org/apache/chemistry/opencmis/inmemory/storedobj/impl/ContentStreamDataImpl.java Tue Sep 14 12:04:30 2010
@@ -28,6 +28,7 @@ import java.io.InputStream;
 import java.math.BigInteger;
 import java.util.List;
 
+import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
 import org.apache.chemistry.opencmis.commons.data.ContentStream;
 
 public class ContentStreamDataImpl implements ContentStream {
@@ -112,11 +113,11 @@ public class ContentStreamDataImpl imple
         return clone;
     }
 
-    public List<Object> getExtensions() {
+    public List<CmisExtensionElement> getExtensions() {
         return null;
     }
 
-    public void setExtensions(List<Object> extensions) {
+    public void setExtensions(List<CmisExtensionElement> extensions) {
         // not implemented
     }
 }

Modified: incubator/chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-fit/src/test/java/org/apache/chemistry/opencmis/fit/runtime/extensions/AbstractExtensionTestIT.java
URL: http://svn.apache.org/viewvc/incubator/chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-fit/src/test/java/org/apache/chemistry/opencmis/fit/runtime/extensions/AbstractExtensionTestIT.java?rev=996858&r1=996857&r2=996858&view=diff
==============================================================================
--- incubator/chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-fit/src/test/java/org/apache/chemistry/opencmis/fit/runtime/extensions/AbstractExtensionTestIT.java (original)
+++ incubator/chemistry/opencmis/trunk/chemistry-opencmis-test/chemistry-opencmis-test-fit/src/test/java/org/apache/chemistry/opencmis/fit/runtime/extensions/AbstractExtensionTestIT.java Tue Sep 14 12:04:30 2010
@@ -22,6 +22,7 @@ import java.util.List;
 
 import org.apache.chemistry.opencmis.client.api.Folder;
 import org.apache.chemistry.opencmis.client.api.Session;
+import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
 import org.apache.chemistry.opencmis.commons.enums.ExtensionLevel;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -64,7 +65,7 @@ public abstract class AbstractExtensionT
 
         // only test getting extensions without check
         // (the InMemory repository does not expose extensions yet)
-        List<Object> extensions = null;
+        List<CmisExtensionElement> extensions = null;
         extensions = rootFolder.getExtensions(ExtensionLevel.OBJECT);
         extensions = rootFolder.getExtensions(ExtensionLevel.PROPERTIES);
         extensions = rootFolder.getExtensions(ExtensionLevel.ACL);