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 2012/11/27 19:40:59 UTC

svn commit: r1414310 - in /chemistry/opencmis/trunk: chemistry-opencmis-android/chemistry-opencmis-android-client/ chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/ che...

Author: fmui
Date: Tue Nov 27 18:40:57 2012
New Revision: 1414310

URL: http://svn.apache.org/viewvc?rev=1414310&view=rev
Log:
CMIS 1.1: Browser Binding: implemented type mutability

Added:
    chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/TypeUtils.java   (with props)
Modified:
    chemistry/opencmis/trunk/chemistry-opencmis-android/chemistry-opencmis-android-client/pom.xml
    chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/AtomEntryWriter.java
    chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/browser/RepositoryServiceImpl.java
    chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/Constants.java
    chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/JSONConstants.java
    chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/JSONConverter.java
    chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/AbstractTypeDefinition.java
    chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/RepositoryService.java
    chemistry/opencmis/trunk/chemistry-opencmis-workbench/chemistry-opencmis-workbench/src/main/java/org/apache/chemistry/opencmis/workbench/TypeSplitPane.java

Modified: chemistry/opencmis/trunk/chemistry-opencmis-android/chemistry-opencmis-android-client/pom.xml
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-android/chemistry-opencmis-android-client/pom.xml?rev=1414310&r1=1414309&r2=1414310&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-android/chemistry-opencmis-android-client/pom.xml (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-android/chemistry-opencmis-android-client/pom.xml Tue Nov 27 18:40:57 2012
@@ -95,6 +95,7 @@
                             	<copy todir="${gendir}">
 									<fileset dir="${client-impl}/${sourcefiles}">
 										<include name="**/*.java" />
+										<exclude name="**/TypeUtils.java" />
 										<exclude name="**/osgi/**" />
 									</fileset>
 								</copy>                                   

Modified: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/AtomEntryWriter.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/AtomEntryWriter.java?rev=1414310&r1=1414309&r2=1414310&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/AtomEntryWriter.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/atompub/AtomEntryWriter.java Tue Nov 27 18:40:57 2012
@@ -197,6 +197,7 @@ public class AtomEntryWriter {
     }
 
     private void writeContent(XMLStreamWriter writer) throws Exception {
+        @SuppressWarnings("resource")
         Base64.InputStream b64stream = new Base64.InputStream(stream, Base64.ENCODE);
 
         byte[] buffer = new byte[BUFFER_SIZE * 3 / 4];

Modified: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/browser/RepositoryServiceImpl.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/browser/RepositoryServiceImpl.java?rev=1414310&r1=1414309&r2=1414310&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/browser/RepositoryServiceImpl.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-bindings/src/main/java/org/apache/chemistry/opencmis/client/bindings/spi/browser/RepositoryServiceImpl.java Tue Nov 27 18:40:57 2012
@@ -18,6 +18,7 @@
  */
 package org.apache.chemistry.opencmis.client.bindings.spi.browser;
 
+import java.io.OutputStream;
 import java.math.BigInteger;
 import java.util.List;
 import java.util.Map;
@@ -29,7 +30,6 @@ import org.apache.chemistry.opencmis.com
 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer;
 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionList;
-import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
 import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
 import org.apache.chemistry.opencmis.commons.impl.Constants;
 import org.apache.chemistry.opencmis.commons.impl.JSONConverter;
@@ -113,14 +113,62 @@ public class RepositoryServiceImpl exten
     }
 
     public TypeDefinition createType(String repositoryId, TypeDefinition type, ExtensionsData extension) {
-        throw new CmisNotSupportedException("Not supported!");
+        // build URL
+        UrlBuilder url = getRepositoryUrl(repositoryId);
+
+        // prepare form data
+        final FormDataWriter formData = new FormDataWriter(Constants.CMISACTION_CREATE_TYPE);
+        if (type != null) {
+            formData.addParameter(Constants.CONTROL_TYPE, JSONConverter.convert(type).toJSONString());
+        }
+
+        // send
+        HttpUtils.Response resp = post(url, formData.getContentType(), new HttpUtils.Output() {
+            public void write(OutputStream out) throws Exception {
+                formData.write(out);
+            }
+        });
+
+        Map<String, Object> json = parseObject(resp.getStream(), resp.getCharset());
+
+        return JSONConverter.convertTypeDefinition(json);
     }
 
     public TypeDefinition updateType(String repositoryId, TypeDefinition type, ExtensionsData extension) {
-        throw new CmisNotSupportedException("Not supported!");
+        // build URL
+        UrlBuilder url = getRepositoryUrl(repositoryId);
+
+        // prepare form data
+        final FormDataWriter formData = new FormDataWriter(Constants.CMISACTION_UPDATE_TYPE);
+        if (type != null) {
+            formData.addParameter(Constants.CONTROL_TYPE, JSONConverter.convert(type).toJSONString());
+        }
+
+        // send
+        HttpUtils.Response resp = post(url, formData.getContentType(), new HttpUtils.Output() {
+            public void write(OutputStream out) throws Exception {
+                formData.write(out);
+            }
+        });
+
+        Map<String, Object> json = parseObject(resp.getStream(), resp.getCharset());
+
+        return JSONConverter.convertTypeDefinition(json);
     }
 
     public void deleteType(String repositoryId, String typeId, ExtensionsData extension) {
-        throw new CmisNotSupportedException("Not supported!");
+        // build URL
+        UrlBuilder url = getRepositoryUrl(repositoryId);
+
+        // prepare form data
+        final FormDataWriter formData = new FormDataWriter(Constants.CMISACTION_DELETE_TYPE);
+        formData.addParameter(Constants.CONTROL_TYPE_ID, typeId);
+
+        // send
+        postAndConsume(url, formData.getContentType(), new HttpUtils.Output() {
+            public void write(OutputStream out) throws Exception {
+                formData.write(out);
+            }
+        });
     }
 }

