Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF "Technology" (Ecore Tools, EMFatic, etc)  » EcoreUtil.copy() that copies derived/noncontainment features?
EcoreUtil.copy() that copies derived/noncontainment features? [message #668430] Thu, 05 May 2011 12:24 Go to next message
Anton is currently offline Anton
Messages: 23
Registered: July 2009
Junior Member
The emf EcoreUtil.copy(T) method creates a copy of T but "skips" the derived
and non-contained features.

Now I need an ecore copy method that DOES copy the derived/non-contained
features and its ok that the contained elements are removed from the
original.

Is there an implementation of EcoreUtil.copy(T) that copies everyhting
(including derived and non-contained features) or do I need to implement one
on my own?
Re: EcoreUtil.copy() that copies derived/noncontainment features? [message #668454 is a reply to message #668430] Thu, 05 May 2011 13:01 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 25999
Registered: July 2009
Senior Member
Anton,

Comments below.

Anton wrote:
> The emf EcoreUtil.copy(T) method creates a copy of T but "skips" the
> derived and non-contained features.
It defers copying of non-containment features until all the containment
ones are copied. It does skip bidirectional reference unless both ends
are part of he copy. Derived references are assumed to by derived from
the things that are copied.
>
>
> Now I need an ecore copy method that DOES copy the
> derived/non-contained features and its ok that the contained elements
> are removed from the original.
Why do you have features that are marked derived but need to be copied.
What are they derived from?
>
> Is there an implementation of EcoreUtil.copy(T) that copies everyhting
> (including derived and non-contained features) or do I need to
> implement one on my own?
I think you've made some assumptions that might be bad. You'll see, if
you look closely, that copyReferences copies non-containment
references. The issue of derived references is another one, but I'm not
sure why you've marked features as derived and yet still need to copy
them. Perhaps you could elaborate on what's going on with that...
Re: EcoreUtil.copy() that copies derived/noncontainment features? [message #668493 is a reply to message #668454] Thu, 05 May 2011 16:27 Go to previous messageGo to next message
Anton is currently offline Anton
Messages: 23
Registered: July 2009
Junior Member
"Ed Merks" wrote in message news:ipuklq$1n1$3@news.eclipse.org...

Anton,

Comments below.

Anton wrote:
> The emf EcoreUtil.copy(T) method creates a copy of T but "skips" the
> derived and non-contained features.
It defers copying of non-containment features until all the containment
ones are copied. It does skip bidirectional reference unless both ends
are part of he copy. Derived references are assumed to by derived from
the things that are copied.


I have created two examples that shows some strange behavior (but maybe what
you write above explains this behaviour):


Example 1
I create a copy of a root project, IProject, which has a list of IConnector
(containment=true). An IConnector has one and only one ISocket
(containment=false). When I iterate the IConnectors in the copy of the
IProject all ISocket are present - good!

Example 2
I iterate the orginal list of IConnectors and create a copy of each
IConnector manually. Next I check that the copy has its ISocket. This FAILS
the ISocket are not copied!

Below are the corresponding code:

public void test(IProject newProject) {

// Create a copy of the root project
IProject copyProject = EcoreUtil.copy(newProject);
EList<IConnector> copyConnectors = copyProject.getConnectors();
String connectorName = "myConnector";

// Example 1

// Verify that each copy of connectors contains a copy of the
socket
for (IConnector iConnector : copyConnectors) {
if (iConnector.getName().equals(connectorName)) {
if (iConnector.getSocket() == null) {
System.out.println("Socket for connector: " +
connectorName + " not copied");
} else {
System.out.println("Socket for connector: " +
connectorName + " copied");
}
}
}

// Example 2

// Copy the connectors individually - socket are not copied!
EList<IConnector> newConnectors = newProject.getConnectors();
for (IConnector iConnector : newConnectors) {
if (iConnector.getName().equals(connectorName)) {
System.out.println(iConnector.getSocket().getId());
IConnector copy = EcoreUtil.copy(iConnector);
if (copy.getSocket() == null) {
System.out.println("Socket was not copied!");
}
System.out.println(copy.getSocket().getId());
}
}
}


Why are the ISockets intact when I iterate the IConnections on the root copy
but not when I copy the IConnectors manually one by one?
Below are some ecore properties for the ISocket

Connector
|--- ..
|--- socket : Socket

where socket has the following properties:

Changeable true
Container false
Containment false
Default Value Literal
Derived false
EKeys
EOpposite connections : Connector
Lower Bound 0
Transient false
Unique true
Upper Bound 1
Volatile false




>
>
> Now I need an ecore copy method that DOES copy the derived/non-contained
> features and its ok that the contained elements are removed from the
> original.
Why do you have features that are marked derived but need to be copied.
What are they derived from?
>
> Is there an implementation of EcoreUtil.copy(T) that copies everyhting
> (including derived and non-contained features) or do I need to implement
> one on my own?
I think you've made some assumptions that might be bad. You'll see, if
you look closely, that copyReferences copies non-containment
references. The issue of derived references is another one, but I'm not
sure why you've marked features as derived and yet still need to copy
them. Perhaps you could elaborate on what's going on with that...


Basically I read two models A and B from disk. Now I need to create a model
C which initially is a full copy of A and will contain some added data from
B based on userinput. C will eventually be written to disk.

Now initalizing C from A seems to be working - since I create it as a root
copy (see above example) but when I start adding data from B some of the
features are missing (eg. the sockets in the connectors). Everything I add
from B to C I add using:

C.getSomeContainer.add(ECoreUtil.copy(someFeatureFromB))


As you described above there are some exceptions when doing copy (eg.
bidirectional reference, derived etc.) but I don't care about that. I need a
strict copy of A with everything - thats why I originally considered
implementing my own copier unless emf already supplies this kind of
implementation?
Re: EcoreUtil.copy() that copies derived/noncontainment features? [message #668541 is a reply to message #668493] Fri, 06 May 2011 03:29 Go to previous message
Ed Merks is currently offline Ed Merks
Messages: 25999
Registered: July 2009
Senior Member
Anton,

Comments below.

Anton wrote:
>
>
> "Ed Merks" wrote in message news:ipuklq$1n1$3@news.eclipse.org...
>
> Anton,
>
> Comments below.
>
> Anton wrote:
>> The emf EcoreUtil.copy(T) method creates a copy of T but "skips" the
>> derived and non-contained features.
> It defers copying of non-containment features until all the containment
> ones are copied. It does skip bidirectional reference unless both ends
> are part of he copy. Derived references are assumed to by derived from
> the things that are copied.
>
>
> I have created two examples that shows some strange behavior (but
> maybe what you write above explains this behaviour):
>
>
> Example 1
> I create a copy of a root project, IProject, which has a list of
> IConnector (containment=true). An IConnector has one and only one ISocket
> (containment=false). When I iterate the IConnectors in the copy of the
> IProject all ISocket are present - good!
>
> Example 2
> I iterate the orginal list of IConnectors and create a copy of each
> IConnector manually.
You'd need to use a single copier and call copyReferences at the very end...
> Next I check that the copy has its ISocket. This FAILS the ISocket are
> not copied!
>
> Below are the corresponding code:
>
> public void test(IProject newProject) {
>
> // Create a copy of the root project
> IProject copyProject = EcoreUtil.copy(newProject);
> EList<IConnector> copyConnectors =
> copyProject.getConnectors();
> String connectorName = "myConnector";
>
> // Example 1
>
> // Verify that each copy of connectors contains a copy of
> the socket
> for (IConnector iConnector : copyConnectors) {
> if (iConnector.getName().equals(connectorName)) {
> if (iConnector.getSocket() == null) {
> System.out.println("Socket for connector: " +
> connectorName + " not copied");
> } else {
> System.out.println("Socket for connector: " +
> connectorName + " copied");
> }
> }
> }
>
> // Example 2
>
> // Copy the connectors individually - socket are not copied!
> EList<IConnector> newConnectors = newProject.getConnectors();
> for (IConnector iConnector : newConnectors) {
> if (iConnector.getName().equals(connectorName)) {
> System.out.println(iConnector.getSocket().getId());
> IConnector copy = EcoreUtil.copy(iConnector);
I suspect that you have a bidirectional reference between a connector
and a socket, otherwise the new connector would reference the original
socket.
> if (copy.getSocket() == null) {
> System.out.println("Socket was not copied!");
> }
> System.out.println(copy.getSocket().getId());
> }
> }
> }
>
>
> Why are the ISockets intact when I iterate the IConnections on the
> root copy but not when I copy the IConnectors manually one by one?
Who contains the sockets? Probably the project which is why it all
works when you copy the whole project.
> Below are some ecore properties for the ISocket
>
> Connector
> |--- ..
> |--- socket : Socket
>
> where socket has the following properties:
>
> Changeable true
> Container false
> Containment false
> Default Value Literal
> Derived false
> EKeys
> EOpposite connections : Connector
As I suspected.

You need to copy both the socket and the connector before copyReferences
is called. You could accomplish that by calling copyAll with a
collection containing both things.
> Lower Bound 0
> Transient false
> Unique true
> Upper Bound 1
> Volatile false
>
>
>
>
>>
>>
>> Now I need an ecore copy method that DOES copy the
>> derived/non-contained features and its ok that the contained elements
>> are removed from the original.
> Why do you have features that are marked derived but need to be copied.
> What are they derived from?
>>
>> Is there an implementation of EcoreUtil.copy(T) that copies
>> everyhting (including derived and non-contained features) or do I
>> need to implement one on my own?
> I think you've made some assumptions that might be bad. You'll see, if
> you look closely, that copyReferences copies non-containment
> references. The issue of derived references is another one, but I'm not
> sure why you've marked features as derived and yet still need to copy
> them. Perhaps you could elaborate on what's going on with that...
>
>
> Basically I read two models A and B from disk. Now I need to create a
> model C which initially is a full copy of A and will contain some
> added data from B based on userinput. C will eventually be written to
> disk.
>
> Now initalizing C from A seems to be working - since I create it as a
> root copy (see above example) but when I start adding data from B some
> of the features are missing (eg. the sockets in the connectors).
> Everything I add from B to C I add using:
>
> C.getSomeContainer.add(ECoreUtil.copy(someFeatureFromB))
>
>
> As you described above there are some exceptions when doing copy (eg.
> bidirectional reference, derived etc.) but I don't care about that.
You have to though. It's necessary to copy all the objects and then
hook up references between those copies. Original objects cannot refer
back to copies, so that's the reason bidirectional references are tricky...
> I need a strict copy of A with everything - thats why I originally
> considered implementing my own copier unless emf already supplies this
> kind of implementation?
Determine the root objects that need to be copied, i.e., the connection
and the socket in your case, and use copyAll to create the complete
interconnected copy of all those things.
Previous Topic:[EMF] two models, using only one editor
Next Topic:[Ecore Editor] Add Additional Resources programmatically
Goto Forum:
  


Current Time: Thu Aug 21 00:32:35 EDT 2014

Powered by FUDForum. Page generated in 0.10481 seconds