Home » Modeling » UML2 » Insert Package Content into another Package
Insert Package Content into another Package [message #902183] |
Thu, 16 August 2012 09:22 |
Tex Iano Messages: 99 Registered: February 2012 |
Member |
|
|
Hi,
I have the following situation: I have two models loaded and selected one certain package A of model 1 and one package B of model 2. Now I want to copy the content of packge A into package B.
Package A can even be the model itself, but as a UML Model is a UML Package too, this should not be a problem.
The important point: I want to keep the XMI IDs of the elements. This is what I have tried first:
public void insertElements(Package source, Package target) {
for (PackageableElement element : source.getPackagedElements()) {
target.getPackagedElements().add(EcoreUtil.copy(element));
}
}
This works good, but the IDs are not kept (as I copy the elements), which is very important. As the packages are within different models there should be no ID collision.
public void insertElements(Package source, Package target) {
for (PackageableElement element : source.getPackagedElements()) {
target.getPackagedElements().add(element);
}
}
This result in a concurrent manipulation of the model with an exception.
So, another way I tried is EMF Compare:
try {
match = MatchService.doMatch(target, source, Collections.<String, Object> emptyMap());
DiffModel diff = DiffService.doDiff(match, false);
List<DiffElement> differences = new ArrayList<DiffElement>(diff.getOwnedElements());
MergeService.merge(differences, true);
System.out.println(diff);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
However in this case, the packages are compared. I am not sure, which is the right order:
match = MatchService.doMatch(target, source, Collections.<String, Object> emptyMap());
or
match = MatchService.doMatch(source, target, Collections.<String, Object> emptyMap());
But the first one seems to be what I am looking for.
So, the result is, that the package is different. Of course it is. This is why I want to insert the elements But the merge does not insert the elements. What I need is not to compare the packages but the content. Can I use EMF Compare for this purpose? Can I set an option that not the package as container is compared but the elements?
Regards,
Tex
|
|
|
Re: Insert Package Content into another Package [message #902191 is a reply to message #902183] |
Thu, 16 August 2012 09:36 |
Ed Willink Messages: 7655 Registered: July 2009 |
Senior Member |
|
|
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">Hi<br>
<br>
The UML tooling is a bit enthusiastic about losing XMI ids,
however in your scenario, your copied objects are <b>not</b> the
same objects so losing the ids seems entirely correct.<br>
<br>
If your appliocation can justify the preservation, then you need
to cache the old ids, maintain an old-to-new object map (Use the
copier's one) and then assign the ids to the new objects yourself.<br>
<br>
When used programmatically, EMF Compare has a variety of control
options. For simple comparison of 'identical' models,
org.eclipse.xtext.util.EmfFormatter is very useful, providing
simple text that differences nicely in the JUnit viewer.
(Normalizer is an enhancement to adjust irrelevant differences.)<br>
<br>
public static void assertSameModel(Resource expectedResource,
Resource actualResource) throws IOException, InterruptedException
{<br>
// Set<Normalizer> normalizations =
normalize(expectedResource);<br>
String expected =
EmfFormatter.listToStr(expectedResource.getContents());<br>
String actual =
EmfFormatter.listToStr(actualResource.getContents());<br>
assertEquals(expected, actual);<br>
// for (Normalizer normalizer : normalizations) {<br>
// normalizer.denormalize();<br>
// }<br>
}<br>
<br>
Regards<br>
<br>
Ed Willink<br>
<br>
On 16/08/2012 10:22, Tex Iano wrote:<br>
</div>
<blockquote cite="mid:k0ie4a$bim$1@xxxxxxxxe.org" type="cite">Hi,
<br>
<br>
I have the following situation: I have two models loaded and
selected one certain package A of model 1 and one package B of
model 2. Now I want to copy the content of packge A into package
B.
<br>
<br>
Package A can even be the model itself, but as a UML Model is a
UML Package too, this should not be a problem.
<br>
<br>
The important point: I want to keep the XMI IDs of the elements.
This is what I have tried first:
<br>
<br>
<br>
public void insertElements(Package source, Package target) {
<br>
<br>
<br>
for (PackageableElement element :
source.getPackagedElements()) {
<br>
target.getPackagedElements().add(EcoreUtil.copy(element));
<br>
}
<br>
} <br>
<br>
<br>
This works good, but the IDs are not kept (as I copy the
elements), which is very important. As the packages are within
different models there should be no ID collision.
<br>
<br>
<br>
public void insertElements(Package source, Package target) {
<br>
<br>
<br>
for (PackageableElement element :
source.getPackagedElements()) {
<br>
target.getPackagedElements().add(element);
<br>
}
<br>
} <br>
<br>
<br>
This result in a concurrent manipulation of the model with an
exception.
<br>
<br>
So, another way I tried is EMF Compare:
<br>
<br>
<br>
<br>
try {
<br>
<br>
match = MatchService.doMatch(target, source,
Collections.<String, Object> emptyMap());
<br>
DiffModel diff = DiffService.doDiff(match, false);
<br>
List<DiffElement> differences = new
ArrayList<DiffElement>(diff.getOwnedElements());
<br>
MergeService.merge(differences, true);
<br>
System.out.println(diff);
<br>
<br>
} catch (InterruptedException e) {
<br>
// TODO Auto-generated catch block
<br>
e.printStackTrace();
<br>
}
<br>
<br>
<br>
However in this case, the packages are compared. I am not sure,
which is the right order: <br>
<br>
<br>
match = MatchService.doMatch(target, source,
Collections.<String, Object> emptyMap());
<br>
<br>
or
<br>
<br>
match = MatchService.doMatch(source, target,
Collections.<String, Object> emptyMap());
<br>
<br>
<br>
But the first one seems to be what I am looking for.
<br>
<br>
So, the result is, that the package is different. Of course it is.
This is why I want to insert the elements :) But the merge does
not insert the elements. What I need is not to compare the
packages but the content. Can I use EMF Compare for this purpose?
Can I set an option that not the package as container is compared
but the elements?
<br>
<br>
Regards,
<br>
<br>
Tex
<br>
</blockquote>
<br>
</body>
</html>
|
|
| |
Re: Insert Package Content into another Package [message #902210 is a reply to message #902183] |
Thu, 16 August 2012 11:41 |
Tex Iano Messages: 99 Registered: February 2012 |
Member |
|
|
Hi,
maybe you can give me one more hint.
Map<EObject, String> originalIds = new HashMap<EObject, String>();
Map<EObject, String> newIds = new HashMap<EObject, String>();
Copier copier = new Copier();
for (Iterator<Object> allContents = UMLUtil.getAllContents(source,
false, false); allContents.hasNext();) {
Object o = allContents.next();
if (!(o instanceof EObject)) continue;
EObject eObject = (EObject)o;
String id = sourceResource.getID(eObject);
originalIds.put(eObject, id);
EObject newObject = copier.copy(eObject);
newIds.put(newObject, id);
if (newObject instanceof Element) {
target.allOwnedElements().add((Element)newObject);
}
}
copier.copyReferences();
This is what I have done so far. I am traversing the tree of the source and get all eObject. I store the original ID and create a copy using the Copier.
But how can I embed the copied object (newObject) into the target UML Package? target.allOwnedElements().add does not work. Or do I have to do this recursively? I.e. copying one element, adding it to the target, selecting the children, copying to the previously copied element etc....
But how can I add an eObject to the target?
Regards,
Tex
|
|
|
Re: Insert Package Content into another Package [message #902213 is a reply to message #902210] |
Thu, 16 August 2012 11:56 |
Ed Willink Messages: 7655 Registered: July 2009 |
Senior Member |
|
|
Hi
allOwnedElements() is a derived union property. You must add to the
appropriate subset so that UML knows what's going on.
Regards
Ed Willink
On 16/08/2012 12:41, Tex Iano wrote:
> Hi,
>
> maybe you can give me one more hint.
>
> Map<EObject, String> originalIds = new HashMap<EObject,
> String>();
> Map<EObject, String> newIds = new HashMap<EObject, String>();
> Copier copier = new Copier();
>
> for (Iterator<Object> allContents =
> UMLUtil.getAllContents(source,
> false, false); allContents.hasNext();) {
>
> Object o = allContents.next();
>
> if (!(o instanceof EObject)) continue;
>
> EObject eObject = (EObject)o;
>
> String id = sourceResource.getID(eObject);
> originalIds.put(eObject, id);
>
> EObject newObject = copier.copy(eObject);
> newIds.put(newObject, id);
>
> if (newObject instanceof Element) {
> target.allOwnedElements().add((Element)newObject);
>
> }
>
> }
>
> copier.copyReferences();
>
>
> This is what I have done so far. I am traversing the tree of the
> source and get all eObject. I store the original ID and create a copy
> using the Copier.
>
> But how can I embed the copied object (newObject) into the target UML
> Package? target.allOwnedElements().add does not work. Or do I have to
> do this recursively? I.e. copying one element, adding it to the
> target, selecting the children, copying to the previously copied
> element etc....
>
> But how can I add an eObject to the target?
> Regards,
>
> Tex
|
|
|
Re: Insert Package Content into another Package [message #902336 is a reply to message #902183] |
Fri, 17 August 2012 07:04 |
Tex Iano Messages: 99 Registered: February 2012 |
Member |
|
|
Hi,
well it is still not working. Here is my code:
public void insertElements(Package source, Package target) {
List<EObject> sourceObjects = new ArrayList<EObject>();
List<EObject> sourceStereotypes = new ArrayList<EObject>();
// Get the packaged elements
for (PackageableElement e : source.getPackagedElements()) {
EObject sourceObject = (EObject) e;
sourceObjects.add(sourceObject);
}
// Get the applied stereotypes
for (EObject o : sourceObjects) {
if (o instanceof Element) {
sourceStereotypes.addAll(((Element) o)
.getStereotypeApplications());
}
Iterator<EObject> contentIterator = o.eAllContents();
while(contentIterator.hasNext()) {
EObject content = contentIterator.next();
if(content instanceof Element) {
sourceStereotypes.addAll(((Element)content).getStereotypeApplications());
}
}
}
sourceObjects.addAll(sourceStereotypes);
// Copy packaged elements and all contained stereotypes
Copier copier = new Copier();
copier.copyAll(sourceObjects);
copier.copyReferences();
// For each packaged element within source add the copy to the target
for (EObject o : source.getPackagedElements()) {
target.getPackagedElements().add((PackageableElement)copier.get(o));
}
}
I am still trying to copy elements. The ID problem is not treated yet.
Well, the code works, and elements are copied. However, the applied stereotypes are not. They are found within the source and are copied by the Copier. And when I request getStereotypeApplications on the copied elements they are found. But unfortunately they are not inserted into the target model. Concretely:
for (EObject o : copier.values()) {
if (o instanceof Element) ((Element)o).getStereotypeApplications(); // Here the stereotypes are found
}
In this example the stereotypes are not found.
for (Iterator<Object> allContents = UMLUtil.getAllContents(target,
false, false); allContents.hasNext();) {
Object o = allContents.next();
if (!(o instanceof EObject))
continue;
EObject sourceObject = (EObject) o;
if (sourceObject instanceof Element) {
System.out.println(((Element)sourceObject).getStereotypeApplications());
}
}
I.e. the stereotypes are not correctly inserted into the target model
Maybe there is something wrong in the way how I add the copied elements to the target. I only add the packagedElements. But obviously automatically all children are inserted too.
Regards,
Tex
[Updated on: Fri, 17 August 2012 07:07] Report message to a moderator
|
|
| | | | |
Goto Forum:
Current Time: Tue Apr 23 12:13:50 GMT 2024
Powered by FUDForum. Page generated in 0.05065 seconds
|