Currently, we only have one implementation of Session - PersistentSessionImpl. 
However, the OpenCMIS client API suggests transient behaviour both in its API 
definition and behaviour, which I believe can be confusing for users. In 
particular, when does OpenCMIS read information from the cache vs from the 
repository, and when does OpenCMIS implicitly update an item in its cache.

I'd like to present the following changes in an attempt to clarify the above 
and trigger discussion on how to improve things in this area...

1) All methods on CmisObject operate against the cache. This means that reading 
a value from an item reads the value from the item in the cache, and updates to 
the item change the cache i.e. refresh the item in the cache. Methods that read 
directly from the repository move to Session. So, the proposal is:

Remove the following from CmisObject...
CmisObject.setName(String)      
CmisObject.setProperty(String, Object)    
CmisObject.updateProperties()

Change CmisObject.updateProperties...
CmisObject CmisObject.updateProperties(Map<String, ?>)    (Note: return 
CmisObject instead of ObjectId)

Note: If the repository creates a new version, a new CmisObject is returned, 
otherwise the existing CmisObject is refreshed in the cache and returned.

The following 'update' methods are also modified to refresh the item in the 
cache after update:

void CmisObject.applyPolicy(ObjectId...)    (Note: accept vararg of policy ids)
void CmisObject.removePolicy(ObjectId...)   (Note: accept vararg of policy ids)
Acl CmisObject.applyAcl(List<Ace>, List<Ace>, AclPropagation)
Acl CmisObject.addAcl(List<Ace>, AclPropagation)   (Note: also return Acl to be 
consistent with applyAcl)
Acl CmisObject.removeAcl(List<Ace>, AclPropagation)   (Note: also return Acl to 
be consistent with applyAcl)

Note: applyPolicy and removePolicy are also changed to accept a vararg of 
ObjectIds.

For use cases where the refresh of an item after update is not necessary, the 
Session interface is used instead. So, the proposal is...

Move following methods from CmisObject to Session...

ItemIterable<Relationship> Session.getRelationships(ObjectId, boolean, 
RelationshipDirection, ObjectType, OperationContext)
Acl Session.getAcl(ObjectId, boolean)

Add...

ObjectId Session.updateProperties(ObjectId, Map<String, ?>)
void applyPolicy(ObjectId, ObjectId...)
void removePolicy(ObjectId, ObjectId...)
Acl applyAcl(ObjectId, List<Ace> addAces, List<Ace> removeAces, AclPropagation 
aclPropagation)
Acl getAcl(ObjectId, boolean onlyBasicPermissions)

2) Following the pattern in 1), setting content on a Document alters slightly 
too.

Document setContentStream(ContentStream contentStream, boolean overwrite)
Document deleteContentStream()

Instead of returning ObjectId, the proposal is to return Document. Depending on 
the repository, the document may be the same item as before (updated in the 
cache), or a new Document, to represent a new version.

Also add to Session...

ObjectId setContentStream(ObjectId, ContentStream contentStream, boolean 
overwrite)
ObjectId deleteContentStream(ObjectId)

3) Remove transient methods from Session.

Until we've thought through transient session behaviour I propose we remove the 
following methods:

Session.save()
Session.cancel()

Regards,
Dave

Reply via email to