Meshing ACCELEO and Xtext [message #901948] |
Wed, 15 August 2012 05:08  |
Eclipse User |
|
|
|
I am in the middle of an ACCELEO Transformation aimed at producing code (i.e. Java) from an input UML model.
Some elements of this UML model (i.e. Activities Opaque actions) contain some text which is conform to an Xtext grammar and I'd like to get the equivalent AST Ecore representation in the ACCELEO transformation.
To this end I have developed a Java class with a method which takes as input a string, containing the DSL excerpt, and produces an ECORE model conform to it (see http://www.eclipse.org/forums/index.php/m/901947/#msg_901947 for further details). I have tested it in a separate Java application and it seems it works properly.
I have therefore written a simple ACCELEO module (i.e. getDSLModel) wrapping that java class and enabling me to get the Ecore model from the DSL textual representation.
Suppose my DSL (and the equivalent ECORE) consist of a root element named DSLModel containing a (0..*) number of DSLStatements (this is a simplification).
When in ACCELEO I invoke the wrapper from a string, containing a correct dsl script, i have noticed it correctly returns a ModelImpl
['statement1;statement2'.getDSLModel()/]
so the Java service and the XText parse is working.
However if I try to get the model statements, i.e.:
['statement1;statement2'.getDSLModel().statements/]
it returns an **"invalid"** string. So I can't use it in a for loop
I have therefore tried to call the eAllContents() ocl service from the model instance i.e.:
['statement1;statement2'.getDSLModel().eAllContents()/]
and it actually returns the list of statements. I do not understand why the features of the Ecore entities returned from the Xtext parser are not working properly.
Any help would be very appreciated! Thank you
here is the Java service which turns a string into a instance of my DSL model (ECORE AST). I have tested it with an independent Java application and it works fine!
public class GetDSLModel {
public DSLModel getDSLModel(String expression){
DSLStandaloneSetupGenerated dslsas = new DSLStandaloneSetupGenerated();
Injector injector = dslsas.createInjectorAndDoEMFRegistration();
XtextResourceSet resourceSet = injector.getInstance(XtextResourceSet.class);
resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL, Boolean.TRUE);
Resource resource = resourceSet.createResource(URI.createURI("dummy:/example.dsl"));
InputStream in = new ByteArrayInputStream(expression.getBytes());
try {
resource.load(in, resourceSet.getLoadOptions());
DSLModel model = (DSLModel) resource.getContents().get(0);
return model;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
Now I need the AST in the main ACCELEO (UML2Text) transformation thus here is the Acceleo wrapper
[query public getDSLModel(str:String): DSLModel = (invoke('sfg.baleno.src.mloaders.GetDSLModel','getDSLModel(java.lang.String)',Sequence{str})).oclAsType(DSLModel)/]
here is what I get if run it
input: ['statement1;statement2'.getDSLModel()/]
output: mypackage.dsl.impl.DSLModelImpl@a1c7a
input: ['statement1;statement2'.getDSLModel().statements/] (Syntactically VALID)
output: invalid
input: ['statement1;statement2'.getDSLModel().eAllContents()/]
output: mypackage.dsl.impl.DSLStatement@e53202 (......
[Updated on: Wed, 15 August 2012 12:15] by Moderator
|
|
|
|
|
|
|
|
|
|
|
|
Re: Meshing ACCELEO and Xtext [message #902139 is a reply to message #902130] |
Thu, 16 August 2012 02:16   |
Eclipse User |
|
|
|
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">Hi<br>
<br>
You provide one erroneous class and expect help.<br>
<br>
I've no idea what it does, but it seems all wrong so just delete
it. Why would you expect your ResourceSet to coexist with
Acceleo's and Xtext's?<br>
<br>
Acceleo generates a Java file for your main template. That file is
full of comments about how to make it work standalone. Try reading
them.<br>
<br>
From the Acceleo documentation:<br>
<br>
<h3>Package registration</h3>
<p> You need to register the package that contains your
classifiers, in order to use it inside of your generator. To do
this, have a look at the method named "registerPackages" in the
Java launcher generated next to your main module. You need to
add the following piece of code: </p>
<pre> /**
* @generated NOT
*/
public void registerPackages(ResourceSet resourceSet) {
super.registerPackages(resourceSet);
if (!isInWorkspace(MyPackage.class)) {
resourceSet.getPackageRegistry().put(MyPackage.eINSTANCE.getNsURI(), MyPackage.eINSTANCE);
}
}
</pre>
<p> The "@generated NOT" tag in the Javadoc is necessary to
prevent the removal of your modification. Once the package is
registered, Acceleo can use EMF to load your input model. If
this does not work, you will see an error message stating that
EMF cannot find the package with the uri "<metamodel_uri>". </metamodel_uri></p>
This is where you can put DSLStandaloneSetup.doSetup();<br>
<br>
If you're paranoid about double initialization you can do:<br>
<br>
@Override<br>
public void initialize(EObject element, File folder, List<?
extends Object> arguments) throws IOException {<br>
preInitialize();<br>
super.initialize(element, folder, arguments);<br>
}<br>
<br>
@Override<br>
public void initialize(URI modelURI, File folder,
List<?> arguments) throws IOException {<br>
preInitialize();<br>
super.initialize(modelURI, folder, arguments);<br>
}<br>
<br>
protected void preInitialize() {<br>
DSLStandaloneSetup.doSetup();<br>
}<br>
<br>
or<br>
<br>
static {<br>
if (!EMFPlugin.IS_ECLIPSE_RUNNING) {<br>
DSLStandaloneSetup.doSetup();<br>
}<br>
}<br>
<br>
Regards<br>
<br>
Ed Willink<br>
<br>
On 16/08/2012 06:47, Andrea Sindico wrote:<br>
</div>
<blockquote cite="mid:k0i1i2$iv5$1@xxxxxxxxe.org" type="cite">Hi
Ed, where are those comments in Acceleo? And how should I invoke
the StandaloneSetup.doSetup() in Acceleo, by means of a different
wrapper?
<br>
Anyway I have also tried to rearrange the code this way:
<br>
<br>
<br>
public class GetDSLModel {
<br>
public DSLModel getDSLModel(String expression){
<br>
DSLStandaloneSetup.doSetup(); <br>
ResourceSet resourceSet = new ResourceSetImpl();
<br>
resourceSet.addLoadOption(XtextResource.OPTION_RESOLVE_ALL,
Boolean.TRUE);
<br>
EcoreUtil.resolveAll(resourceSet);
<br>
Resource resource =
resourceSet.createResource(URI.createURI("dummy:/example.dsl"));
<br>
InputStream in = new
ByteArrayInputStream(expression.getBytes());
<br>
try {
<br>
resource.load(in, resourceSet.getLoadOptions());
<br>
DSLModel model = (DSLModel)
resource.getContents().get(0);
<br>
EcoreUtil.resolveAll(model);
<br>
return model;
<br>
} catch (IOException e) {
<br>
// TODO Auto-generated catch block
<br>
e.printStackTrace();
<br>
}
<br>
return null;
<br>
<br>
}
<br>
<br>
}
<br>
<br>
<br>
<br>
different code same behavior. It works fine when invoked from a
different java class but when invoked from Acceleo, though I see
it returns correct ClassImpl instances they are apparently not
properly turned into the equivalent ECORE entities.
<br>
</blockquote>
<br>
</body>
</html>
|
|
|
Re: Meshing ACCELEO and Xtext [message #902173 is a reply to message #902139] |
Thu, 16 August 2012 04:43   |
Eclipse User |
|
|
|
Ed I have added these lines to the Acceleo main module Java class:
@Override
public void initialize(EObject element, File folder, java.util.List<? extends Object> arguments) throws IOException { preInitialize();
super.initialize(element, folder, arguments);
}
@Override
public void initialize(URI modelURI, File folder, java.util.List<?> arguments) throws IOException {
preInitialize();
super.initialize(modelURI, folder, arguments);
}
protected void preInitialize() {
DSLStandaloneSetup.doSetup();
}
and
@Override
public void registerPackages(ResourceSet resourceSet) {
super.registerPackages(resourceSet);
if (!isInWorkspace(org.eclipse.uml2.uml.UMLPackage.class)) {
resourceSet.getPackageRegistry().put(org.eclipse.uml2.uml.UMLPackage.eINSTANCE.getNsURI(), org.eclipse.uml2.uml.UMLPackage.eINSTANCE);
}
if (!isInWorkspace(mypackages.DSLPackage.class)) {
resourceSet.getPackageRegistry().put(mypackages.DSLPackage.eINSTANCE.getNsURI(), mypackages.DSLPackage.eINSTANCE);
}
but I still experience the same problem.
I have however noticed something new that I guess may help to understand the problem.
If I try this let:
[let dm:DSLModel = 'statement1;statement2;'.getDSLModel().oclAsType(DSLModel)]
I get this warning:
Undefined "Let" expression at line xx in Module ww for block let dm : DSLModel = getDSLModel('statement1;statement2').oclAsType(dsl::DSLModel). Last recorded value of self was org.eclipse.uml2.uml.internal.impl.ClassImpl@96f20a
|
|
|
Re: Meshing ACCELEO and Xtext [message #902176 is a reply to message #902173] |
Thu, 16 August 2012 04:48   |
Eclipse User |
|
|
|
Hi
The error means that
'statement1;statement2;'.getDSLModel().oclAsType(DSLModel)
evaluated to invalid so you can debug that with a breakpoint in
getDSLModel().
Regards
Ed Willink
On 16/08/2012 09:43, Andrea Sindico wrote:
> Ed I have added these lines to the Acceleo main module Java class:
>
>
> @Override
> public void initialize(EObject element, File folder,
> java.util.List<? extends Object> arguments) throws IOException {
> preInitialize();
> super.initialize(element, folder, arguments);
> }
> @Override
> public void initialize(URI modelURI, File folder, java.util.List<?>
> arguments) throws IOException {
> preInitialize();
> super.initialize(modelURI, folder, arguments);
> }
> protected void preInitialize() {
> DSLStandaloneSetup.doSetup();
> }
>
>
> and
>
>
> @Override
> public void registerPackages(ResourceSet resourceSet) {
> super.registerPackages(resourceSet);
> if (!isInWorkspace(org.eclipse.uml2.uml.UMLPackage.class)) {
> resourceSet.getPackageRegistry().put(org.eclipse.uml2.uml.UMLPackage.eINSTANCE.getNsURI(),
> org.eclipse.uml2.uml.UMLPackage.eINSTANCE);
> }
> if (!isInWorkspace(mypackages.DSLPackage.class)) {
> resourceSet.getPackageRegistry().put(mypackages.DSLPackage.eINSTANCE.getNsURI(),
> mypackages.DSLPackage.eINSTANCE);
> }
>
>
> but I still experience the same problem.
>
> I have however noticed something new that I guess may help to
> understand the problem. If I try this let:
>
>
> [let dm:DSLModel =
> 'statement1;statement2;'.getDSLModel().oclAsType(DSLModel)]
>
>
> I get this warning:
>
> Undefined "Let" expression at line xx in Module ww for block let dm :
> DSLModel =
> getDSLModel('statement1;statement2').oclAsType(dsl::DSLModel). Last
> recorded value of self was
> mailto:org.eclipse.uml2.uml.internal.impl.ClassImpl@96f20a
>
>
>
|
|
|
|
|
|
|
|
|
Re: Meshing ACCELEO and Xtext [message #902455 is a reply to message #902452] |
Fri, 17 August 2012 12:37  |
Eclipse User |
|
|
|
Hi
Do not abuse Xtext; in particular multiple initialization may corrupt
registries. The Xtext ResourceSet is for Xtext only.
Writing to global registries can also cause strange behaviours.
I don't understand this service business. I've looked at Acceleo
services a couple of times and always rejected them as not suitable for
my problem.
Regards
Ed Willink
On 17/08/2012 17:13, Andrea Sindico wrote:
>
> Hi Ed,
> In the Acceleo terminlogy a service is a Java class implementing some
> "complex" operation wrapped by an acceleo module. In this case I meant
> the java class transforming a string with a DSL into an Ecore AST by
> means of XText.
> To quickly if the problem was due to the resource set just to check I
> have added a static ReousceSet variable to the main acceleo module
> java class. I have therefore retrieved that from the XText java
> service and used that instead of instantiating a new one.
> Unfortunately it still behaves the same Acceleo does not seem to
> associate the implementation to the related ECORE.
> while trying I have however noticed a weird thing I don't know if it
> could clarify or create more confusion. It happens that sometimes when
> I launch the Eclipse environment (but not every time I do that!) and
> run the acceleo transformation it properly manages the model elements
> retrieved from the Java XText service. It thus works. However as soon
> as I slightly change the code (i.e. add another tag) it stops working
> again.
>
> Again thanks for your help
>
> Regards
|
|
|
Powered by
FUDForum. Page generated in 0.10227 seconds