Welcome 微信登录

首页 / 软件开发 / JAVA / 使用EMP进行建模,第2部分:使用Eclipse的Java Emitter Templates生成代码

使用EMP进行建模,第2部分:使用Eclipse的Java Emitter Templates生成代码2011-03-26 IBM Adrian PowellJava Emitter Templates(JET)概述

开发人员通常都使用一些工具来生成常用的代码。Eclipse 用户可能对一些标准的工 具非常熟悉,这些工具可以为选定的属性生成 for(;;) 循环, main() 方法, 以及选定 属性的访问方法。将这些简单而机械的任务变得自动化,可以加快编程的速度,并简化编 程的过程。在某些情况中,例如为 J2EE 服务器生成部署代码,自动生成代码就可以节省 大量时间,并可以隐藏具体实现特有的一些复杂性,这样就可以将程序部署到不同的 J2EE 服务器上。自动生成代码的功能并不只是为开发大型工具的供应商提供的,在很多 项目中都可以使用这种功能来提高效率。Eclipse 的 JET 被包装为 EMF 的一部分,可以 简单而有效地向项目中添加自动生成的代码。本文将介绍在各种环境中如何使用 JET 。

JET 是什么?

JET 与 JSP 非常类似:二者使用相同的语法,实际上在后台都被编译成 Java 程序; 二者都用来将呈现页面与模型和控制器分离开来;二者都可以接受输入的对象作为参数, 都可以在代码中插入字符串值(表达式),可以直接使用 Java 代码执行循环、声明变量 或执行逻辑流程控制(脚本);二者都可以很好地表示所生成对象的结构,(Web 页面、 Java 类或文件),而且可以支持用户的详细定制。

JET 与 JSP 在几个关键的地方存在区别。在 JET 中,可以变换标记的结构来支持在 不同的语言中生成代码。通常 JET 程序的输入都是一个配置文件,而不是用户的输入( 当然也不禁止这样使用)。而且对于一个给定的工作流来说,JET 通常只会执行一次。这 并不是技术上的限制;您可以看到 JET 有很多完全不同的用法。

开始

创建模板

要使用 JET,创建一个新 Java 项目 JETExample ,并将源文件夹设置为 src 。为了 让 JET 启用这个项目,请点击鼠标右键,然后选择 Add JET Nature。这样就会在新项目 的根目录下创建一个 templates 目录。JET 的缺省配置使用项目的根目录来保存编译出 来的 Java 文件。要修改这种设置,打开该项目的 properties 窗口,选择 JET Settings,并将 source container 设置为 src 。这样在运行 JET 编译器时,就会将编 译出来的 JET Java 文件保存到这个正确的源文件夹中。

现在我们已经准备好创建第一个 JET 了。JET 编译器会为每个 JET 都创建一个 Java 源文件,因此习惯上是将模板命名为 NewClass.javajet ,其中 NewClass 是要生成的类 名。虽然这种命名方式不是强制的,但是这样可以避免产生混乱。

首先在模板目录中创建一个新文件 GenDAO.javajet 。这样系统会出现一个对话框, 警告您在这个新文件的第 1 行第 1 列处有编译错误。如果您详细地看以下警告信息,就 会发现它说 "The jet directive is missing"(没有 jet 指令)。虽然这在技术上没有 什么错误,因为我们刚才只不过是创建了一个空文件,但是这个警告信息却很容易产生混 乱并误导我们的思路。单击 "OK" 关闭警告对话框,然后单击 "Cancel" 清除 New File 对话框(这个文件已经创建了)。为了防止再次出现这种问题,我们的首要问题是创建 jet 指令。

每个 JET 都必须以 jet 指令开始。这样可以告诉 JET 编译器编译出来的 Java 模板 是什么样子(并不是模板生成了什么内容,而是编译生成的模板类是什么样子;请原谅, 这个术语有些容易让人迷惑)。此处还要给出一些标准的 Java 类信息。例如,在下面这 个例子中使用了以下信息:

清单 1. 样例 jet 声明

<%@ jet
package="com.ibm.pdc.example.jet.gen"
class="GenDAO"
imports="java.util.* com.ibm.pdc.example.jet.model.*"
%>

清单 1 的内容是真正自解释的。在编译 JET 模板时,会创建一个 Java 文件 GenDAO ,并将其保存到 com.ibm.pdc.example.jet.gen 中,它将导入指定的包。重复一遍,这 只是说明模板像什么样子,而不是模板将要生成的内容 -- 后者稍后将会介绍。注意 JET 输出结果的 Java 文件名是在 jet 的声明中定义的,它并不局限于这个文件名。如果两 个模板声明了相同的类名,那么它们就会相互影响到对方的变化,而不会产生任何警告信 息。如果您只是拷贝并粘贴模板文件,而没有正确地修改所有的 jet 声明,那就可能出 现这种情况。因为在模板目录中创建新文件时会产生警告,而拷贝和粘贴是非常常见的, 因此要自己小心这个问题。

JSP 可以通过预先声明的变量(例如会话、错误、上下文和请求)获取信息, JET 与 此类似,也可以使用预先声明的变量向模板传递信息。JET 只使用两个隐式的变量: stringBuffer ,其类型为 StringBuffer (奇怪吧?),它用来在调用 generate() 时 构建输出字符串;以及一个参数,出于方便起见,我们称之为 argument ,它是 Object 类型。典型的 JET 模板的第一行会将其转换为一个更适合的类,如清单 2 所示。

清单 2. JET 参数的初始化

<% GenDBModel genDBModel = (GenDBModel)argument; %>
package <%= genDBModel.getPackageName() %>;

正如您可以看到的一样,JET 的缺省语法与 JSP 相同:使用 <%...%> 包括代 码,使用 <%= ... %> 打印表达式的值。与 JSP 类似,正确地使用 <% ... % > 标签就可以添加任何逻辑循环或结构,就像是在任何 Java 方法中一样。例如:

清单 3. 脚本和表达式

Welcome <%= user.getName() %>!
<% if ( user.getDaysSinceLastVisit() > 5 ) { %>
Whew, thanks for coming back. We thought we"d lost you!
<% } else { %>
Back so soon? Don"t you have anything better to do?
<% } %>