Home » Modeling » EMF » [CDO] Notification disabled while instanciating objects from repo?
|
Re: [CDO] Notification disabled while instanciating objects from repo? [message #774639 is a reply to message #774303] |
Wed, 04 January 2012 10:23 |
|
Am 03.01.2012 17:58, schrieb Alexandre Borgoltz:
> Hi,
> I am migrating an existing EMF model from XML files to a CDO repo.
> I have migrated the .genmodel using CDO's migrator ("dynamic feature delegation").
>
> Everything's doing quite good so far. Except we are facing some "regression" in the behaviour of our model. The reason
> for that is that we have custom Adapters (listeners) attached to our model objects at constructor time.
> public MyModel() {
> super();
> eAdapters().add(new AdapterImpl() {
>
> @Override
> public void notifyChanged(Notification msg) {
> //do something when this is modified...
Although I don't know exactly what this "something" is, it strikes me that this is uncommon (maybe poor) design. Can't
you compute lazily instead?
> }
>
> });
> }
>
> The problem: these adapters are not notified while CDO is instanciating the object. Even if I override eDeliver() to
> force it to always return true.
>
> Technically, my adapters are not notified when the following code is executed
>
> session=...
> view=...
> resource=...
> MyModel myObject = (MyModel) resource.getContents().get(0);
> //until there no notification
No, because at this point the object is not logically modified.
>
>
> Yet of course, they are notified if I subsequentely call my model's setters and getters explicitely:
>
> //next line generate a notification
> myObject.setAttribute1(...);
>
>
> I must add that the behaviour is OK if I use the legacy mode - which calls my setters and triggers notifications,
> thanks to the overrinding of eDeliver().
That's not the intended usage and it may well corrupt certain aspects of CDO or CDO's legacy mode.
>
>
> My question: why doesn't CDO trigger notification when materializing the objects?
Because that's not considered a *change* of the logical object (with a well-defined long-term and multi-branch lifecycle).
> Analogously why is notification disabled then restored during e.g. LegacyCDOWrapper.revisionToInstance()?
For exactly the reason outlined above. CDO synchronizes the persistent lifecycle of a logical object with an in-memory
Java/EMF technical object. Adapters must only "see" the logical changes, that's why all resource implementations,
including CDO, turn off eDeliver during technical changes such as loading. We'd have to ask Martin about the legacy mode
but I guess it even relies on controlling eDeliver because it's based on adapters, too.
> What can I do to turn it on?
Not much, I fear. Maybe I'd have to understand your use case better to give advice for an alternative design.
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
>
>
>
>
> protected void revisionToInstance()
> {
> ...
>
> boolean deliver = instance.eDeliver();
> if (deliver)
> {
> instance.eSetDeliver(false);
> }
>
> ...
>
> }
> finally
> {
> if (deliver)
> {
> instance.eSetDeliver(true);
> }
>
> ...
> }
> }
>
>
> I thank you in advance for your answer!
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
| |
Re: [CDO] Notification disabled while instanciating objects from repo? [message #774792 is a reply to message #774639] |
Wed, 04 January 2012 16:18 |
Alexandre Borgoltz Messages: 31 Registered: July 2009 Location: France |
Member |
|
|
Hey Eike, thanks for your reply - I'll try to make myself understood a little bit better... Take a deep breath!
Eike Stepper wrote on Wed, 04 January 2012 11:23Am 03.01.2012 17:58, schrieb Alexandre Borgoltz:
> [...] we have custom Adapters (listeners) attached to our model objects at constructor time.
> public MyModel() {
> super();
> eAdapters().add(new AdapterImpl() {
>
> @Override
> public void notifyChanged(Notification msg) {
> //do something when this is modified...
Although I don't know exactly what this "something" is, it strikes me that this is uncommon (maybe poor) design. Can't
you compute lazily instead?
Hope my design isn't that poor - or that you will help enrich it a bit!
The reason for these adapters is that we have implemented derived features - and they're computed lazily actually.
And we want notifications fired for them, when the features they depend on are modified.
I just respected the official EMF Recipe called "Derived Attribute Notifier" - see /EMF/Recipes#Recipe:_Derived_Attribute_Notifier at wiki.eclipse.org
Eike Stepper wrote on Wed, 04 January 2012 11:23
> [...]
> The problem: these adapters are not notified while CDO is instanciating the object.
> [...]
No, because at this point the object is not logically modified.
I am unsure I understand what logically means. The fact is I did not consider that Adapters should be notified only for logical changes - and I am not sure the EMF Recipe I followed does neither.
Here's my -potentially wrong, and very humble- point of view:
My code somehow always looks like
EObject myModel = MyFrameWork.getAHoldOnMyModel(...);
And I see -at least- 3 differents ways of implementing the getAHoldOnMyModel() method.
- low-level, manual, based on EMF Factory + calls of setter methods
- using a "classical" resource (typically XML/XMI)
- using a CDO resource
Sample illustration of 1.
MyModel model1 = MyModel1Factory.createMyModel();
model1.setDummy("dummy");
model1.setDummy2("dummy too");
//...
Sample illustration of 2.
ResourceSet rs = new ResourceSetImpl();
Resource r = rs.createResource(xmlFileURI);
MyModel model1 = (MyModel) r.getContents().get(0);
Sample illustration of 3.
CDOSession session = ...;
CDOView view = session.openView();
Resource resource = view.getOrCreateResource("...");
MyModel model1 = (MyModel) resource.getContents().get(0);
So we have three different ways of getting an instance of our model, and I'd tend to beleive it would be quite enjoyable if these 3 ways were seamlessly interchangeable. Meaning that once you have your EObject instance, it should be seamless wether it comes from CDO or an XMIResource or whatever.
The fact is : "my" adapters are notified in methods 1. and 2. but not with 3. (CDO)... CDO is not seamless
Eike Stepper wrote on Wed, 04 January 2012 11:23
> [...]
> thanks to the overrinding of eDeliver().
That's not the intended usage and it may well corrupt certain aspects of CDO or CDO's legacy mode.
Yes, of course. It was just to underline that the legacy mode triggers notification but disables explicitely their delivery whereas native mode does not even trigger notifications. I was awaiting CDO to populate my model through the "classic" EMF way : setters or eSet, thus triggering notifications, even if disabling their delivery. The test I did by overriding eDeliver() shows it's not exactly the case...
Eike Stepper wrote on Wed, 04 January 2012 11:23
[...]Adapters must only "see" the logical changes, that's why all resource implementations,
including CDO, turn off eDeliver during technical changes such as loading.[...]
Well, as explained above, my tests show that XMLResourceImpl does notify my eAdapters during loading (cf below)!
Illustration: (I can provide you with the sources)
I have added a simple adapter in the constructor of my model. It throws a RuntimeException whenever it is notified - of course throwing the exception is just for the demo...:
public MyModelImpl() {
eAdapters().add(new AdapterImpl() {
@Override
public void notifyChanged(Notification msg) {
throw new RuntimeException("The Adapter was called");
}});
}
I then load an instance of MyModel using a standard XMI resource - see the following snippet : the exception is thrown, proving the adapter is notified during loading.
//The following code outputs "OK : The adapter was called".
//It would output "KO - Adapters not called" if there was no notification.
public static void main(String[] args) {
try {
//Register our Package
BidonPackage.eINSTANCE.eClass();
//Register the resource factory
Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
Map<String, Object> m = reg.getExtensionToFactoryMap();
m.put("xmi", new XMIResourceFactoryImpl());
String path = "file:/path/to/my/file.xmi";
ResourceSet rs = new ResourceSetImpl();
Resource r = rs.getResource(URI.createURI(path), true);
System.out.println(r.getContents().get(0));
System.out.println("KO - Adapters not called");
} catch (Throwable t) {
System.out.println("OK : " + t.getCause().getCause().getMessage());
}
}
If you read this line, it means you had the courage to go through it all : congrats (and respect) !!
Conclusion - at last!:
- it somehow surprises me that CDO's behaviour during loading seems different from e.g. XMl/XMI resource loading. Is it something I do/understand wrong?
- How else can I acheive notification firing for my derived features?
Thank you much for reading!
PS: I guess complete sample code would help. Don't hesistate to ask me.
|
|
|
Re: [CDO] Notification disabled while instanciating objects from repo? [message #774840 is a reply to message #774792] |
Wed, 04 January 2012 18:40 |
|
Am 04.01.2012 17:18, schrieb Alexandre Borgoltz:
> Hey Eike, thanks for your reply - I'll try to make myself understood a little bit better... Take a deep breath! ;)
>
> Eike Stepper wrote on Wed, 04 January 2012 11:23
>> Am 03.01.2012 17:58, schrieb Alexandre Borgoltz:
>> > [...] we have custom Adapters (listeners) attached to our model objects at constructor time.
>> > public MyModel() {
>> > super();
>> > eAdapters().add(new AdapterImpl() {
>> >
>> > @Override
>> > public void notifyChanged(Notification msg) {
>> > //do something when this is modified...
>> Although I don't know exactly what this "something" is, it strikes me that this is uncommon (maybe poor) design.
>> Can't you compute lazily instead?
>
>
> Hope my design isn't that poor - or that you will help enrich it a bit! :)
>
> The reason for these adapters is that we have implemented derived features - and they're computed lazily actually. And
> we want notifications fired for them, when the features they depend on are modified. I just respected the official EMF
> Recipe called "Derived Attribute Notifier" - see /EMF/Recipes#Recipe:_Derived_Attribute_Notifier at wiki.eclipse.org
Where in that example/snippet is the eDeliver() method overridden? Or is the XMLResource.OPTION_DISABLE_NOTIFY involved?
>
> Eike Stepper wrote on Wed, 04 January 2012 11:23
>> > [...]
>> > The problem: these adapters are not notified while CDO is instanciating the object. > [...]
>> No, because at this point the object is not logically modified.
>
> I am unsure I understand what logically means. The fact is I did not consider that Adapters should be notified only
> for logical changes - and I am not sure the EMF Recipe I followed does neither.
>
>
> Here's my -potentially wrong, and very humble- point of view:
> My code somehow always looks like
>
> EObject myModel = MyFrameWork.getAHoldOnMyModel(...);
>
> And I see -at least- 3 differents ways of implementing the getAHoldOnMyModel() method.
>
>
> low-level, manual, based on EMF Factory + calls of setter methods
> using a "classical" resource (typically XML/XMI)
> using a CDO resource
>
>
> Sample illustration of 1.
>
>
> MyModel model1 = MyModel1Factory.createMyModel();
> model1.setDummy("dummy");
> model1.setDummy2("dummy too");
> //...
>
>
> Sample illustration of 2.
>
>
> ResourceSet rs = new ResourceSetImpl();
> Resource r = rs.createResource(xmlFileURI);
> MyModel model1 = (MyModel) r.getContents().get(0);
>
>
> Sample illustration of 3.
>
>
> CDOSession session = ...;
> CDOView view = session.openView();
> Resource resource = view.getOrCreateResource("...");
> MyModel model1 = (MyModel) resource.getContents().get(0);
>
>
>
> So we have three different ways of getting an instance of our model, and I'd tend to beleive it would be quite
> enjoyable if these 3 ways were seamlessly interchangeable. Meaning that once you have your EObject instance, it should
> be seamless wether it comes from CDO or an XMIResource or whatever.
>
> The fact is : "my" adapters are notified in methods 1. and 2. but not with 3. (CDO)... CDO is not seamless :(
Of course CDO is not seamless for all aspects. For example some aspects of EMF have not been designed for distributed
models (e.g. remote deletion notification is missing). If the resource to be loaded contains 5000 billion objects it
would also not be seamless because only your third scenario could ever load that resource and let you navigate it.
While we certainly must (and want to) accept that some things are not seamless, we can discuss if we can make CDO a bit
more seamless in this regard. A general problem I see with your many adapters that keep references to other objects is
that it does not scale very well. It can easily (load and) keep your entire object graph into memory. Even worse, the
default strong reference policy of a CDOView (see CDOView.Options.setStrongReferencePolicy) prevents object with
adapters from being unloaded. But if you want to be seamless with a technology (EMF) that does not have this property,
well... ;-)
I have a solution for CDO native objects in mind. Can you please submit a bugzilla to discuss problems and track progress?
>
> Eike Stepper wrote on Wed, 04 January 2012 11:23
>> > [...] > thanks to the overrinding of eDeliver().
>> That's not the intended usage and it may well corrupt certain aspects of CDO or CDO's legacy mode.
>
> Yes, of course. It was just to underline that the legacy mode triggers notification but disables explicitely their
> delivery whereas native mode does not even trigger notifications. I was awaiting CDO to populate my model through the
> "classic" EMF way : setters or eSet, thus triggering notifications, even if disabling their delivery. The test I did
> by overriding eDeliver() shows it's not exactly the case...
>
> Eike Stepper wrote on Wed, 04 January 2012 11:23
>> [...]Adapters must only "see" the logical changes, that's why all resource implementations, including CDO, turn off
>> eDeliver during technical changes such as loading.[...]
>
> Well, as explained above, my tests show that XMLResourceImpl does notify my eAdapters during loading (cf below)!
>
> Illustration: (I can provide you with the sources)
> I have added a simple adapter in the constructor of my model. It throws a RuntimeException whenever it is notified -
> of course throwing the exception is just for the demo...:
>
>
> public MyModelImpl() {
> eAdapters().add(new AdapterImpl() {
>
> @Override
> public void notifyChanged(Notification msg) {
> throw new RuntimeException("The Adapter was called");
> }});
> }
>
>
> I then load an instance of MyModel using a standard XMI resource - see the following snippet : the exception is
> thrown, proving the adapter is notified during loading.
>
>
> //The following code outputs "OK : The adapter was called".
> //It would output "KO - Adapters not called" if there was no notification.
>
> public static void main(String[] args) {
>
> try {
> //Register our Package
> BidonPackage.eINSTANCE.eClass();
>
> //Register the resource factory
> Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE;
> Map<String, Object> m = reg.getExtensionToFactoryMap();
> m.put("xmi", new XMIResourceFactoryImpl());
>
> String path = "file:/path/to/my/file.xmi";
> ResourceSet rs = new ResourceSetImpl();
> Resource r = rs.getResource(URI.createURI(path), true);
> System.out.println(r.getContents().get(0));
> System.out.println("KO - Adapters not called");
> } catch (Throwable t) {
> System.out.println("OK : " + t.getCause().getCause().getMessage());
> }
>
> }
>
>
>
> If you read this line, it means you had the courage to go through it all : congrats (and respect) !! :)
>
> Conclusion - at last!:
>
> it somehow surprises me that CDO's behaviour during loading seems different from e.g. XMl/XMI resource loading. Is it
> something I do/understand wrong?
It's not surprising at all because object loading and unloading itself is very different in CDO.
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
> How else can I acheive notification firing for my derived features?
>
>
> Thank you much for reading!
>
> PS: I guess complete sample code would help. Don't hesistate to ask me.
>
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
| | |
Goto Forum:
Current Time: Tue Mar 19 08:25:56 GMT 2024
Powered by FUDForum. Page generated in 0.01787 seconds
|