4

I created a class diagram using papyrus and I got a *.uml model. Now I want to iterate through the *.uml elements by writing some Java Code.

I tried this code:

URI uri = URI.createURI("*.uml");

ResourceSet set = new ResourceSetImpl();

set.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
set.getResourceFactoryRegistry().getExtensionToFactoryMap()
       .put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
EPackage.Registry.INSTANCE.put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap()
       .put("uml", UMLResource.Factory.INSTANCE);

set.getResourceFactoryRegistry().getExtensionToFactoryMap()
       .put("xmi", new XMIResourceFactoryImpl());
//set.createResource(uri);
Resource res = set.getResource(URI.createURI(new URL("*.uml").toString(),true),true);

but I got exception:

Exception in thread "main" java.lang.NoSuchMethodError: org.eclipse.emf.ecore.resource.URIConverter.createInputStream( Lorg/eclipse/emf/common/util/URI;Ljava/util/Map;)Ljava/io/InputStream;

How can I load papyrus uml model by using Java?

Keale
  • 3,924
  • 3
  • 29
  • 46
Ahmadkt
  • 91
  • 6

1 Answers1

7

You've got almost everything, it misses only few details and there is some lines to remove.

But first, .uml files are not directly related to Papyrus. Papyrus is able to produce .uml files, but they are not Papyrus files only. This file extension is managed by the UML plugin which provides the UML metamodel (defined in Ecore), it's implementation and different facilities to handle these files.

If we take your code:

ResourceSet set = new ResourceSetImpl();
set.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
set.getResourceFactoryRegistry().getExtensionToFactoryMap()
   .put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap()
   .put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);

This part should be enough to register the UML metamodel and its factory to your ResourceSet.

This line:

EPackage.Registry.INSTANCE.put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);

is not required as long as you use set to load your model. The package Registry contained in ResourceSetImpl is hierachical: if it cannot find your metamodel package instance linked to the metamodel URI, it tries to find it in the global EPackage.Registry. So, Either you register the binding (URI string, EPackage instance) in the global registry or you register the binding in your ResourceSet instance. Both is not required.

Also, the xmi factory registering is not required too in your case.

Finally, the resource loading using the getResource from ResourcetSet is almost good, here is the modified version:

Resource res = set.getResource(URI.createFileURI("/path/to/my_model.uml"), true);

This fragment creates a URI which points to a file on your disk and load it. From your resource, you can then access your elements using the getContents() method.

res.getContents().get(0); // For example to get the root of your model.

Also, try to use the UMLUtil, UML2Util and the EcoreUtil static classes as much as possible, it provides a lot of facilities to find/copy/filter... elements

Here is the final fragment I used:

ResourceSet set = new ResourceSetImpl();
set.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
set.getResourceFactoryRegistry().getExtensionToFactoryMap()
   .put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap()
   .put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);

Resource res = set.getResource(URI.createFileURI("/path/to/my_model.uml"), true);

EDIT > Most part of the issue is the EMF versions used. Going from EMF 2.3 to >2.4 fixed the exception throwing. The rest of the answer is still valid in order to clean the unecessary code.

Vincent Aranega
  • 1,441
  • 10
  • 21
  • Thank you so much, another question plz. How can i iterate through model elements and how to know the type for every element ? – Ahmadkt Dec 03 '15 at 19:28
  • You can test each eobject as you do for normal java object: _e.g._: `if (myobj instanceof org.eclipse.uml2.uml.Class) {...}`. As an alternative way, you can also check the metaclass through the `eClass()` method: _e.g._: `if (myobj.eClass() == UMLPackage.eInstance.getClass_()) {...}`. If you need to filter elements, you can play with the `UMLUtil.findEObject(...)` method which takes a collection and a filter (there is also a lot of other methods in this class). – Vincent Aranega Dec 03 '15 at 20:23
  • @Ahmadkt its quite late from when the question was asked, but I want to remind you that you forgot to accpet the answer as correct. – Ruli Mar 09 '22 at 13:57