Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Notification on any eContainer change
Notification on any eContainer change [message #1860388] Wed, 02 August 2023 18:53 Go to next message
Frank Benoit is currently offline Frank BenoitFriend
Messages: 179
Registered: July 2009
Senior Member
Hi,

I have a model. To avoid programming errors, I want to verify changes in the model where containments are changed.

Is there a way to have an adapter to get a notification on this?
Object is added to a parent, removed from a parent, moved to another parent.

regards
Frank
Re: Notification on any eContainer change [message #1860397 is a reply to message #1860388] Thu, 03 August 2023 05:44 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33143
Registered: July 2009
Senior Member
You could use an org.eclipse.emf.ecore.util.EContentAdapter. Any given object can only listen to changes to its modeled features, so unless there is a modeled container feature, an object will not get notifications about changes to the eContainer, but of course the container will get notifications about changes to it containment features.

Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Notification on any eContainer change [message #1860447 is a reply to message #1860397] Sun, 06 August 2023 17:09 Go to previous message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
The commonest eContainer problem is child stealing. See 3.4 of https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwjVlIzWwMiAAxVKTEEAHUrHD9UQFnoECCAQAQ&url=https%3A%2F%2Fwww.eclipse.org%2Fmmt%2Fqvt%2Fdocs%2FICMT2014%2FQVTtraceability.pdf&usg=AOvVaw3RU8rzse9xZmJU7eiRmd6d&opi=89978449

If you ensure that your model has a root 'ElementImpl' class you can just add


	@Override
	protected void eBasicSetContainer(InternalEObject newContainer, int newContainerFeatureID) {
		if (newContainer != null) {
			EObject oldContainer = eInternalContainer();
			assert (oldContainer == null) || oldContainer.eIsProxy() || (newContainer == oldContainer) || (oldContainer.eResource() == null);
		}
		super.eBasicSetContainer(newContainer, newContainerFeatureID);
	}


to detect abuse and occasionally call


       /**
	 * Detach object from its container so that a child-stealing detection is avoided when attaching to a new container.
	 */
	public static void resetContainer(@NonNull EObject eObject) {
		EStructuralFeature eContainingFeature = eObject.eContainingFeature();
		if (eContainingFeature != null) {
			EObject eContainer = eObject.eContainer();
			if (eContainer != null) {
				if (!eContainingFeature.isMany()) {
					eContainer.eSet(eContainingFeature, null);
				}
				else {
					Object objects = eContainer.eGet(eContainingFeature);
					if (objects instanceof List<?>) {
						((List<?>)objects).remove(eObject);
					}
				}
			}
		}
	}


in those usually very few places where you really do migrate an EObject.

Previous Topic:[CDO] Managing async view invalidation
Next Topic:How can you change properties of attributes at runtime?
Goto Forum:
  


Current Time: Thu May 02 05:06:38 GMT 2024

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

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

Back to the top