Closed lwrage closed 5 years ago
FYI, you can do standalone application using the current mechanism (via extension point) if your standalone application is an osgi application (this is what we did to do non regression tests in RAMSES)
@Etienne13 Do you have any documentation that shows how to create such an osgi application?
Based on current work on #1387 I copied the revised AnnexRegistry
to this branch (1388_stand_alone_property_sets), and created another test program LoadDeclarativeModelAndContributedProperties
.
I'm using the test model
package test
public
annex fake {** fake **};
data d
properties
Source_language => (Java, C);
end d;
end test;
When I load it the verifier is unable to resolve the name of the property Source_Language
or of the enumeration elements Java
and C
:
Loading...
Validating...
Couldn't resolve reference to property definition 'Source_language'. Property set name may be missing.
Couldn't resolve reference to Property Constant, Property Definition, Enumeration or Unit literal 'Java'. For classifier references use classifier( <ref> ).
Couldn't resolve reference to Property Constant, Property Definition, Enumeration or Unit literal 'C'. For classifier references use classifier( <ref> ).
Packge test has duplicates /SEI/Tools/Eclipses/osate2_2018-12-develop-2019-02-13/ws/LoadDeclarativeModelAndContributedProperities/aadl_files/test.aadl
Traversing...
*** aadl_files/test.aadl ***
org.osate.aadl2.impl.AadlPackageImpl@31142d58 (name: test)
org.osate.aadl2.impl.PublicPackageSectionImpl@e38f0b7 (name: null) (noAnnexes: false, noProperties: false)
org.osate.aadl2.impl.DataTypeImpl@1192b58e (name: d) (noPrototypes: false, noAnnexes: false, noProperties: false) (derivedModes: false, noFlows: false, noModes: false) (noFeatures: false)
org.osate.aadl2.impl.PropertyAssociationImpl@4f8d86e4 (append: false, constant: false)
org.osate.aadl2.impl.ModalPropertyValueImpl@25f723b0 (name: null)
org.osate.aadl2.impl.ListValueImpl@4aa11206
org.osate.aadl2.impl.NamedValueImpl@40d60f2
org.osate.aadl2.impl.NamedValueImpl@6d8796c1
org.osate.aadl2.impl.DefaultAnnexLibraryImpl@784223e9 (name: fake) (sourceText: {** fake **})
org.osate.aadl2.impl.DefaultAnnexLibraryImpl@7316523a (name: fake) (sourceText: fake )
-- -- -- -- -- -- -- --
This is the problem that we need to fix: Having the contributed property sets installed and loaded.
Need to update PluginSupportUtil.getContributedAadl()
the same that I updated AnnexRegistry
. Probably should even merge the two fixes to make sure the extension registry is only created once.
I'm not entirely sure how the contributed aadl is loaded and "linked" in OSATE. But I think what I want to do here is provide a mechanism for getting the list of contributed aadl from the plugin.xml
files and then adding them to the ResourceSet
that is used by the stand-alone program.
See org.osate.testsupport.TestResourceSetHelper.initialize()
for loading of contributed resources. Pay attention to the URI mapping business.
As with #1387, supporting registration of contributions from the manifest files and through direct registration via method calls.
This is not working in any kind of straightforward way. I have modified the LoadDeclarativeModel
example from Issue #1387 to add some property sets to the resource set and to add them to the URI map as is done in org.osate.testsupport.TestResourceSetHelper.initialize()
.
final URI psURI1 = URI.createPlatformPluginURI(
"org.osate.workspace/resources/properties/Predeclared_Property_Sets/Programming_Properties.aadl",
false);
final URI psURI2 = URI.createPlatformPluginURI(
"org.osate.workspace/resources/properties/Predeclared_Property_Sets/AADL_Project.aadl",
false);
final List<Resource> resources = new ArrayList<>();
final Map<URI, URI> uriMap = rs.getURIConverter().getURIMap();
resources.add(rs.getResource(psURI1, true));
uriMap.put(psURI1, URI.createPlatformResourceURI(psURI1.path().substring(7), false));
resources.add(rs.getResource(psURI2, true));
uriMap.put(psURI2, URI.createPlatformResourceURI(psURI2.path().substring(7), false));
References are not being resolved between the property sets or the example that uses them:
...aadl_files/test.aadl
Couldn't resolve reference to property definition 'Source_language'. Property set name may be missing.
Couldn't resolve reference to Property Constant, Property Definition, Enumeration or Unit literal 'Java'. For classifier references use classifier( <ref> ).
Couldn't resolve reference to Property Constant, Property Definition, Enumeration or Unit literal 'C'. For classifier references use classifier( <ref> ).
Futhermore, all kinds of weird messages are output regarding the property sets:
Validating...
...platform:/plugin/org.osate.workspace/resources/properties/Predeclared_Property_Sets/Programming_Properties.aadl
1 [main] INFO t.linking.impl.ImportedNamesAdapter - getElements should be called with a QualifiedName during linking.
11 [main] INFO t.linking.impl.ImportedNamesAdapter - getElements should be called with a QualifiedName during linking.
17 [main] INFO t.linking.impl.ImportedNamesAdapter - getElements should be called with a QualifiedName during linking.
18 [main] INFO t.linking.impl.ImportedNamesAdapter - getElements should be called with a QualifiedName during linking.
19 [main] INFO t.linking.impl.ImportedNamesAdapter - getElements should be called with a QualifiedName during linking.
19 [main] INFO t.linking.impl.ImportedNamesAdapter - getElements should be called with a QualifiedName during linking.
20 [main] INFO t.linking.impl.ImportedNamesAdapter - getElements should be called with a QualifiedName during linking.
20 [main] INFO t.linking.impl.ImportedNamesAdapter - getElements should be called with a QualifiedName during linking.
21 [main] INFO t.linking.impl.ImportedNamesAdapter - getElements should be called with a QualifiedName during linking.
...
It is highly possible that the URI map we are creating is wrong. But it's unclear what it should be.
If you load the property sets from the local directory as a regular .aadl file, things do work correctly.
I have a version that works, at least it seems to resolve all references.
We still need a way to get the list of predeclared property sets in standalone mode.
Working on an example that reads the contributed resources from the plugin.xml extensions.
To run this kind of example you need to put the jars that contain the contributed resources on the classpath (this should be obvious), but you also need the jar for org.osate.pluginsupport
org.osate.pluginsupport
has the schema for the contributed resource extensionsjava -cp ".\runit.jar;.\org.osate.contribution.sei_1.0.0.v20190228-2050.jar;.\org.osat
e.workspace_1.0.0.v20180511-1311.jar;.\org.osate.pluginsupport_1.0.0.v20190403-1541.jar" org.osate.standalone.emf.LoadDeclarativeModelAndContributedProperties_extensions
Had to tweak AnnexRegistry
(more so than from the tweaks for #1387). It was not enough to check whether the extension registry is null
. Need also to check the extension point itself. If neither is present just install the default registry handler.
Not sure how to set up the URI map when loading the contributed resources from extensions automatically. I tried using the scheme from TestResourceSetHelper
but that doesn't seem to work.
When loading contributed resources from the extension registry, the URIs should be converted to classpath:/ URIs. I added a method to PluginSupportUtil
to get them in this format.
Summary of the important points here:
For the cross-references to work between the models, we must pretend that the file are organized as a project. For example, here we create a project "foo" that is in the directory aadl_files
of the current directory:
// URI mapping for loading files this defines the "workspace" needed to resolve relative references
String wsRoot = Paths.get(".").toAbsolutePath().normalize().toString();
EcorePlugin.getPlatformResourceMap().put("foo", URI.createFileURI(wsRoot + "/aadl_files/"));
The upshot of this is that when we load the files we refer to them as being in foo
and not in aadl_files
. So for example, if the names are being passed on the command line, they should be named foo/test.aadl
even though they are located in aadl_files/test.aadl
.
(In the future, there should probably be some library methods to make this process more transparent to the user of the program, but right now we don't have enough experience with how this is going to work in practice.)
As with annexes, there are two ways to proceed with finding the contributed resources.
To get the list of contributed resources from the plug-ins on the classpath, use
EcorePlugin.ExtensionProcessor.process(null);
final List<URI> contributed = PluginSupportUtil.getContributedAadlAsClasspath();
This is the same process()
method as for annexes. It only needs to be called once for the entire program to make sure that all the plugin.xml
files are read and processed. The method call PluginSupportUtil.getContributedAadlAsClasspath()
gets the URIs to all the contributed resources as classpath:/
URIs. You just add them to the resource set as you any other resource:
for (final URI uri : contributed) {
rs.getResource(uri, true);
}
When executing the program you need to make sure the plug-in jar files containing the contributed resources you need are on the classpath. You also need to have the the jar for org.osate.pluginsupport
on the classpath because it contains the scheme for the contributed aadl extension.
Searching all the plug-ins on the classpath can be slow, so it may be better to simply name the needed contributed resources directly. To do this you just create your own classpath:/
URIs. For example, if you need the resources AADL_Project.aadl
and Programming_Properties.aadl
you would use code like the following:
final String jar = "classpath:/";
final String path = "resources/properties/Predeclared_Property_Sets/";
final URI psURI1 = URI.createURI(jar + path + "AADL_Project.aadl");
final URI psURI2 = URI.createURI(jar + path + "Programming_Properties.aadl");
rs.getResource(psURI1, true);
rs.getResource(psURI2, true);
Note that you need to know the location of the contributed resource within the jar file.
Again, at runtime you need to make sure that the plugin jar file containing the contributed resources is on the classpath.
When directly loading the contributed resource, you must also set up the URI mappings to map the plug-in to the jar file. This is necessary so that names in instance models can be resolved correctly. (The URI map is set up by the process()
method when loading information from the plugin.xml
files.)
// set up URI mappings for reference resolution
final Map<URI, URI> uriMap = rs.getURIConverter().getURIMap();
// mapped URIs end in '/' => prefix mapping
uriMap.put(URI.createPlatformPluginURI("/org.osate.workspace/", false), URI.createURI(jar));
Here jar
still refers to "classpath:/"
as above. Here we map org.osate.workspace
because that is the plug-in that contains the contributed resources we are using. If we were using contributed resources from other plug-ins we would have to map those plug-ins as well.
(Again, should any one ever write a real program that uses this stuff we should probably create some library methods to help out with this process.)
Copied the above to the OSATE2 wiki: https://github.com/osate/osate2/wiki/Using-contributed-resources-in-stand-alone-applications
AADL model units are currently contributed via an extension point. We need a registry that can be populated programmatically to operate in standalone mode. child of #1538