Thursday 18 April 2019

openCMIS: Type Mutability: Manage types: Create new types


From CMIS 1.1 specification onwards, you can create, read, update and delete new type definitions. You can create new types by extending the existing ones.

Every type has three type mutability properties associated with them.

Property
Description
Create
Indicates if a sub type of this type can be created.
Delete
Indicates if this type can be updated.
Update
Indicates if this type can be deleted.

You can check whether you have permission to create a subtype to given property by calling the ‘getTypeMutability()’ function of object type.

Example
Folder folder = session.getRootFolder();
ObjectType objectType = folder.getType();

boolean canCreate = objectType.getTypeMutability().canCreate();
boolean canDelete = objectType.getTypeMutability().canDelete();
boolean canUpdate = objectType.getTypeMutability().canUpdate();

TestCmis.java
package com.sample.util;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.chemistry.opencmis.client.api.Folder;
import org.apache.chemistry.opencmis.client.api.ObjectType;
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.enums.BindingType;

public class TestCmis {

 private static String serverURL = "http://localhost:8080/chemistry-opencmis-server-inmemory-1.1.0/browser";
 private static String repositoryId = "A1";

 public static Session getSession() {
  Map<String, String> parameters = new HashMap<>();
  parameters.put(SessionParameter.BINDING_TYPE, BindingType.BROWSER.value());

  parameters.put(SessionParameter.USER, "");
  parameters.put(SessionParameter.PASSWORD, "");

  parameters.put(SessionParameter.REPOSITORY_ID, repositoryId);
  parameters.put(SessionParameter.BROWSER_URL, serverURL);

  SessionFactory sessionFactory = SessionFactoryImpl.newInstance();
  return sessionFactory.createSession(parameters);
 }

 public static void main(String args[]) throws IOException {
  Session session = getSession();

  Folder folder = session.getRootFolder();
  ObjectType objectType = folder.getType();

  boolean canCreate = objectType.getTypeMutability().canCreate();
  boolean canDelete = objectType.getTypeMutability().canDelete();
  boolean canUpdate = objectType.getTypeMutability().canUpdate();

  System.out.println("canCreate : " + canCreate);
  System.out.println("canDelete : " + canDelete);
  System.out.println("canUpdate : " + canUpdate);
 }
}


Output
canCreate : true
canDelete : false
canUpdate : false

Above output tells that, we can create sub type  to the folder type, but we can’t update and delete it.

From CMIS specification 1.1, following are the common attributes for all the types.

id
localName
localNamespace
queryName
displayName
baseId
parentId
description
created
fileable
queryable
controlleablePolicy
controlleableACL
fulltextIndexed
includedInSupertypeQuery
typeMutability.create
typeMutability.update
typeMutability.delete

While creating the new type, you need to set the values for above attributes. But depends on the repository, you may not be able to set the values to some of the above attributes.

By calling the method 'getNewTypeSettableAttributes' of repositoryInfo, you can able to know, what all properties you can able to set.

Example
NewTypeSettableAttributes settableAttributes = session.getRepositoryInfo().getCapabilities().getNewTypeSettableAttributes();


TestCmis.java
package com.sample.util;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

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.NewTypeSettableAttributes;
import org.apache.chemistry.opencmis.commons.enums.BindingType;

public class TestCmis {

 private static String serverURL = "http://localhost:8080/chemistry-opencmis-server-inmemory-1.1.0/browser";
 private static String repositoryId = "A1";

 public static Session getSession() {
  Map<String, String> parameters = new HashMap<>();
  parameters.put(SessionParameter.BINDING_TYPE, BindingType.BROWSER.value());

  parameters.put(SessionParameter.USER, "");
  parameters.put(SessionParameter.PASSWORD, "");

  parameters.put(SessionParameter.REPOSITORY_ID, repositoryId);
  parameters.put(SessionParameter.BROWSER_URL, serverURL);

  SessionFactory sessionFactory = SessionFactoryImpl.newInstance();
  return sessionFactory.createSession(parameters);
 }

