Also consider that modifying a list produces notifications and the
handling of those notifications could invoke arbitrary and long running
This does raise a use case that may need support from within the
framework: the ability for eAdapters to create a CopyOnWriteArrayList type
structure. The EAdapterList implementation comes part way by calling
ensureSafety on each modification to create the new copy on write, however
ensureSafety itself is not thread-safe.
When you say this should be solved at the "application level", are there
are any patterns for this? I expect that CDO must do something under the
covers, but a general approach would be good.
One pattern I've seen used in WTP (although the thread-safety benefits are
not fully exploited) is force writers to implement a Runnable rather than
call setters directly. Using commands and a thread-safe command stack a
la the EMF transaction framework is a similar pattern.
However, this leaves the question of what to do with readers. It also
opens the question of how to restrict the generated model so that users
are forced to use commands to do writes.
Some questions:
1) Is there a way to generate a model with setters suppressed on the
interface? When I use the suppressedSetVisibility genmodel annotation,
this solves part of the problem by hiding the setter, however the
reflective set is presumably still available off the interface since I'm
still extending EObject. I still want some of the EObject interface since
I want add model listeners through eAdapters().add().
2) Is there a way to generate immutable value objects? This seems
trickier, since the factory methods don't take arguments (unless there's a
way I haven't seen to generate this). A useful pattern would be to
somehow add arguments to the factory methods when setters are suppressed.
Perhaps a type-safe composite of Setting delegates could be generated for
each such EObject.