Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » UML2 » Insert Package Content into another Package
Insert Package Content into another Package [message #902183] Thu, 16 August 2012 09:22 Go to next message
Tex Iano is currently offline 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 Smile 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 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 4098
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&lt;Normalizer&gt; 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.&lt;String, Object&gt; emptyMap());
<br>
            DiffModel diff = DiffService.doDiff(match, false);
<br>
            List&lt;DiffElement&gt; differences = new
ArrayList&lt;DiffElement&gt;(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.&lt;String, Object&gt; emptyMap());
<br>
<br>
or
<br>
<br>
            match = MatchService.doMatch(source, target,
Collections.&lt;String, Object&gt; 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 #902192 is a reply to message #902191] Thu, 16 August 2012 09:42 Go to previous messageGo to next message
Tex Iano is currently offline Tex Iano
Messages: 99
Registered: February 2012
Member
Hey Ed,

ok thanks. Will try to assign the IDs manually.

Regards,

Tex
Re: Insert Package Content into another Package [message #902210 is a reply to message #902183] Thu, 16 August 2012 11:41 Go to previous messageGo to next message
Tex Iano is currently offline 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 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 4098
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 Go to previous messageGo to next message
Tex Iano is currently offline 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

Re: Insert Package Content into another Package [message #902355 is a reply to message #902336] Fri, 17 August 2012 09:35 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 4098
Registered: July 2009
Senior Member
Hi

If you examine the XMI file you will see that stereotype applications
are a kludge; it seems whoever decided on the XMI format didn't want to
use models!

So you either need to handle them separately or find a UMLUtil helper
that does it for you.

Regards

Ed Willink


On 17/08/2012 08:04, Tex Iano wrote:
> 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.
>
>
> 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
Re: Insert Package Content into another Package [message #902359 is a reply to message #902355] Fri, 17 August 2012 10:11 Go to previous messageGo to next message
Tex Iano is currently offline Tex Iano
Messages: 99
Registered: February 2012
Member
Hi Ed,

yes, I know how they are stored. So I added these lines:

// targetStereotypes contains the copied stereotypes
for (EObject o : targetStereotypes) {
			targetResource.getContents().add(o);
		
		}


The stereotypes are stored. But obviously I have to reload the resource. Can this be? Because otherwise the manually added stereotypes are not recognized.

After reloading the resource everything is ok. Is this the solution? Or is there something like a reload Stereotypes? Smile

Regards,

Tex
Re: Insert Package Content into another Package [message #902368 is a reply to message #902359] Fri, 17 August 2012 11:02 Go to previous messageGo to next message
Ed Willink is currently offline Ed Willink
Messages: 4098
Registered: July 2009
Senior Member
Hi

I've no idea; I'm still learning. You may have noticed that the current
and former UML committers rarely respond on this newsgroup.

Regards

Ed Willink


On 17/08/2012 11:11, Tex Iano wrote:
> Hi Ed,
>
> yes, I know how they are stored. So I added these lines:
>
>
> // targetStereotypes contains the copied stereotypes
> for (EObject o : targetStereotypes) {
> targetResource.getContents().add(o);
>
> }
>
>
> The stereotypes are stored. But obviously I have to reload the
> resource. Can this be? Because otherwise the manually added
> stereotypes are not recognized.
>
> After reloading the resource everything is ok. Is this the solution?
> Or is there something like a reload Stereotypes? :)
>
> Regards,
>
> Tex
Re: Insert Package Content into another Package [message #902369 is a reply to message #902368] Fri, 17 August 2012 11:13 Go to previous message
Tex Iano is currently offline Tex Iano
Messages: 99
Registered: February 2012
Member
Hi,

yeah, I see. But thank you very much for your help. My solution: Saving and reloading the model and everything is as I expect it to be Smile

So obviously changing the resource directly outside the scope of the model (i.e. at the place where the stereotypes are added) does not impact the model directly without reloading.

Regards,

Tex
Previous Topic:Possible Children
Next Topic:Persons and Responsibilities
Goto Forum:
  


Current Time: Sun Oct 26 04:34:36 GMT 2014

Powered by FUDForum. Page generated in 0.02002 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software