Showing posts with label CMIS. Show all posts
Showing posts with label CMIS. Show all posts

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.

Sunday, July 18, 2010

Exploring CMIS: Adding folder and document in alfresco using Http Client

This blog assumes that reader has basic understanding of CMIS. This blog organization is as follows: It starts with creating a folder structure in alfresco CMIS repository using apache client and atom pub binding of repository. Then we will use different discovery services to enquire our newly created folders. Hope you will have good time learning this.
Lets jump in....

First we will start with the code to create a folder name shiv_lib in alfresco. Find below the http client code and sample post xml used.

File input = new File("C:\\Users\\shivendra\\workspace\\ApacheClient\\src\\PostData.xml");
PostMethod post = new PostMethod("http://cmis.alfresco.com/service/cmis/p/children");
RequestEntity entity = new FileRequestEntity(input, "application/atom+xml; charset=ISO-8859-1");
post.setRequestEntity(entity);
HttpClient httpclient = new HttpClient();
httpclient.getState().setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("admin", "admin")
);
try {
int result = httpclient.executeMethod(post);
// Display status code
System.out.println("Response status code: " + result);
System.out.println(post.getResponseBodyAsString());
} finally {
post.releaseConnection();
}

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:cmisra="http://docs.oasis-open.org/ns/cmis/restatom/200908/"
xmlns:cmis="http://docs.oasis-open.org/ns/cmis/core/200908/">
<title>Shiv_Lib</title>
<cmisra:object>
<cmis:properties>
<cmis:propertyId propertyDefinitionId="cmis:objectTypeId"><cmis:value>cmis:folder</cmis:value></cmis:propertyId>
</cmis:properties>
</cmisra:object>
</entry>

Notice the post method url(http://cmis.alfresco.com/service/cmis/p/children), since we haven't given any any path after p/{path} so this folder will be created on root folder. Newly created folder can be verified hitting http://cmis.alfresco.com/service/cmis/p/children in IE.

Now lets create some children folder inside this.All you have to do is change the post url and post xml as follows.

PostMethod post = new PostMethod("http://cmis.alfresco.com/service/cmis/p/Shiv_Lib/children");
<title>Meditation</title>
Hit http://cmis.alfresco.com/service/cmis/p/Shiv_Lib/children in IE and you will find out that Meditation folder is created inside Shiv_Lib.

Lets try putting some content in meditation folder. The only thing you have to take care here is cmis:objectTypeId will be cmis:document and the content need to added in document will go as base64 encoded and will be part of atom entry as follows.

<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:cmisra="http://docs.oasis-open.org/ns/cmis/restatom/200908/"
xmlns:cmis="http://docs.oasis-open.org/ns/cmis/core/200908/">
<title>Suggested Reading11</title>
<summary>Suggested Reading</summary>
<content type="text/plain">
MS4gR2l0YSAKIDIuIEthcm1heW9nYSBieSBWaXZla2FuYW5k
</content>
<cmisra:object>
<cmis:properties>
<cmis:propertyId propertyDefinitionId="cmis:objectTypeId"><cmis:value>cmis:document</cmis:value></cmis:propertyId>
</cmis:properties>
</cmisra:object>
</entry>


Since we want to create this in meditation folder so the URL will be: http://cmis.alfresco.com/service/cmis/p/Shiv_Lib/Meditation/children.

Once you run http client code with above changes, hit http://cmis.alfresco.com/service/cmis/p/shiv_lib/Meditation/children and you should be able to see document added. You can view content of document as plain text.

Next blog in this series I will cover CMIS query and discovery service.

Q and A

1. From where I get the AtomPub services URLs for alfresco.
The answer is alfresco list them at this http://cmis.alfresco.com/service/index/family/CMIS