Modeling using Eclipse Modeling Framework, Part 2

xiaoxiao2021-03-06  78

Use Eclipse Java Emitter Templates Generation Code

Level: Intermediate

Adrian Powell

Senior software developers, IBM 2004 June

Eclipse's Java Emitter Templates (JET) is an open source tool that generates code in Eclipse Modeling Framework (EMF). Jet is very similar to JSP, which is more powerful in JET functions, more flexible, can generate Java, SQL, and any other language code, including JSP. This article describes how to create and configure Jet and deploy them into a variety of environments.

Java Emitter Templates (JET) Overview Developers typically use some tools to generate common code. Eclipse users may be very familiar with some standard tools, which can generate for (;;) loops, main () methods, and access methods for selecting properties for selected properties. Alternatively, these simple and mechanical tasks can speed up the speed of programming, and simplify the process of programming. In some cases, for example, a deployment code is generated for the J2EE server, you can save a lot of time and you can hide some specific complexity, so you can deploy the program to a different J2EE server. The function of automatically generating code is not just providing a supplier of large tools, which can be used in many projects to improve efficiency. Eclipse's JET is packaged as part of EMF, which can simply add automatically generated code to the project. This article will introduce how to use Jet in various environments.

What is JET? Jet is very similar to JSP: Both use the same syntax, in fact, it is compiled into a Java program in the background; both are used to separate the presentation page from the model and controller; both can accept the input object as a The parameters can be inserted into a string value (expression) in the code, and the Java code can be used directly to perform a loop, declare the variable, or perform logic flow control (script); both can represent the structure of the generated object, Web page, Java class or file), and can support user detailed customization.

Jet and JSP differ in several critical places. In JET, the structure of the tag can be transformed to support generating code in different languages. Usually the input of the JET program is a configuration file, not the user's input (of course, not allowing this). And Jet usually only executes only once for a given workflow. This is not a technical limit; you can see that Jet has a lot of completely different usage.

Start

Creating a template To use Jet, create a new Java project JETEXAMPLE and set the source folder to SRC. In order to enable Jet to enable this project, click the right mouse and select Add Jet Nature. This will create a Templates directory in the root of the new project. Jet default configuration Use the root of the project to save the compiled Java file. To modify this setting, open the project's Properties window, select Jet Settings, and set the Source Container to SRC. This will save the compiled Jet Java file in this correct source folder when you run the Jet compiler.

Now we are ready to create the first Jet. The JET compiler creates a Java source file for each Jet, so habits are named newclass.javajet in the template, where newclass is the class name to generate. Although this naming method is not forced, this can avoid confusion. First create a new file gendao.javajet in the template directory. This system will have a dialog box that warns your compilation errors at the first line of this new file. If you look at the following warning information in detail, it will find "The Jet Directive IS Missing" (no Jet Directive). Although this is nothing wrong with this technology, because we just created an empty file, this warning message is easily confusing and misleading our ideas. Click 'OK' to close the Warning dialog box, and then click 'Cancel' to clear the New File dialog (this file has been created). In order to prevent this problem again, our primary problem is to create JET instructions.

Each Jet must start with Jet instructions. This can tell the Jet compiler to compile what is like (not what is the template generated, but what is the template class of compilation generation; please forgive, this term is very easy to confuse). Also give some standard Java information. For example, the following information is used in the following example:

Listing 1. Sample Jet statement

<% @ Jet

Package = "com.ibm.pdc.example.jet.gen"

Class = "gendao"

Imports = "java.util. * com.ibm.pdc.example.jet.model. *"

%>

The content of the list 1 is really self-explanatory. When compiling the Jet template, a Java file gendao is created and saved to com.ibm.pdc.example.jet.gen, which will import the specified package. Repeat it, this is only what template is like, not the content of the template to generate - the latter will introduce later. Note that the Java file name of the JET output result is defined in the Jet declaration, which is not limited to this file name. If the two templates declare the same class name, they will affect each other's changes without any warning messages. If you just copy and paste the template file, this is not correctly modified, this may happen. Because the new file is created in the template catalog, the copy and paste are very common, so be careful about this problem.

