Loading UML Model with model library in standalone [message #1834166] |
Wed, 04 November 2020 09:14 |
Jonas Geschke Messages: 9 Registered: November 2020 |
Junior Member |
|
|
I am trying to load a uml model that I designed in Papyrus with a custom profile and a common model library. I managed to successfully load the profile and afterwards loading the model with resolved cross references. However I do not understand how to load the model library in addition, since all referenced classifiers from the model library are not resolved (are eProxies).
Do I have to add the model library only to the URIConverterMap or do I have to register the package of the model library in the factory map as well?
This is my code for loading a profile from a File URI and add it to a given resourceSet2:
ResourceSet resourceSet = new ResourceSetImpl();
UMLResourcesUtil.initLocalRegistries(resourceSet);
Resource resource = resourceSet.createResource(profileFileUri);
Map<Object, Object> optionsMap = new HashMap<>();
optionsMap.put("OPTION_RESOLVE", true);
try {
resource.load(optionsMap);
} catch (IOException e) {
e.printStackTrace();
System.err.println("Could not load profile: " + profileFileUri.toString());
}
EcoreUtil.resolveAll(resource);
Profile profile = (Profile) EcoreUtil.getObjectByType(resource.getContents(), UMLPackage.Literals.PROFILE);
EPackage profilePackageDefinition = profile.getDefinition();
resourceSet2.getPackageRegistry().put(profilePackageDefinition.getNsURI(), profilePackageDefinition);
UMLPlugin.getEPackageNsURIToProfileLocationMap().put(profilePackageDefinition.getNsURI(), profileURI);
resourceSet2.getResourceFactoryRegistry().getContentTypeToFactoryMap().put(profilePackageDefinition.getNsURI(), profilePackageDefinition.getEFactoryInstance());
And this is my code to load the model itself from a given modelInputStream:
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("uml", UMLResource.Factory.INSTANCE);
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("uml2", UMLResource.Factory.INSTANCE);
ResourceSet resourceSet = new ResourceSetImpl();
UMLResourcesUtil.initLocalRegistries(resourceSet);
// here I register the profile with the above code
URI uri = URI.createURI("file:///anonymous.uml");
URIConverter.URI_MAP.put(URI.createURI(UMLResource.LIBRARIES_PATHMAP), uri.appendSegment("libraries").appendSegment(""));
URIConverter.URI_MAP.put(URI.createURI(UMLResource.METAMODELS_PATHMAP), uri.appendSegment("metamodels").appendSegment(""));
URIConverter.URI_MAP.put(URI.createURI(UMLResource.PROFILES_PATHMAP), uri.appendSegment("profiles").appendSegment(""));
URIConverter.URI_MAP.put(URI.createURI(UMLResource.ECORE_PRIMITIVE_TYPES_LIBRARY_URI), uri.appendSegment("ecore_primitive_types").appendSegment(""));
URIConverter.URI_MAP.put(URI.createURI(UMLResource.LIBRARIES_PATHMAP), URI.createFileURI(library));
Resource resource = resourceSet.createResource(uri);
org.eclipse.uml2.uml.Model mModel = null;
try {
Map<Object, Object> optionsMap = new HashMap<>();
optionsMap.put("OPTION_RESOLVE", true); // Is this option relevant? Since XMLResource does not contain it.
optionsMap.put(XMLResource.OPTION_DEFER_IDREF_RESOLUTION, true);
resource.load(modelInputStream, optionsMap);
DEBUG.info("... loaded");
EcoreUtil.resolveAll(resource);
DEBUG.info("... resolved");
mModel = (org.eclipse.uml2.uml.Model)EcoreUtil.getObjectByType(resource.getContents(), UMLPackage.Literals.MODEL);
DEBUG.info("... done");
// mModel = (org.eclipse.uml2.uml.Model)resource.getContents().get(0);
// EcoreUtil.resolveAll(mModel);
}
catch (Exception e) {
e.printStackTrace();
throw new UModelException("XMI 2.1 parsing failed: " + e);
}
if (mModel == null)
throw new UModelException("No model found in XMI 2.1 input");
|
|
|
|
|
|
Re: Loading UML Model with model library in standalone [message #1834221 is a reply to message #1834214] |
Thu, 05 November 2020 09:46 |
German Vega Messages: 104 Registered: December 2015 Location: Grenoble, France |
Senior Member |
|
|
Hi,
You have two things to do to make this work in standalone , setting up appropriately all the registries in the ResourceSet, and setting up your classpath with all the appropriate dependencies.
For setting up the ResourcSet use UMLResourcesUtil.init() ** not UMLResourcesUtil.initLocalRegistries() ** it will take care of the file extension registration, mapping pathmaps that you are doing manually
Something like this (not tested, just copy/pasted snippets from my own code) should work
ResourceSet resources= new ResourceSetImpl();
UMLResourcesUtil.init(resources);
URI profileURI = URI.createFileURI(*** your profile file location *** );
Resource profileResource = resources.getResource(profileURI,true);
Profile profile = (Profile ) EcoreUtil.getObjectByType(profileResource.getContents(),UMLPackage.Literals.PROFILE);
EPackage definitionPackage = (EPackage) profile.getDefinition();
resources.getPackageRegistry().put(definitionPackage.getNsURI(),definitionPackage);
UMLPlugin.getEPackageNsURIToProfileLocationMap().put(definitionPackage.getNsURI(), EcoreUtil.getURI(profile));
URI modelURI = URI.createFileURI(** your model file location **);
Resource modelResource =resources.getResource(modelURI , true);
Package umlPackage = (Package) EcoreUtil.getObjectByType(modelResource.getContents(),UMLPackage.Literals.PACKAGE);
If your common library is referenced using relatives URIs that point to the right place in the file system this should be enough to lazily load the library when resolving proxies. However if your file directory structure is not the same as your workspace project structure you may have problems.
Where is located your common library? open your UML model with a text file editor and look at the URI used to reference the elements in the library.
If the URIs do not map well to your file system structure , you may need to add an URI mapping to the resource set
something like this (not tested)
/*
* The logical location of the library
*/
URI libraryURI = URI.createURI(** the resolved absolute URI of the library as referenced from the model**);
/*
* The physical location of the library
*/
URI libraryLocation = URI.createFileURI(** your library file location **);
/*
* Map the logical location to the corresponding physical location
*
*/
resources.getURIConverter().getURIMap().put(libraryURI,libraryLocation );
Have you tried to print the proxy URi for the unresolved elements of the library?
[Updated on: Thu, 05 November 2020 12:27] Report message to a moderator
|
|
|
|
Powered by
FUDForum. Page generated in 0.02344 seconds