Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » M2T (model-to-text transformation) » JET2 vs JMerge vs Codegen vs EMF
JET2 vs JMerge vs Codegen vs EMF [message #35804] Wed, 07 November 2007 17:20 Go to next message
robert searle is currently offline robert searleFriend
Messages: 4
Registered: July 2009
Junior Member
Dear Mr. Elder,

I have an "EMF direction" question to ask you for an open source project
I am working with.

First, what am I trying to do? Eventually I am trying to create a new eclipse
plug-in for JACOB (http://jacob-project.sourceforge.net/). The new plug-in
will ask for three or four parameters and then generate a strongly type Java
object for a Window's COM type library (TLB file). The generated classes
are roughly a proxy hiding all the JACOB low level calls, I hope. I have
written the code to construct the ecore model for the given TLB at runtime.
If I create a genmodel file, I can then generate source code for the model.
This is the part I am not sure about--how to over-ride the new classes'
method output.

Again, I am creating an ecore model based on a parse of a TLB file. From
the ecore model, I create a .genmodel to generate source code. So far so
good. The code it generates is good with a couple of weakness for what
I need.
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public String getPath() {
return path;
}


What I would prefer is to over-ride / destroy / replace the auto generated
code with my own. Obviously, the line inserted into the method call is dynamic,
i.e. changes for the method I want to over-ride. The resulting code is not
run-time dynamic, e.g. changing for each run time call to the method. For
the sample bellow, notice the parameter to JACOB is always "Path" since the
attribute is Path.
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public String getPath() {
return com.jacob.com.Dispatch.get(null, "Path").getString();
}


Is what I describe even possible? Is JMerge the best way to do this? No
one will ever change or view the auto-created code! Another idea I have
is to use "override" listeners or adapters of the initial code generation
phase, if they exist. Is there a code gen switch or option I am missing
which allows be to override the generator? Again since the above code is
almost perfect, I think JET2 templates are over kill for what I need, or
are they?

Any of your thoughts or comments are greatly appreciated.
Re: JET2 vs JMerge vs Codegen vs EMF [message #35839 is a reply to message #35804] Wed, 07 November 2007 19:10 Go to previous messageGo to next message
Paul Elder is currently offline Paul ElderFriend
Messages: 849
Registered: July 2009
Senior Member
Robert:

Thanks for posting this to the group and please, Paul will do :-)

Let me start by restating your question, to make sure I understand.

1) You are creating an ECore model based on a COM TLB file.
2) You then create a .genmodel for this ECore file.
3) You want EMF to generate the Java code, all except for a few methods,
here and there. For those methods, you'd like to insert your own
implementations, rather than those provided by the EMF code generator.
4) You don't expect users of your tool to modify any of the generated Java
code.

Assuming I've got it right (which I probably didn't), you have a couple of
choices:
A. Extend the EMF code generator
B. Inject your code after running the standard EMF code generator
C. Generate your own subclasses of the generated EMF Impl classes,
overriding the methods you want.

A. Extending the EMF code generator
In the .genmodel file, you can specify a location of templates that override
those defined in the EMF code generator. You then have to take a look at the
EMF code generator templates (org.eclipse.emf.codegen.ecore plug-in). Here's
a link to the CVS repository location for the Model templates:

http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf/plugins/org.eclipse.emf.codegen.ecore/templates /model/?root=Modeling_Project

Your alternative location can just implement the templates you want. Some of
the templates include @include directives for files you can supply to
override parts of the templates. An example of this approach is the UML2
project. You can see their extension templates here:

http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.mdt/org .eclipse.uml2/plugins/org.eclipse.uml2.codegen.ecore/templat es/model/?root=Modeling_Project

Taking this path, though, requires a significant investment in learning how
the EMF code generator works. If you do go this root, the org.eclipse.emf
newsgroup will be helpful..

BTW, the EMF code generator uses "JET1" templates. These don't use tag
libraries, but only Java scriptlets and expressions.


B. Inject your code after running the standard EMF code generator.

This approach leaves the EMF code generator as a black box, and instead
tries to add your methods after the fact. That EMF includes @generated tags
on all the code it generates is a big help. You could write a JET2
'transformation' that emits just the Java code you want to replace, and then
JMerges them into the already generated class. Your templates for these
class could include just the methods you want to replace, plus a
<java:merge/> tag. Since the standard JMerge rules will 'sweep' out any code
not referenced in your new version, you may want to customize them by
removing the <merge:sweep> element at line 146. The standard rules are found
here:

You can find the standard JMerge rules here:

http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.emf/plugins/org.eclipse.emf.codegen.ecore/templates /emf-merge.xml?annotate=1.12&root=Modeling_Project

C. Generate your own Impl subclasses and factory

A final approach is to leave EMFs generator code alone, and instead generate
subclasses of the EMF generated classes. So that your clients can create
these instances, you would have to create your own FactoryImpl class,
probably extending the generated one.


Other things you may want to consider:
* If going for option A or B, set the EAttributes that you want to override
as 'derived'. This will prevent the EMF code generator from creating fields
to store the value. Instead, you'll get method bodies like:
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
public String getLength() {
// TODO: implement this method to return the 'Length' attribute
// Ensure that you remove @generated or mark it @generated NOT
throw new UnsupportedOperationException();
}


Let me know if this helps, or if you have other questions.