 public static void main(String args[]) throws IOException {
  Session session = getSession();

  NewTypeSettableAttributes settableAttributes = session.getRepositoryInfo().getCapabilities()
    .getNewTypeSettableAttributes();

  boolean canSetControllableAcl = settableAttributes.canSetControllableAcl();
  boolean canSetControllablePolicy = settableAttributes.canSetControllablePolicy();
  boolean canSetCreatable = settableAttributes.canSetCreatable();
  boolean canSetDescription = settableAttributes.canSetDescription();
  boolean canSetDisplayName = settableAttributes.canSetDisplayName();
  boolean canSetFileable = settableAttributes.canSetFileable();
  boolean canSetFulltextIndexed = settableAttributes.canSetFulltextIndexed();
  boolean canSetId = settableAttributes.canSetId();
  boolean canSetIncludedInSupertypeQuery = settableAttributes.canSetIncludedInSupertypeQuery();
  boolean canSetLocalName = settableAttributes.canSetLocalName();
  boolean canSetLocalNamespace = settableAttributes.canSetLocalNamespace();
  boolean canSetQueryable = settableAttributes.canSetQueryable();
  boolean canSetQueryName = settableAttributes.canSetQueryName();

  System.out.println("canSetControllableAcl : " + canSetControllableAcl);
  System.out.println("canSetControllablePolicy : " + canSetControllablePolicy);
  System.out.println("canSetCreatable : " + canSetCreatable);
  System.out.println("canSetDescription : " + canSetDescription);
  System.out.println("canSetDisplayName : " + canSetDisplayName);
  System.out.println("canSetFileable : " + canSetFileable);
  System.out.println("canSetFulltextIndexed : " + canSetFulltextIndexed);
  System.out.println("canSetId : " + canSetId);
  System.out.println("canSetIncludedInSupertypeQuery : " + canSetIncludedInSupertypeQuery);
  System.out.println("canSetLocalName : " + canSetLocalName);
  System.out.println("canSetLocalNamespace : " + canSetLocalNamespace);
  System.out.println("canSetQueryable : " + canSetQueryable);
  System.out.println("canSetQueryName : " + canSetQueryName);
 }
}


Output
canSetControllableAcl : false
canSetControllablePolicy : false
canSetCreatable : true
canSetDescription : true
canSetDisplayName : true
canSetFileable : false
canSetFulltextIndexed : false
canSetId : true
canSetIncludedInSupertypeQuery : false
canSetLocalName : true
canSetLocalNamespace : true
canSetQueryable : false
canSetQueryName : true

Constraints while creating property types
 While creating new type, you need to add property definition to every property of this new type. The type attribute of the property can be one of 8 cmis predefined data types.

openCMIS 'org.apache.chemistry.opencmis.commons.enums.PropertyType' enum defined all the 8 property data types supported by CMIS.

public enum PropertyType {

    BOOLEAN("boolean"), ID("id"), INTEGER("integer"), DATETIME("datetime"), DECIMAL("decimal"), HTML("html"), STRING("string"), URI("uri");

}                        

Not all the repository allows you to create property of all types. Some repositories may restrict to create properties of specific data types.

By using following statement, you can get all the creatable property types supported by the repository.
session.getRepositoryInfo().getCapabilities().getCreatablePropertyTypes();


TestCmis.java
package com.sample.util;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

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.CreatablePropertyTypes;
import org.apache.chemistry.opencmis.commons.enums.BindingType;
import org.apache.chemistry.opencmis.commons.enums.PropertyType;

public class TestCmis {

 private static String serverURL = "http://localhost:8080/chemistry-opencmis-server-inmemory-1.1.0/browser";
 private static String repositoryId = "A1";

 public static Session getSession() {
  Map<String, String> parameters = new HashMap<>();
  parameters.put(SessionParameter.BINDING_TYPE, BindingType.BROWSER.value());

  parameters.put(SessionParameter.USER, "");
  parameters.put(SessionParameter.PASSWORD, "");

  parameters.put(SessionParameter.REPOSITORY_ID, repositoryId);
  parameters.put(SessionParameter.BROWSER_URL, serverURL);

  SessionFactory sessionFactory = SessionFactoryImpl.newInstance();
  return sessionFactory.createSession(parameters);
 }

 public static void main(String args[]) throws IOException {
  Session session = getSession();

  CreatablePropertyTypes creatablePropertyTypes = session.getRepositoryInfo().getCapabilities()
    .getCreatablePropertyTypes();

  Set<PropertyType> propTypes = creatablePropertyTypes.canCreate();

  for (PropertyType prop : propTypes) {
   System.out.println(prop);
  }

 }
}


