专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »编程综合 » eclipse源代码:使用 JET 在 Eclipse 中创建更多更好的代码 »正文

eclipse源代码:使用 JET 在 Eclipse 中创建更多更好的代码

来源: 发布时间:星期二, 2009年2月10日 浏览:2次 评论:0
  代码生成不是个新概念它出现有段时间了而且作为提高生产力种方式随着模型驱动开发(MDD)发展而普及开来Eclipse 项目有个称为 JET 技术项目就是个专门代码生成器JET 所能生成不仅仅是 “代码”无论如何在本文中我们称这些非编码物件为工件(artiact)

  开始

  在本节中我们将介绍 JET 项目设置基础讨论 JET 项目结构然后运行个快速转换

  创建个 JET 项目

  在实际接触 JET 的前我们需要创建个项目使用创建项目标准 Eclipse 思路方法来实现就 JET 来说使用命令 File > New > Other > EMFT JET Transformations > EMFT JET Transformation Project(请参见图 1)创建个 EMFT JET Transformation Project

  图 1. JET 项目向导



  JET 项目结构

  让我们分析项目结构来搞清楚 JET 是如何工作在上面部分我们创建了个 JET 项目(参见图 2)在该 JET 项目中我们需要浏览 6个文件

  图 2. JET 项目结构



  Eclipse 项目文件(MANIFEST.MF, plugin.xml, build.properties) 这是使用 Eclipse 项目时所创建标准文件对于这些文件需要注意件重要事情是:在 plugin.xml 中JET 将自动添加 org.eclipse.jet.transform通过扩展该扩展点我们让 JET 知道我们在提供个 JET 转换控制和模板文件(dump.jet, .jet) 这是在转换中所使用模板和控制文件将在下面概念部分讨论其细节输入模型(sample.xml) 这里我们可以看到用于转换个举例输入文件注意该输入可以来自任何源并不限于项目  运行 JET 转换

  旦有了个项目拥有合适模板、控制文件和个输入模型我们就可以运行转换通过熟悉 Eclipse 概念 —— 启动配置(参见图 3)JET 提供了个方便方式来转换要访问 JET 启动配置我们转到 Run > JET Transformation填充合适选项然后单击 Run

  图 3. JET 启动配置



  概念

  JET 是指定模板输出工件语言实现些应用模板集合被称为蓝图(bluepr)(用我们术语)JET 范例可以用下列等式表示:

  参数 + 蓝图 = 所需工件

  蓝图是由 JET 创建而参数是由蓝图用户提供蓝图由 3个区别文件集组成:

  1. 参数 用于蓝图参数使用 XML 格式这赋予它强大表现力 XML 允许使用层次化关系、允许每个节点具有属性输入参数被称为输入模型蓝图将定义描述其期望参数模式例如下面是蓝图创建网络嗅探器输入例子:

  清单 1. 网络嗅探器蓝图输入

<app project="NetworkSnfer" >
  <snfer name="sampler" sample_probability=".7" >
    <logFile name="packet_types" />
    <packet type="TCP" subType="SYN" >
      <logToFile name="packet_types" />
      <findResponse type="TCP" subType="ACK" timeout="1" />
    </packet>
    <packet type="UDP" >
      <logToFile name="packet_types" />
    </packet>
  </snfer>
</app>


  蓝图将转换这些输入参数为实现该网络嗅探器代码蓝图参数可视为自定义编程语言而蓝图扮演 “编译器” 角色将输入转换为本机工件2. 控制文件 这些文件控制代码生成执行控制标记中最重要标记是 <ws:file>它将执行个模板并将结果转储至指定文件代码生成执行从 .jet 开始这和 类似3. 模板文件 模板文件指定如何以及何种情况下生成文本该文本可以是代码、配置文件或其他  XPath

  既然任何 JET 蓝图输入都是个 XML 模型XPath 语言被用来引用节点和属性此外在表达式里 XPath 有自己参数使用方式这在 JET 里使用得非常多要点如下:

  路径表达式 和文件系统路径相似路径是由斜杠分开系列步(/)

  从左向右估算步如果这样做通常会下行模型树

  每步通过其名字定义树节点(尽管存在其他可能性)

  在步结尾步可以在方括号([ 和 ])中编写可选过滤器条件

  斜杠(/)指示表达式开始于模型树

  路径表达式还可以以变量开始变量是以美元符号($)开头名字

  有关 JET 中 XPath 应记住以下几个要点:

  变量是由几个 JET 标记定义 - 注意 var 属性它们可能也是由 c:Variable 标签定义

  需要路径表达式 JET 标签有个 select 属性

  任何标签属性都可能包含个动态 XPath 表达式是由括号({ 和 })所包含 XPath 表达式

  JET 标签

  下例将使用下列输入模型

  清单 2. 输入模型

