Creating a type

Java command-line example using the CMIS 1.1 type mutability feature.

    package typeMutability.enabled;
    
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.math.BigInteger;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.LinkedHashMap;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Properties;
    
    import org.apache.chemistry.opencmis.client.api.ObjectType;
    import org.apache.chemistry.opencmis.client.api.Repository;
    import org.apache.chemistry.opencmis.client.api.Session;
    import org.apache.chemistry.opencmis.client.api.SessionFactory;
    import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl;
    import org.apache.chemistry.opencmis.commons.SessionParameter;
    import org.apache.chemistry.opencmis.commons.data.CmisExtensionElement;
    import org.apache.chemistry.opencmis.commons.data.RepositoryInfo;
    import org.apache.chemistry.opencmis.commons.definitions.Choice;
    import org.apache.chemistry.opencmis.commons.definitions.DocumentTypeDefinition;
    import org.apache.chemistry.opencmis.commons.definitions.PropertyBooleanDefinition;
    import org.apache.chemistry.opencmis.commons.definitions.PropertyDefinition;
    import org.apache.chemistry.opencmis.commons.definitions.PropertyIdDefinition;
    import org.apache.chemistry.opencmis.commons.definitions.PropertyIntegerDefinition;
    import org.apache.chemistry.opencmis.commons.definitions.PropertyStringDefinition;
    import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
    import org.apache.chemistry.opencmis.commons.definitions.TypeMutability;
    import org.apache.chemistry.opencmis.commons.enums.BaseTypeId;
    import org.apache.chemistry.opencmis.commons.enums.Cardinality;
    import org.apache.chemistry.opencmis.commons.enums.ContentStreamAllowed;
    import org.apache.chemistry.opencmis.commons.enums.PropertyType;
    import org.apache.chemistry.opencmis.commons.enums.Updatability;
    import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
    
    import typeMutability.util.TestStringChoice;
    
    /* 
     * Licensed 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.
     *
     *
     * This code is based on the Apache Chemistry OpenCMIS FileShare project
     * <http://chemistry.apache.org/java/developing/repositories/dev-repositories-fileshare.html>.
     *
     * This code is part of a training exercise and not intended for production use!
     *
     */
    
    /**
     * Running this test requires an input file containing the connection 
     * properties for your CMIS server. 
     *
     * The default/static location is /temp/cmis.properties
     * and is hard coded in the main() method. 
     * See the loadConnectionProperties() call if you 
     * need to change this location or make it dynamic. 
     * 
     * Example format for a typical cmis.properties file:
     * You can also refer to the properties section in the 
     * Workbench page here:
     * http://chemistry.apache.org/java/developing/tools/dev-tools-workbench.html
     * 
     * ******************************************
     * SAMPLE cmis.properties *******************
     * ******************************************
     * 
     *     org.apache.chemistry.opencmis.binding.spi.type=browser
     *     org.apache.chemistry.opencmis
     *     org.apache.chemistry.opencmis.binding.browser.url=http://localhost:8080/openfncmis/browser
     *     org.apache.chemistry.opencmis.user=username_here
     *     org.apache.chemistry.opencmis.password=password_here
     *     org.apache.chemistry.opencmis.binding.compression=true
     *     org.apache.chemistry.opencmis.binding.cookies=true
     * 
     */
    
    /*
     * This class serves as a simple example of how to create a new TypeDefinintion
     * in CMIS using the OpenCMIS client. (all in one self contained file) This code
     * was tested with the FileNet CMIS 1.1 tech preview but can be modified to work
     * with any CMIS client that supports type mutability.
     * 
     * Code will create a new subclass of cmis:document with 4 properties 
     * String, Int, Boolean and Id, and two choice list values on the String prop
     */
    public class CreateTestCommandLine {
    
        // Modify these values to conform to your local repository requirements
        //
        // property id's and names here 
        private static final String property_stringPropertyId = "StringPropertyDefinition";
        private static final String property_intPropertyId = "IntPropertyDefinition";
        private static final String property_boolPropertyId = "BoolPropertyDefinition";
        private static final String property_idPropertyId = "IdPropertyDefinition";
    
        //
        // type related
        // the id of the new type's parent
        private static final String type_idOfParentType = "cmis:document";
        // Id of the new subclass we will be creating
        private static final String type_idOfNewClass = "cmis_newDocSubclass1";
        // other information about type
        private static final String type_description = "Test document type definition";
        private static final String type_displayName = "TestTypeDefinition";
        private static final String type_localName = "some test local name";
        private static final String type_localNamespace = "some test local name space";
    
        // globals
        private static Session session = null;
    
        public static void main(String[] args) {
    
            System.out.println("An example of type creation with CMIS TypeMutability from OpenCMIS.");
    
            // Assume /cmis.properties is the name of the input file containing all
            // of the session parameters (test only)
            Map<String, String> parameters = loadConnectionProperties("/temp/cmis.properties");
    
            session = getSession(parameters);
    
            // Look at repository info - demonstrates a valid connection
            RepositoryInfo repositoryInfo = session.getRepositoryInfo();
            System.out.println("Connected to repository.  Supports CMIS version:"
                    + repositoryInfo.getCmisVersionSupported());
    
            
            // Check here to verify the types we will be creating are permissible 
            // for this repository.
            Boolean canCreateStringProperty = false;
            Boolean canCreateIdProperty = false;
            Boolean canCreateBoolProperty = false;
            Boolean canCreateIntProperty = false;
            for (PropertyType propCreatable : repositoryInfo.getCapabilities().getCreatablePropertyTypes().canCreate()) {
    
                if (propCreatable.equals(PropertyType.STRING)) {
                    canCreateStringProperty = true;
                } else if (propCreatable.equals(PropertyType.INTEGER)) {
                    canCreateIntProperty = true;
                } else if (propCreatable.equals(PropertyType.ID)) {
                    canCreateIdProperty = true;
                } else if (propCreatable.equals(PropertyType.BOOLEAN)) {
                    canCreateBoolProperty = true;
                }
               
                System.out.println("Repository can create property of : " + propCreatable.toString());
            }
           
            assert canCreateStringProperty: "String is not one of the createable properties.";
            assert canCreateIdProperty: "Id is not one of the createable properties.";
            assert canCreateBoolProperty: "Boolean is not one of the createable properties.";
            assert canCreateIntProperty: "Integer is not one of the createable properties.";
    
            // Create new type with string property
            // and verify it exists in type collection
            ObjectType newType = createNewType();
    
            // clean up the type if permitted
            // TODO - check to see if delete is permitted first...
            session.deleteType(newType.getId());
    
            // TODO - verify delete here for completeness.
            System.out.println("Cleanup completed.");
        }
    
        /**
         * Create the new type with with our 4 test property types.
         * 
         * @return
         */
        public static ObjectType createNewType() {
            // assuming the following default (change if your repository
            // does not support these settings
            Boolean isCreatable = true;
            Boolean includedInSupertypeQuery = true;
            Boolean queryable = true;
            ContentStreamAllowed contentStreamAllowed = ContentStreamAllowed.ALLOWED;
            Boolean versionable = false;
    
            // build property definitions - string, int, boolean and id
            Map<String, PropertyDefinition<?>> propertyDefinitions = new LinkedHashMap<String, PropertyDefinition<?>>();
            TestStringPropertyDefinition spd = createStringPropertyDefinition();
            TestIntegerPropertyDefinition ipd = createIntPropertyDefinition();
            TestBooleanPropertyDefinition bpd = createBooleanPropertyDefinition();
            TestIdPropertyDefinition idpd = createIDPropertyDefinition();
    
            propertyDefinitions.put(spd.getId(), spd);
            propertyDefinitions.put(ipd.getId(), ipd);
            propertyDefinitions.put(bpd.getId(), bpd);
            propertyDefinitions.put(idpd.getId(), idpd);
    
            TestDocumentTypeDefinition typeToCreate = new TestDocumentTypeDefinition(type_idOfNewClass, type_description,
                    type_displayName, type_localName, type_localNamespace, type_idOfParentType, isCreatable,
                    includedInSupertypeQuery, queryable, contentStreamAllowed, versionable, propertyDefinitions);
    
            TypeDefinition createdType = null;
            try {
                createdType = session.createType(typeToCreate);
                System.out.println("Type created: " + createdType.toString());
            } catch (Exception e) {
                assert false: "An exception was thrown when trying to create a new type definition. Message: " + e.getMessage();
            }
    
            ObjectType retrievedType = null;
            try {
                retrievedType = session.getTypeDefinition(createdType.getId());
                assert retrievedType != null: "Unable to retrieve new type. ";
            } catch (Exception e) {
                assert false: "Got exception. Cannot get the type definition from the repository. Message: " + e.getMessage();
            }
    
            return retrievedType;
        }
    
        public static Session getSession(Map<String, String> parameters) {
            Session session = null;
    
            SessionFactory factory = SessionFactoryImpl.newInstance();
            if (parameters.containsKey(SessionParameter.REPOSITORY_ID)) {
                session = factory.createSession(parameters);
            } else {
                // Create session for the first repository.
                List<Repository> repositories = factory.getRepositories(parameters);
                session = repositories.get(0).createSession();
            }
    
            // reset op context to default
            session.setDefaultContext(session.createOperationContext());
    
            return session;
        }
    
        /*
         * Load our connection properties from a local file
         * 
         * Note file should use the same format as the expert settings for Workbench
         */
        public static final Map<String, String> loadConnectionProperties(String configResource) {
            Properties testConfig = new Properties();
            if (configResource == null) {
                throw new CmisRuntimeException("Filename with connection parameters was not supplied.");
            }
    
            FileInputStream inStream;
            try {
                inStream = new FileInputStream(configResource);
                testConfig.load(inStream);
                inStream.close();
            } catch (FileNotFoundException e1) {
                throw new CmisRuntimeException("Test properties file '" + configResource + "' was not found at:"
                        + configResource);
            } catch (IOException e) {
                throw new CmisRuntimeException("Exception loading test properties file " + configResource, e);
            }
    
            Map<String, String> map = new HashMap<String, String>();
            for (Entry<?, ?> entry : testConfig.entrySet()) {
                System.out.println("Found key: " + entry.getKey() + " Value:" + entry.getValue());
                map.put((String) entry.getKey(), ((String) entry.getValue()).trim());
            }
            return map;
        }
    
        /**
         * Create a single string property definition with a choice list
         */
        private static TestStringPropertyDefinition createStringPropertyDefinition() {
        
            Cardinality cardinality = Cardinality.SINGLE;
            String description = "String property definition";
            String displayName = "StringPropertyDefinition";
            String localName = "StringPropertyDefinition";
            String localNameSpace = "StringPropertyDefinition";    
            Updatability updatability = Updatability.READWRITE;
            Boolean orderable = false;
            Boolean queryable = false;
            ArrayList<String> defaults = new ArrayList<String>();
            defaults.add("test");
    
            List<String> vals1 = new LinkedList<String>();
            vals1.add("val1");
    
            List<String> vals2 = new LinkedList<String>();
            vals2.add("val2");
    
            TestStringChoice strChoice1 = new TestStringChoice("choice1", vals1, null);
            TestStringChoice strChoice2 = new TestStringChoice("choice2", vals2, null);
            List<Choice<String>> choiceList = new LinkedList<Choice<String>>();
            choiceList.add (strChoice1);
            choiceList.add (strChoice2);
    
            TestStringPropertyDefinition spd = new TestStringPropertyDefinition(property_stringPropertyId, cardinality, 
                    description, displayName, localName, localNameSpace, updatability, orderable, queryable, 
                    defaults, choiceList, null);
    
            return spd;      
        }
    
        private static TestIntegerPropertyDefinition createIntPropertyDefinition() {
            Cardinality cardinality = Cardinality.MULTI;
            String description = "Int property definition";
            String displayName = "IntPropertyDefinition";
            String localName = "IntPropertyDefinition";
            String localNameSpace = "IntPropertyDefinition";
            Updatability updatability = Updatability.READWRITE;
            Boolean orderable = false;
            Boolean queryable = false;
            ArrayList<BigInteger> defaults = new ArrayList<BigInteger>();
            // defaults.add(new BigInteger("101"));
            BigInteger minVal = new BigInteger("100");
            BigInteger maxVal = new BigInteger("1000");
    
            TestIntegerPropertyDefinition ipd = new TestIntegerPropertyDefinition(property_intPropertyId, cardinality,
                    description, displayName, localName, localNameSpace, updatability, orderable, queryable, defaults,
                    minVal, maxVal, null);
            return ipd;
        }
    
        private static TestBooleanPropertyDefinition createBooleanPropertyDefinition() {
    
            Cardinality cardinality = Cardinality.SINGLE;
            String description = "Boolean property definition";
            String displayName = "BooleanPropertyDefinition";
            String localName = "BooleanPropertyDefinition";
            String localNameSpace = "BooleanPropertyDefinition";
            Updatability updatability = Updatability.ONCREATE;
            Boolean orderable = false;
            Boolean queryable = false;
            ArrayList<Boolean> defaults = new ArrayList<Boolean>();
            defaults.add(false);
    
            TestBooleanPropertyDefinition spd = new TestBooleanPropertyDefinition(property_boolPropertyId, cardinality,
                    description, displayName, localName, localNameSpace, updatability, orderable, queryable, defaults);
            return spd;
        }
    
        private static TestIdPropertyDefinition createIDPropertyDefinition() {
            Cardinality cardinality = Cardinality.SINGLE;
            String description = "ID property definition";
            String displayName = "IDPropertyDefinition";
            String localName = "IDPropertyDefinition";
            String localNameSpace = "IDPropertyDefinition";
            Updatability updatability = Updatability.READWRITE;
            Boolean orderable = false;
            Boolean queryable = false;
    
            TestIdPropertyDefinition idpd = new TestIdPropertyDefinition(property_idPropertyId, cardinality, description,
                    displayName, localName, localNameSpace, updatability, orderable, queryable, null);
            return idpd;
        }
    
        /**
         * **************************************************************************
         * Inner classes follow
         * **************************************************************************
         * 
         * All of the abstract base classes (for properties and types) 
         * that are used in this example are defined here
         * along with their subclasses for each type that we support in this example.
         * 
         * These classes can be further extended and reused for additional type 
         * mutability operations. 
         * 
         * These were made inner classes so the entire example would be contained
         * in a single Java file. (no design reason) 
         * 
         */
    
        private static class TestStringPropertyDefinition extends TestPropertyDefinition<String> implements
                PropertyStringDefinition {
    
            BigInteger maxLength = null;
    
            public TestStringPropertyDefinition(String idAndQueryName, Cardinality cardinality, String description,
                    String displayName, String localName, String localNameSpace, Updatability updatability,
                    Boolean orderable, Boolean queryable, List<String> defaultValue, List<Choice<String>> choiceList,
                    BigInteger maxLength) {
                super(idAndQueryName, cardinality, description, displayName, localName, localNameSpace, updatability,
                        orderable, queryable, defaultValue, choiceList);
    
                this.maxLength = maxLength;
            }
    
            @Override
            public PropertyType getPropertyType() {
                return PropertyType.STRING;
            }
    
            @Override
            public BigInteger getMaxLength() {
                return maxLength;
            }
    
        }
    
        private static class TestIntegerPropertyDefinition extends TestPropertyDefinition<BigInteger> implements
                PropertyIntegerDefinition {
    
            private BigInteger minVal = null;
            private BigInteger maxVal = null;
    
            public TestIntegerPropertyDefinition(String idAndQueryName, Cardinality cardinality, String description,
                    String displayName, String localName, String localNameSpace, Updatability updatability,
                    Boolean orderable, Boolean queryable, List<BigInteger> defaultValue, BigInteger minVal,
                    BigInteger maxVal, List<Choice<BigInteger>> choiceList) {
                super(idAndQueryName, cardinality, description, displayName, localName, localNameSpace, updatability,
                        orderable, queryable, defaultValue, choiceList);
    
                this.minVal = minVal;
                this.maxVal = maxVal;
            }
    
            @Override
            public PropertyType getPropertyType() {
                return PropertyType.INTEGER;
            }
    
            @Override
            public BigInteger getMaxValue() {
                return this.maxVal;
            }
    
            @Override
            public BigInteger getMinValue() {
                return this.minVal;
            }
        }
    
        private static class TestBooleanPropertyDefinition extends TestPropertyDefinition<Boolean> implements
                PropertyBooleanDefinition {
    
            public TestBooleanPropertyDefinition(String idAndQueryName, Cardinality cardinality, String description,
                    String displayName, String localName, String localNameSpace, Updatability updatability,
                    Boolean orderable, Boolean queryable, List<Boolean> defaultValue) {
    
                super(idAndQueryName, cardinality, description, displayName, localName, localNameSpace, updatability,
                        orderable, queryable, defaultValue, null);
            }
    
            @Override
            public PropertyType getPropertyType() {
                return PropertyType.BOOLEAN;
            }
        }
    
        private static class TestIdPropertyDefinition extends TestPropertyDefinition<String> implements
                PropertyIdDefinition {
    
            public TestIdPropertyDefinition(String idAndQueryName, Cardinality cardinality, String description,
                    String displayName, String localName, String localNameSpace, Updatability updatability,
                    Boolean orderable, Boolean queryable, List<String> defaultValue) {
                super(idAndQueryName, cardinality, description, displayName, localName, localNameSpace, updatability,
                        orderable, queryable, defaultValue, null);
            }
    
            @Override
            public PropertyType getPropertyType() {
                return PropertyType.ID;
            }
    
        }
    
        /** 
         * Base class for all property definition types
         * 
         * See TestStringPropertyDefinition for example of how to subclass this.
         *
         * @param <T>
         */
        abstract private static class TestPropertyDefinition<T> implements PropertyDefinition<T> {
    
            private String idAndQueryName = null;
            private Cardinality cardinality = null;
            private String description = null;
            private String displayName = null;
            private String localName = null;
            private String localNameSpace = null;
            private Updatability updatability = null;
            private Boolean orderable = null;
            private Boolean queryable = null;
    
            private List<T> defaultValue = null;
            private List<Choice<T>> choiceList = null;
    
            public TestPropertyDefinition(String idAndQueryName, Cardinality cardinality, String description,
                    String displayName, String localName, String localNameSpace, Updatability updatability,
                    Boolean orderable, Boolean queryable, List<T> defaultValue, List<Choice<T>> choiceList) {
                super();
                this.idAndQueryName = idAndQueryName;
                this.cardinality = cardinality;
                this.description = description;
                this.displayName = displayName;
                this.localName = localName;
                this.localNameSpace = localNameSpace;
                this.updatability = updatability;
                this.orderable = orderable;
                this.queryable = queryable;
                this.defaultValue = defaultValue;
                this.choiceList = choiceList;
            }
    
            @Override
            public String getId() {
                return idAndQueryName;
            }
    
            @Override
            public Cardinality getCardinality() {
                return cardinality;
            }
    
            @Override
            public String getDescription() {
                return description;
            }
    
            @Override
            public String getDisplayName() {
                return displayName;
            }
    
            @Override
            public String getLocalName() {
                return localName;
            }
    
            @Override
            public String getLocalNamespace() {
                return localNameSpace;
            }
    
            @Override
            abstract public PropertyType getPropertyType();
    
            @Override
            public String getQueryName() {
                return idAndQueryName;
            }
    
            @Override
            public Updatability getUpdatability() {
                return updatability;
            }
    
            @Override
            public Boolean isOrderable() {
                return orderable;
            }
    
            @Override
            public Boolean isQueryable() {
                return queryable;
            }
    
            // methods with static content
    
            @Override
            public List<Choice<T>> getChoices() {
                return this.choiceList;
            }
    
            @Override
            public List<T> getDefaultValue() {
                return this.defaultValue;
            }
    
            
            /**
             * TODO For these remaining attributes you will want to set them 
             * accordingly.  They are all set to static values only 
             * because this is sample code. 
             */
            @Override
            public Boolean isInherited() {
                return false;
            }
    
            @Override
            public Boolean isOpenChoice() {
                return false;
            }
    
            @Override
            public Boolean isRequired() {
                return false;
            }
    
            @Override
            public List<CmisExtensionElement> getExtensions() {
                return null;
            }
    
            @Override
            public void setExtensions(List<CmisExtensionElement> arg0) {
            }
    
        }
    
        /**
         * Base class for all typeDefinitions.  
         * See TestDocumentTypeDefinition for an example of how to subclass this for document.
         *
         */
        private static abstract class TestTypeDefinition implements TypeDefinition {
    
            private String description = null;
            private String displayName = null;
            private String idAndQueryName = null;
            private String localName = null;
            private String localNamespace = null;
            private String parentTypeId = null;
            private Boolean isCreatable = null;
            private Boolean includedInSupertypeQuery = null;
            private Boolean queryable = null;
            private Map<String, PropertyDefinition<?>> propertyDefinitions = new HashMap<String, PropertyDefinition<?>>();
    
            public TestTypeDefinition(String idAndQueryName, String description, String displayName, String localName,
                    String localNamespace, String parentTypeId, Boolean isCreatable, Boolean includedInSupertypeQuery,
                    Boolean queryable, Map<String, PropertyDefinition<?>> propertyDefinitions) {
    
                this.description = description;
                this.displayName = displayName;
                this.idAndQueryName = idAndQueryName;
                this.localName = localName;
                this.localNamespace = localNamespace;
                this.parentTypeId = parentTypeId;
                this.isCreatable = isCreatable;
                this.includedInSupertypeQuery = includedInSupertypeQuery;
                this.queryable = queryable;
    
                if (propertyDefinitions != null) {
                    this.propertyDefinitions = propertyDefinitions;
                }
            }
    
            @Override
            abstract public BaseTypeId getBaseTypeId();
    
            @Override
            public String getDescription() {
                return description;
            }
    
            @Override
            public String getDisplayName() {
                return displayName;
            }
    
            @Override
            public String getId() {
                return idAndQueryName;
            }
    
            @Override
            public String getLocalName() {
                return localName;
            }
    
            @Override
            public String getLocalNamespace() {
                return localNamespace;
            }
    
            @Override
            public String getParentTypeId() {
                return parentTypeId;
            }
    
            @Override
            public Map<String, PropertyDefinition<?>> getPropertyDefinitions() {
                return propertyDefinitions;
            }
    
            @Override
            public String getQueryName() {
                return idAndQueryName;
            }
    
            @Override
            public Boolean isCreatable() {
                return isCreatable;
            }
    
            @Override
            public Boolean isIncludedInSupertypeQuery() {
                return includedInSupertypeQuery;
            }
    
            @Override
            public Boolean isQueryable() {
                return queryable;
            }
    
            
            /**
             * TODO For these remaining attributes you will want to set them 
             * accordingly.  They are all set to static values only 
             * because this is sample code. 
             */
    
            @Override
            public TypeMutability getTypeMutability() {
                return new TestTypeMutability();
            }
    
            @Override
            public Boolean isControllableAcl() {
                return true;
            }
    
            @Override
            public Boolean isControllablePolicy() {
                return false;
            }
    
            @Override
            public Boolean isFileable() {
                return true;
            }
    
            @Override
            public Boolean isFulltextIndexed() {
                return false;
            }
    
            @Override
            public List<CmisExtensionElement> getExtensions() {
                return null;
            }
    
            @Override
            public void setExtensions(List<CmisExtensionElement> extension) {
            }
    
        }
    
        private static class TestDocumentTypeDefinition extends TestTypeDefinition implements DocumentTypeDefinition {
    
            private ContentStreamAllowed contentStreamAllowed = null;
            private Boolean versionable = null;
    
            public TestDocumentTypeDefinition(String idAndQueryName, String description, String displayName,
                    String localName, String localNamespace, String parentTypeId, Boolean isCreatable,
                    Boolean includedInSupertypeQuery, Boolean queryable, ContentStreamAllowed contentStreamAllowed,
                    Boolean versionable, Map<String, PropertyDefinition<?>> propertyDefinitions) {
    
                super(idAndQueryName, description, displayName, localName, localNamespace, parentTypeId, isCreatable,
                        includedInSupertypeQuery, queryable, propertyDefinitions);
    
                this.contentStreamAllowed = contentStreamAllowed;
                this.versionable = versionable;
            }
    
            @Override
            public BaseTypeId getBaseTypeId() {
                return BaseTypeId.CMIS_DOCUMENT;
            }
    
            @Override
            public ContentStreamAllowed getContentStreamAllowed() {
                return contentStreamAllowed;
            }
    
            @Override
            public Boolean isVersionable() {
                return versionable;
            }
    
        }
    
        public static class TestTypeMutability implements TypeMutability {
           
            /**
             * TODO:
             * Change these values based on your repository and requirements
             */
            
            @Override
            public List<CmisExtensionElement> getExtensions() {
                return null;
            }
    
            @Override
            public void setExtensions(List<CmisExtensionElement> arg0) {
            }
            
            @Override
            public Boolean canCreate() {
                return true;
            }
    
            @Override
            public Boolean canDelete() {
                return true;
            }
    
            @Override
            public Boolean canUpdate() {
                return true;
            }
        }
    }