Hi David,
I'm a bit confused by some of the vocabulary I must confess. Could we
make sure we don't confuse the term "cache" and the term "transient
space", as they have different uses.
So do you want to remove completely any transient space and only have
methods that write to the remote side on each method call? So, do you
want to remove the fact that we can do:
object.setProperty("foo1", "bar1");
object.setProperty("foo2", "bar2");
...
object.updateProperties();
i.e. today there's a mini transient space tied to the properties of
the object, flushed on updateProperties. I think this is quite useful
as it avoids having the user building a map by hand and passing it to
updateProperties, which is ugly for a high-level interface.
I'm ok with most methods that can do remote writes returning a CmisObject.
But I don't like removing convenience methods on CmisObject like
getRelationships, getAcl, etc. as they provide convenient access to
the users.
OTOH I'm completely for clarifying the caching aspects, for instance
it's not clear today when caches are invalidated or updated, or what
happens when you ask for a property that's not in the initial property
filter that led to the creation of the object (in a number of my unit
tests in Nuxeo I have to refresh() explicitly but this shouldn't be
needed when all the writes were mine).
Florent
On Tue, Oct 12, 2010 at 12:49 PM, David Caruana
<[email protected]> wrote:
> 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
--
Florent Guillaume, Director of R&D, Nuxeo
Open Source, Java EE based, Enterprise Content Management (ECM)
http://www.nuxeo.com http://www.nuxeo.org +33 1 40 33 79 87