Added: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/TypeUtils.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/TypeUtils.java?rev=1414310&view=auto
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/TypeUtils.java (added)
+++ chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/TypeUtils.java Tue Nov 27 18:40:57 2012
@@ -0,0 +1,135 @@
+/*
+ * 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.client.util;
+
+import static org.apache.chemistry.opencmis.commons.impl.Converter.convert;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.Map;
+
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.chemistry.opencmis.client.api.ObjectType;
+import org.apache.chemistry.opencmis.client.runtime.repository.ObjectFactoryImpl;
+import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.impl.Converter;
+import org.apache.chemistry.opencmis.commons.impl.JSONConverter;
+import org.apache.chemistry.opencmis.commons.impl.JaxBHelper;
+import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisTypeDefinitionType;
+import org.apache.chemistry.opencmis.commons.impl.json.parser.JSONParser;
+
+public class TypeUtils {
+
+    private TypeUtils() {
+    }
+
+    /**
+     * Serializes the type definition to XML, using the format defined in the
+     * CMIS specification.
+     * 
+     * The XML is UTF-8 encoded and the stream is not closed.
+     */
+    public static void writeToXML(ObjectType type, OutputStream stream) throws Exception {
+        if (type == null) {
+            throw new IllegalArgumentException("Type must be set!");
+        }
+        if (stream == null) {
+            throw new IllegalArgumentException("Output stream must be set!");
+        }
+
+        try {
+            JaxBHelper.marshal(JaxBHelper.CMIS_EXTRA_OBJECT_FACTORY.createTypeDefinition(convert(type)), stream, false);
+        } catch (JAXBException e) {
+            throw new IOException("Marshaling failed!", e);
+        }
+    }
+
+    /**
+     * Serializes the type definition to JSON, using the format defined in the
+     * CMIS specification.
+     * 
+     * The JSON is UTF-8 encoded and the stream is not closed.
+     */
+    public static void writeToJSON(ObjectType type, OutputStream stream) throws Exception {
+        if (type == null) {
+            throw new IllegalArgumentException("Type must be set!");
+        }
+        if (stream == null) {
+            throw new IllegalArgumentException("Output stream must be set!");
+        }
+
+        Writer writer = new BufferedWriter(new OutputStreamWriter(stream, "UTF-8"));
+        JSONConverter.convert(type).writeJSONString(writer);
+        writer.flush();
+    }
+
+    /**
+     * Reads a type definition from a XML stream.
+     * 
+     * The stream must be UTF-8 encoded.
+     */
+    public static ObjectType readFromXML(InputStream stream) throws Exception {
+        if (stream == null) {
+            throw new IllegalArgumentException("Input stream must be set!");
+        }
+
+        Unmarshaller u = JaxBHelper.createUnmarshaller();
+
+        @SuppressWarnings("unchecked")
+        JAXBElement<CmisTypeDefinitionType> jaxb = (JAXBElement<CmisTypeDefinitionType>) u.unmarshal(stream);
+
+        TypeDefinition typeDef = Converter.convert(jaxb.getValue());
+
+        ObjectFactoryImpl of = new ObjectFactoryImpl();
+        return of.convertTypeDefinition(typeDef);
+    }
+
+    /**
+     * Reads a type definition from a JSON stream.
+     * 
+     * The stream must be UTF-8 encoded.
+     */
+    public static ObjectType readFromJSON(InputStream stream) throws Exception {
+        if (stream == null) {
+            throw new IllegalArgumentException("Input stream must be set!");
+        }
+
+        JSONParser parser = new JSONParser();
+        Object json = parser.parse(new InputStreamReader(stream, "UTF-8"));
+
+        if (!(json instanceof Map)) {
+            throw new CmisRuntimeException("Invalid stream! Not a type definition!");
+        }
+
+        @SuppressWarnings("unchecked")
+        TypeDefinition typeDef = JSONConverter.convertTypeDefinition((Map<String, Object>) json);
+
+        ObjectFactoryImpl of = new ObjectFactoryImpl();
+        return of.convertTypeDefinition(typeDef);
+    }
+}

