Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Best practice for EMF Notification propagation
Best practice for EMF Notification propagation [message #630645] Mon, 04 October 2010 13:28 Go to next message
Michael Jastram is currently offline Michael JastramFriend
Messages: 235
Registered: April 2010
Location: Düsseldorf, Germany
Senior Member
Howdy,

My question feels rather... basic, yet I couldn't find a proper answer online (nor in the EMF-Book, or maybe I missed it):

My problem: I would like to be notified if attributes of a referenced object change. But I do not want to register a listener in the object's implementation. In other words, I'd like to realize this with the ItemProviders.

Some background: I am working on a project where I am using the data model from a different project. Requesting changes in the data model is kind of a last resort. Besides, intuitively it feels like that this should be doable with the ItemProviders.

I set up a tiny project to demonstrate the issue (I just hacked the AdapterFactory in for testing, sorry):
	public void testNotificationsShirt() {
		getFixture().eAdapters().add(new AdapterImpl() {
			@Override
			public void notifyChanged(Notification msg) {
				System.out.println("  >> " + msg);
				super.notifyChanged(msg);
			}
		});

		EmftestItemProviderAdapterFactory factory = new EmftestItemProviderAdapterFactory();
		getFixture().eAdapters().add(factory.createBagAdapter());
		System.out.println("Creating shirt...");
		Shirt shirt = EmftestFactory.eINSTANCE.createShirt();
		shirt.eAdapters().add(factory.createShirtAdapter());
		System.out.println("Adding shirt...");
		getFixture().setShirt(shirt);
		System.out.println("Updating shirt...");
		shirt.setColor("red");
	}


As Expected, I got the following output:

Creating shirt...
Adding shirt...
  >> org.eclipse.emf.ecore.impl.ENotificationImpl@1d256fa ...
Updating shirt...


But I am trying to get a notification on Bag when I update the Shirt's color.

I managed to realize this by changing ShirtItemProvider.notifyChanged(), but the result feels messy:

	public void notifyChanged(Notification notification) {
		updateChildren(notification);

		switch (notification.getFeatureID(Shirt.class)) {
		case EmftestPackage.SHIRT__COLOR:
			fireNotifyChanged(new ViewerNotification(notification,
					notification.getNotifier(), false, true));

			Bag bag = (Bag) ((EObject) notification.getNotifier()).eContainer();
			if (bag != null) {
				bag.eNotify(new ENotificationImpl((InternalEObject) bag,
						ENotificationImpl.SET, EmftestPackage.BAG__SHIRT,
						notification.getNotifier(), notification.getNotifier()));
			}
			return;
		}
		super.notifyChanged(notification);
	}


Is this the right way? Is there a better way?

thanks,

- Michael
Re: Best practice for EMF Notification propagation [message #630659 is a reply to message #630645] Mon, 04 October 2010 13:48 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 33140
Registered: July 2009
Senior Member
Michael,

Comments below.

Michael Jastram wrote:
> Howdy,
>
> My question feels rather... basic, yet I couldn't find a proper answer
> online (nor in the EMF-Book, or maybe I missed it):
>
> My problem: I would like to be notified if attributes of a referenced
> object change. But I do not want to register a listener in the
> object's implementation. In other words, I'd like to realize this
> with the ItemProviders.
ItemProviders are listeners too.
>
> Some background: I am working on a project where I am using the data
> model from a different project. Requesting changes in the data model
> is kind of a last resort. Besides, intuitively it feels like that
> this should be doable with the ItemProviders.
>
> I set up a tiny project to demonstrate the issue (I just hacked the
> AdapterFactory in for testing, sorry):
>
> public void testNotificationsShirt() {
> getFixture().eAdapters().add(new AdapterImpl() {
> @Override
> public void notifyChanged(Notification msg) {
> System.out.println(" >> " + msg);
> super.notifyChanged(msg);
> }
> });
>
> EmftestItemProviderAdapterFactory factory = new
> EmftestItemProviderAdapterFactory();
> getFixture().eAdapters().add(factory.createBagAdapter());
> System.out.println("Creating shirt...");
> Shirt shirt = EmftestFactory.eINSTANCE.createShirt();
> shirt.eAdapters().add(factory.createShirtAdapter());
> System.out.println("Adding shirt...");
> getFixture().setShirt(shirt);
> System.out.println("Updating shirt...");
> shirt.setColor("red");
> }
>
>
> As Expected, I got the following output:
>
> Creating shirt...
> Adding shirt...
> >> org.eclipse.emf.ecore.impl.ENotificationImpl@1d256fa ...
> Updating shirt...
>
> But I am trying to get a notification on Bag when I update the Shirt's
> color.
>
> I managed to realize this by changing
> ShirtItemProvider.notifyChanged(), but the result feels messy:
>
>
> public void notifyChanged(Notification notification) {
> updateChildren(notification);
>
> switch (notification.getFeatureID(Shirt.class)) {
> case EmftestPackage.SHIRT__COLOR:
> fireNotifyChanged(new ViewerNotification(notification,
> notification.getNotifier(), false, true));
>
> Bag bag = (Bag) ((EObject)
> notification.getNotifier()).eContainer();
> if (bag != null) {
> bag.eNotify(new ENotificationImpl((InternalEObject) bag,
> ENotificationImpl.SET, EmftestPackage.BAG__SHIRT,
> notification.getNotifier(),
> notification.getNotifier()));
> }
> return;
> }
> super.notifyChanged(notification);
> }
>
>
> Is this the right way?
It's not totally bad.
> Is there a better way?
The only way is to add listeners so in this case you're exploiting the
fact that the contained child has a listener and you're propagating a
notification. EGenericTypeItemProvider does something similar...
>
> thanks,
>
> - Michael
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Previous Topic:[Announce] EMF for GWT
Next Topic:Implementing a DSL with Classes, Instances and Function Calls
Goto Forum:
  


Current Time: Thu Apr 25 14:44:13 GMT 2024

Powered by FUDForum. Page generated in 0.03450 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top