Output
BOOLEAN
ID
INTEGER
DATETIME
DECIMAL
HTML
STRING
URI


Notify above output, it is confirmed that in memory repository supports all the predefined data types usage in custom object types.

Create Custom Object Type
Now it is time to create custom object type by extending existing object types. Best way to define new custom types is, export the existing type definition as xml (or) json and update this xml (or) json as per our need and create new type using the updated json.

Let’s try to create new folder type.

Export existing folder type to json file

Go to CMIS work bench -> Click on Types


Select Folder(cmis:folder) and click the button ‘Save Type Definition’.


Select the option ‘Save Type Definition to JSON’.


cmis_folder.json
{
 "id": "cmis:folder",
 "localName": "cmis:folder",
 "localNamespace": "http:\/\/apache.org",
 "displayName": "Folder",
 "queryName": "cmis:folder",
 "description": "Folder",
 "baseId": "cmis:folder",
 "creatable": true,
 "fileable": true,
 "queryable": true,
 "fulltextIndexed": false,
 "includedInSupertypeQuery": true,
 "controllablePolicy": true,
 "controllableACL": true,
 "typeMutability": {
  "create": true,
  "update": false,
  "delete": false
 },
 "propertyDefinitions": {
  "cmis:name": {
   "id": "cmis:name",
   "localName": "cmis:name",
   "displayName": "Name",
   "queryName": "cmis:name",
   "description": "Name",
   "propertyType": "string",
   "cardinality": "single",
   "updatability": "readwrite",
   "inherited": false,
   "required": true,
   "queryable": true,
   "orderable": true
  },
  "cmis:description": {
   "id": "cmis:description",
   "localName": "cmis:description",
   "displayName": "Description",
   "queryName": "cmis:description",
   "description": "Description",
   "propertyType": "string",
   "cardinality": "single",
   "updatability": "readwrite",
   "inherited": false,
   "required": false,
   "queryable": false,
   "orderable": false
  },
  "cmis:objectId": {
   "id": "cmis:objectId",
   "localName": "cmis:objectId",
   "displayName": "Object Id",
   "queryName": "cmis:objectId",
   "description": "Object Id",
   "propertyType": "id",
   "cardinality": "single",
   "updatability": "readonly",
   "inherited": false,
   "required": false,
   "queryable": true,
   "orderable": false
  },
  "cmis:baseTypeId": {
   "id": "cmis:baseTypeId",
   "localName": "cmis:baseTypeId",
   "displayName": "Base Type Id",
   "queryName": "cmis:baseTypeId",
   "description": "Base Type Id",
   "propertyType": "id",
   "cardinality": "single",
   "updatability": "readonly",
   "inherited": false,
   "required": false,
   "queryable": true,
   "orderable": false
  },
  "cmis:objectTypeId": {
   "id": "cmis:objectTypeId",
   "localName": "cmis:objectTypeId",
   "displayName": "Object Type Id",
   "queryName": "cmis:objectTypeId",
   "description": "Object Type Id",
   "propertyType": "id",
   "cardinality": "single",
   "updatability": "oncreate",
   "inherited": false,
   "required": true,
   "queryable": true,
   "orderable": false
  },
  "cmis:secondaryObjectTypeIds": {
   "defaultValue": [],
   "id": "cmis:secondaryObjectTypeIds",
   "localName": "cmis:secondaryObjectTypeIds",
   "displayName": "Secondary Type Ids",
   "queryName": "cmis:secondaryObjectTypeIds",
   "description": "Secondary Type Ids",
   "propertyType": "id",
   "cardinality": "multi",
   "updatability": "readwrite",
   "inherited": false,
   "required": false,
   "queryable": true,
   "orderable": false
  },
  "cmis:createdBy": {
   "id": "cmis:createdBy",
   "localName": "cmis:createdBy",
   "displayName": "Created By",
   "queryName": "cmis:createdBy",
   "description": "Created By",
   "propertyType": "string",
   "cardinality": "single",
   "updatability": "readonly",
   "inherited": false,
   "required": false,
   "queryable": true,
   "orderable": true
  },
  "cmis:creationDate": {
   "id": "cmis:creationDate",
   "localName": "cmis:creationDate",
   "displayName": "Creation Date",
   "queryName": "cmis:creationDate",
   "description": "Creation Date",
   "propertyType": "datetime",
   "cardinality": "single",
   "updatability": "readonly",
   "inherited": false,
   "required": false,
   "queryable": true,
   "orderable": true
  },
  "cmis:lastModifiedBy": {
   "id": "cmis:lastModifiedBy",
   "localName": "cmis:lastModifiedBy",
   "displayName": "Last Modified By",
   "queryName": "cmis:lastModifiedBy",
   "description": "Last Modified By",
   "propertyType": "string",
   "cardinality": "single",
   "updatability": "readonly",
   "inherited": false,
   "required": false,
   "queryable": true,
   "orderable": true
  },
  "cmis:lastModificationDate": {
   "id": "cmis:lastModificationDate",
   "localName": "cmis:lastModificationDate",
   "displayName": "Last Modification Date",
   "queryName": "cmis:lastModificationDate",
   "description": "Last Modification Date",
   "propertyType": "datetime",
   "cardinality": "single",
   "updatability": "readonly",
   "inherited": false,
   "required": false,
   "queryable": true,
   "orderable": true
  },
  "cmis:changeToken": {
   "id": "cmis:changeToken",
   "localName": "cmis:changeToken",
   "displayName": "Change Token",
   "queryName": "cmis:changeToken",
   "description": "Change Token",
   "propertyType": "string",
   "cardinality": "single",
   "updatability": "readonly",
   "inherited": false,
   "required": false,
   "queryable": false,
   "orderable": false
  },
  "cmis:parentId": {
   "id": "cmis:parentId",
   "localName": "cmis:parentId",
   "displayName": "Parent Id",
   "queryName": "cmis:parentId",
   "description": "Parent Id",
   "propertyType": "id",
   "cardinality": "single",
   "updatability": "readonly",
   "inherited": false,
   "required": false,
   "queryable": false,
   "orderable": false
  },
  "cmis:path": {
   "id": "cmis:path",
   "localName": "cmis:path",
   "displayName": "Path",
   "queryName": "cmis:path",
   "description": "Path",
   "propertyType": "string",
   "cardinality": "single",
   "updatability": "readonly",
   "inherited": false,
   "required": false,
   "queryable": false,
   "orderable": false
  },
  "cmis:allowedChildObjectTypeIds": {
   "defaultValue": [],
   "id": "cmis:allowedChildObjectTypeIds",
   "localName": "cmis:allowedChildObjectTypeIds",
   "displayName": "Allowed Child Object Type Ids",
   "queryName": "cmis:allowedChildObjectTypeIds",
   "description": "Allowed Child Object Type Ids",
   "propertyType": "id",
   "cardinality": "multi",
   "updatability": "readonly",
   "inherited": false,
   "required": false,
   "queryable": false,
   "orderable": false
  }
 }
}

