Mixin / Aspect Support
Some of the systems in CMIS support additional / attachable metadata as Mixins or Aspects. This includes EMC Documentum, Alfresco and JCR. It is sometimes necessary to access, update and query this metadata. The mixins/aspects may be automatically available, but it may be necessary to apply these metadata attachments. Within the context of the preliminary CMIS proposal, how is possible to use and access these mixins. (Note: I may use mixin and aspect interchangeably. Although they are not quite the same thing, they are close enough for this discussion.)
From the IBM description of JCR in http://www.ibm.com/developerworks/java/library/j-jcr/, here is the following description of mixin:
Every node has one and only one primary node type. A primary node type defines the characteristics of the node, such as the properties and child nodes that the node is allowed to have. In addition to the primary node type, a node may also have one or more mixin types. A mixin type acts a lot like a decorator, providing extra characteristics to a node. A JCR implementation, in particular, can provide three predefined mixin types:
mix:versionable: allows a node to support versioning
mix:lockable: enables locking capabilities for a node
mix:referenceable: provides an auto-created jcr:uuid property that gives the node a unique, referenceable identifier
From Wikipedia http://en.wikipedia.org/wiki/Mixin:
A mixin is a class that provides a certain functionality to be inherited by a subclass, but is not meant to stand alone. Inheriting from a mixin is not a form of specialization but is rather a means to collect functionality.
From the JCR spec:
General background on types and mixins: http://www.day.com/specs/jcr/1.0/6.7.4_Primary_and_Mixin_Node_Types.html.
More on mixin usage (search for 'mixin'): http://www.day.com/specs/jcr/1.0/.
- Optional Functionality. As in the case of JCR above, functionality may be optionally attached to an object, such as versioning, therefore any metadata associated with versioning would be part of the mixin. Therefore, versioning in these systems would not be possible without access to the appropriate mixins. Systems that don't have mixins would just automatically include this information as part of their types. Record management / disposition is another example of optional functionality attached to content.
- Avoiding Multiple Inheritence. Systems that provide only single inheritence can avoid multiple inheritence by applying common information as part of aspects or mixins. For instance, a type hierarchy may be modeled based upon a departmental structure (e.g. sales, marketing, management), but need to have content type information such as resolution for images or security for PDF. Adding more dimensions of properties and types in a single hierarchy explodes the number of types.
- Adding behavior. Some systems add behavior by adding declarative metadata to content with the metadata determining the functions to be performed. For example, adding life cycle information as part of an aspect could actually define and execute the life cycle.
- Get / Set properties that are not defined by a primary type, but are defined by an attached mixin / aspect. Example:
- Query properties that are defined in a mixin and return a target list that includes both primary type and mixin / aspect properties
- Mechanism to set and remove aspects (although these may be automatically added by default, in the background, by other processes or actions)
There are two approaches to take to mixins. JCR makes them an integral part of the model and it is up to the underlying implementation to expose them as necessary. If an underlying system does not support aspects, then the core types just include the extended metadata and logic is required whether to expose this extended metadata.
The other approach is to extend the model to the minimum amount necessary to make mixins usable. This would define existing CMIS behavior in the presence of a mixin. If there is no way around exposing that a mixin does exist, only then add that mechanism.
Most of the CMS systems participating in CMIS support mixins, therefore the latter approach seems to make the most sense.
Get / Set Mixin Properties
If an object has a mixin attached, then get / set should work as it would normally. The mixin must not have a name conflict with the base type of the object. These properties would not be defined by the base type, but the properties are still addressable on the object.
Query Mixin Properties
It may be possible to support queries against mixin properties without any special mechanism, except that mixin properties are just assumed as part of the base types. However, it would be possible to bridge Mixin and Non-mixin implementations by assuming that Mixins are types that can be joined against the base types through an equijoin on their common ids.
Ideally, aspects or mixins would be a separate type from documents or folders. They have no content and they have no children as folders do. Ideally, mixins should be their own type off the base type, so this would be an addition to the core specification.
Adding / Removing Mixins
There is no mechanism to add or remove mixins. However, the add / remove policy could be used to add or remove mixins from objects. Non-mixin systems could just ignore these directives. It would be helpful to add a policy type to the parameters of the policy mechanism.
The following are possible implementations discussed between John Newton and David Caruana.
Pool of properties
This is a list of properties that may be associated with an object. They are not necessarily part of the type, but are available and accessible to any object. They can be considered a set of optional properties that may be associated with a supertype. Some examples might be records properties, process information or media type information, such as photo or image informtion.
- Simple - easy to implement
- Maps to Sharepoint
- Can map existing Aspect systems to optional properties
- Messy - no structure or discoverability of properties
- No organization of aspects - if there are aspects, it would be difficult to detect
- Limited usability beyond a few aspects - would need to be pre-defined
- How do you handle Optional mandatory properties?
Separate Object (different ID?) connected with association
This would model the aspect as a separate object, perhaps with a different ID, and is connected to the base type with an association. This association may be synthesized if there is an aspect underneath the implementation. It also allows for extended properties to be implemented as actual separate objects if this is the way it is implemented.
- Works with current model - no extensions required
- Query model works easily - this follows the existing query language
- Need to create Aspect object after creating object - could have hidden consequences
- If Aspects are actually implemented, this would be difficult to model as separate objects
- Query complex with full join and artificial Aspect association - would need to have an explicit association for aspect association
- Need constraint to avoid reuse/linking Aspect - Aspects should be specific to only one object at a time.
- Need filters on Type discovery to filter Aspects - separate them from core types
Aspects as Children of Object
This model would have aspects modeled as children similar to items in a folder. Although there is no mechanism existing specifically for aspects, but it would be very similar to the pattern established for folders and children. It also allows several objects attached.
- Add / Remove similar to folder - take advantage of patterns established with folders
- Navigation patterns similar to folder
- Works with current model - no major changes needed to the model, just additional APIs similar to folder APIs
- Query is complex (use in Folder? search aspect props?) - How do you query against Aspect properties and have the parents returned?
- New constraints required like Separate Object to avoid reuse
- New folder-like hierarchy
- ID handling can be messy - Separate IDs for aspects?
- What happens on create? Implicit creation of Aspect children?
- Need filters on Type discovery to filter Aspects as in the associated separate objects
New type with no separate ID with implicit assoc.
Separate object has a foreign key with the ID of the core object that links the separate object to the core object. If the implementation actually has aspects, then it would be able to provide the join mechanism. If the implementation is separate objects, then it can still map as long as an association can be mapped to a foreign key in the aspect object.
- Simple model - Just looks like two objects joined on a foreign key
- No artificial assocs. - If there are no associations, then none need to be synthesized
- Query is simple - Join two objects on foreign key
- Handles properties well - refer to separate object and update properties
- Requires new type - Aspect
- Mapping not easy to systems that implement aspects as just a pool of properties or as a separate object with an association
- Add / Remove need to be defined (like Policies)