cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ben Pope <benpop...@gmail.com>
Subject Re: [CForms] Repeater: why not hashCode for id?
Date Wed, 30 Mar 2005 09:19:06 GMT
Sylvain Wallez wrote:
> Ben Pope wrote:
> 
>> Sylvain Wallez wrote:
>>
>>> No, no identity at all! Since you replay the add/move/delete events, 
>>> you just need to be able to remove/add items at specific positions. 
>>> That means that the underlying collection should be a java.util.list 
>>> or a dom Element.
>>>
>>> But actually this can be even simpler and we don't need this 
>>> record/replay thing :-)
>>>
>>> Have a look at the dynamic template sample [1] and play with 
>>> add/delete/move actions: each row has an ID which indicates the row's 
>>> creation order. In the case of binding, we won't use exactly use this 
>>> ID, but store in rows the position in the original collection as an 
>>> attribute (e.g. "load-position").
>>>
>>> When the repeater is saved, with this information it's easy to know 
>>> where and how to bind its rows:
>>> - if the "load-position" attribute exists, we bind to the 
>>> corresponding object in the original collection,
>>> - if the "load-position" attribute doesn't exist, that means the row 
>>> is newly created, and we therefore create a new object to save it.
>>>
>>> Row moves can be managed either by reordering the original collection 
>>> or by creating a new collection to which objects will be added.
>>>
>>> I like this more, and this has the potential to kill both the current 
>>> (complicated) repeater binding and also the simple-repeater binding 
>>> which becomes useless :-)
>>>
>>> Sylvain
>>>
>>> [1] http://localhost:8888/samples/blocks/forms/do-dynaRepeater.flow
>>
>>
>>
>> What if the underlying structure can have different (previous) rows 
>> removed from it between when you load the model and save it back?
>>
>> Obviously you would usually lock the back end model, but you should 
>> only need to lock the rows that you have retrieved, and deal with 
>> unique IDs in a common manner.
>>
>> If you're just playing back positions and actions over the model, then 
>> you prevent simultaneous access to the data.  Either that or you just 
>> push the complications into the users model.
>>
>> I suppose you could just tag old rows as dead, instead of removing 
>> them.  And then clean up when nothing is locked.
>>
>> Having the identity solved this problem.  Or have I missed something?
> 
> 
> 
> It all depends if you consider the repeater and the underlying 
> collection to be part of the application data model or just a 
> convenience container to show a set of independent objects to the user.
> 
> If it's a application-level collection, then the repeater should be 
> considered just the same as finer-grained objects and locked as a whole, 
> or checked for concurrent modification to prevent lost update if locking 
> isn't an option.

With the identity mapping, as it is now, it's possible to select a 
subset of the children contained within a node:

<fruits>
    <fruit id="0">
       <name>Apple</name>
       <colour>green</colour>
    </fruit>
    <fruit id="1">
       <name>Orange</name>
       <colour>orange</colour>
    </fruit>
    <fruit id="2">
       <name>Mango</name>
       <colour>orange</colour>
    </fruit>

<fb:reapeater parent-path="fruits" row-path="fruit[colour='orange']" 
row-path-insert="fruit">

So now I can modify orange fruits without locking apple (or any other 
non-orange fruit).  You could easily modify green fruit, as long as the 
id is being tracked.

If I start modifying orange fruit, then you start modifying green fruit 
by deleting apple, then I save the model back, obviously we have a 
problem as the positions are now off-by-one.  So unless the replaying 
can take into account simultaneous accesses, all of the ones that 
happend since the form was loaded (what if using hibernate!), we've lost 
functionality.

> If it's just a holder, then only individual rows are bound and saved to 
> the underlying storage. Modified rows lead to an update and new rows 
> lead to an insert. There is a problem though for deleted rows as the 
> repeater does not track rows that have been deleted (and the 
> corresponding IDs). But if the repeater is just a dumb container, 
> deletion can occur as soon as the users triggers the delete action.
> 
> Does this answer your concerns, or did I missed something also?

I'm concerned that functionality has been lost - perhaps it's bad 
practice to bind directly to the back end model.  Perhaps it should be 
discouraged in favour of having the user always deal with an 
intermediate layer which, for example, uses an identity.  So surely by 
simplifying the repeater, you're just pushing the complicated identity 
stuff to the user?

I know that the repeater is a complicated beast as I've been trying to 
modify it for my own purposes.  I'd love for there to be a much easier 
way of dealing with the binding, I just feel that using the identity is 
a very robust way of doing it and it's better to have it in the binding 
framework than the users code.

Thanks for your time,
Ben.

Mime
View raw message