Title: Create 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; } } }