Now update the above json file as per your needs.

For example, I updated like below.


cmis_myOrgFolder.json
{
 "id": "myOrgFolder",
 "localName": "myOrg:folder",
 "localName": "myOrg:folder",
 "localNamespace": "local",
 "displayName": "OrganizationSpecificFolder",
 "queryName": "myOrg:folder",
 "description": "Organization SpecificFolder",
 "baseId": "cmis:folder",
 "creatable": true,
 "fileable": true,
 "queryable": true,
 "fulltextIndexed": false,
 "includedInSupertypeQuery": true,
 "controllablePolicy": true,
 "controllableACL": true,
 "parentId": "cmis:folder",
 "typeMutability": {
  "create": true,
  "update": false,
  "delete": false
 }
 "propertyDefinitions": {
  "organization:name": {
   "id": "organization:name",
   "localName": "organization:name",
   "displayName": "OrganizationDisplayName",
   "queryName": "organization:name",
   "description": "Organization specific name",
   "propertyType": "string",
   "cardinality": "single",
   "updatability": "readwrite",
   "inherited": false,
   "required": true,
   "queryable": true,
   "orderable": true
  }
 }

}

Create new type using above json file

Go to workbench and Click on the button ‘Types’.

Click on ‘Create Type’ -> Load Type Definition from JSON

Browse the json file and press ok. You can able to see new type in the ‘CMIS workbench’ window.


As you observe above screen shot, property definitions like ‘cmis:name’, ‘cmis:description’ are inherited from parent type. Here parent type is ‘cmis:folder’.

How to delete a type?
Right click on the type and press ‘Delete Type’.

Previous                                                 Next                                                 Home

No comments:

Post a Comment