Home » Modeling » TMF (Xtext) » How do I implement methods in my generated model?
How do I implement methods in my generated model? [message #494504] |
Fri, 30 October 2009 22:22 |
Ray Kelm Messages: 20 Registered: July 2009 |
Junior Member |
|
|
I've been looking at Xtext for a few days, and I seem to be stuck.
I've worked through the "getting started" example. That worked out well, and I'm pretty sure I understood everything.
I've watched some of the video presentations, and looked at several of the example models that were associated with the project. Again, no problems.
I've designed a model for a simple language to describe sequences of animations. The language syntax is good, and I am able to use the generated editor to create nice animation scripts that fully describe what is supposed to happen during the animation. So far so good.
Now I want to implement the animation framework, and I'm stuck.
Some background: I have already implemented this system using an ECore model and EMF, and I am simple re-implementing it using Xtext for the purpose of learning Xtext. The actual project that I intend to do is much larger in scope, and I want to get a handle on the technologies that I plan to use for it.
So with the help of google, these forums, several blogs, and lots of time and caffeine, I've managed to figure out how to use Xtend to add EOperations to the ECore model. I have created a few "render" methods in classes that need them, and want to provide an implementation.
I first tried to add the implementation in an annotation in the Xtend script, but found that I could not add new import statements to the class file, or at least I didn't know how to do so.
I've seen suggestions to use a visitor pattern combined with the package switch pattern to implement behavior, but that seems like a lot more work that necessary, even for my simple animation model.
I've also read a bit about the "generation gap" pattern, and wanted to try using that method with Xtext, but I can't seem to figure out how to do it. It seems I would need to change the implementation of the package factory to produce my new objects, which extend the generated implementations. I have not found a way to do that.
I'm currently waiting for the EMF book to arrive to see if there are more annotations that I'm not aware of, because let's face it, online documentation for this stuff is scarce at best. Or more precisely, documentation that details all of the available options does not exist online, unless you read through thousands of lines of code in EMF to figure out how it works.
So my questions are:
What is the recommended practice for implementing the behavior of a model?
Are there any good examples of using that practice?
|
|
|
Re: How do I implement methods in my generated model? [message #494531 is a reply to message #494504] |
Sat, 31 October 2009 08:39 |
Ed Merks Messages: 33216 Registered: July 2009 |
Senior Member |
|
|
This is a multi-part message in MIME format.
--------------020600040105030003020108
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Ray,
The generator will fetch a body annotation like this is GenOperationImpl:
protected String getBody()
{
EOperation eOperation = getEcoreOperation();
EAnnotation eAnnotation =
eOperation.getEAnnotation(GenModelPackage.eNS_URI);
return eAnnotation == null ? null :
(String)eAnnotation.getDetails().get("body");
}
You can of course also implement the operation directly in the generated
code.
Ray Kelm wrote:
> I've been looking at Xtext for a few days, and I seem to be stuck.
>
> I've worked through the "getting started" example. That worked out
> well, and I'm pretty sure I understood everything.
>
> I've watched some of the video presentations, and looked at several of
> the example models that were associated with the project. Again, no
> problems.
>
> I've designed a model for a simple language to describe sequences of
> animations. The language syntax is good, and I am able to use the
> generated editor to create nice animation scripts that fully describe
> what is supposed to happen during the animation. So far so good.
>
> Now I want to implement the animation framework, and I'm stuck.
>
> Some background: I have already implemented this system using an ECore
> model and EMF, and I am simple re-implementing it using Xtext for the
> purpose of learning Xtext. The actual project that I intend to do is
> much larger in scope, and I want to get a handle on the technologies
> that I plan to use for it.
>
> So with the help of google, these forums, several blogs, and lots of
> time and caffeine, I've managed to figure out how to use Xtend to add
> EOperations to the ECore model. I have created a few "render" methods
> in classes that need them, and want to provide an implementation.
>
> I first tried to add the implementation in an annotation in the Xtend
> script, but found that I could not add new import statements to the
> class file, or at least I didn't know how to do so.
>
> I've seen suggestions to use a visitor pattern combined with the
> package switch pattern to implement behavior, but that seems like a
> lot more work that necessary, even for my simple animation model.
>
> I've also read a bit about the "generation gap" pattern, and wanted to
> try using that method with Xtext, but I can't seem to figure out how
> to do it. It seems I would need to change the implementation of the
> package factory to produce my new objects, which extend the generated
> implementations. I have not found a way to do that.
>
> I'm currently waiting for the EMF book to arrive to see if there are
> more annotations that I'm not aware of, because let's face it, online
> documentation for this stuff is scarce at best. Or more precisely,
> documentation that details all of the available options does not exist
> online, unless you read through thousands of lines of code in EMF to
> figure out how it works.
>
> So my questions are:
>
> What is the recommended practice for implementing the behavior of a
> model?
>
> Are there any good examples of using that practice?
>
>
--------------020600040105030003020108
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Ray,<br>
<br>
The generator will fetch a body annotation like this is
GenOperationImpl:<br>
<blockquote> protected String getBody()<br>
{<br>
EOperation eOperation = getEcoreOperation();<br>
EAnnotation eAnnotation =
eOperation.getEAnnotation(GenModelPackage.eNS_URI);<br>
return eAnnotation == null ? null :
(String)eAnnotation.getDetails().get("body");<br>
}<br>
</blockquote>
You can of course also implement the operation directly in the
generated code.<br>
<br>
<br>
Ray Kelm wrote:
<blockquote cite="mid:hcfous$afo$1@build.eclipse.org" type="cite">I've
been looking at Xtext for a few days, and I seem to be stuck.
<br>
<br>
I've worked through the "getting started" example. That worked out
well, and I'm pretty sure I understood everything.
<br>
<br>
I've watched some of the video presentations, and looked at several of
the example models that were associated with the project. Again, no
problems.
<br>
<br>
I've designed a model for a simple language to describe sequences of
animations. The language syntax is good, and I am able to use the
generated editor to create nice animation scripts that fully describe
what is supposed to happen during the animation. So far so good.
<br>
<br>
Now I want to implement the animation framework, and I'm stuck.
<br>
<br>
Some background: I have already implemented this system using an ECore
model and EMF, and I am simple re-implementing it using Xtext for the
purpose of learning Xtext. The actual project that I intend to do is
much larger in scope, and I want to get a handle on the technologies
that I plan to use for it.
<br>
<br>
So with the help of google, these forums, several blogs, and lots of
time and caffeine, I've managed to figure out how to use Xtend to add
EOperations to the ECore model. I have created a few "render" methods
in classes that need them, and want to provide an implementation.
<br>
<br>
I first tried to add the implementation in an annotation in the Xtend
script, but found that I could not add new import statements to the
class file, or at least I didn't know how to do so.
<br>
<br>
I've seen suggestions to use a visitor pattern combined with the
package switch pattern to implement behavior, but that seems like a lot
more work that necessary, even for my simple animation model.
<br>
<br>
I've also read a bit about the "generation gap" pattern, and wanted to
try using that method with Xtext, but I can't seem to figure out how to
do it. It seems I would need to change the implementation of the
package factory to produce my new objects, which extend the generated
implementations. I have not found a way to do that.
<br>
<br>
I'm currently waiting for the EMF book to arrive to see if there are
more annotations that I'm not aware of, because let's face it, online
documentation for this stuff is scarce at best. Or more precisely,
documentation that details all of the available options does not exist
online, unless you read through thousands of lines of code in EMF to
figure out how it works.
<br>
<br>
So my questions are:
<br>
<br>
What is the recommended practice for implementing the behavior of a
model?
<br>
<br>
Are there any good examples of using that practice?
<br>
<br>
<br>
</blockquote>
</body>
</html>
--------------020600040105030003020108--
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
| |
Re: How do I implement methods in my generated model? [message #494571 is a reply to message #494531] |
Sat, 31 October 2009 15:05 |
Ray Kelm Messages: 20 Registered: July 2009 |
Junior Member |
|
|
Ed Merks wrote on Sat, 31 October 2009 04:39 |
The generator will fetch a body annotation like this is GenOperationImpl:
protected String getBody()
{
EOperation eOperation = getEcoreOperation();
EAnnotation eAnnotation =
eOperation.getEAnnotation(GenModelPackage.eNS_URI);
return eAnnotation == null ? null :
(String)eAnnotation.getDetails().get("body");
}
You can of course also implement the operation directly in the generated
code.
|
As I said, I tried that, and it does work somewhat. But it's a messy way to inject snippets of code into the generated java files. No refactoring, no syntax checking in the original script, have to generate, look at the errors, regenerate, etc.
Then there's the issue of imports. I can attach a body in this way, but I didn't see how to generate the import statements that the class file needed in order to support the code that I injected. I'm sure there is a way, since those imports need to be generated in the first place.
I'd rather implement the operation directly in the generated code, but the Xtext generator does not merge code, it overwrites, which makes that impossible.
I've been using EMF for a little while now, and I've gotten pretty comfortable working with it. Now I'm just trying to learn how to work with Xtext and EMF together.
|
|
|
Re: How do I implement methods in my generated model? [message #494572 is a reply to message #494544] |
Sat, 31 October 2009 15:13 |
Ray Kelm Messages: 20 Registered: July 2009 |
Junior Member |
|
|
Sven Efftinge wrote on Sat, 31 October 2009 06:08 | Ray Kelm schrieb:
> So my questions are:
>
> What is the recommended practice for implementing the behavior of a model?
In the case of EMF, I recommend to use JMerge and modify the generated
code. It's not ideal and you need to be very careful (don't forget to
remove the @generated annotation) and you'll have to manage all of the
generated code, but it's IMHO the best available alternative.
|
And that's exactly what I've been doing with the models I've created using Ecore and EMF. Now I want to learn to do similar things with Xtext.
Quote: |
Using the annotation Ed suggested is very inconvenient and hard to
maintain, since the java code is hidden somewhere in the ecore model.
|
I agree. Plus it eliminates the ability to easily refactor, use syntax highlight, in-editor syntax checking, references, etc. In other words, all the reasons I use eclipse in the first place instead of a text editor and makefiles/ant.
Quote: |
That said, the EcoreGeneratorFragment which Xtext uses to generate the
Java code for the ecore model does currently not support JMerge.
So you'll have to manually generate the code.
|
Ahh, so the idea would be to modify the workflow to eliminate the code generation part, then run that step manually afterwards. That makes sense. Then I can use the merge capabilities, but still have the model generated by the grammar.
This might be the missing piece that makes it all fit. I'll give it a try.
Quote: |
> Are there any good examples of using that practice?
Basically any EMF model in the world is using this approach (look at
Ecore itself, for instance).
In the long term, I see two ways to improve this:
1) introduce possibility for using the generation-gap pattern to the
Ecore generator.
2) Come up with a nice textual language to define Ecore models including
the implmentation of derived properties and eoperations.
|
I'm not familiar enough with the internals of the EMF code generator, but I have to imagine that there is some kind of annotation that would allow you to override the concrete class referenced by the generated package factory. That's all it would take to support generation gap, at least initially.
Maybe I'll go dig through org.eclipse.emf.codegen to see what I can find.
|
|
|
Re: How do I implement methods in my generated model? [message #494617 is a reply to message #494571] |
Sun, 01 November 2009 08:56 |
Ed Merks Messages: 33216 Registered: July 2009 |
Senior Member |
|
|
Ray,
Comments below.
Ray Kelm wrote:
> Ed Merks wrote on Sat, 31 October 2009 04:39
>> The generator will fetch a body annotation like this is
>> GenOperationImpl:
>>
>> protected String getBody()
>> {
>> EOperation eOperation = getEcoreOperation();
>> EAnnotation eAnnotation =
>> eOperation.getEAnnotation(GenModelPackage.eNS_URI);
>> return eAnnotation == null ? null :
>> (String)eAnnotation.getDetails().get("body");
>> }
>>
>> You can of course also implement the operation directly in the
>> generated code.
>
>
> As I said, I tried that, and it does work somewhat. But it's a messy
> way to inject snippets of code into the generated java files. No
> refactoring, no syntax checking in the original script, have to
> generate, look at the errors, regenerate, etc.
Yep.
>
> Then there's the issue of imports. I can attach a body in this way,
> but I didn't see how to generate the import statements that the class
> file needed in order to support the code that I injected.
You can of course use fully qualified names. You can also use <%a.b.C%>
to make it import a.b.C and use C in the body.
> I'm sure there is a way, since those imports need to be generated in
> the first place.
>
> I'd rather implement the operation directly in the generated code, but
> the Xtext generator does not merge code, it overwrites, which makes
> that impossible.
I thought the EMF generator always did merging...
>
> I've been using EMF for a little while now, and I've gotten pretty
> comfortable working with it. Now I'm just trying to learn how to work
> with Xtext and EMF together.
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Re: How do I implement methods in my generated model? [message #494618 is a reply to message #494572] |
Sun, 01 November 2009 08:58 |
Ed Merks Messages: 33216 Registered: July 2009 |
Senior Member |
|
|
Ray,
Note that in https://bugs.eclipse.org/bugs/show_bug.cgi?id=255469 there
is work being done along the lines of what Sven mentioned.
Ray Kelm wrote:
> Sven Efftinge wrote on Sat, 31 October 2009 06:08
>> Ray Kelm schrieb:
>> > So my questions are:
>> > > What is the recommended practice for implementing the behavior of
>> a model?
>>
>> In the case of EMF, I recommend to use JMerge and modify the
>> generated code. It's not ideal and you need to be very careful (don't
>> forget to remove the @generated annotation) and you'll have to manage
>> all of the generated code, but it's IMHO the best available alternative.
>
>
> And that's exactly what I've been doing with the models I've created
> using Ecore and EMF. Now I want to learn to do similar things with
> Xtext.
>
> Quote:
>> Using the annotation Ed suggested is very inconvenient and hard to
>> maintain, since the java code is hidden somewhere in the ecore model.
>
>
> I agree. Plus it eliminates the ability to easily refactor, use syntax
> highlight, in-editor syntax checking, references, etc. In other words,
> all the reasons I use eclipse in the first place instead of a text
> editor and makefiles/ant.
>
> Quote:
>> That said, the EcoreGeneratorFragment which Xtext uses to generate
>> the Java code for the ecore model does currently not support JMerge.
>>
>> So you'll have to manually generate the code.
>
>
> Ahh, so the idea would be to modify the workflow to eliminate the code
> generation part, then run that step manually afterwards. That makes
> sense. Then I can use the merge capabilities, but still have the model
> generated by the grammar.
>
> This might be the missing piece that makes it all fit. I'll give it a
> try.
>
> Quote:
>> > Are there any good examples of using that practice?
>>
>> Basically any EMF model in the world is using this approach (look at
>> Ecore itself, for instance).
>>
>> In the long term, I see two ways to improve this:
>> 1) introduce possibility for using the generation-gap pattern to the
>> Ecore generator.
>> 2) Come up with a nice textual language to define Ecore models
>> including the implmentation of derived properties and eoperations.
>
>
> I'm not familiar enough with the internals of the EMF code generator,
> but I have to imagine that there is some kind of annotation that would
> allow you to override the concrete class referenced by the generated
> package factory. That's all it would take to support generation gap,
> at least initially.
>
> Maybe I'll go dig through org.eclipse.emf.codegen to see what I can find.
>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Re: How do I implement methods in my generated model? [message #494643 is a reply to message #494544] |
Sun, 01 November 2009 16:51 |
Ray Kelm Messages: 20 Registered: July 2009 |
Junior Member |
|
|
Sven Efftinge wrote on Sat, 31 October 2009 06:08 |
That said, the EcoreGeneratorFragment which Xtext uses to generate the
Java code for the ecore model does currently not support JMerge.
So you'll have to manually generate the code.
|
After looking into this further, EcoreGeneratorFragment generates the ecore file, the genmodel file, and then runs the EMF generator. Perhaps these should be split into separate operations?
In order to manually generate the code, I'm going to have to remove this fragment completely, and create the ecore and genmodel myself. So it starts to look like the use case where the ecore model is provided in advance to the Xtext grammar.
For my simple test project, that will work, because I had already defined an ecore model, but it does eliminate one of the more powerful features of Xtext, which is that it will define the model based on the grammar, which then can evolve as the grammar is developed.
I suspect that my workflow will now be that I will develop the initial grammar and model using EcoreGeneratorFragment, then once it's close to fully formed, I'll switch to importing the model.
I'm going to try that now.
|
|
|
Re: How do I implement methods in my generated model? [message #494684 is a reply to message #494643] |
Mon, 02 November 2009 08:11 |
Sebastian Zarnekow Messages: 3118 Registered: July 2009 |
Senior Member |
|
|
Hi Ray,
please see below.
Ray Kelm schrieb:
> Sven Efftinge wrote on Sat, 31 October 2009 06:08
>> That said, the EcoreGeneratorFragment which Xtext uses to generate the
>> Java code for the ecore model does currently not support JMerge.
>>
>> So you'll have to manually generate the code.
>
>
> After looking into this further, EcoreGeneratorFragment generates the
> ecore file, the genmodel file, and then runs the EMF generator. Perhaps
> these should be split into separate operations?
>
> In order to manually generate the code, I'm going to have to remove this
> fragment completely, and create the ecore and genmodel myself. So it
> starts to look like the use case where the ecore model is provided in
> advance to the Xtext grammar.
>
> For my simple test project, that will work, because I had already
> defined an ecore model, but it does eliminate one of the more powerful
> features of Xtext, which is that it will define the model based on the
> grammar, which then can evolve as the grammar is developed.
>
> I suspect that my workflow will now be that I will develop the initial
> grammar and model using EcoreGeneratorFragment, then once it's close to
> fully formed, I'll switch to importing the model.
>
We consider the metamodel inference to be exactly what you describe: A
bootstrapping helper for an Ecore model that will be refined manually to
fit the actual requirements.
> I'm going to try that now.
>
Regards,
Sebastian
--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
|
|
| |
Goto Forum:
Current Time: Mon Sep 23 03:18:29 GMT 2024
Powered by FUDForum. Page generated in 0.04545 seconds
|