Copying a UML2 model including a deep copy of PackageImports [message #1717508] |
Mon, 14 December 2015 08:24  |
Eclipse User |
|
|
|
Hi,
I'm using the EcoreUtil.copyAll(model.eResource().getContents()) API to make a copy of a model. This works fine but I also want the PackageImport'ed Packages to be copied so they will be local to the model also. So essentially I want one model with no external dependencies to other UML models.
I assume there is no API for doing this? I couldn't see one.
I then thought I could perform copyAll() on all the PackageImport'ed Packages but then I end up with a model for each PackageImport and it is tricky to get everything back into one model.
Any ideas?
Regards,
Ronan
|
|
|
Re: Copying a UML2 model including a deep copy of PackageImports [message #1717518 is a reply to message #1717508] |
Mon, 14 December 2015 09:22   |
Eclipse User |
|
|
|
Hi, Ronan,
You can customize the copy behaviour by defining a subclass of the
EcoreUtil.Copier and overriding/extending methods such as the various
copyReference(...) and friends. This would let you, for example, copy
the model referenced by a PackageImport::importedPackage. You would
still have to find a suitable place to contain such a copied package,
of course, because it would be a root element. There's simply no way
around that.
HTH,
Christian
On 2015-12-14 13:24:39 +0000, Ronan B said:
> Hi,
> I'm using the EcoreUtil.copyAll(model.eResource().getContents()) API to
> make a copy of a model. This works fine but I also want the
> PackageImport'ed Packages to be copied so they will be local to the
> model also. So essentially I want one model with no external
> dependencies to other UML models.
>
> I assume there is no API for doing this? I couldn't see one.
> I then thought I could perform copyAll() on all the PackageImport'ed
> Packages but then I end up with a model for each PackageImport and it
> is tricky to get everything back into one model.
>
> Any ideas?
> Regards,
> Ronan
|
|
|
|
|
Re: Copying a UML2 model including a deep copy of PackageImports [message #1717893 is a reply to message #1717883] |
Thu, 17 December 2015 09:13   |
Eclipse User |
|
|
|
Hi, Ronan,
The reference type's instance-class will be something that conforms to
the PackageImport interface, yes, but the result of eGet on the feature
will be an EList of some kind.
So, you might try something like this, typed directly into this usenet
reader and not tested in the slightest:
-------- 8< --------
if (eReference != UMLPackage.Literals.PACKAGE__PACKAGE_IMPORT) {
// Copy non-PackageImports in the usual way
super.copyContainment(eReference, eObject, copyEObject);
} else {
Collection<?> imports = (Collection<?>) eObject.eGet(eReference);
List<PackageImport> libraryImports = new ArrayList<>(imports.size());
// Collect all imports of model libraries
for (Object next : imports) {
PackageImport nextImport = (PackageImport)next;
if ((nextImport.getImportedPackage() != null)
&& nextImport.getImportedPackage().isModelLibrary()) {
libraryImports.add(nextImport);
}
}
// And copy them into the copied package. This must be a package
// if it has the package-import feature
ECollections.setEList(((Package) copyEObject).getPackageImports(),
copyAll(libraryImports));
}
-------- >8 --------
HTH,
Christian
On 2015-12-17 13:54:48 +0000, Ronan B said:
> Hi,
> I have had some time to make some progress on this. I now have a
> prototype but I am having trouble with the following bit where I
> override the copyContainment part of the Copier to *not* copy
> PackageImports which target packages which are not model libraries. The
> code is as follows:
>
> @Override
> protected void copyContainment(EReference eReference, EObject eObject,
> EObject copyEObject)
> {
> if(!(eReference.getEType().getInstanceClass().equals(PackageImport.class)))
> {
> //Copy non PackageImports untouched
> super.copyContainment(eReference,eObject, copyEObject);
> }
> else
> {
> //Copy PackageImports that target library models but not other models
> /*
> PackageImport pi = (PackageImport)eObject.eGet(eReference);
> if(pi.getImportedPackage().isModelLibrary())
> {
> //the PackageImport is to a library so copy it
> super.copyContainment(eReference,eObject, copyEObject);
> }
> */
> }
> }
> The problem is that i'm not getting access to the PackageImport
> instance in the commented out section to be able to differentiate
> whether the PackageImport is to a library or not.
|
|
|
Re: Copying a UML2 model including a deep copy of PackageImports [message #1718006 is a reply to message #1717893] |
Fri, 18 December 2015 09:09   |
Eclipse User |
|
|
|
Hi Christian,
Thanks for the excellent input. Only a few modifications needed to get it running Below is the modified code. Just 2 issues remain. One of which I'd like to follow up on. I'd like to "//deep copy packages which are not model libraries", as commented below, but the stereotypes get lost in the move. I assume this is because I don't actually pass in the eResource() contents into the copy, instead I'm passing in the packages to be copied. Any clues as to what I should do?
Copier copier = new Copier(true){
@Override
protected void copyContainment(EReference eReference, EObject eObject, EObject copyEObject)
{
if(eReference.getEReferenceType() != UMLPackage.Literals.PACKAGE_IMPORT)
{
// Copy non-PackageImports without modification
super.copyContainment(eReference,eObject, copyEObject);
}
else
{
//Check to see if a PackageImports is a <<ModelLibrary>> or not. <<ModelLibrary>> packages should be copied.
Collection<?> packageImportRef = (Collection<?>) eObject.eGet(eReference);
List<PackageImport> piModelLibraryList = new ArrayList<>(packageImportRef.size());
// Collect all imports of model libraries
for (Object next : packageImportRef)
{
PackageImport pi = (PackageImport)next;
if ((pi.getImportedPackage() != null) && pi.getImportedPackage().isModelLibrary())
{
//add model libraries to be copied
piModelLibraryList.add(pi);
}
//TODO:Working on this bit below
else if((pi.getImportedPackage() != null) && !pi.getImportedPackage().isModelLibrary())
{
//deep copy packages which are not model libraries
org.eclipse.uml2.uml.Package p = pi.getImportedPackage();
List<org.eclipse.uml2.uml.Package> piPackageList = new ArrayList<>();
//add the new package and the existing ones to the list
piPackageList.add(p);
piPackageList.addAll(((org.eclipse.uml2.uml.Package) copyEObject).getNestedPackages());
Copier piCopier = new Copier(true);
//Collection<EObject> results2 = piCopier.copyAll(p.eResource().getContents());
//Collection<EObject> results2 = piCopier.copyAll(p.allOwnedElements());
//piCopier.copyReferences();
//List list = new ArrayList(results2);
//TODO:Stereotypes on the copied package are lost!
//TODO:If the original model has Packages which are not PackageImports then the copying
//procedure doesn't work for the non model library packageimported models
//i.e. only the original package models are shown
ECollections.setEList(((org.eclipse.uml2.uml.Package) copyEObject).getNestedPackages(),
(List<? extends org.eclipse.uml2.uml.Package>) piCopier.copyAll(piPackageList));
piCopier.copyReferences();
}
}
// Copy the imports into the copied package.
ECollections.setEList(((org.eclipse.uml2.uml.Package) copyEObject).getPackageImports(),
(List<? extends PackageImport>) copyAll(piModelLibraryList));
}
}
};
Regards,
Ronan
|
|
|
Re: Copying a UML2 model including a deep copy of PackageImports [message #1719515 is a reply to message #1718006] |
Fri, 08 January 2016 09:36  |
Eclipse User |
|
|
|
Hi,
Just getting back to this after the Christmas. I have created, and attached, a sample plugin along with some test models to demonstrate the problems i'm having. It seems to be non trivial to fix this, in fact I suspect it might not be possible for the #2 result below to work at all. The 2 issues I reported before persist.
Assuming you have the plugin "UMLPICopy" deployed, select one of the test models from the Project SamplePIModels and use the context menu to select "Copy Package Imports". You will see the following incorrect results:
1) When running off the model "MyInput.uml" the PackageImport B is totally lost. The expected result is that it should be deep copied. The presence of the Package D causes this.
2) When running off the model "MyInputNoD.uml" the PackageImport B is copied as expected but the stereotypes on B and its children are lost.
Any tips appreciated!
Regards,
Ronan
|
|
|
Powered by
FUDForum. Page generated in 0.20479 seconds