Wednesday, March 2, 2011

Updates to Alfresco Aspect Properties using CMIS (Part 2)

This is a follow-up to my previous post about how to update aspect properties on documents using CMIS in Alfresco. In the earlier post I provided a bit of a hack that permits aspect-defined properties to be updated just like regular document properties -- with no changes to the atom entry sent by CMIS to the server.  I should say that this hack is frowned on because Alfresco is purposely disabling support for aspects in their implementation of the CMIS API.

The reason why aspects are disabled is because Alfresco wants to comply totally with the CMIS 1.0 standard, and that first version of the standard does not provide support for aspects. Actually, the possibility of adding support for aspects in CMIS has been a topic of discussion on the Alfresco forums for some time.

The interim solution for getting at aspect properties using CMIS is to use custom Alfresco CMIS extensions.  But any code you write using an Alfresco extension of course will not work with any other CMIS repository.  Using an extension seems to defeat the purpose of the 'write once, deploy against any repository' selling point for CMIS, but the alternative is to introduce hacks that allows Alfresco CMIS to recognize aspect properties as regular properties, which isn't pretty either.

A page on the Alfresco website describes how CMIS extensions can enable the handling of aspects:

CMIS extensions are XML fragments placed in different parts of a CMIS object. The Alfresco aspect fragments are documented on the Alfresco Wiki. So, theoretically, they are available to all CMIS clients out there including OpenCMIS.
In reality, dealing with CMIS extensions isn't fun and can require quite a lot of code. OpenCMIS does all the XML parsing for you but, since it doesn't know anything about aspects, it can't provide pretty interfaces.

For example, when properties are updated using CMIS against an Alfresco repository, properties need to be partitioned between those properties that are related to aspects and those that aren't.  This is done by using Alfresco-specific extension tags as shown in bold in the atom entry below.  In this example, the first property cmis:name is not included within the Alfresco tags, while aspect properties edm:program_project and cm:author are.  These extension tags enable the partitioning out of aspect properties.

<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/" 
       xmlns:alf="http://www.alfresco.org">
<title>2d_house_plan.dwg</title>
<cmisra:object>
<cmis:properties>
<cmis:propertyString propertyDefinitionId="cmis:name" queryName="cmis:name"><cmis:value>My CAD Drawing</cmis:value></cmis:propertyString>
<alf:setAspects>
<alf:properties>
<cmis:propertyString propertyDefinitionId="edm:program_project" queryName="edm:program_project"><cmis:value>Big Project</cmis:value></cmis:propertyString>
<cmis:propertyString propertyDefinitionId="cm:author" queryName="cm:author"><cmis:value>admin</cmis:value></cmis:propertyString>
</alf:properties>
</alf:setAspects>
</cmis:properties>
</cmisra:object>
</entry>