JSP can obtain information by pre-declare variables such as sessions, errors, contexts, and requests), similar to this, or use a pre-declared variable to the template. Jet only uses two implicit variables: StringBuffer, its type StringBuffer (strange, it is used to build output strings when calling generate (); and a parameter, for convenience, we call Argument It is an Object type. The first line of the typical Jet template will convert it to a more suitable class, as shown in Listing 2.

Listing 2. Initialization of Jet parameters

<% Gendbmodel gendbmodel = (gendbmodel) argument;%>

Package <% = gendbmodel.getPackageName ()%> As you can see, Jet's default syntax is the same as JSP: use <% ...%> including code, use <% = ...%> Print The value of the expression. Similar to JSP, use the <% ...%> tag correctly, you can add any logical loop or structure, just like in any Java method. E.g:

Listing 3. Scripts and expressions

Welcome <% = User.getName ()%>!

<% IF (user.getdayssincelastvisit ()> 5) {%>

Whew, thanks for coming back. We wisht we'd lost you!

<%} else {%>

Back so soon? Don't you have anything better to do?

<%}%>

After defining the Jet, save the file and right click on this file in the package browser, select Compile Template. If everything is normal, create a class gendao in a com.ibm.pdc.example.jet.gen package. There is only one method of public String Generate (see Listing 4), the result of this is the content defined in the Javajet template.

Listing 4. A basic JET compiled Java class, which is printed "Hello <% = argument%>"

Package com.ibm.pdc.example.jet.gen;

Import java.util. *;

Public Class Gendao

{

Protected final string nl = system.getproperties (). getproperty ("line.separator");

Protected final string text_1 = nl "Hello,";

Protected final string text_2 = nl "/ t";

Public String Generate (Object Argument)

{

StringBuffer stringbuffer = new stringbuffer ();

StringBuffer.Append (Text_1);

StringBuffer.Append (argument);

StringBuffer.Append (Text_2);

Return stringbuffer.tostring ();

}

}

After preparing a public code, you may notice some public elements that will appear repeatedly, such as copyright information added to all generated code. In JSP, this is declared by include. Put all the content you want to add to a file and name the file 'Copyright.inc' and add <% @ include file = "CopyRight.inc"%> "in the Javajet template. The specified container file is added to the compiled output, so it can reference any variables already declared so far. Extended .inc can be arbitrary, just do not use the name ending with JET or Jet, otherwise it will try to compile the included file so that this file is naturally poor. Custom JET Compilation If you use the included file or you can't meet the requirements, you may want to add some other methods, or customize the code generation process; the easiest way is to create a new Jet skeleton. The skeleton file is a template that describes the compiled Jet template. The default skeleton is shown in Listing 5.

Listing 5. Default Jet Skeleton

Public Class Class

{

Public String Generate (Object Argument)

{

""; "

}

}

All IMPORT statements are at the beginning, and the class will be replaced with class names set in the Class property of the JET declaration, and the code of the generate () method is replaced with code that performs the generated operation. Therefore, to modify the composition of the compiled template code, we only need to create a new skeleton file and make the customs you want, but still reserve the basic elements in the original place.

To create a custom skeleton, create a new file in the Custom.Skeleton template directory, as shown in Listing 6.

Listing 6. Custom JET skeleton

Public Class Class

{

Private java.util.date getdate () {

Return new java.util.date ();

}

Public String generate (Object argument) {

""; "

}

}

Then add the Skeleton = "Custom.Skeleton" property to the Jet declaration in the Javajet file in any Jet template to use this custom skeleton.

Alternatively, it is also possible to expand the base class, such as the Public Class Class Extends MyGenerator, and all necessary help methods are added to the base class. This may be harder because it retains the versatility of the code and simplifies the development process because the Jet compiler does not always give the most correct error message.

The custom skeleton can also be used to modify the parameter list of the method name and the generate () method, so that very picky developers can freely customize templates. Say that Jet wants to replace the code of Generate () as the code to be generated, is actually not accurate. In fact, it will only replace the code of the last method declared in the skeleton, so if you carefully modify the code of the skeleton, it is easy to make mistakes, and you will make your colleague confused.

As you can see, once you can see, once the template is compiled, it is a standard Java class. To use this class in the program, you only need to distribute the compiled template class without dispensing the Javajet template. Alternatively, you may want users to modify templates and automatically recompile templates when booting. EMF can implement this feature, anyone who needs this function or interested in this can enter PLUGINS / Org.ECLIPSE.EMF.CODEGEN.ECORE / TEMPLATES and modify the mode of EMF generation model or editor. If you just want to distribute the compiled template class, the compilation process can be automated. So far, we only see how to compile Jet templates using Jet Eclipse plugins, but in fact we can write some scripts to implement this function, or will generate job work as an ANT task.

Runtime Compilation Template To make the end user can customize the template (and debug the template), you can choose to compile the template at runtime. There are several ways to implement this feature. First we use a very useful class org.eclipse.emf.codegen.jet.jetemitter, it can abstract the details. Common (but usually wrong) code is very simple, as shown in Listing 7.

Listing 7. Simple usage of Jetemitter (usually wrong)

String Uri = "Platform: /Templates/myclass.javajet";

Jetemitter Jetemitter = New Jetemitter (URI);

String generated = jetemitter.generate (New NullProgressMonitor (), new object [] {argument});

If you try to run this code in a standard main () method, you will find the first question. The generate () method triggers a nullpointRexception exception because Jetemitter assumes that it is called by a plugin. In the initialization process, it will call codegenplugin.getplugin (). GetString (), this function will fail because CodegenPlugin.getPlugin () is empty.

Solving this problem has a simple way: put this code in a plugin, which can be used, but it is not a complete solution. Now Jetemitter's implementation creates a hidden item. Jetemitters, which contains the generated code. However, Jetemitter does not add this plug-in's classPath to this new project, so if the generated code references objects other than the standard Java library, it will not be successfully compiled. 2.0.0 The initial period seems to solve this problem, but until the beginning of April, this has not been fully implemented. To solve this problem, you must extend the Jetemitter class to override the initialize () method and add it to your own classpath item. Remko Popma has prepared a good example JP.AZZurri.jet.Article2.codegen.myjetemitter (see) This example can be handled, which can be used before Jet adds this correct feature. The modified code is shown in Listing 8.

Listing 8. Correct Jetemitter call

String base = platform.getPlugin (Plugin_ID) .GetDescriptor (). GetInstallURL (). Tostring (); string uri = base "templates / gentestcase.javajet";

Myjetemitter Jetemitter = New Myjetemitter (URI);

Jetemitter.addclassPathVariable ("jet_example", plugin_id);

String generated = jetemitter.generate (New NullProgressMonitor (),

New Object [] {genclass});

The command line compiled Jet in the command line is very simple, and it is not very difficult to compile a main () method. In this case, the difficulty is not compiling Javajet into Java code, but compiles this Java code into .class. In the command line, we can better control the classpath, which can break each step, and finally combine it, you can make the entire work smoothly and simple. The only skill is that we need to run Eclipse with a "no head" mode (no user interface), but even this problem has also been considered. To compile Jet, check out plugins / org.eclipse.emf.codegen_1.1.0 / test. This catalog contains scripts used by Windows and UNIX, as well as a JET example to be verified.

As an Ant task, there is an ANT task Jetc, which can be used with a template property, or there is a fileset property for multiple templates. Once the classpath of the Jetc task is configured, the template compile is as simple as the standard Java class. For more information on how to get and use this task, see Resources.

Custom JET to generate JSP ultimately, JET uses "<%" and "%>" to mark templates, however this is the same as the tag used by JSP. If you want to generate a JSP program, you can only modify the delimiter. This can be implemented using the StartTAG and EndTag properties in the JET declaration of the template, as shown in Listing 9. In this case, I use "[%" and "%]" as the start delimiter and end delimiter. As you can see, "[% = expression%]" can be handled correctly, just like the previous "<% = expression%>".

Listing 9. The Jet Template after the tag is modified

<% @ Jet

Package = "com.ibm.pdc.example.jet.gen"

Class = "jspgen"

Imports = "java.util. *"

StartTag = "[%"

Endtag = "%]"

%>

[% String argvalue = (string) argument;%]

Package [% = argvalue%];

Conclusion There is an unfortunate fact: many of the code is reused by copy / paste, whether it is large software or small software. Many times this problem has no obvious solution, even if the object-oriented language can not solve the problem. In the case of repeating the same basic code mode, only some modifications are made slightly, put the universal code in a template, then use Jet to generate various changes, this is a good time saving time and Effective approach. JSP has long used this method, so JET can learn from the success of JSP. JET uses the same basic layout and semantics as JSP, but allows more flexible customization. In order to achieve better control, the template can be pre-compiled; in order to achieve higher flexibility, it can be compiled and distributed at runtime. In the next article of this series, we will show how to generate code for the Prime Time, including allowing user custom code, and integration, or methods, even finer granular levels, allowing to regenerate code. We will also bind them into a plugin to show a way to integrate the generated code to the development process.

Reference

Other articles on the Eclipse Modeling Framework Series on developerWorks: Part 1 creates and uses the EMF model, and Part 3 merges the generated code into existing code. All documents, source code, and latest compiler are available on the EMF project home page. IBM Red Books Eclipse Development Using The Graphical Edition Framework and The Eclipse Modeling Framework has more detailed examples, which describes more customization features. For more information on Jet, you can read the REMKO POPMA JET Guide Part 1 and Part 2. If you want to build a template at runtime, you can refer to the code included in Part 2. If you have any questions, you can access the EMF newsgroup. If you have not used the Eclipse newsgroup, read the rules and how to apply for a password. There is more articles provided for Eclipse users in the open source project area of ​​DeveloperWorks. See the latest Eclipse technology download area in AlphaWorks. On the Open Source Area of ​​Developer Bookstore, hundreds of books on open source topics can be found, including several books on Eclipse. Subscribe to developerWorks, use the latest IBM tools and middleware introduced and test applications: You can get the IBM's various software, from Eclipse-based WebSphere, DB2, Lotus, Rational, and Tivoli, as a period of 12 software The license of a month, these content can only be obtained very much. Subscribe developerWorks, download a free trial version that runs on Linux product from Speed-start your Linux app section of developerWorks, including WebSphere Studio Site Developer, WebSphere SDK for Web services, WebSphere Application Server, DB2 Universal Database Personal Developers Edition, Tivoli Access Manager and Lotus Domino Server. This will be gate faster and helps to collect documents and technical support for each product.

转载请注明原文地址:https://www.9cbs.com/read-94083.html

New Post(0)