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