Propchange: chemistry/opencmis/trunk/chemistry-opencmis-client/chemistry-opencmis-client-impl/src/main/java/org/apache/chemistry/opencmis/client/util/TypeUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/Constants.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/Constants.java?rev=1414310&r1=1414309&r2=1414310&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/Constants.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/Constants.java Tue Nov 27 18:40:57 2012
@@ -160,6 +160,8 @@ public final class Constants {
     public static final String CONTROL_CONTENT_TYPE = "contenttype";
     public static final String CONTROL_FILENAME = "filename";
     public static final String CONTROL_IS_LAST_CHUNK = "isLastChunk";
+    public static final String CONTROL_TYPE = "type";
+    public static final String CONTROL_TYPE_ID = "typeId";
 
     // parameter
     public static final String PARAM_ACL = "includeACL";

Modified: chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/JSONConstants.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/JSONConstants.java?rev=1414310&r1=1414309&r2=1414310&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/JSONConstants.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/JSONConstants.java Tue Nov 27 18:40:57 2012
@@ -329,6 +329,7 @@ public final class JSONConstants {
     public static final String JSON_TYPE_CONTROLABLE_POLICY = "controllablePolicy";
     public static final String JSON_TYPE_CONTROLABLE_ACL = "controllableACL";
     public static final String JSON_TYPE_PROPERTY_DEFINITIONS = "propertyDefinitions";
+    public static final String JSON_TYPE_TYPE_MUTABILITY = "typeMutability";
 
     public static final String JSON_TYPE_VERSIONABLE = "versionable"; // document
     public static final String JSON_TYPE_CONTENTSTREAM_ALLOWED = "contentStreamAllowed"; // document
@@ -358,6 +359,7 @@ public final class JSONConstants {
         TYPE_KEYS.add(JSON_TYPE_CONTENTSTREAM_ALLOWED);
         TYPE_KEYS.add(JSON_TYPE_ALLOWED_SOURCE_TYPES);
         TYPE_KEYS.add(JSON_TYPE_ALLOWED_TARGET_TYPES);
+        TYPE_KEYS.add(JSON_TYPE_TYPE_MUTABILITY);
     }
 
     public static final String JSON_PROPERTY_TYPE_ID = "id";
@@ -413,6 +415,17 @@ public final class JSONConstants {
         PROPERTY_TYPE_KEYS.add(JSON_PROPERTY_TYPE_CHOICE);
     }
 
+    public static final String JSON_TYPE_TYPE_MUTABILITY_CREATE = "create";
+    public static final String JSON_TYPE_TYPE_MUTABILITY_UPDATE = "update";
+    public static final String JSON_TYPE_TYPE_MUTABILITY_DELETE = "delete";
+
+    public static final Set<String> JSON_TYPE_TYPE_MUTABILITY_KEYS = new HashSet<String>();
+    static {
+        JSON_TYPE_TYPE_MUTABILITY_KEYS.add(JSON_TYPE_TYPE_MUTABILITY_CREATE);
+        JSON_TYPE_TYPE_MUTABILITY_KEYS.add(JSON_TYPE_TYPE_MUTABILITY_UPDATE);
+        JSON_TYPE_TYPE_MUTABILITY_KEYS.add(JSON_TYPE_TYPE_MUTABILITY_DELETE);
+    }
+
     public static final String JSON_TYPESLIST_TYPES = "types";
     public static final String JSON_TYPESLIST_HAS_MORE_ITEMS = "hasMoreItems";
     public static final String JSON_TYPESLIST_NUM_ITEMS = "numItems";

Modified: chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/JSONConverter.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/JSONConverter.java?rev=1414310&r1=1414309&r2=1414310&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/JSONConverter.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/JSONConverter.java Tue Nov 27 18:40:57 2012
@@ -79,6 +79,7 @@ import org.apache.chemistry.opencmis.com
 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionContainer;
 import org.apache.chemistry.opencmis.commons.definitions.TypeDefinitionList;
+import org.apache.chemistry.opencmis.commons.definitions.TypeMutability;
 import org.apache.chemistry.opencmis.commons.enums.AclPropagation;
 import org.apache.chemistry.opencmis.commons.enums.Action;
 import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
@@ -144,6 +145,7 @@ import org.apache.chemistry.opencmis.com
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.RepositoryInfoBrowserBindingImpl;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.TypeDefinitionContainerImpl;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.TypeDefinitionListImpl;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.TypeMutabilityImpl;
 import org.apache.chemistry.opencmis.commons.impl.json.JSONArray;
 import org.apache.chemistry.opencmis.commons.impl.json.JSONObject;
 
@@ -512,6 +514,19 @@ public final class JSONConverter {
         result.setParentTypeId(getString(json, JSON_TYPE_PARENT_ID));
         result.setQueryName(getString(json, JSON_TYPE_QUERYNAME));
 
+        Map<String, Object> typeMutabilityJson = getMap(json.get(JSON_TYPE_TYPE_MUTABILITY));
+        if (typeMutabilityJson != null) {
+            TypeMutabilityImpl typeMutability = new TypeMutabilityImpl();
+
+            typeMutability.setCanCreate(getBoolean(json, JSON_TYPE_TYPE_MUTABILITY_CREATE));
+            typeMutability.setCanUpdate(getBoolean(json, JSON_TYPE_TYPE_MUTABILITY_UPDATE));
+            typeMutability.setCanDelete(getBoolean(json, JSON_TYPE_TYPE_MUTABILITY_DELETE));
+
+            convertExtension(typeMutabilityJson, typeMutability, JSON_TYPE_TYPE_MUTABILITY_KEYS);
+
+            result.setTypeMutability(typeMutability);
+        }
+
         Map<String, Object> propertyDefinitions = getMap(json.get(JSON_TYPE_PROPERTY_DEFINITIONS));
         if (propertyDefinitions != null) {
             for (Object propDef : propertyDefinitions.values()) {
@@ -1277,6 +1292,19 @@ public final class JSONConverter {
         result.put(JSON_TYPE_CONTROLABLE_POLICY, type.isControllablePolicy());
         result.put(JSON_TYPE_CONTROLABLE_ACL, type.isControllableAcl());
 
+        if (type.getTypeMutability() != null) {
+            TypeMutability typeMutability = type.getTypeMutability();
+            JSONObject typeMutabilityJson = new JSONObject();
+
+            typeMutabilityJson.put(JSON_TYPE_TYPE_MUTABILITY_CREATE, typeMutability.canCreate());
+            typeMutabilityJson.put(JSON_TYPE_TYPE_MUTABILITY_UPDATE, typeMutability.canUpdate());
+            typeMutabilityJson.put(JSON_TYPE_TYPE_MUTABILITY_DELETE, typeMutability.canDelete());
+
+            convertExtension(typeMutability, typeMutabilityJson);
+
+            result.put(JSON_TYPE_TYPE_MUTABILITY, typeMutabilityJson);
+        }
+
         if (type instanceof DocumentTypeDefinition) {
             result.put(JSON_TYPE_VERSIONABLE, ((DocumentTypeDefinition) type).isVersionable());
             result.put(JSON_TYPE_CONTENTSTREAM_ALLOWED, ((DocumentTypeDefinition) type).getContentStreamAllowed()

Modified: chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/AbstractTypeDefinition.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/AbstractTypeDefinition.java?rev=1414310&r1=1414309&r2=1414310&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/AbstractTypeDefinition.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-commons/chemistry-opencmis-commons-impl/src/main/java/org/apache/chemistry/opencmis/commons/impl/dataobjects/AbstractTypeDefinition.java Tue Nov 27 18:40:57 2012
@@ -48,7 +48,7 @@ public abstract class AbstractTypeDefini
     private Boolean isFulltextIndexed;
     private Boolean isControllableACL;
     private Boolean isControllablePolicy;
-    private Map<String, PropertyDefinition<?>> propertyDefinitions;
+    private LinkedHashMap<String, PropertyDefinition<?>> propertyDefinitions;
     private TypeMutability typeMutability;
 
     public void initialize(TypeDefinition typeDefinition) {
@@ -200,7 +200,13 @@ public abstract class AbstractTypeDefini
     }
 
     public void setPropertyDefinitions(Map<String, PropertyDefinition<?>> propertyDefinitions) {
-        this.propertyDefinitions = propertyDefinitions;
+        if (propertyDefinitions == null) {
+            this.propertyDefinitions = null;
+        } else if (propertyDefinitions instanceof LinkedHashMap) {
+            this.propertyDefinitions = (LinkedHashMap<String, PropertyDefinition<?>>) propertyDefinitions;
+        } else {
+            this.propertyDefinitions = new LinkedHashMap<String, PropertyDefinition<?>>(propertyDefinitions);
+        }
     }
 
     /**

Modified: chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/RepositoryService.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/RepositoryService.java?rev=1414310&r1=1414309&r2=1414310&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/RepositoryService.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-server/chemistry-opencmis-server-bindings/src/main/java/org/apache/chemistry/opencmis/server/impl/browser/RepositoryService.java Tue Nov 27 18:40:57 2012
@@ -18,6 +18,8 @@
  */
 package org.apache.chemistry.opencmis.server.impl.browser;
 
+import static org.apache.chemistry.opencmis.commons.impl.Constants.CONTROL_TYPE;
+import static org.apache.chemistry.opencmis.commons.impl.Constants.CONTROL_TYPE_ID;
 import static org.apache.chemistry.opencmis.commons.impl.Constants.PARAM_DEPTH;
 import static org.apache.chemistry.opencmis.commons.impl.Constants.PARAM_MAX_ITEMS;
 import static org.apache.chemistry.opencmis.commons.impl.Constants.PARAM_PROPERTY_DEFINITIONS;
@@ -32,6 +34,7 @@ import static org.apache.chemistry.openc
 import java.math.BigInteger;
 import java.net.URLDecoder;
 import java.util.List;
+import java.util.Map;
 
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
@@ -47,6 +50,7 @@ import org.apache.chemistry.opencmis.com
 import org.apache.chemistry.opencmis.commons.impl.json.JSONArray;
 import org.apache.chemistry.opencmis.commons.impl.json.JSONObject;
 import org.apache.chemistry.opencmis.commons.impl.json.JSONValue;
+import org.apache.chemistry.opencmis.commons.impl.json.parser.JSONParser;
 import org.apache.chemistry.opencmis.commons.server.CallContext;
 import org.apache.chemistry.opencmis.commons.server.CmisService;
 
@@ -198,7 +202,28 @@ public final class RepositoryService {
      */
     public static void createType(CallContext context, CmisService service, String repositoryId,
             HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // TODO
+        // get parameters
+        String typeStr = getStringParameter(request, CONTROL_TYPE);
+        if (typeStr == null) {
+            throw new CmisInvalidArgumentException("Type definition missing!");
+        }
+
+        // convert type definition
+        JSONParser parser = new JSONParser();
+        Object typeJson = parser.parse(typeStr);
+        if (!(typeJson instanceof Map)) {
+            throw new CmisInvalidArgumentException("Invalid type definition!");
+        }
+
+        @SuppressWarnings("unchecked")
+        TypeDefinition typeIn = JSONConverter.convertTypeDefinition((Map<String, Object>) typeJson);
+
+        // execute
+        TypeDefinition typeOut = service.createType(repositoryId, typeIn, null);
+        JSONObject jsonType = JSONConverter.convert(typeOut);
+
+        response.setStatus(HttpServletResponse.SC_OK);
+        BrowserBindingUtils.writeJSON(jsonType, request, response);
     }
 
     /**
@@ -206,7 +231,28 @@ public final class RepositoryService {
      */
     public static void updateType(CallContext context, CmisService service, String repositoryId,
             HttpServletRequest request, HttpServletResponse response) throws Exception {
-        // TODO
+        // get parameters
+        String typeStr = getStringParameter(request, CONTROL_TYPE);
+        if (typeStr == null) {
+            throw new CmisInvalidArgumentException("Type definition missing!");
+        }
+
+        // convert type definition
+        JSONParser parser = new JSONParser();
+        Object typeJson = parser.parse(typeStr);
+        if (!(typeJson instanceof Map)) {
+            throw new CmisInvalidArgumentException("Invalid type definition!");
+        }
+
+        @SuppressWarnings("unchecked")
+        TypeDefinition typeIn = JSONConverter.convertTypeDefinition((Map<String, Object>) typeJson);
+
+        // execute
+        TypeDefinition typeOut = service.updateType(repositoryId, typeIn, null);
+        JSONObject jsonType = JSONConverter.convert(typeOut);
+
+        response.setStatus(HttpServletResponse.SC_OK);
+        BrowserBindingUtils.writeJSON(jsonType, request, response);
     }
 
     /**
@@ -215,7 +261,7 @@ public final class RepositoryService {
     public static void deleteType(CallContext context, CmisService service, String repositoryId,
             HttpServletRequest request, HttpServletResponse response) throws Exception {
         // get parameters
-        String typeId = getStringParameter(request, PARAM_TYPE_ID);
+        String typeId = getStringParameter(request, CONTROL_TYPE_ID);
 
         service.deleteType(repositoryId, typeId, null);
 

Modified: chemistry/opencmis/trunk/chemistry-opencmis-workbench/chemistry-opencmis-workbench/src/main/java/org/apache/chemistry/opencmis/workbench/TypeSplitPane.java
URL: http://svn.apache.org/viewvc/chemistry/opencmis/trunk/chemistry-opencmis-workbench/chemistry-opencmis-workbench/src/main/java/org/apache/chemistry/opencmis/workbench/TypeSplitPane.java?rev=1414310&r1=1414309&r2=1414310&view=diff
==============================================================================
--- chemistry/opencmis/trunk/chemistry-opencmis-workbench/chemistry-opencmis-workbench/src/main/java/org/apache/chemistry/opencmis/workbench/TypeSplitPane.java (original)
+++ chemistry/opencmis/trunk/chemistry-opencmis-workbench/chemistry-opencmis-workbench/src/main/java/org/apache/chemistry/opencmis/workbench/TypeSplitPane.java Tue Nov 27 18:40:57 2012
@@ -18,17 +18,27 @@
  */
 package org.apache.chemistry.opencmis.workbench;
 
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.GridLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
 import javax.swing.JMenuItem;
+import javax.swing.JPanel;
 import javax.swing.JPopupMenu;
 import javax.swing.JScrollPane;
 import javax.swing.JSplitPane;
@@ -38,6 +48,7 @@ import javax.swing.table.AbstractTableMo
 import javax.swing.table.TableColumn;
 
 import org.apache.chemistry.opencmis.client.api.ObjectType;
+import org.apache.chemistry.opencmis.client.util.TypeUtils;
 import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition;
 import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
 import org.apache.chemistry.opencmis.commons.definitions.RelationshipTypeDefinition;
@@ -53,6 +64,7 @@ public class TypeSplitPane extends JSpli
     private final ClientModel model;
 
     private TypeInfoPanel typePanel;
+    private TypeButtonPanel typeButtonPanel;
     private PropertyDefinitionTable propertyDefinitionTable;
 
     public TypeSplitPane(ClientModel model) {
@@ -69,9 +81,14 @@ public class TypeSplitPane extends JSpli
 
     private void createGUI() {
         typePanel = new TypeInfoPanel(model);
+        typeButtonPanel = new TypeButtonPanel();
         propertyDefinitionTable = new PropertyDefinitionTable();
 
-        setLeftComponent(new JScrollPane(typePanel));
+        JPanel typeBorderPanel = new JPanel(new BorderLayout());
+        typeBorderPanel.add(typePanel, BorderLayout.CENTER);
+        typeBorderPanel.add(typeButtonPanel, BorderLayout.LINE_END);
+
+        setLeftComponent(new JScrollPane(typeBorderPanel));
         setRightComponent(new JScrollPane(propertyDefinitionTable));
 
         setDividerLocation(300);
@@ -79,6 +96,7 @@ public class TypeSplitPane extends JSpli
 
     public void setType(ObjectType type) {
         typePanel.setType(type);
+        typeButtonPanel.setType(type);
         propertyDefinitionTable.setType(type);
     }
 
@@ -104,6 +122,7 @@ public class TypeSplitPane extends JSpli
         private JTextField contentStreamAllowedField;
         private JTextField allowedSourceTypesField;
         private JTextField allowedTargetTypesField;
+        private JTextField typeMutabilityField;
 
         public TypeInfoPanel(ClientModel model) {
             super(model);
@@ -127,6 +146,31 @@ public class TypeSplitPane extends JSpli
                 aclLabel.setValue(is(type.isControllableAcl()));
                 policyLabel.setValue(is(type.isControllablePolicy()));
 
+                if (type.getTypeMutability() != null) {
+                    StringBuilder sb = new StringBuilder();
+
+                    if (Boolean.TRUE.equals(type.getTypeMutability().canCreate())) {
+                        sb.append("create");
+                    }
+
+                    if (Boolean.TRUE.equals(type.getTypeMutability().canUpdate())) {
+                        if (sb.length() > 0) {
+                            sb.append(", ");
+                        }
+                        sb.append("update");
+                    }
+
+                    if (Boolean.TRUE.equals(type.getTypeMutability().canDelete())) {
+                        if (sb.length() > 0) {
+                            sb.append(", ");
+                        }
+                        sb.append("delete");
+                    }
+
+                } else {
+                    typeMutabilityField.setText("");
+                }
+
                 if (type instanceof DocumentTypeDefinition) {
                     DocumentTypeDefinition docType = (DocumentTypeDefinition) type;
                     versionableLabel.setVisible(true);
@@ -170,6 +214,7 @@ public class TypeSplitPane extends JSpli
                 contentStreamAllowedField.setVisible(false);
                 allowedSourceTypesField.setVisible(false);
                 allowedTargetTypesField.setVisible(false);
+                typeMutabilityField.setText("");
             }
 
             revalidate();
@@ -192,6 +237,7 @@ public class TypeSplitPane extends JSpli
             fulltextIndexedLabel = addYesNoLabel("Full text indexed:");
             aclLabel = addYesNoLabel("ACL controlable:");
             policyLabel = addYesNoLabel("Policy controlable:");
+            typeMutabilityField = addLine("Type mutability:");
             versionableLabel = addYesNoLabel("Versionable:");
             contentStreamAllowedField = addLine("Content stream allowed:");
             allowedSourceTypesField = addLine("Allowed source types:");
@@ -207,6 +253,106 @@ public class TypeSplitPane extends JSpli
         }
     }
 
+    static class TypeButtonPanel extends JPanel {
+
+        private static final long serialVersionUID = 1L;
+
+        private JButton saveToXMLButton;
+        private JButton saveToJSONButton;
+
+        private ObjectType type;
+
+        public TypeButtonPanel() {
+            super();
+            createGUI();
+        }
+
+        private void createGUI() {
+            setBackground(Color.WHITE);
+
+            saveToXMLButton = new JButton("Save type to XML");
+            saveToJSONButton = new JButton("Save type to JSON");
+
+            saveToXMLButton.setEnabled(false);
+            saveToJSONButton.setEnabled(false);
+
+            JPanel buttonPanel = new JPanel(new GridLayout(4, 1));
+            buttonPanel.setBackground(Color.WHITE);
+
+            buttonPanel.add(saveToXMLButton);
+            buttonPanel.add(saveToJSONButton);
+
+            add(buttonPanel);
+
+            saveToXMLButton.addActionListener(new ActionListener() {
+                @Override
+                public void actionPerformed(ActionEvent event) {
+                    JFileChooser fileChooser = new JFileChooser();
+                    fileChooser.setSelectedFile(new File(getFilename() + ".xml"));
+
+                    int chooseResult = fileChooser.showDialog(TypeButtonPanel.this.getParent(), "Save XML");
+                    if (chooseResult == JFileChooser.APPROVE_OPTION) {
+                        try {
+                            OutputStream out = new BufferedOutputStream(new FileOutputStream(fileChooser
+                                    .getSelectedFile()));
+                            TypeUtils.writeToXML(type, out);
+                            out.flush();
+                            out.close();
+                        } catch (Exception e) {
+                            ClientHelper.showError(TypeButtonPanel.this.getParent(), e);
+                        }
+                    }
+                }
+            });
+
+            saveToJSONButton.addActionListener(new ActionListener() {
+                @Override
+                public void actionPerformed(ActionEvent event) {
+                    JFileChooser fileChooser = new JFileChooser();
+                    fileChooser.setSelectedFile(new File(getFilename() + ".json"));
+
+                    int chooseResult = fileChooser.showDialog(TypeButtonPanel.this.getParent(), "Save JSON");
+                    if (chooseResult == JFileChooser.APPROVE_OPTION) {
+                        try {
+                            OutputStream out = new BufferedOutputStream(new FileOutputStream(fileChooser
+                                    .getSelectedFile()));
+                            TypeUtils.writeToJSON(type, out);
+                            out.flush();
+                            out.close();
+                        } catch (Exception e) {
+                            ClientHelper.showError(TypeButtonPanel.this.getParent(), e);
+                        }
+                    }
+                }
+            });
+        }
+
+        private String getFilename() {
+            if (type != null) {
+                String filename = type.getId();
+                filename = filename.replace(':', '_');
+                filename = filename.replace('/', '_');
+                filename = filename.replace('\\', '_');
+
+                return filename;
+            }
+
+            return "type";
+        }
+
+        public void setType(ObjectType type) {
+            this.type = type;
+
+            if (type != null) {
+                saveToXMLButton.setEnabled(true);
+                saveToJSONButton.setEnabled(true);
+            } else {
+                saveToXMLButton.setEnabled(false);
+                saveToJSONButton.setEnabled(false);
+            }
+        }
+    }
+
     static class PropertyDefinitionTable extends JTable {
 
         private static final long serialVersionUID = 1L;