<app middle="Hello" >
  <person name="Chris" gender="Male" />
  <person name="Nick" gender="Male" />
  <person name="Lee" gender="Male" />
  <person name="Yasmary" gender="Female" />
</app>


  ws:file 该标签属于蓝图 control 部分个模板例如:

<ws:file template="templates/house.java.jet"
path="{$org.eclipse.jet.resource.project.name}/house1.java">


  将在输入模型上运行 house.java.jet 模板并将结果转储在 $(Project Root)/house1.java 中{$org.eclipse.jet.resource.project.name} 是个动态 XPath 表达式用 org.eclipse.jet.resource.project.name 变量值替换部分该变量是由 JET 引擎定义c:get 该标签将输出 XPath 表达式结果例如Pre<c:get select="/app/@middle" />Post 将输出 PreHelloPost注意 select 参数将使用 XPath 表达式要在期望静态参数中使用 XPath 表达式可以通过将表达式封装在括号({ 和 })中来动态 XPath 表达式c:iterate   该标签将遍历具有特定名称节点为每个节点执行 iterate 主体例如:

<c:iterate select="/app/person" var="currNode" delimiter="," >
Name = <c:get select="$currNode/@name" />
</c:iterate>


  将输出 Name = Chris, Name = Nick, Name = Lee, Name = Yasmary

  iterate 标签通常也用于控制模板其实标记例如如果要为模型中每个人创建 Java™ 类可使用如下代码:

<c:iterate select="/app/person" var="currPerson">
<ws:file template="templates/PersonClass.java.jet"
path="{$org.eclipse.jet.resource.project.name}/{$currPerson/@name}.java"/>
</c:iterate>


  这将创建 4个 Java 类文件:Chris.java、Nick.java、Lee.java 和 Yasmary.java注意启动标记 path 属性中 {$currPerson/@name} 既然 path 参数不需要 XPath 表达式(像 select 参数样){...} 告知 JET 引擎通过计算 XPath 表达式代替这部分$currPerson/@name 告诉引擎用 currPerson 节点(是定义在 iterate 标签中变量) name 属性来代替其

  此外在 PersonClass.java.jet 模板中它可以引用定义在 iterate 标签中 currPerson 节点变量例如假设 PersonClass.java.jet 如下所示:

  清单 3. PersonClass.java.jet

<c:get select="$currPerson/@name" />Person {
  public String getName {
     "<c:get select="$currPerson/@name" />";
  }
  public void shout {
    .out.prln("Hello!!!");
  }
}


  Yasmary.java 形式将如下:

  清单 4. Yasmary.java

YasmaryPerson {
  public String getName {
     "Yasmary";
  }
  public void shout {
    .out.prln("Hello!!!");
  }
}


  Lee.java 形式如下:

  清单 5. Lee.java

LeePerson {
  public String getName {
     "Lee";
  }
  public void shout {
    .out.prln("Hello!!!");
  }
}


  c:choose 和 c:when 这些标签允许模板根据值有条件地转储文本例如下列代码:

  清单 6. c:choose/c:when 举例

<c:iterate select="/app/person" var="p" >
  <c:choose select="$p/@gender" >
    <c:when test="'Male'" > Brother </c:when>
    <c:when test="'Female'" > Sister </c:when>
  </c:choose>
</c:iterate>


  将输出:

  Brother

  Brother

  Brother

  Sister

  注意 c:when 标签需要 test 参数这需要个 XPath 表达式既然我们要通过个常量比较 select 参数可用单引号 ('') 包含常量

  c: 该标签允许模板动态更改输入模型属性个例子是:在串以多个方式映射输出文本时像 Chris 可能映射到 Chris、chris、ChrisClass、CHRIS_CONSTANT 等c: 将其内容设置为指定属性下面例子为每个人存储名为 Name 属性并在名字的后简单添加词 Class

  清单 7. c: 例子

