|
|
Re: Copy EObject with eOpposite refs [message #1007135 is a reply to message #1007132] |
Mon, 04 February 2013 15:23 |
Erdal Karaca Messages: 854 Registered: July 2009 |
Senior Member |
|
|
Imaginary model:
EClass Master
- details: Detail 0..* (eOpposite = true, containment = true)
EClass Detail
- master: Master (eOpposite = true, container = true)
Just imagine a master/detail UI where the details of the master are shown in a table.
If I select one of the details and copy it to the details list of the master, then, I think, it is ok to let the master know of its new detail.
Maybe, I missed something...
Ed Merks wrote on Mon, 04 February 2013 16:06Erdal,
Comments below.
On 04/02/2013 3:56 PM, Erdal Karaca wrote:
> Do you know of a ('simple') way to copy EObjects with eOpposite refs?
> I am aware of eOpposite refs that would change the container. That is
> ok for my use case.
I doubt it's okay. How can it possibly be okay?
>
> The javadocs of
> org.eclipse.emf.ecore.util.EcoreUtil.Copier.copyReference(EReference,
> EObject, EObject) say:
>
> """
> Called to handle the copying of a cross reference; this adds values or
> sets a single value as appropriate for the multiplicity while omitting
> any bidirectional reference that isn't in the copy map.
> """
>
> Is it sufficient to manually 'extend' the copy map?
>
> I just ended up with this copy function:
>
>
> private Collection<EObject> copyAll(Collection<EObject> objectsToCopy,
> final boolean includeEopposites) {
> EcoreUtil.Copier copier = new Copier() {
> private static final long serialVersionUID = 1L;
>
> @Override
> public EObject get(Object key) {
> EObject eObject = super.get(key);
>
> if (eObject == null && includeEopposites) {
> if (key instanceof EObject) {
> eObject = (EObject) key;
> }
> }
>
> return eObject;
> }
> };
> Collection<EObject> copyAll = copier.copyAll(objectsToCopy);
> copier.copyReferences();
> return copyAll;
> }
>
>
> It seems to work for some EObjects with eOpposite refs but with others
> I get:
>
>
> java.util.ConcurrentModificationException
> at
> org.eclipse.emf.common.util.AbstractEList$EIterator.checkModCount(AbstractEList.java:756)
> at
> org.eclipse.emf.common.util.AbstractEList$EIterator.doNext(AbstractEList.java:710)
> at
> org.eclipse.emf.common.util.AbstractEList$EIterator.next(AbstractEList.java:690)
> at
> org.eclipse.emf.ecore.util.EcoreUtil$Copier.copyReference(EcoreUtil.java:717)
> at
> org.eclipse.emf.ecore.util.EcoreUtil$Copier.copyReferences(EcoreUtil.java:641)
That's not surprising given that you're adding references to the
original list while iterating over it. Before I explain what you'd need
to do, I'd prefer you explain why you think it's okay for the original
object to be modified...
|
|
|
Re: Copy EObject with eOpposite refs [message #1007151 is a reply to message #1007135] |
Mon, 04 February 2013 15:49 |
Ed Merks Messages: 33113 Registered: July 2009 |
Senior Member |
|
|
Erdal,
Comments below.
On 04/02/2013 4:23 PM, Erdal Karaca wrote:
> Imaginary model:
>
> EClass Master
> - details: Detail 0..* (eOpposite = true, containment = true)
>
> EClass Detail
> - master: Master (eOpposite = true, container = true)
>
> Just imagine a master/detail UI where the details of the master are
> shown in a table.
It's not a good example because it's a containment reference...
> If I select one of the details and copy it to the details list of the
> master, then, I think, it is ok to let the master know of its new detail.
If you're doing this in the IDE you need a command to modify the state
of the original model otherwise undo will be broken... That would be
true even for a non-containment reference example. Think about how
badly behaved your scenario (it it weren't a containment) would be if
you copied the Master object. All Details would be removed from the
original and added to the copy; that can't possibly be a good thing, right?
> Maybe, I missed something...
>
> Ed Merks wrote on Mon, 04 February 2013 16:06
>> Erdal,
>>
>> Comments below.
>>
>> On 04/02/2013 3:56 PM, Erdal Karaca wrote:
>> > Do you know of a ('simple') way to copy EObjects with eOpposite refs?
>> > I am aware of eOpposite refs that would change the container. That
>> is > ok for my use case.
>> I doubt it's okay. How can it possibly be okay?
>> >
>> > The javadocs of >
>> org.eclipse.emf.ecore.util.EcoreUtil.Copier.copyReference(EReference,
>> > EObject, EObject) say:
>> >
>> > """
>> > Called to handle the copying of a cross reference; this adds values
>> or > sets a single value as appropriate for the multiplicity while
>> omitting > any bidirectional reference that isn't in the copy map.
>> > """
>> >
>> > Is it sufficient to manually 'extend' the copy map?
>> >
>> > I just ended up with this copy function:
>> >
>> >
>> > private Collection<EObject> copyAll(Collection<EObject>
>> objectsToCopy,
>> > final boolean includeEopposites) {
>> > EcoreUtil.Copier copier = new Copier() {
>> > private static final long serialVersionUID = 1L;
>> >
>> > @Override
>> > public EObject get(Object key) {
>> > EObject eObject = super.get(key);
>> >
>> > if (eObject == null && includeEopposites) {
>> > if (key instanceof EObject) {
>> > eObject = (EObject) key;
>> > }
>> > }
>> >
>> > return eObject;
>> > }
>> > };
>> > Collection<EObject> copyAll = copier.copyAll(objectsToCopy);
>> > copier.copyReferences();
>> > return copyAll;
>> > }
>> >
>> >
>> > It seems to work for some EObjects with eOpposite refs but with
>> others > I get:
>> >
>> >
>> > java.util.ConcurrentModificationException
>> > at >
>> org.eclipse.emf.common.util.AbstractEList$EIterator.checkModCount(AbstractEList.java:756)
>> > at >
>> org.eclipse.emf.common.util.AbstractEList$EIterator.doNext(AbstractEList.java:710)
>> > at >
>> org.eclipse.emf.common.util.AbstractEList$EIterator.next(AbstractEList.java:690)
>> > at >
>> org.eclipse.emf.ecore.util.EcoreUtil$Copier.copyReference(EcoreUtil.java:717)
>> > at >
>> org.eclipse.emf.ecore.util.EcoreUtil$Copier.copyReferences(EcoreUtil.java:641)
>> That's not surprising given that you're adding references to the
>> original list while iterating over it. Before I explain what you'd
>> need to do, I'd prefer you explain why you think it's okay for the
>> original object to be modified...
>
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
|
Re: Copy EObject with eOpposite refs [message #1007160 is a reply to message #1007154] |
Mon, 04 February 2013 16:10 |
Ed Merks Messages: 33113 Registered: July 2009 |
Senior Member |
|
|
Erdal,
You'd need to specialize copyReference. Essentially copying the whole
method and changing the parts the filter out the things you want copied
anyway. You'll need to make a copy of the bidirectional list you're
iterator over that's changing during the iteration and iterate over that
copy.
On 04/02/2013 5:00 PM, Erdal Karaca wrote:
> Yes, you are right... Anyways, what would be the solution? It (the
> code) is for educational purposes (dont do this) :)
>
> Ed Merks wrote on Mon, 04 February 2013 16:49
>> It's not a good example because it's a containment reference...
>> > If I select one of the details and copy it to the details list of
>> the > master, then, I think, it is ok to let the master know of its
>> new detail.
>> If you're doing this in the IDE you need a command to modify the
>> state of the original model otherwise undo will be broken... That
>> would be true even for a non-containment reference example. Think
>> about how badly behaved your scenario (it it weren't a containment)
>> would be if you copied the Master object. All Details would be
>> removed from the original and added to the copy; that can't possibly
>> be a good thing, right?
>
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
|
Powered by
FUDForum. Page generated in 0.03109 seconds