|
|
|
Re: EcoreUtil.copy() that copies derived/noncontainment features? [message #668541 is a reply to message #668493] |
Fri, 06 May 2011 07:29 |
Ed Merks Messages: 33113 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.
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Powered by
FUDForum. Page generated in 0.05157 seconds