<c:iterate select="/app/person" var="p" >
  <c: select="$p" name="Name" >
  <c:get select="$p/@name" />Class</c:>
</c:iterate>


  Variable 该标签允许模板声明和使用个全局变量使用 XPath 全部能力来在任何时候操纵该变量例如假设要输出在输入模型中提供了多少个 person 节点可以利用以下代码:

  清单 8. c:Variable 举例

<c:Variable select="0" var="i" />
  <c:iterate select="/app/person" var="p" >
    <c:Variable select="$i+1" var="i" />
  </c:iterate>
Number of people = <c:get select="$i" />.


  输出 Number of people = 4

  可以使用 get 输出变量如上例所示

  有超过 45 个标签这使输出文本具有强大表现力表现力大多源于存在条件逻辑、动态更改输入模型和控制执行流标签

  扩展 JET

  JET 是可扩展通过使用 Eclipse 扩展点机制以下是 JET 提供 6个扩展点

  org.eclipse.jet.tagLibraries 该扩展点负责定义标记库JET 已经包含 4个标记库(控制、格式、工作空间、Java)如果您要添加自己标签功能可从这里入手 org.eclipse.jet.xpathFunctions 这允许在 JET XPath 执行时启用自定义 XPath 表达式个 JET 中这样例子是:通过扩展该扩展点在 XPath 表达式中使用 camel(参见 JET 源代码中 CamelCaseFunction) org.eclipse.jet.transform 用于声明您插件在提供 JET 转换这是更改您使用什么来启动模板(取代 .jet)位置 org.eclipse.jet.modelInspectors 这允许您定义检查器使得 JET XPath 引擎来将加载 Java 对象解释为 XPath 节点检查器是将对象适配为 XPath 信息模型作为例子JET 使用个模型来浏览 Eclipse 工作空间注意这是临时 API并可能随时间而发生变化org.eclipse.jet.modelLoaders 这允许您定义 JET 转换和从文件系统加载 JET <c:load> 标签以怎样方式使用模型作为举例JET 提供模型加载器 loader org.eclipse.jet.resource将加载 Eclipse IResource(文件文件夹或项目)并允许通过该资源导航 Eclipse 工作空间org.eclipse.jet.deployTransforms 这允许您来将个 JET 转换打包为个用于简单发行插件(包)这可以被 UI 用来查看哪些转换可用  例子:编写代码来生成代码

  下列例子是个模板用于创建拥有任意数量属性每个属性将有 getter 和 ter 和的关联还有此外名称将输出到命令行通过这种方式模板即可为各添加简单日志

  清单 9. 属性模板

