Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Is there a "CanAdd" API?(An API that tells whether an EObject would accept another EObject as child)
Is there a "CanAdd" API? [message #1805075] Fri, 05 April 2019 12:26 Go to next message
Ingo Mohr is currently offline Ingo MohrFriend
Messages: 23
Registered: September 2011
Junior Member
Hi all!

I am currently searching some EMF-Reflection API like "canAdd", "accepts" or something like that which - for two EObjects A and B - tells me whether I can add B as a child to A.

i.e. something like this

EcoreUtil.canAdd(EObject, EObject) :: bool

... that accesses the structuralFeatures, references incl. types and bounds etc. to answer accordingly.

Is there such an API? (I didn't find something like that, yet. Maybe, I missed something).


Thanks in advance,
Ingo
Re: Is there a "CanAdd" API? [message #1805080 is a reply to message #1805075] Fri, 05 April 2019 13:14 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33137
Registered: July 2009
Senior Member
No, there isn't something like that. You can iterate over A.eClass().getEAllReferences() and for each such eReference you can test eReference.getEReferenceType().isInstance(B) to find one (of possibly many) of A's EReferences that can reference a B. You might only be interested in A.eClass().getEAllContainments() if you want to find a containment reference.

Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Is there a "CanAdd" API? [message #1805085 is a reply to message #1805080] Fri, 05 April 2019 13:30 Go to previous messageGo to next message
Aurélien Mora is currently offline Aurélien MoraFriend
Messages: 38
Registered: July 2014
Member
Something like that should do the trick:

public static boolean canAdd(EObject container, EObject potentialChild)
{
	return getContainmentReference(container, potentialChild) != null;
}

public static EReference getContainmentReference(EObject container, EObject potentialChild)
{
	EReference res = null;

	for (final EReference eReference : container.eClass().getEAllContainments())
	{
		final EClass refEClass = eReference.getEReferenceType();
		if (refEClass.isInstance(potentialChild))
		{
			res = eReference;
			break;
		}
	}

	return res;
}

@SuppressWarnings("unchecked")
public static boolean add(EObject container, EObject potentialChild)
{
	boolean res = false;
	final EReference eReference = getContainmentReference(container, potentialChild);

	if (eReference != null)
	{
		if (eReference.isMany())
		{
			final var values = (List<EObject>) container.eGet(eReference);
			values.add(potentialChild);
		}
		else
		{
			container.eSet(eReference, potentialChild);
		}

		res = true;
	}

	return res;
}

[Updated on: Mon, 08 April 2019 09:40]

Report message to a moderator

Re: Is there a "CanAdd" API? [message #1805087 is a reply to message #1805085] Fri, 05 April 2019 13:40 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
Hi

For an arbitrary metamodel a "canAdd" seems dangerously uncontrolled since there may be many possible children. Which to use? I suggest revisiting your requirement.

For a specific metamodel, you are presumably in control and so you might add your own canAdd API to your model elements or implement a derived XXXSwitch to give the correct answer.

Regards

Ed Willink
Re: Is there a "CanAdd" API? [message #1805091 is a reply to message #1805087] Fri, 05 April 2019 14:55 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33137
Registered: July 2009
Senior Member
Note that this only works for generated models:
		final Class<?> instanceClass = eReference.getEReferenceType().getInstanceClass();
		if (instanceClass.isAssignableFrom(childClass))
Better just to use EClass.isInstance which for a generated model will use Class.isInstance.


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Is there a "CanAdd" API? [message #1805134 is a reply to message #1805091] Mon, 08 April 2019 07:21 Go to previous messageGo to next message
Ingo Mohr is currently offline Ingo MohrFriend
Messages: 23
Registered: September 2011
Junior Member
Thanks for your quick help!
That should do the job.
Re: Is there a "CanAdd" API? [message #1805140 is a reply to message #1805091] Mon, 08 April 2019 09:42 Go to previous message
Aurélien Mora is currently offline Aurélien MoraFriend
Messages: 38
Registered: July 2014
Member
Ed Merks wrote on Fri, 05 April 2019 14:55
Note that this only works for generated models:
		final Class<?> instanceClass = eReference.getEReferenceType().getInstanceClass();
		if (instanceClass.isAssignableFrom(childClass))
Better just to use EClass.isInstance which for a generated model will use Class.isInstance.


Ok, I edited my previous post.
Previous Topic:Save Emf probleme with many reference to save
Next Topic:How can I contribute
Goto Forum:
  


Current Time: Fri Apr 19 12:04:40 GMT 2024

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

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

Back to the top