Extending EcoreUtil.Copier to include bidirectional references [message #1802224] |
Mon, 04 February 2019 16:16 |
Pablo Gomez Abajo Messages: 8 Registered: February 2019 |
Junior Member |
|
|
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 #1802292 is a reply to message #1802280] |
Wed, 06 February 2019 05:00 |
Ed Merks Messages: 33216 Registered: July 2009 |
Senior Member |
|
|
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...
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03801 seconds