<c:get select="/app/@" /> {
<c:iterate select="/app/property" var="p" >
  private <c:get select="$p/@type" /> <c:get select="$p/@name" />;
</c:iterate>
  public <c:get select="/app/@" /> {
  <c:iterate select="/app/property" var="p" >
    this.<c:get select="$p/@name" /> = <c:choose select="$p/@type" >
    <c:when test="'String'">"<c:get select="$p/@initial" />"</c:when>
    <c:otherwise><c:get select="$p/@initial" /></c:otherwise>
    </c:choose>
;
  </c:iterate>
  }
<c:iterate select="/app/property" var="p" >
  public void <c:get select=
  "camelCase($p/@name)" />(<c:get select="$p/@type" />
  <c:get select="$p/@name" />) {
    .out.prln
    ("In <c:get select=
    "camelCase($p/@name)" />");
    this.<c:get select="$p/@name" /> = <c:get select="$p/@name" />;
  }
  
  public <c:get select=
  "$p/@type" /> get<c:get select="camelCase($p/@name)" /> {
    .out.prln("In get<c:get select="camelCase($p/@name)" />");
     <c:get select="$p/@name" />;
  }
  
</c:iterate>
}


  这里是该模板输入模型例子:

  清单 10. 输入参数

<app ="Car">
  <property name="model" type="String" initial="Honda Accord" />
  <property name="horsepower" type="" initial="140" />
  <property name="spareTires" type="boolean" initial="true" />
</app>


  这些输入参数生成如下类:

  清单 11. 生成

Car {
  private String model;
  private horsepower;
  private boolean spareTires;
  public Car {
    this.model = "Honda Accord";
    this.horsepower = 140;
    this.spareTires = true;
  }
  public void Model(String model) {
    .out.prln("In Model");
    this.model = model;
  }
  
  public String getModel {
    .out.prln("In getModel");
     model;
  }
  
  public void Horsepower( horsepower) {
    .out.prln("In Horsepower");
    this.horsepower = horsepower;
  }
  
  public getHorsepower {
    .out.prln("In getHorsepower");
     horsepower;
  }
  
  public void Sparetires(boolean spareTires) {
    .out.prln("In Sparetires");
    this.spareTires = spareTires;
  }
  
  public boolean getSparetires {
    .out.prln("In getSparetires");
     spareTires;
  }
  
}


  例子:编写处理代码

  为强调 JET 不仅仅可用来生成代码我们给出了下面这个例子这是个模板生成具有区别语气电子邮件消息所生成各电子邮件是是向某人索要求各种东西下面提供控制文件(.jet)及其模板(email.jet)

  清单 12. .jet

<c:iterate select="/app/email" var="currEmail" >
  <ws:file template="templates/email.jet"
  path="{$org.eclipse.jet.resource.project.name}/{$currEmail/@to}.txt" />
</c:iterate>


  清单 13. email.jet

<c:Variable var="numItems" select="0" />
<c:iterate select="$currEmail/request" var="r">
  <c:Variable var="numItems" select="$numItems+1" />
</c:iterate>
<c: select="$currEmail" name="numItems"><c:get select="$numItems" /></c:>
  <c:choose select="$currEmail/@mood" >
  <c:when test="'happy'">My dear</c:when>
  <c:when test="'neutral'">Dear</c:when>
  <c:when test="'angry'">My enemy</c:when>
</c:choose> <c:get select="$currEmail/@to" />,
I am writing you <c:choose select="$currEmail/@mood" >
<c:when test="'happy'">in joy </c:when>
<c:when test="'neutral'"></c:when>
<c:when test="'angry'">in burning anger </c:when>
</c:choose>to ask for <c:choose select="$currEmail/@numItems" >
<c:when test="1">
a <c:get select="$currEmail/request/@item" />.
</c:when>
<c:otherwise>
the following:
<c:Variable var="i" select="0" />
<c:iterate select="$currEmail/request" var="r">
  <c:Variable var="i" select="$i+1" />
  <c:get select="$i" />. <c:get select="$r/@item" />
</c:iterate>
</c:otherwise>
</c:choose>
<c:choose select="$currEmail/@mood">
  <c:when test="'happy'">Please</c:when>
  <c:when test="'neutral'">Please</c:when>
  <c:when test="'angry'">Either suffer my wrath, or</c:when>
</c:choose> send me <c:choose select="$currEmail/@numItems">
<c:when test="1">
this item</c:when>
<c:otherwise>
these items</c:otherwise>
</c:choose> <c:choose select="$currEmail/@mood" >
<c:when test="'happy'">at your earliest convenience.</c:when>
<c:when test="'neutral'">promptly.</c:when>
<c:when test="'angry'">immediately!</c:when>
</c:choose>
<c:choose select="$currEmail/@mood" >
<c:when test="'happy'">Your friend,</c:when>
<c:when test="'neutral'">Sincerely,</c:when>
<c:when test="'angry'">In rage,</c:when>
</c:choose>
<c:get select="/app/@from" />




  该模板输入模型例子如下:

  清单 14. sample.xml

<app from="Nathan" >
  <email to="Chris" mood="angry" >
    <request item="well-written article" />
  </email>
  <email to="Nick" mood="happy" >
    <request item="Piano" />
    <request item="Lollipop" />
    <request item="Blank DVDs" />
  </email>
</app>


  将 mood 电子邮件蓝图应用于这些参数生成下列两个文件

  清单 15. Chris.txt

My enemy Chris,
I am writing you in burning anger to ask for a well-written article.
Either suffer my wrath, or send me this item immediately!
In rage,
Nathan


  清单 16. Nick.txt

My dear Nick,
I am writing you in joy to ask for the following:
1. Piano
2. Lollipop
3. Blank DVDs
Please send me these items at your earliest convenience.
Your friend,
Nathan


  结束语

  在结束的前我们希望感谢 Paul Elder 提供了宝贵意见整体上来说JET 用途不仅限于简化代码生成JET 是个新 Eclipse 技术项目我们期待有更多开发人员在工作中使用它



0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: