public MyModel() { super(); eAdapters().add(new AdapterImpl() { @Override public void notifyChanged(Notification msg) { //do something when this is modified... } }); }
session=... view=... resource=... MyModel myObject = (MyModel) resource.getContents().get(0); //until there no notification
//next line generate a notification myObject.setAttribute1(...);
protected void revisionToInstance() { ... boolean deliver = instance.eDeliver(); if (deliver) { instance.eSetDeliver(false); } ... } finally { if (deliver) { instance.eSetDeliver(true); } ... } }
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?
> [...]
> The problem: these adapters are not notified while CDO is instanciating the object.
> [...]
No, because at this point the object is not logically modified.
EObject myModel = MyFrameWork.getAHoldOnMyModel(...);
MyModel model1 = MyModel1Factory.createMyModel(); model1.setDummy("dummy"); model1.setDummy2("dummy too"); //...
ResourceSet rs = new ResourceSetImpl(); Resource r = rs.createResource(xmlFileURI); MyModel model1 = (MyModel) r.getContents().get(0);
CDOSession session = ...; CDOView view = session.openView(); Resource resource = view.getOrCreateResource("..."); MyModel model1 = (MyModel) resource.getContents().get(0);
> [...]
> 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.
[...]Adapters must only "see" the logical changes, that's why all resource implementations,
including CDO, turn off eDeliver during technical changes such as loading.[...]
public MyModelImpl() { eAdapters().add(new AdapterImpl() { @Override public void notifyChanged(Notification msg) { throw new RuntimeException("The Adapter was called"); }}); }
//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()); } }
I have a solution for CDO native objects in mind.
Can you please submit a bugzilla to discuss problems and track progress?
I'm adding the following new API:
- CDOView.Options.isLoadNotificationEnabled()
- CDOView.Options.setLoadNotificationEnabled(boolean)
The default value is false (i.e. the former behaviour)