Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
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 Go to next message
Ray Kelm is currently offline 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 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26130
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--
Re: How do I implement methods in my generated model? [message #494544 is a reply to message #494504] Sat, 31 October 2009 10:08 Go to previous messageGo to next message
Sven Efftinge is currently offline Sven Efftinge
Messages: 1769
Registered: July 2009
Senior Member
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.

Using the annotation Ed suggested is very inconvenient and hard to
maintain, since the java code is hidden somewhere in the ecore model.

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.

> 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.

Cheers,
Sven



--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com


--
Need professional support on Xtext or Xtend?
Mail to: xtext (at) itemis.com
Twitter : @svenefftinge
Blog : blog.efftinge.de
Re: How do I implement methods in my generated model? [message #494571 is a reply to message #494531] Sat, 31 October 2009 15:05 Go to previous messageGo to next message
Ray Kelm is currently offline 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 Go to previous messageGo to next message
Ray Kelm is currently offline 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 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26130
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.
>
Re: How do I implement methods in my generated model? [message #494618 is a reply to message #494572] Sun, 01 November 2009 08:58 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26130
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.
>
Re: How do I implement methods in my generated model? [message #494643 is a reply to message #494544] Sun, 01 November 2009 16:51 Go to previous messageGo to next message
Ray Kelm is currently offline 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 Go to previous messageGo to next message
Sebastian Zarnekow is currently offline Sebastian Zarnekow
Messages: 2900
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
Re: How do I implement methods in my generated model? [message #494782 is a reply to message #494684] Mon, 02 November 2009 16:05 Go to previous message
Ray Kelm is currently offline Ray Kelm
Messages: 20
Registered: July 2009
Junior Member
Sebastian Zarnekow wrote on Mon, 02 November 2009 03:11

Ray Kelm schrieb:

> 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.
>



After much reading, some stepping through the debugger, and then a few head slaps, I got it working. I did have to tweak the model a bit to match what Xtext was able to supply, and I'll probably make a new post about that with some questions I had.

The biggest problem I had was that the error reporting from MWE made it difficult to determine what the problems were. The stack trace that was printed was not triggered until much later, which was misleading as to what the source of the problem was. It turned out that I needed to add registerGeneratedEPackage to my MWE file.
Previous Topic:terminal converter and exceptions
Next Topic:What does this mean: attribute is not a token, parameter, or return value: current
Goto Forum:
  


Current Time: Tue Oct 21 20:10:25 GMT 2014

Powered by FUDForum. Page generated in 0.09911 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software