代码自动生成技术学习之一JET

JET(Java Emitter Templates)一种语法和思想都和jsp非常相似的代码生成模板技术。他是EMF代码生成中使用的技术。模板技术的思想都是描述某个东东的大体样子,然后加上一些参数和条件控制语句来生成目标的的东东。JET在.jetXx文件中定义要生成代码的结构,然后编译生成java文件,使用生成java代码来输出目标的代码。(其中Xx代表要生成代码的文件类型,例如像生成java代码则后缀名为.jetjava)这个过程和jsp非常相似,jsp相当于.jetXxx,而jsp编译成的servlet则和.jetXxx模板编译生成的java文件一样。.jet和jsp类似也有隐含变量:argument, stringBuffer,它代表输入参数。
下面看一个例子来说明这个过程:
我们定义能够生成一个像别人问好,而这个人可以参数话来定制:
首先创建一个java工程,然后New > Other... > Java Emitter Templates > Convert Projects to JET Projects,就转化成jet project了,然后生成了template文件夹,在里面来写模板(.jetXx)和骨架(.skeleton)。

<%@ jet package="hello" class="GreetingTemplate" %>
Hello, <%=argument%>!

当我们保存完整个模板的时候,我们发现在hello包中,自动translate成一个GreetingTemplate类:

package hello;

public class TranslationDemoTemplate
{
protected final String NL = System.getProperties().getProperty("line.separator");
protected final String TEXT_1 = "Hello, ";
protected final String TEXT_2 = "!";

public String generate(Object argument)
{
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(TEXT_1);
stringBuffer.append(argument);
stringBuffer.append(TEXT_2);
return stringBuffer.toString();
}
}

我们发现这个思想和实现方法完全jsp相同,jsp是生成一大堆的out.println
我们在模版中加上一句:
<%@ jet package="hello" class="TranslationDemoTemplate" %>

Hello, <%=argument%>!
<% stringBuffer.append("Hello again!"); %>
结果翻译成jav类的代码在
<b>stringBuffer.append(TEXT_2);</b>
后面多了一个
<b>stringBuffer.append("Hello again!");</b>

然而这个翻译的过程可以被定制,默认的翻译过程使用了骨架:

public class CLASS
{
public String generate(Object argument)
{
return "";
}
}

我们可以通过这个骨架来定制生成的代码,如:我们希望生成的代码继承接口

public interface IGenerator {
String generate(Object argument);
}

那么只需要改变一下这个骨架:
在template文件夹中建一个generator.skeleton文件,代码如下:
 
public class CLASS implements IGenerator
{
/* (non-javadoc)
* @see IGenerator#generate(Object)
*/
public String generate(Object argument)
{
return "";
}
}

然后再模板中指定这个skeleton="generator.skeleton"

<%@ jet package="hello" class="GreetingTemplate" skeleton="generator.skeleton" %>
Hello, <%=argument%>!
The current time is <%=new java.util.Date()%>.

然后生成的代码如下:

package hello;

public class GreetingTemplate implements IGenerator
{
protected final String NL = System.getProperties().getProperty("line.separator");
protected final String TEXT_1 = "Hello, ";
protected final String TEXT_2 = "!" + NL + "The current time is ";
protected final String TEXT_3 = ".";
protected final String TEXT_4 = NL;


/* (non-javadoc)
* @see IGenerator#generate(Object)
*/
public String generate(Object argument)
{
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(TEXT_1);
stringBuffer.append(argument);
stringBuffer.append(TEXT_2);
stringBuffer.append(new java.util.Date());
stringBuffer.append(TEXT_3);
stringBuffer.append(TEXT_4);
return stringBuffer.toString();
}
}

jet可以同时用startTag和endTag来指明模板使用scriptlet, expression, or include directive开始和结束,这个对于生成jsp代码很有用:

<%@ jet package="tags.demo" class="JspTemplate" startTag="<$" endTag="$>" %>

<$ String paramName = (String) argument; /* This is an executed scriptlet */ $>
<$ if (paramName != null) { $>
<%= request.getParameter("<$=paramName$>") %> <!-- this is generated JSP -->

<$ } $>

生成的代码为:

<%= request.getParameter("button") %> <!-- this is generated JSP -->

jet可以向jsp一样使用<%@ include file="copyright.inc" %>来导入一段公用的模板。
jet可以使用条件控制scriptlet和内置的标签和jsp一样的<c:if><c:get>等

<% if (Calendar.getInstance().get(Calendar.AM_PM) == Calendar.AM) {%>
Good Morning
<% } else { %>
Good Afternoon
<% } %>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值