Home » Modeling » Epsilon » Accessing OSGi component instance(Possibility of using pre-existing Native instances in ETL)
Accessing OSGi component instance [message #1787545] |
Mon, 28 May 2018 15:06 |
Flavio Costa Messages: 23 Registered: February 2018 |
Junior Member |
|
|
Hello,
My source model may contain expressions that I want to resolve/calculate during the model transformation, using information available on runtime. For instance, the source model may have mayDrink="currentUser.age > 18" and the equivalent value on the target model may be mayDrink=true.
This calculation is done by a class named ExpressionCalculator, and it is an OSGI component instantiated by the Equinox framework. If I do new Native("my.package.ExpressionCalculator") in the ETL script itself, I would not get the pre-existing component instance that I need to use.
After creating a standalone EtlModule module instance, how can I pass an object to it to be used as a Native variable? Ultimately, I'd like to do something like this inside the transformation rule:
target.mayDrink = calculator.asBoolean(source.mayDrink);
Thanks,
Flavio
[Updated on: Mon, 28 May 2018 15:12] Report message to a moderator
|
|
| | |
Re: Accessing OSGi component instance [message #1791091 is a reply to message #1790093] |
Fri, 22 June 2018 17:21 |
Flavio Costa Messages: 23 Registered: February 2018 |
Junior Member |
|
|
Hi Dimitris,
Regarding the issue mentioned above, of EPackage.Registry being empty, I found out that when the system finishes loading, the packages are gone... not sure where/why this happens, but I am able to retrieve a reference to the EPackage while the system is still loading, so this is fine for now.
I continued working on this approach of making usage of Java service objects in the transformation script and I have two other requirements you can probably help with:
1) Injecting an import statement at runtime
The ETL module is currently loaded as follows:
URL etlScript = this.getClass().getResource("myfile.etl");
IEtlModule etlModule = new EtlModule();
module.parse(etlScript.toURI());
Now for the "myfile.etl" that is provided by the end-user, I'd like to make all rules defined in another file such as "library.etl" to be made available transparently. In order words, I want the Java code to make the user-provided ETL module import this "library.etl" without the user having to put an explicit import statement on their script.
I guess that something such as etlModule.getImports().add(...); could allow that, or maybe there is a way to parse both files and somehow combine them. Can you help me understand how something like this can be achieved?
2) Using org.eclipse.epsilon.eol.dom to generate and calculate expressions at runtime
The aforementioned ExpressionCalculator class essentially takes an expression represented in EMF/Xtext and produces a result (String, Integer, etc.) for this expression. However, I realize that this design may force me to introduce EMF dependencies to parts of the system where such dependencies are not welcome.
To prevent that, instead of performing the calculation directly with the Xtext input, I am trying to convert the Xtext expression tree into org.eclipse.epsilon.eol.dom.Expression, and then run
eolExpression.execute(context) , thus delegating the actual calculation logic to Epsilon. I am more comfortable with having Epsilon as a dependency instead of EMF, since Epsilon abstracts the source model technology so it can be eventually changed without impacting the rest of the system.
I did a quick test with boolean and arithmetic expressions, it works as expected. However, in certain expressions I also need to call a Java method to do some processing and I am not sure which Expression subclass to use for that. Is it PropertyCallExpression? Would it work if the method to be called is not named as a getter? What should I pass on the constructor?
Thanks,
Flavio
[Updated on: Fri, 22 June 2018 17:25] Report message to a moderator
|
|
|
Re: Accessing OSGi component instance [message #1791093 is a reply to message #1791091] |
Fri, 22 June 2018 17:40 |
|
Hi Flavio,
Regarding your first question, what you're proposing should work. See EolModule.getImportsByExtension for code that shows how to initialise imports.
I'm not sure I understand your second question. Could you please elaborate a bit more or provide some code I can run?
Thanks,
Dimitris
|
|
| | | | |
Re: Accessing OSGi component instance [message #1792105 is a reply to message #1791104] |
Wed, 11 July 2018 14:07 |
Flavio Costa Messages: 23 Registered: February 2018 |
Junior Member |
|
|
Hi Dimitris,
It's me again :)
This is how I did the programmatic import of another ETL module, I will leave the code here in case it's useful for anyone in the future:
private void addImplicitImport(IEtlModule etlModule, String importName) {
Import implicitImport = new Import();
implicitImport.setParent(etlModule);
implicitImport.setPathLiteral(new StringLiteral(importName));
implicitImport.setImportedModule(new EtlModule());
try {
implicitImport.load(this.getClass().getResource(importName).toURI());
etlModule.getImports().add(implicitImport);
} catch (URISyntaxException e) {
logger.error("Could not import the {} module: {}", importName, e.getMessage());
}
}
Other than this, while I move forward with my implementation I realize the best way of getting certain functionality may be by writing my own Expression subclasses, to add some custom logic to certain expressions. Can you please give me an overview of what the methods build(...) and compile(...) are expected to do and when they are used, so I can give them a proper implementations?
Thanks,
Flavio
|
|
| |
Re: Accessing OSGi component instance [message #1792154 is a reply to message #1792113] |
Thu, 12 July 2018 08:26 |
|
Hi Flavio,
build() builds ModuleElements from ASTs effectively decoupling execution code from the parser implementation. compile() performs static analysis and records warnings/errors but only a few classes implement it at the moment and analysis is very basic.
Regarding your AbstractModuleElement constructor question, I've tried moving the contents of the constructor to setParent and then calling the method from the constructor but a few of our tests fail after doing this. Could you please raise an enhancement request [1] so that we can investigate?
Cheers,
Dimitris
[1] https://bugs.eclipse.org/bugs/enter_bug.cgi?product=epsilon
|
|
|
Goto Forum:
Current Time: Thu Sep 26 21:12:44 GMT 2024
Powered by FUDForum. Page generated in 0.05444 seconds
|