Paul
Re: JET2 vs JMerge vs Codegen vs EMF [message #35906 is a reply to message #35839] Wed, 07 November 2007 21:35 Go to previous messageGo to next message
robert searle is currently offline robert searleFriend
Messages: 4
Registered: July 2009
Junior Member
Paul,

You are right except for a small issue with point 3. Since the code is a
proxy into the JACOB project, I will _unconditionally_ replace all generated
methods, including getters and setters. I do not need the class's private
storage variables. Thank you for the idea of setting the EAttributes to
'derived' to remove the generated classes' attributes.

I do not want developers wondering which classes or sub-classes to use in
choice C. I think my preference is choice B since it is more eclipse / EMF
version independent than choice A.

I assume for choice B, JMerge is the injector not JET2, correct? For choice
B, JET2 will create the methods bodies one at a time. The JET2 tag <java:merge/>
causes the JET2 result to be merged into the pre-existing java file, right?

One last question, is there any sample java code showing how to transform
an ecore / .genmodel via a JET2 template?

Thanks for your answers.

--Robert


> Robert:
>
> Thanks for posting this to the group and please, Paul will do :-)
>
> Let me start by restating your question, to make sure I understand.
>
> 1) You are creating an ECore model based on a COM TLB file.
> 2) You then create a .genmodel for this ECore file.
> 3) You want EMF to generate the Java code, all except for a few
> methods,
> here and there. For those methods, you'd like to insert your own
> implementations, rather than those provided by the EMF code generator.
> 4) You don't expect users of your tool to modify any of the generated
> Java
> code.
> Assuming I've got it right (which I probably didn't), you have a
> couple of
> choices:
> A. Extend the EMF code generator
> B. Inject your code after running the standard EMF code generator
> C. Generate your own subclasses of the generated EMF Impl classes,
> overriding the methods you want.
> A. Extending the EMF code generator
> In the .genmodel file, you can specify a location of templates that
> override
> those defined in the EMF code generator. You then have to take a look
> at the
> EMF code generator templates (org.eclipse.emf.codegen.ecore plug-in).
> Here's
> a link to the CVS repository location for the Model templates:
> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.e
> mf/plugins/org.eclipse.emf.codegen.ecore/templates/model/?ro ot=Modelin
> g_Project
>
> Your alternative location can just implement the templates you want.
> Some of the templates include @include directives for files you can
> supply to override parts of the templates. An example of this approach
> is the UML2 project. You can see their extension templates here:
>
> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.mdt/org .eclipse.u
> ml2/plugins/org.eclipse.uml2.codegen.ecore/templates/model/? root=Model
> ing_Project
>
> Taking this path, though, requires a significant investment in
> learning how the EMF code generator works. If you do go this root, the
> org.eclipse.emf newsgroup will be helpful..
>
> BTW, the EMF code generator uses "JET1" templates. These don't use tag
> libraries, but only Java scriptlets and expressions.
>
> B. Inject your code after running the standard EMF code generator.
>
> This approach leaves the EMF code generator as a black box, and
> instead tries to add your methods after the fact. That EMF includes
> @generated tags on all the code it generates is a big help. You could
> write a JET2 'transformation' that emits just the Java code you want
> to replace, and then JMerges them into the already generated class.
> Your templates for these class could include just the methods you want
> to replace, plus a <java:merge/> tag. Since the standard JMerge rules
> will 'sweep' out any code not referenced in your new version, you may
> want to customize them by removing the < > element at line
> 146. The standard rules are found here:
>
> You can find the standard JMerge rules here:
>
> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.e
> mf/plugins/org.eclipse.emf.codegen.ecore/templates/emf-merge .xml?annot
> ate=1.12&root=Modeling_Project
>
> C. Generate your own Impl subclasses and factory
>
> A final approach is to leave EMFs generator code alone, and instead
> generate subclasses of the EMF generated classes. So that your clients
> can create these instances, you would have to create your own
> FactoryImpl class, probably extending the generated one.
>
> Other things you may want to consider:
> * If going for option A or B, set the EAttributes that you want to
> override
> as 'derived'. This will prevent the EMF code generator from creating
> fields
> to store the value. Instead, you'll get method bodies like:
> /**
> * <!-- begin-user-doc -->
> * <!-- end-user-doc -->
> * @generated
> */
> public String getLength() {
> // TODO: implement this method to return the 'Length' attribute
> // Ensure that you remove @generated or mark it @generated NOT
> throw new UnsupportedOperationException();
> }
> Let me know if this helps, or if you have other questions.
>
> Paul
>
Re: JET2 vs JMerge vs Codegen vs EMF [message #35975 is a reply to message #35906] Thu, 08 November 2007 17:21 Go to previous messageGo to next message
Paul Elder is currently offline Paul ElderFriend
Messages: 849
Registered: July 2009
Senior Member
Robert:

I would write a single JET2 template that produced all the getters/setters
you want. In pseudo-JET, it look something like:

<%-- run JMerge using the modified emf-rules, as described in a previous
post --%>
<java:merge rules="templates/modified-emf-rules.xml"/>

package ...;

/**
* @generated
*/
public class ...Impl implements ... extends ... {

<c:iterate select="$genClass/genAttributes" var="genAttribute">
/**
* ...
* @generated
*/
public ... get... () {
... your implementation here...
}

/**
* ...
* @generated
*/
public void set... (... new...) {
... your implementation here...
}

</c:iterate>
}

The JMerge happens automatically as part of invoking the template with
either the <ws:file> tag or the <java:class> tag.

I'm assuming you'd work off of the same GenModel as it probably has most of
the information you'll need. The only unfortunate bit is that alot of the
GenModel methods (including getXXX) methods are not declared to EMF, so
you'll have to resort to Java code to get their values. There are a couple
of choices.

1) Use <c:set> to create 'derived attributes' gen model elements. These
appear to be attributes to the XPath engine, but are not actually stored in
the GenModel. For example, you might do the following in main.jet:

<%-- you will have to add org.eclipse.emf.codegen.ecore to adjust the JET
plug-ins dependencies to get the generated Java to compile --%>
<%@jet imports="org.eclipse.emf.codegen.ecore.genmodel.*"%>

<c:setVariable var="genModel" select="/GenModel"/>
<%-- create derived attributes to contain genmodel methods JET Xpath cannot
see --%>
<c:iterate select="$genModel/genPackages" select="genPackage">
<%
GenPackage genPackage =
(GenClass)context.getVariable("genPackage");
%>
<c:set var="$genPackage" name="interfacePackageName"><%=
getPackage.getInterfacePackageName() %></c:set>
<c:set var="$genPackage" name="classPackageName"><%=
getPackage.getClassPackageName() %></c:set>
<c:iterate select="$genPackage/genClasses" var="genClass">
<%
GenClass genClass = (GenClass)context.getVariable("genClass");
%>
<c:set select="$genClass" name="className"><%=
genClass.getClassName() %></c:set>
<c:set select="$genClass" name="typeParameters"><%=
genClass.getTypeParameters() %></c:set>
<c:set select="$genClass" name="classExtends"><%=
genClass.getClassExtends() %></c:set>
<c:set select="$genClass" name="classImplements"><%=
genClass.getClassImplements() %></c:set>
</c:iterate>
</c:iterate>
<%-- Invoke the template --%>
<c:iterate select="$genModel/genPackages" select="genPackage">
<c:iterate select="$genPackage/genClasses" var="genClass">
<java:class srcFolder="{$genModel/@modelDirectory}"
package="{ $genPackage/@classPackageName}"
name="{ $genPackage/@className}"
tempate="templates/class/MyGetters.java.jet"/>
</c:iterate>
</c:iterate>

Then, in your template, you can just you JET tags.

2) Do the <% .. %> and <%= %> blocks directly in your templates, and don't
bother with the derived attributes.

Lastly, its easy to get a JET transformation to load a GenModel. You need to
specify the org.eclipse.jet.emf 'model loader' in the plugin.xml. See the
JET FAQ:

http://wiki.eclipse.org/JET_FAQ_What_kind_of_input_model_can _JET_handle%3F

