Skip to main content



      Home
Home » Modeling » EMF » Extending EcoreUtil.Copier to include bidirectional references(EcreUtil.Copier)
Extending EcoreUtil.Copier to include bidirectional references [message #1802224] Mon, 04 February 2019 11:16 Go to next message
Eclipse UserFriend
Hi,

I'm trying to extend EcoreUtil.Copier class to include bidirectional references (references with an EOpposite value), but I'm not reaching the solution. I would appreciate any help.

This is my modified not working yet extension of EcoreUtil.Copier.

public class EMFCopier extends EcoreUtil.Copier {

	private static final long serialVersionUID = 1L;

	@Override
	protected void copyReference(EReference eReference, EObject eObject, EObject copyEObject)
	{
		if (eObject.eIsSet(eReference))
		{
			EStructuralFeature.Setting setting = getTarget(eReference, eObject, copyEObject);
			if (setting != null)
			{
				Object value = eObject.eGet(eReference, resolveProxies);
				if (eReference.isMany())
				{
					@SuppressWarnings("unchecked") InternalEList<EObject> source = (InternalEList<EObject>)value;
					@SuppressWarnings("unchecked") InternalEList<EObject> target = (InternalEList<EObject>)setting;
					if (source.isEmpty())
					{
						target.clear();
					}
					else
					{
						boolean isBidirectional = eReference.getEOpposite() != null && !eReference.getEOpposite().isMany();
						int index = 0;
						for (Iterator<EObject> k = resolveProxies ? source.iterator() : source.basicIterator(); k.hasNext();)
						{
							EObject referencedEObject = k.next();
							EObject copyReferencedEObject = get(referencedEObject);
							if (copyReferencedEObject == null)
							{
								if (useOriginalReferences && !isBidirectional)
								{
									target.addUnique(index, referencedEObject);
									++index;
								}
							}
							else
							{
								if (isBidirectional)
								{
									int position = target.indexOf(copyReferencedEObject);
									if (position == -1)
									{
										target.addUnique(index, copyReferencedEObject);
									}
									else if (index != position)
									{
										target.move(index, copyReferencedEObject);
									}
								}
								else
								{
									target.addUnique(index, copyReferencedEObject);
								}
								++index;
							}
						}
					}
				}
				else
				{
					if (value == null)
					{
						setting.set(null);
					}
					else
					{
						Object copyReferencedEObject = get(value);
						if (copyReferencedEObject == null)
						{
							if (useOriginalReferences && !(eReference.getEOpposite() != null && !eReference.getEOpposite().isMany()))
							{
								setting.set(value);
							}
						}
						else
						{
							setting.set(copyReferencedEObject);
						}
					}
				}
			}
		}
	}
}


Many thanks in advance.
Re: Extending EcoreUtil.Copier to include bidirectional references [message #1802280 is a reply to message #1802224] Tue, 05 February 2019 14:44 Go to previous messageGo to next message
Eclipse UserFriend
HI

EcoreUtil.Copier does a good job of deep copying which includes opposites.

I suggest you revisit your use case to understand why it isn't working. Perhaps you just didn't give the copier all the roots.

Regards

Ed Willink
Re: Extending EcoreUtil.Copier to include bidirectional references [message #1802292 is a reply to message #1802280] Wed, 06 February 2019 00:00 Go to previous messageGo to next message
Eclipse UserFriend
Firstly, your attempt to modify this behavior is probably, in fact no doubt, misguided. There's a good reason that opposites are copied conditionally and you've not specified the "not working" aspect of your attempt to change the behavior. The reason that opposites are copied only if the reference is also part of the set of objects being copied is because otherwise, the original set of objects will be modified during the copying. I.e., the original set of objects will end up with references to the copy, and in the case of single-valued reference that means the original object will reference the copy, but will no longer reference the object it originally referenced. No doubt that will be perceived as "not working" so there's not much point in me trying to test your changes against some unspecified model and determine if the new behavior is "working" according to our unspecified definition of "working".

Most likely you should be focused on using EcoreUtil.copyAll to copy a larger set of object in a simple operation such that bidirectional references among the copies reflect exactly the bidirectional references among the originals. In any case, if you wish to augment the behavior in some way that truly does involve the original objects referencing the copied objects, you should clearly state what you intend for that behavior to be...
Re: Extending EcoreUtil.Copier to include bidirectional references [message #1802308 is a reply to message #1802292] Wed, 06 February 2019 02:49 Go to previous messageGo to next message
Eclipse UserFriend
Many thanks, Ed. I will try to fix this... But I'm not sure how to do it. I'm calling EcoreUtil.copyAll this way to deep clone a Resource:

EMFCopier copier = new EMFCopier();
resource.getContents().addAll(copier.copyAll(model.getContents()))
copier.copyReferences();


Also

EcoreUtil.Copier copier = new EcoreUtil.Copier();
resource.getContents().addAll(copier.copyAll(model.getContents()))
copier.copyReferences();


But not getting the expected result...

Best regards,

Pablo

Re: Extending EcoreUtil.Copier to include bidirectional references [message #1802310 is a reply to message #1802308] Wed, 06 February 2019 03:18 Go to previous messageGo to next message
Eclipse UserFriend
Do any of the resource's contents (I assume "model" is a resource) have bidirectional references to objects in other resources? If so, those will of course not be in the copy, nor should they be. So what exactly is "the expect result" of this operation supposed to be? Keep in mind that your goal should remain that original objects are not touched by copying. You might want some original object to end up with a reference to the copy, but you should be explicit about exactly those cases and explain the underlying thinking and details to me so I can understand your goal and help figure out the best direction to take.
Re: Extending EcoreUtil.Copier to include bidirectional references [message #1802316 is a reply to message #1802310] Wed, 06 February 2019 04:48 Go to previous messageGo to next message
Eclipse UserFriend
Yes, Ed, many thanks for your fast support. Te expected result is a deep clone of the source resource (object model) in the target resource (object resource)... A clone which also includes the bidirectional references, which is not happening now. These bidirectional references must refer to the corresponding cloned objects of the new created resource.

I hope I explained it better now.

Best wishes,

Pablo

Re: Extending EcoreUtil.Copier to include bidirectional references [message #1802317 is a reply to message #1802316] Wed, 06 February 2019 04:57 Go to previous messageGo to next message
Eclipse UserFriend
And the objects in the source resource only have references to its own contents.

Re: Extending EcoreUtil.Copier to include bidirectional references [message #1802319 is a reply to message #1802317] Wed, 06 February 2019 05:28 Go to previous messageGo to next message
Eclipse UserFriend
Sorry, but I don't believe you. I would suggest setting a breakpoint at these two lines:

https://git.eclipse.org/c/emf/org.eclipse.emf.git/tree/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/util/EcoreUtil.java#n786
                if (copyReferencedEObject == null)
                {
                  if (useOriginalReferences && !isBidirectional)


https://git.eclipse.org/c/emf/org.eclipse.emf.git/tree/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/util/EcoreUtil.java#n826
              if (copyReferencedEObject == null)
              {
                if (useOriginalReferences && eReference.getEOpposite() == null)
                {


If what you say is true, i.e., "objects in the source resource only have references to its own contents", then you will not hit those breakpoints. If what you say is false, then you will hit them, and you'll see that you have a reference to an object that has not been copied, and you'll know exactly which object that is.
Re: Extending EcoreUtil.Copier to include bidirectional references [message #1802546 is a reply to message #1802319] Mon, 11 February 2019 13:08 Go to previous message
Eclipse UserFriend
You were right, Ed, many thanks. I had a bug in my implementation and the way I was setting some references in objects.

Many thanks!!!!
Previous Topic:Resource /library.editor does not exist
Next Topic:[CDO]
Goto Forum:
  


Current Time: Tue Jul 08 08:14:52 EDT 2025

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

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

Back to the top