Sunday, August 15, 2010

How to extend CMIS data model

By going through CMIS doc I got an impression that I should be able to create my custom object type by extending standard object type. That make sense, isn't it. My business model may have some specific data model and for that I should be able to extend standard data model provided by CMIS.

But now the question is how to achieve it? Do you think just adding a custom property.object type in the atom entry you send to create the document will server the purpose?

Let's try it using Open-CMIS client library.

Map parameter = new HashMap();

// connection settings
parameter.put(SessionParameter.ATOMPUB_URL, "http://localhost:8080/chemistry-opencmis-server-inmemory-0.2.0-incubating-SNAPSHOT/atom");
parameter.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
parameter.put(SessionParameter.REPOSITORY_ID, "A1");

Session s = f.createSession(parameter);
Map pMap = new HashMap();
pMap.put("cmis:objectTypeId", "IITLib");
pMap.put("cmis:name", "MyDoc");
s.createDocument(pMap, s.createObjectId(s.getRepositoryInfo().getRootFolderId()), null, null, null, null, null));

When I ran this I got following exception.
org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException: Not Found

That says CmisObject type "IITLib" doesn't exist. But how come my client knows whether this type exist in repository where I am trying to post the document.

Well client know this by analyzing response received for the request http://localhost:8080/chemistry-opencmis-server-inmemory-0.2.0-incubating-SNAPSHOT/atom/A1/type?id=IITLib submitted to the repository.

Client generates this URL by investigating service document uritemplate of type typebyid. I have added a snippet below taken from service document of CMIS in-memory repository.

<cmisra:uritemplate>
<cmisra:template>http://localhost:8080/chemistry-opencmis-server-inmemory-0.2.0-incubating-SNAPSHOT/atom/A1/type?id={id}
</cmisra:template>
<cmisra:type>typebyid</cmisra:type>
<cmisra:mediatype>application/atom+xml;type=entry</cmisra:mediatype>
</cmisra:uritemplate>

Why this is called in-memory repository? No prize for guessing! once you restart your repository all your stored documents will be gone. So it's good for testing and not meant for production.

We still have to find out on how to extend CMIS data model.

Different repositories have different mechanism using which you can extend CMIS data model.

Lets try with in-memory Open-CMIS repository. All you have to do to register your extension is implement org.apache.chemistry.opencmis.inmemory.TypeCreator interface. class org.apache.chemistry.opencmis.inmemory.types.DefaultTypeSystemCreator.java can be used as an example. To register my extension I have added following snippet in DefaultTypeSystemCreator.java file

InMemoryDocumentTypeDefinition rootDocType = new InMemoryDocumentTypeDefinition("MyLib",
"My Type 1 Level 1",InMemoryDocumentTypeDefinition.getRootDocumentType());
Map<String, PropertyDefinition<?>> propertyDefinitions1 = new HashMap<String, PropertyDefinition<?>>();
PropertyDefinition<Boolean> prop_1 = PropertyCreationHelper.createBooleanDefinition("Is_BelongTo_Shiv_Lib",
"Sample Boolean Property");
propertyDefinitions1.put(prop_1.getId(), prop_1);
rootDocType.setPropertyDefinitions(propertyDefinitions1);
typesList.add(rootDocType);

build the in-memory repository war with changes and deploy it in your favorite servlet container. Lets try to execute our earlier code to create document

Session s = f.createSession(parameter);
Map pMap = new HashMap();
pMap.put("cmis:objectTypeId", "IITLib");
pMap.put("cmis:name", "MyDoc");
pMap.put("Is_BelongTo_Shiv_Lib", true);
s.createDocument(pMap, s.createObjectId(s.getRepositoryInfo().getRootFolderId()), null, null, null, null, null));

You should be able to see newly created document in repository.

No comments:

Post a Comment