You can test it out simply creating a new JET project, and modifying
plugin.xml to use the org.eclipse.jet.emf model loader. If you then launch
the transformation against a .genmodel file, you'll get a not-very-useful
dump.xml file produced by the transformation. (The c:dump tag is not very
good at showing you the contents of an EMF-based model like a .genmodel.

Hope this helps,

Paul

"robert" <robertsearle@hotmail.com> wrote in message
news:2d21903416f28c9ef6283e46b26@news.eclipse.org...
> Paul,
>
> You are right except for a small issue with point 3. Since the code is a
> proxy into the JACOB project, I will _unconditionally_ replace all
> generated methods, including getters and setters. I do not need the
> class's private storage variables. Thank you for the idea of setting the
> EAttributes to 'derived' to remove the generated classes' attributes.
> I do not want developers wondering which classes or sub-classes to use in
> choice C. I think my preference is choice B since it is more eclipse /
> EMF version independent than choice A.
> I assume for choice B, JMerge is the injector not JET2, correct? For
> choice B, JET2 will create the methods bodies one at a time. The JET2 tag
> <java:merge/> causes the JET2 result to be merged into the pre-existing
> java file, right?
>
> One last question, is there any sample java code showing how to transform
> an ecore / .genmodel via a JET2 template?
>
> Thanks for your answers.
>
> --Robert
>
>
>> Robert:
>>
>> Thanks for posting this to the group and please, Paul will do :-)
>>
>> Let me start by restating your question, to make sure I understand.
>>
>> 1) You are creating an ECore model based on a COM TLB file.
>> 2) You then create a .genmodel for this ECore file.
>> 3) You want EMF to generate the Java code, all except for a few
>> methods,
>> here and there. For those methods, you'd like to insert your own
>> implementations, rather than those provided by the EMF code generator.
>> 4) You don't expect users of your tool to modify any of the generated
>> Java
>> code.
>> Assuming I've got it right (which I probably didn't), you have a
>> couple of
>> choices:
>> A. Extend the EMF code generator
>> B. Inject your code after running the standard EMF code generator
>> C. Generate your own subclasses of the generated EMF Impl classes,
>> overriding the methods you want.
>> A. Extending the EMF code generator
>> In the .genmodel file, you can specify a location of templates that
>> override
>> those defined in the EMF code generator. You then have to take a look
>> at the
>> EMF code generator templates (org.eclipse.emf.codegen.ecore plug-in).
>> Here's
>> a link to the CVS repository location for the Model templates:
>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.e
>> mf/plugins/org.eclipse.emf.codegen.ecore/templates/model/?ro ot=Modelin
>> g_Project
>>
>> Your alternative location can just implement the templates you want.
>> Some of the templates include @include directives for files you can
>> supply to override parts of the templates. An example of this approach
>> is the UML2 project. You can see their extension templates here:
>>
>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.mdt/org .eclipse.u
>> ml2/plugins/org.eclipse.uml2.codegen.ecore/templates/model/? root=Model
>> ing_Project
>>
>> Taking this path, though, requires a significant investment in
>> learning how the EMF code generator works. If you do go this root, the
>> org.eclipse.emf newsgroup will be helpful..
>>
>> BTW, the EMF code generator uses "JET1" templates. These don't use tag
>> libraries, but only Java scriptlets and expressions.
>>
>> B. Inject your code after running the standard EMF code generator.
>>
>> This approach leaves the EMF code generator as a black box, and
>> instead tries to add your methods after the fact. That EMF includes
>> @generated tags on all the code it generates is a big help. You could
>> write a JET2 'transformation' that emits just the Java code you want
>> to replace, and then JMerges them into the already generated class.
>> Your templates for these class could include just the methods you want
>> to replace, plus a <java:merge/> tag. Since the standard JMerge rules
>> will 'sweep' out any code not referenced in your new version, you may
>> want to customize them by removing the < > element at line
>> 146. The standard rules are found here:
>>
>> You can find the standard JMerge rules here:
>>
>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse.e
>> mf/plugins/org.eclipse.emf.codegen.ecore/templates/emf-merge .xml?annot
>> ate=1.12&root=Modeling_Project
>>
>> C. Generate your own Impl subclasses and factory
>>
>> A final approach is to leave EMFs generator code alone, and instead
>> generate subclasses of the EMF generated classes. So that your clients
>> can create these instances, you would have to create your own
>> FactoryImpl class, probably extending the generated one.
>>
>> Other things you may want to consider:
>> * If going for option A or B, set the EAttributes that you want to
>> override
>> as 'derived'. This will prevent the EMF code generator from creating
>> fields
>> to store the value. Instead, you'll get method bodies like:
>> /**
>> * <!-- begin-user-doc -->
>> * <!-- end-user-doc -->
>> * @generated
>> */
>> public String getLength() {
>> // TODO: implement this method to return the 'Length' attribute
>> // Ensure that you remove @generated or mark it @generated NOT
>> throw new UnsupportedOperationException();
>> }
>> Let me know if this helps, or if you have other questions.
>>
>> Paul
>>
>
>
Re: JET2 vs JMerge vs Codegen vs EMF [message #36342 is a reply to message #35975] Fri, 16 November 2007 17:52 Go to previous messageGo to next message
robert searle is currently offline robert searleFriend
Messages: 4
Registered: July 2009
Junior Member
Hello Paul,

I was looking at "Eclipse Development using the Graphical Editing Framework
and the Eclipse Modeling Framework" found at http://www.redbooks.ibm.com/redbooks/pdfs/sg246302.pdf.
Inside they have an "Example 2-38 Our version of Header.javajet". I followed
the instructions on page 81. I always close down all the files, make the
edits, close them down again, delete all the old generated source files,
and then open the GenModel file to generate the source code.

What I expect to find is the generated source code with my new header at
the top of the files. Did I miss the point of the example? Is the example
too old? What I get is
/**
* <copyright>
* </copyright>
*
* $Id$
*/

instead of
/**
* WorkflowModel
*
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
*/



> Robert:
>
> I would write a single JET2 template that produced all the
> getters/setters you want. In pseudo-JET, it look something like:
>
> <%-- run JMerge using the modified emf-rules, as described in a
> previous
> post --%>
> <java:merge rules="templates/modified-emf-rules.xml"/>
> package ...;
>
> /**
> * @generated
> */
> public class ...Impl implements ... extends ... {
> <c:iterate select="$genClass/genAttributes" var="genAttribute">
> /**
> * ...
> * @generated
> */
> public ... get... () {
> ... your implementation here...
> }
> /**
> * ...
> * @generated
> */
> public void set... (... new...) {
> ... your implementation here...
> }
> </c:iterate>
> }
> The JMerge happens automatically as part of invoking the template with
> either the <ws:file> tag or the <java:class> tag.
>
> I'm assuming you'd work off of the same GenModel as it probably has
> most of the information you'll need. The only unfortunate bit is that
> alot of the GenModel methods (including getXXX) methods are not
> declared to EMF, so you'll have to resort to Java code to get their
> values. There are a couple of choices.
>
> 1) Use <c:set> to create 'derived attributes' gen model elements.
> These appear to be attributes to the XPath engine, but are not
> actually stored in the GenModel. For example, you might do the
> following in main.jet:
>
> <%-- you will have to add org.eclipse.emf.codegen.ecore to adjust the
> JET
> plug-ins dependencies to get the generated Java to compile --%>
> <%@jet imports="org.eclipse.emf.codegen.ecore.genmodel.*"%>
> <c:setVariable var="genModel" select="/GenModel"/>
> <%-- create derived attributes to contain genmodel methods JET Xpath
> cannot
> see --%>
> <c:iterate select="$genModel/genPackages" select="genPackage">
> <%
> GenPackage genPackage =
> (GenClass)context.getVariable("genPackage");
> %>
> <c:set var="$genPackage" name="interfacePackageName"><%=
> getPackage.getInterfacePackageName() %></c:set>
> <c:set var="$genPackage" name="classPackageName"><%=
> getPackage.getClassPackageName() %></c:set>
> <c:iterate select="$genPackage/genClasses" var="genClass">
> <%
> GenClass genClass =
> (GenClass)context.getVariable("genClass");
> %>
> <c:set select="$genClass" name="className"><%=
> genClass.getClassName() %></c:set>
> <c:set select="$genClass" name="typeParameters"><%=
> genClass.getTypeParameters() %></c:set>
> <c:set select="$genClass" name="classExtends"><%=
> genClass.getClassExtends() %></c:set>
> <c:set select="$genClass" name="classImplements"><%=
> genClass.getClassImplements() %></c:set>
> </c:iterate>
> </c:iterate>
> <%-- Invoke the template --%>
> <c:iterate select="$genModel/genPackages" select="genPackage">
> <c:iterate select="$genPackage/genClasses" var="genClass">
> <java:class srcFolder="{$genModel/@modelDirectory}"
> package="{ $genPackage/@classPackageName}"
> name="{ $genPackage/@className}"
> tempate="templates/class/MyGetters.java.jet"/>
> </c:iterate>
> </c:iterate>
> Then, in your template, you can just you JET tags.
>
> 2) Do the <% .. %> and <%= %> blocks directly in your templates, and
> don't bother with the derived attributes.
>
> Lastly, its easy to get a JET transformation to load a GenModel. You
> need to specify the org.eclipse.jet.emf 'model loader' in the
> plugin.xml. See the JET FAQ:
>
> http://wiki.eclipse.org/JET_FAQ_What_kind_of_input_model_can _JET_handl
> e%3F
>
> You can test it out simply creating a new JET project, and modifying
> plugin.xml to use the org.eclipse.jet.emf model loader. If you then
> launch the transformation against a .genmodel file, you'll get a
> not-very-useful dump.xml file produced by the transformation. (The
> c:dump tag is not very good at showing you the contents of an
> EMF-based model like a .genmodel.
>
> Hope this helps,
>
> Paul
>
> "robert" <robertsearle@hotmail.com> wrote in message
> news:2d21903416f28c9ef6283e46b26@news.eclipse.org...
>
>> Paul,
>>
>> You are right except for a small issue with point 3. Since the code
>> is a
>> proxy into the JACOB project, I will _unconditionally_ replace all
>> generated methods, including getters and setters. I do not need the
>> class's private storage variables. Thank you for the idea of setting
>> the
>> EAttributes to 'derived' to remove the generated classes' attributes.
>> I do not want developers wondering which classes or sub-classes to
>> use in
>> choice C. I think my preference is choice B since it is more eclipse
>> /
>> EMF version independent than choice A.
>> I assume for choice B, JMerge is the injector not JET2, correct? For
>> choice B, JET2 will create the methods bodies one at a time. The JET2
>> tag
>> <java:merge/> causes the JET2 result to be merged into the
>> pre-existing
>> java file, right?
>> One last question, is there any sample java code showing how to
>> transform an ecore / .genmodel via a JET2 template?
>>
>> Thanks for your answers.
>>
>> --Robert
>>
>>> Robert:
>>>
>>> Thanks for posting this to the group and please, Paul will do :-)
>>>
>>> Let me start by restating your question, to make sure I understand.
>>>
>>> 1) You are creating an ECore model based on a COM TLB file.
>>> 2) You then create a .genmodel for this ECore file.
>>> 3) You want EMF to generate the Java code, all except for a few
>>> methods,
>>> here and there. For those methods, you'd like to insert your own
>>> implementations, rather than those provided by the EMF code
>>> generator.
>>> 4) You don't expect users of your tool to modify any of the
>>> generated
>>> Java
>>> code.
>>> Assuming I've got it right (which I probably didn't), you have a
>>> couple of
>>> choices:
>>> A. Extend the EMF code generator
>>> B. Inject your code after running the standard EMF code generator
>>> C. Generate your own subclasses of the generated EMF Impl classes,
>>> overriding the methods you want.
>>> A. Extending the EMF code generator
>>> In the .genmodel file, you can specify a location of templates that
>>> override
>>> those defined in the EMF code generator. You then have to take a
>>> look
>>> at the
>>> EMF code generator templates (org.eclipse.emf.codegen.ecore
>>> plug-in).
>>> Here's
>>> a link to the CVS repository location for the Model templates:
>>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse
>>> .e
>>> mf/plugins/org.eclipse.emf.codegen.ecore/templates/model/?ro ot=Model
>>> in
>>> g_Project
>>> Your alternative location can just implement the templates you want.
>>> Some of the templates include @include directives for files you can
>>> supply to override parts of the templates. An example of this
>>> approach is the UML2 project. You can see their extension templates
>>> here:
>>>
>>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.mdt/org .eclipse
>>> .u
>>> ml2/plugins/org.eclipse.uml2.codegen.ecore/templates/model/? root=Mod
>>> el ing_Project
>>>
>>> Taking this path, though, requires a significant investment in
>>> learning how the EMF code generator works. If you do go this root,
>>> the org.eclipse.emf newsgroup will be helpful..
>>>
>>> BTW, the EMF code generator uses "JET1" templates. These don't use
>>> tag libraries, but only Java scriptlets and expressions.
>>>
>>> B. Inject your code after running the standard EMF code generator.
>>>
>>> This approach leaves the EMF code generator as a black box, and
>>> instead tries to add your methods after the fact. That EMF includes
>>> @generated tags on all the code it generates is a big help. You
>>> could
>>> write a JET2 'transformation' that emits just the Java code you want
>>> to replace, and then JMerges them into the already generated class.
>>> Your templates for these class could include just the methods you
>>> want
>>> to replace, plus a <java:merge/> tag. Since the standard JMerge
>>> rules
>>> will 'sweep' out any code not referenced in your new version, you
>>> may
>>> want to customize them by removing the < > element at line
>>> 146. The standard rules are found here:
>>> You can find the standard JMerge rules here:
>>>
>>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclipse
>>> .e
>>> mf/plugins/org.eclipse.emf.codegen.ecore/templates/emf-merge .xml?ann
>>> ot ate=1.12&root=Modeling_Project
>>>
>>> C. Generate your own Impl subclasses and factory
>>>
>>> A final approach is to leave EMFs generator code alone, and instead
>>> generate subclasses of the EMF generated classes. So that your
>>> clients can create these instances, you would have to create your
>>> own FactoryImpl class, probably extending the generated one.
>>>
>>> Other things you may want to consider:
>>> * If going for option A or B, set the EAttributes that you want to
>>> override
>>> as 'derived'. This will prevent the EMF code generator from
>>> creating
>>> fields
>>> to store the value. Instead, you'll get method bodies like:
>>> /**
>>> * <!-- begin-user-doc -->
>>> * <!-- end-user-doc -->
>>> * @generated
>>> */
>>> public String getLength() {
>>> // TODO: implement this method to return the 'Length' attribute
>>> // Ensure that you remove @generated or mark it @generated NOT
>>> throw new UnsupportedOperationException();
>>> }
>>> Let me know if this helps, or if you have other questions.
>>> Paul
>>>
Re: JET2 vs JMerge vs Codegen vs EMF [message #36561 is a reply to message #36342] Tue, 20 November 2007 02:00 Go to previous messageGo to next message
robert searle is currently offline robert searleFriend
Messages: 4
Registered: July 2009
Junior Member
FYI,

If anyone cares, the file should be called Header.javajetinc not Header.javajet.

> Hello Paul,
>
> I was looking at "Eclipse Development using the Graphical Editing
> Framework
> and the Eclipse Modeling Framework" found at
> http://www.redbooks.ibm.com/redbooks/pdfs/sg246302.pdf.
> Inside they have an "Example 2-38 Our version of Header.javajet". I
> followed
> the instructions on page 81. I always close down all the files, make
> the
> edits, close them down again, delete all the old generated source
> files,
> and then open the GenModel file to generate the source code.
> What I expect to find is the generated source code with my new header
> at
> the top of the files. Did I miss the point of the example? Is the
> example
> too old? What I get is
> /**
> * <copyright>
> * </copyright>
> *
> * $Id$
> */
> instead of
> /**
> * WorkflowModel
> *
> * Copyright (c) 2000, 2003 IBM Corporation and others.
> * All rights reserved. This program and the accompanying
> materials
> * are made available under the terms of the Common Public
> License v1.0
> * which accompanies this distribution, and is available at
> * http://www.eclipse.org/legal/cpl-v10.html
> *
> */
>> Robert:
>>
>> I would write a single JET2 template that produced all the
>> getters/setters you want. In pseudo-JET, it look something like:
>>
>> <%-- run JMerge using the modified emf-rules, as described in a
>> previous
>> post --%>
>> <java:merge rules="templates/modified-emf-rules.xml"/>
>> package ...;
>> /**
>> * @generated
>> */
>> public class ...Impl implements ... extends ... {
>> <c:iterate select="$genClass/genAttributes" var="genAttribute">
>> /**
>> * ...
>> * @generated
>> */
>> public ... get... () {
>> ... your implementation here...
>> }
>> /**
>> * ...
>> * @generated
>> */
>> public void set... (... new...) {
>> ... your implementation here...
>> }
>> </c:iterate>
>> }
>> The JMerge happens automatically as part of invoking the template
>> with
>> either the <ws:file> tag or the <java:class> tag.
>> I'm assuming you'd work off of the same GenModel as it probably has
>> most of the information you'll need. The only unfortunate bit is that
>> alot of the GenModel methods (including getXXX) methods are not
>> declared to EMF, so you'll have to resort to Java code to get their
>> values. There are a couple of choices.
>>
>> 1) Use <c:set> to create 'derived attributes' gen model elements.
>> These appear to be attributes to the XPath engine, but are not
>> actually stored in the GenModel. For example, you might do the
>> following in main.jet:
>>
>> <%-- you will have to add org.eclipse.emf.codegen.ecore to adjust the
>> JET
>> plug-ins dependencies to get the generated Java to compile --%>
>> <%@jet imports="org.eclipse.emf.codegen.ecore.genmodel.*"%>
>> <c:setVariable var="genModel" select="/GenModel"/>
>> <%-- create derived attributes to contain genmodel methods JET Xpath
>> cannot
>> see --%>
>> <c:iterate select="$genModel/genPackages" select="genPackage">
>> <%
>> GenPackage genPackage =
>> (GenClass)context.getVariable("genPackage");
>> %>
>> <c:set var="$genPackage" name="interfacePackageName"><%=
>> getPackage.getInterfacePackageName() %></c:set>
>> <c:set var="$genPackage" name="classPackageName"><%=
>> getPackage.getClassPackageName() %></c:set>
>> <c:iterate select="$genPackage/genClasses" var="genClass">
>> <%
>> GenClass genClass =
>> (GenClass)context.getVariable("genClass");
>> %>
>> <c:set select="$genClass" name="className"><%=
>> genClass.getClassName() %></c:set>
>> <c:set select="$genClass" name="typeParameters"><%=
>> genClass.getTypeParameters() %></c:set>
>> <c:set select="$genClass" name="classExtends"><%=
>> genClass.getClassExtends() %></c:set>
>> <c:set select="$genClass" name="classImplements"><%=
>> genClass.getClassImplements() %></c:set>
>> </c:iterate>
>> </c:iterate>
>> <%-- Invoke the template --%>
>> <c:iterate select="$genModel/genPackages" select="genPackage">
>> <c:iterate select="$genPackage/genClasses" var="genClass">
>> <java:class srcFolder="{$genModel/@modelDirectory}"
>> package="{ $genPackage/@classPackageName}"
>> name="{ $genPackage/@className}"
>> tempate="templates/class/MyGetters.java.jet"/>
>> </c:iterate>
>> </c:iterate>
>> Then, in your template, you can just you JET tags.
>> 2) Do the <% .. %> and <%= %> blocks directly in your templates, and
>> don't bother with the derived attributes.
>>
>> Lastly, its easy to get a JET transformation to load a GenModel. You
>> need to specify the org.eclipse.jet.emf 'model loader' in the
>> plugin.xml. See the JET FAQ:
>>
>> http://wiki.eclipse.org/JET_FAQ_What_kind_of_input_model_can _JET_hand
>> l e%3F
>>
>> You can test it out simply creating a new JET project, and modifying
>> plugin.xml to use the org.eclipse.jet.emf model loader. If you then
>> launch the transformation against a .genmodel file, you'll get a
>> not-very-useful dump.xml file produced by the transformation. (The
>> c:dump tag is not very good at showing you the contents of an
>> EMF-based model like a .genmodel.
>>
>> Hope this helps,
>>
>> Paul
>>
>> "robert" <robertsearle@hotmail.com> wrote in message
>> news:2d21903416f28c9ef6283e46b26@news.eclipse.org...
>>
>>> Paul,
>>>
>>> You are right except for a small issue with point 3. Since the code
>>> is a
>>> proxy into the JACOB project, I will _unconditionally_ replace all
>>> generated methods, including getters and setters. I do not need the
>>> class's private storage variables. Thank you for the idea of
>>> setting
>>> the
>>> EAttributes to 'derived' to remove the generated classes'
>>> attributes.
>>> I do not want developers wondering which classes or sub-classes to
>>> use in
>>> choice C. I think my preference is choice B since it is more
>>> eclipse
>>> /
>>> EMF version independent than choice A.
>>> I assume for choice B, JMerge is the injector not JET2, correct?
>>> For
>>> choice B, JET2 will create the methods bodies one at a time. The
>>> JET2
>>> tag
>>> <java:merge/> causes the JET2 result to be merged into the
>>> pre-existing
>>> java file, right?
>>> One last question, is there any sample java code showing how to
>>> transform an ecore / .genmodel via a JET2 template?
>>> Thanks for your answers.
>>>
>>> --Robert
>>>
>>>> Robert:
>>>>
>>>> Thanks for posting this to the group and please, Paul will do :-)
>>>>
>>>> Let me start by restating your question, to make sure I understand.
>>>>
>>>> 1) You are creating an ECore model based on a COM TLB file.
>>>> 2) You then create a .genmodel for this ECore file.
>>>> 3) You want EMF to generate the Java code, all except for a few
>>>> methods,
>>>> here and there. For those methods, you'd like to insert your own
>>>> implementations, rather than those provided by the EMF code
>>>> generator.
>>>> 4) You don't expect users of your tool to modify any of the
>>>> generated
>>>> Java
>>>> code.
>>>> Assuming I've got it right (which I probably didn't), you have a
>>>> couple of
>>>> choices:
>>>> A. Extend the EMF code generator
>>>> B. Inject your code after running the standard EMF code generator
>>>> C. Generate your own subclasses of the generated EMF Impl classes,
>>>> overriding the methods you want.
>>>> A. Extending the EMF code generator
>>>> In the .genmodel file, you can specify a location of templates that
>>>> override
>>>> those defined in the EMF code generator. You then have to take a
>>>> look
>>>> at the
>>>> EMF code generator templates (org.eclipse.emf.codegen.ecore
>>>> plug-in).
>>>> Here's
>>>> a link to the CVS repository location for the Model templates:
>>>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclips
>>>> e
>>>> .e
>>>> mf/plugins/org.eclipse.emf.codegen.ecore/templates/model/?ro ot=Mode
>>>> l
>>>> in
>>>> g_Project
>>>> Your alternative location can just implement the templates you
>>>> want.
>>>> Some of the templates include @include directives for files you can
>>>> supply to override parts of the templates. An example of this
>>>> approach is the UML2 project. You can see their extension templates
>>>> here:
>>>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.mdt/org .eclips
>>>> e .u
>>>> ml2/plugins/org.eclipse.uml2.codegen.ecore/templates/model/? root=Mo
>>>> d el ing_Project
>>>>
>>>> Taking this path, though, requires a significant investment in
>>>> learning how the EMF code generator works. If you do go this root,
>>>> the org.eclipse.emf newsgroup will be helpful..
>>>>
>>>> BTW, the EMF code generator uses "JET1" templates. These don't use
>>>> tag libraries, but only Java scriptlets and expressions.
>>>>
>>>> B. Inject your code after running the standard EMF code generator.
>>>>
>>>> This approach leaves the EMF code generator as a black box, and
>>>> instead tries to add your methods after the fact. That EMF includes
>>>> @generated tags on all the code it generates is a big help. You
>>>> could
>>>> write a JET2 'transformation' that emits just the Java code you
>>>> want
>>>> to replace, and then JMerges them into the already generated class.
>>>> Your templates for these class could include just the methods you
>>>> want
>>>> to replace, plus a <java:merge/> tag. Since the standard JMerge
>>>> rules
>>>> will 'sweep' out any code not referenced in your new version, you
>>>> may
>>>> want to customize them by removing the < > element at line
>>>> 146. The standard rules are found here:
>>>> You can find the standard JMerge rules here:
>>>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclips
>>>> e .e
>>>> mf/plugins/org.eclipse.emf.codegen.ecore/templates/emf-merge .xml?an
>>>> n ot ate=1.12&root=Modeling_Project
>>>>
>>>> C. Generate your own Impl subclasses and factory
>>>>
>>>> A final approach is to leave EMFs generator code alone, and instead
>>>> generate subclasses of the EMF generated classes. So that your
>>>> clients can create these instances, you would have to create your
>>>> own FactoryImpl class, probably extending the generated one.
>>>>
>>>> Other things you may want to consider:
>>>> * If going for option A or B, set the EAttributes that you want to
>>>> override
>>>> as 'derived'. This will prevent the EMF code generator from
>>>> creating
>>>> fields
>>>> to store the value. Instead, you'll get method bodies like:
>>>> /**
>>>> * <!-- begin-user-doc -->
>>>> * <!-- end-user-doc -->
>>>> * @generated
>>>> */
>>>> public String getLength() {
>>>> // TODO: implement this method to return the 'Length' attribute
>>>> // Ensure that you remove @generated or mark it @generated NOT
>>>> throw new UnsupportedOperationException();
>>>> }
>>>> Let me know if this helps, or if you have other questions.
>>>> Paul
Re: JET2 vs JMerge vs Codegen vs EMF [message #36662 is a reply to message #36561] Tue, 20 November 2007 13:56 Go to previous message
Paul Elder is currently offline Paul ElderFriend
Messages: 849
Registered: July 2009
Senior Member
Robert:

Thanks for the update, and the context. I notice the redbook as information
on how to provide feedback in the preface.

There are significant differences between JET as used in the redbook, and
M2T JET:

JET used in the Redbook (JET1)
* Found in the plug-ins org.eclipse.emf.codegen*.
* developed and used the EMF for the EMF code generator
* Based on JSP. All template expansion and control is done through Java code
('scriptlets' <% ... java statements ... %> and 'expressions' <%= java
expression %>).
* Each template gets compiled into a Java class with a singled method:
String generate(Object argument).
* No infrastructure provided to help you use the template result. You must
typically write a number of Java classes that invoke JET1 templates and that
save the resulting strings.
* Infrastructure provided to dynamically compile and load templates (the
JETEmitter class).
* Companion infrastructures: JMerge, Java imports management

M2T JET (JET2)
* Found in the plug-ins org.eclipse.jet*
* A major goal of JET2 was to make to possible to create simple code
generators without requiring deep knowledge of the Eclipse platform, its
APIs or even Java.
* Base on JSP: tag libraries as well as scriptlets and expressions.
* Each template gets compiled into a Java class with a single method: void
generated(JET2Context context, JET2Writer out).
* Standard tag libraries provided.
* Infrastructure provided to load an input model, traverse it, invoke
templates and save results to the eclipse workspace. This is what JET2 calls
a 'transformation'. Transformations may all be created entirely with the
provided tag libraries. There is no need to write any Java code.
* JET transformation projects are standard Eclipse plug-ins.
* Infrastructure provided to dynamically load and execute JET
transformations from the Eclipse workspace (JET2Platform.runTransformOnXXX).
That is, there is no need to create runtime workbenches to test a JET
transformation. (The dynamically loading does not, however, extend to
dependent plug-ins, so runtime workbenches may still be required in some
cases.)
* Tags are included to take an advantage of JET1 technologies (java:merge
for JMerge, java:import & java:importsLocation for Java imports management).
* Since 0.8, JET2 has started to add some compatibility support for JET1
templates. The compiler is capable of compiling JET1 templates. However,
there is still not enough UI to support this, nor is there a direct
replacement for the JETEmitter class. I will try to contribute more to this
in the Ganymede release.

Paul

"robert" <robertsearle@hotmail.com> wrote in message
news:2d2190341b638c9f8f5915340f6@news.eclipse.org...
> FYI,
>
> If anyone cares, the file should be called Header.javajetinc not
> Header.javajet.
>
>> Hello Paul,
>>
>> I was looking at "Eclipse Development using the Graphical Editing
>> Framework
>> and the Eclipse Modeling Framework" found at
>> http://www.redbooks.ibm.com/redbooks/pdfs/sg246302.pdf.
>> Inside they have an "Example 2-38 Our version of Header.javajet". I
>> followed
>> the instructions on page 81. I always close down all the files, make
>> the
>> edits, close them down again, delete all the old generated source
>> files,
>> and then open the GenModel file to generate the source code.
>> What I expect to find is the generated source code with my new header
>> at
>> the top of the files. Did I miss the point of the example? Is the
>> example
>> too old? What I get is
>> /**
>> * <copyright>
>> * </copyright>
>> *
>> * $Id$
>> */
>> instead of
>> /**
>> * WorkflowModel
>> *
>> * Copyright (c) 2000, 2003 IBM Corporation and others.
>> * All rights reserved. This program and the accompanying
>> materials
>> * are made available under the terms of the Common Public
>> License v1.0
>> * which accompanies this distribution, and is available at
>> * http://www.eclipse.org/legal/cpl-v10.html
>> *
>> */
>>> Robert:
>>>
>>> I would write a single JET2 template that produced all the
>>> getters/setters you want. In pseudo-JET, it look something like:
>>>
>>> <%-- run JMerge using the modified emf-rules, as described in a
>>> previous
>>> post --%>
>>> <java:merge rules="templates/modified-emf-rules.xml"/>
>>> package ...;
>>> /**
>>> * @generated
>>> */
>>> public class ...Impl implements ... extends ... {
>>> <c:iterate select="$genClass/genAttributes" var="genAttribute">
>>> /**
>>> * ...
>>> * @generated
>>> */
>>> public ... get... () {
>>> ... your implementation here...
>>> }
>>> /**
>>> * ...
>>> * @generated
>>> */
>>> public void set... (... new...) {
>>> ... your implementation here...
>>> }
>>> </c:iterate>
>>> }
>>> The JMerge happens automatically as part of invoking the template
>>> with
>>> either the <ws:file> tag or the <java:class> tag.
>>> I'm assuming you'd work off of the same GenModel as it probably has
>>> most of the information you'll need. The only unfortunate bit is that
>>> alot of the GenModel methods (including getXXX) methods are not
>>> declared to EMF, so you'll have to resort to Java code to get their
>>> values. There are a couple of choices.
>>>
>>> 1) Use <c:set> to create 'derived attributes' gen model elements.
>>> These appear to be attributes to the XPath engine, but are not
>>> actually stored in the GenModel. For example, you might do the
>>> following in main.jet:
>>>
>>> <%-- you will have to add org.eclipse.emf.codegen.ecore to adjust the
>>> JET
>>> plug-ins dependencies to get the generated Java to compile --%>
>>> <%@jet imports="org.eclipse.emf.codegen.ecore.genmodel.*"%>
>>> <c:setVariable var="genModel" select="/GenModel"/>
>>> <%-- create derived attributes to contain genmodel methods JET Xpath
>>> cannot
>>> see --%>
>>> <c:iterate select="$genModel/genPackages" select="genPackage">
>>> <%
>>> GenPackage genPackage =
>>> (GenClass)context.getVariable("genPackage");
>>> %>
>>> <c:set var="$genPackage" name="interfacePackageName"><%=
>>> getPackage.getInterfacePackageName() %></c:set>
>>> <c:set var="$genPackage" name="classPackageName"><%=
>>> getPackage.getClassPackageName() %></c:set>
>>> <c:iterate select="$genPackage/genClasses" var="genClass">
>>> <%
>>> GenClass genClass =
>>> (GenClass)context.getVariable("genClass");
>>> %>
>>> <c:set select="$genClass" name="className"><%=
>>> genClass.getClassName() %></c:set>
>>> <c:set select="$genClass" name="typeParameters"><%=
>>> genClass.getTypeParameters() %></c:set>
>>> <c:set select="$genClass" name="classExtends"><%=
>>> genClass.getClassExtends() %></c:set>
>>> <c:set select="$genClass" name="classImplements"><%=
>>> genClass.getClassImplements() %></c:set>
>>> </c:iterate>
>>> </c:iterate>
>>> <%-- Invoke the template --%>
>>> <c:iterate select="$genModel/genPackages" select="genPackage">
>>> <c:iterate select="$genPackage/genClasses" var="genClass">
>>> <java:class srcFolder="{$genModel/@modelDirectory}"
>>> package="{ $genPackage/@classPackageName}"
>>> name="{ $genPackage/@className}"
>>> tempate="templates/class/MyGetters.java.jet"/>
>>> </c:iterate>
>>> </c:iterate>
>>> Then, in your template, you can just you JET tags.
>>> 2) Do the <% .. %> and <%= %> blocks directly in your templates, and
>>> don't bother with the derived attributes.
>>>
>>> Lastly, its easy to get a JET transformation to load a GenModel. You
>>> need to specify the org.eclipse.jet.emf 'model loader' in the
>>> plugin.xml. See the JET FAQ:
>>>
>>> http://wiki.eclipse.org/JET_FAQ_What_kind_of_input_model_can _JET_hand
>>> l e%3F
>>>
>>> You can test it out simply creating a new JET project, and modifying
>>> plugin.xml to use the org.eclipse.jet.emf model loader. If you then
>>> launch the transformation against a .genmodel file, you'll get a
>>> not-very-useful dump.xml file produced by the transformation. (The
>>> c:dump tag is not very good at showing you the contents of an
>>> EMF-based model like a .genmodel.
>>>
>>> Hope this helps,
>>>
>>> Paul
>>>
>>> "robert" <robertsearle@hotmail.com> wrote in message
>>> news:2d21903416f28c9ef6283e46b26@news.eclipse.org...
>>>
>>>> Paul,
>>>>
>>>> You are right except for a small issue with point 3. Since the code
>>>> is a
>>>> proxy into the JACOB project, I will _unconditionally_ replace all
>>>> generated methods, including getters and setters. I do not need the
>>>> class's private storage variables. Thank you for the idea of
>>>> setting
>>>> the
>>>> EAttributes to 'derived' to remove the generated classes'
>>>> attributes.
>>>> I do not want developers wondering which classes or sub-classes to
>>>> use in
>>>> choice C. I think my preference is choice B since it is more
>>>> eclipse
>>>> /
>>>> EMF version independent than choice A.
>>>> I assume for choice B, JMerge is the injector not JET2, correct?
>>>> For
>>>> choice B, JET2 will create the methods bodies one at a time. The
>>>> JET2
>>>> tag
>>>> <java:merge/> causes the JET2 result to be merged into the
>>>> pre-existing
>>>> java file, right?
>>>> One last question, is there any sample java code showing how to
>>>> transform an ecore / .genmodel via a JET2 template?
>>>> Thanks for your answers.
>>>>
>>>> --Robert
>>>>
>>>>> Robert:
>>>>>
>>>>> Thanks for posting this to the group and please, Paul will do :-)
>>>>>
>>>>> Let me start by restating your question, to make sure I understand.
>>>>>
>>>>> 1) You are creating an ECore model based on a COM TLB file.
>>>>> 2) You then create a .genmodel for this ECore file.
>>>>> 3) You want EMF to generate the Java code, all except for a few
>>>>> methods,
>>>>> here and there. For those methods, you'd like to insert your own
>>>>> implementations, rather than those provided by the EMF code
>>>>> generator.
>>>>> 4) You don't expect users of your tool to modify any of the
>>>>> generated
>>>>> Java
>>>>> code.
>>>>> Assuming I've got it right (which I probably didn't), you have a
>>>>> couple of
>>>>> choices:
>>>>> A. Extend the EMF code generator
>>>>> B. Inject your code after running the standard EMF code generator
>>>>> C. Generate your own subclasses of the generated EMF Impl classes,
>>>>> overriding the methods you want.
>>>>> A. Extending the EMF code generator
>>>>> In the .genmodel file, you can specify a location of templates that
>>>>> override
>>>>> those defined in the EMF code generator. You then have to take a
>>>>> look
>>>>> at the
>>>>> EMF code generator templates (org.eclipse.emf.codegen.ecore
>>>>> plug-in).
>>>>> Here's
>>>>> a link to the CVS repository location for the Model templates:
>>>>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclips
>>>>> e
>>>>> .e
>>>>> mf/plugins/org.eclipse.emf.codegen.ecore/templates/model/?ro ot=Mode
>>>>> l
>>>>> in
>>>>> g_Project
>>>>> Your alternative location can just implement the templates you
>>>>> want.
>>>>> Some of the templates include @include directives for files you can
>>>>> supply to override parts of the templates. An example of this
>>>>> approach is the UML2 project. You can see their extension templates
>>>>> here:
>>>>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.mdt/org .eclips
>>>>> e .u
>>>>> ml2/plugins/org.eclipse.uml2.codegen.ecore/templates/model/? root=Mo
>>>>> d el ing_Project
>>>>>
>>>>> Taking this path, though, requires a significant investment in
>>>>> learning how the EMF code generator works. If you do go this root,
>>>>> the org.eclipse.emf newsgroup will be helpful..
>>>>>
>>>>> BTW, the EMF code generator uses "JET1" templates. These don't use
>>>>> tag libraries, but only Java scriptlets and expressions.
>>>>>
>>>>> B. Inject your code after running the standard EMF code generator.
>>>>>
>>>>> This approach leaves the EMF code generator as a black box, and
>>>>> instead tries to add your methods after the fact. That EMF includes
>>>>> @generated tags on all the code it generates is a big help. You
>>>>> could
>>>>> write a JET2 'transformation' that emits just the Java code you
>>>>> want
>>>>> to replace, and then JMerges them into the already generated class.
>>>>> Your templates for these class could include just the methods you
>>>>> want
>>>>> to replace, plus a <java:merge/> tag. Since the standard JMerge
>>>>> rules
>>>>> will 'sweep' out any code not referenced in your new version, you
>>>>> may
>>>>> want to customize them by removing the < > element at line
>>>>> 146. The standard rules are found here:
>>>>> You can find the standard JMerge rules here:
>>>>> http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.emf/org .eclips
>>>>> e .e
>>>>> mf/plugins/org.eclipse.emf.codegen.ecore/templates/emf-merge .xml?an
>>>>> n ot ate=1.12&root=Modeling_Project
>>>>>
>>>>> C. Generate your own Impl subclasses and factory
>>>>>
>>>>> A final approach is to leave EMFs generator code alone, and instead
>>>>> generate subclasses of the EMF generated classes. So that your
>>>>> clients can create these instances, you would have to create your
>>>>> own FactoryImpl class, probably extending the generated one.
>>>>>
>>>>> Other things you may want to consider:
>>>>> * If going for option A or B, set the EAttributes that you want to
>>>>> override
>>>>> as 'derived'. This will prevent the EMF code generator from
>>>>> creating
>>>>> fields
>>>>> to store the value. Instead, you'll get method bodies like:
>>>>> /**
>>>>> * <!-- begin-user-doc -->
>>>>> * <!-- end-user-doc -->
>>>>> * @generated
>>>>> */
>>>>> public String getLength() {
>>>>> // TODO: implement this method to return the 'Length' attribute
>>>>> // Ensure that you remove @generated or mark it @generated NOT
>>>>> throw new UnsupportedOperationException();
>>>>> }
>>>>> Let me know if this helps, or if you have other questions.
>>>>> Paul
>
>
Previous Topic:Re: Using variables in JET
Next Topic:Executing JET Transformations in ANT
Goto Forum:
  


Current Time: Wed Apr 24 19:59:06 GMT 2024

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

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

Back to the top