Last week I started building a CMIS browser with Adobe AIR.
I have built POCs with Flex before, but that was about it. Then, I downloaded thwirl and I remembered why I like AIR so much. It was easy to install, the UI is nice, and I imagine it was not too difficult to write. This is also a great example of why I like RESTful services too. I believe in the physical separation of the presentation tier, and working with RESTful services is a breeze. So is writing them for that matter. Twitter is a great example of building a social services platform and allowing for the development of third party applications to utilize it. It is a win, win situation. Perhaps ‘platform’ is the key word there. I’d like to shift from building web applications to building web platforms.
So, I decided to build a CMIS browser with AIR.
Update: The CMIS Explorer is now available for download. See this post.
I didn’t really have too many issues with the Flex/AIR side, but here are a few things that tripped me up.
I’ve now spent some quality time with CMIS. For the most part, things have gone smoothly. Here are a few things of note.
Don’t forget to set your content type when posting XML. When I was posting a query, I was not setting the content type to ‘application/cmisquery+xml’ and Alfresco was not happy about it. Once I did, it worked like a charm.
<cmis:repositoryInfo>
<cmis:repositoryId>9920fa2a-7a3c</cmis:repositoryId>
<cmis:repositoryName>Main Repository</cmis:repositoryName>
<cmis:repositoryRelationship>self</cmis:repositoryRelationship>
<cmis:capabilities>
<cmis:capabilityMultifiling>true</cmis:capabilityMultifiling>
<cmis:capabilityUnfiling>false</cmis:capabilityUnfiling>
</cmis:capabilities>
</cmis:repositoryInfo>
I think this is a little too rigid. I don’t like that every property/capability is a unique element. I’m also not too happy to see the capabilities in the form of a complex property. All of this can make the client code a little more complex and a little more difficult to maintain than it needs to be.
I’d prefer something along these lines…
<cmis:repositoryInfo>
<cmis:properties>
<cmis:property type="id">9920fa2a-7a3c</cmis:property>
<cmis:property type="name">Main Repository</cmis:property>
<cmis:property type="relationship">self</cmis:property>
</cmis:properties>
<cmis:capabilities>
<cmis:capability type="multifiling">true</cmis:capability>
<cmis:capability type="unfiling">false</cmis:capability>
</cmis:capabilities>
</cmis:repositoryInfo>
I think a schema like this would be much more flexible. Perhaps it is because I’m using E4X.
<cmis:object>
<cmis:properties>
<cmis:propertyId cmis:name="ObjectId">
<cmis:value>workspace://SpacesStore/a0e6612b-9771</cmis:value>
</cmis:propertyId>
<cmis:propertyString cmis:name="BaseType">
<cmis:value>document</cmis:value>
</cmis:propertyString>
<cmis:propertyDateTime cmis:name="CreationDate">
<cmis:value>2009-01-20T14:23:27.867-06:00</cmis:value>
</cmis:propertyDateTime>
<cmis:propertyBoolean cmis:name="IsImmutable">
<cmis:value>false</cmis:value>
</cmis:propertyBoolean>
<cmis:propertyInteger cmis:name="ContentStreamLength">
<cmis:value>0</cmis:value>
</cmis:propertyInteger>
</cmis:properties>
</cmis:object>
And again, I’d rather seem something along these lines.
<cmis:object>
<cmis:properties>
<cmis:property type="id" cmis:name="ObjectId">
<cmis:value>workspace://SpacesStore/a0e6612b-9771</cmis:value>
</cmis:propertyId>
<cmis:property type="string" cmis:name="BaseType">
<cmis:value>document</cmis:value>
</cmis:propertyString>
<cmis:property type="dateTime" cmis:name="CreationDate">
<cmis:value>2009-01-20T14:23:27.867-06:00</cmis:value>
</cmis:propertyDateTime>
<cmis:property type="boolean" cmis:name="IsImmutable">
<cmis:value>false</cmis:value>
</cmis:propertyBoolean>
<cmis:property type="integer" cmis:name="ContentStreamLength">
<cmis:value>0</cmis:value>
</cmis:propertyInteger>
</cmis:properties>
</cmis:object>
Next up is the fact that the getChildren service returns every single property for all of the objects returned by default. I guess this is both good and bad. It can be good if you expect to display the properties of a majority of the objects, or if you want to reduce the number of requests. However, it makes the response quite large. I think I’d rather not have any of the properties returned by default. There does appear to be the option of using a filter. I need to explore this some more. Perhaps I’d have liked the opposite. Rather than having to specify a filter, I’d prefer to specify the properties returned.
I’m a little bit uncertain about having to post XML and use a specific content type in order to search a repository via CMIS. I suppose I’d rather see it done with URL path and query parameters. I’m also wondering if a full blow query language is really in order here. It seems a bit overkill.
Hats off to Alfresco for helping bring about CMIS and delivering the first implementation. I’ve actually worked in an enterprise where SharePoint was used for project collaboration, Alfresco for document management, and Day Communique for web content management. I bet I could have made use of CMIS there if it was around at the time. I found the CMIS specification easy to understand and the Alfresco implementation easy to use. I don’t really have any issues with the decision to use ATOM.
That being said…
| M | T | W | T | F | S | S |
|---|---|---|---|---|---|---|
| « Oct | ||||||
| 1 | 2 | 3 | 4 | 5 | ||
| 6 | 7 | 8 | 9 | 10 | 11 | 12 |
| 13 | 14 | 15 | 16 | 17 | 18 | 19 |
| 20 | 21 | 22 | 23 | 24 | 25 | 26 |
| 27 | 28 | 29 | 30 | |||
Exciting stuff, Shane.
I’m eager to see it…
Great post, Shane.
Are we including the CMIS Browser on the VMWare image we will be giving out at our Chicago Alfresco Code Camp next week?
Absolutely,
I’ll probably add it at the last minute though. I’m going to try to add a few more features to include uploading & downloading documents.
We may need some input from Sten though because it is definitely lacking in the creative design department and his stuff is always cool looking!
Even though I’m down with Flex, Sten has me thinking about JavaFX a lot now.
Great post. Thanks for sharing your experience and we are looking forward to the CityTech Codecamp next week in Chicago.
See you there!
I’m looking forward to the code camp. I just hope I can add a few more features in time. I think CMIS is going to play a large role moving forward.
[...] while back my colleague, Shane Johnson, blogged about a CMIS browser he had written using [...]
Im new to flex and cmis. trying to get it to work with CMIS for documentum. I get the following response
9103The security header is invalid: com.sun.xml.wss.XWSSecurityException: Message does not conform to configured policy [ AuthenticationTokenPolicy(S) ]: No Security Header found: Message does not conform to configured policy [ AuthenticationTokenPolicy(S) ]: No Security Header found
Can you gimme some pointers how I can resolve this. I could share the code also.
It might help to see the code. Here is what I can tell you off the bat though.
The flex-cmis-client (used by CMIS Explorer) talks to the repository via the ATOM services, and relies on HTTP basic authentication. While I don’t plan on supporting the web services implementation, I may have to add support for additional authentication methods.
Feel free to drop me an email, or post a message on the CMIS Explorer Google Group.
http://groups.google.com/group/cmis-explorer