4

我正在尝试执行以下操作:

编写一个接收 Class 类型的对象作为参数的 JET 模板。该对象应该代表一个 Java 接口。模板生成一个实现接口的类,即为它定义的所有方法签名提供方法。生成的类的名称应该是 XImplementation,其中 X 是参数接口的名称。生成的类中的方法什么都不做或只返回常量值:0 表示 int 和 double,false 表示布尔值,null 表示引用类型。您不需要考虑任何其他返回类型。例如,对于以下接口 A,将生成类 AImplementation:

interface A {  
    void m1(int x, int y);  
    int m2(Object a);  
    Object m3();  
}  

class AImplementation implements A {  
    public void m1(int p1, int p2) { }  
    public int m2(Object p1) { return 0; }  
    public Object m3() { return null; }  
}  

提示:可以通过在对应的 Class 对象上使用 getSimpleName() 方法来获取类型的非限定(简单)名称。

我已阅读在 eclipse.org 上找到的有关 JET 的教程,但我仍然无法理解我需要做什么。

当我制作要翻译的 .txtjet 文件时,我是否试图让 .txtjet 文件的实现用我想在generate方法中生成的代码写入一个巨大的字符串?这是正确的概念吗?

如果是这种情况,我在某​​个特定方面遇到了麻烦。这是我到目前为止提出的 JET 模板:

<%@ jet imports="java.lang.reflect.*" class="Q2Generator" %>
<%Object o = (Object) argument;%>
<%Class c = o.getClass();%>

public class <%=c.getName()%>Implementation implements <%=c.getName()%> {
<%for (Method m : c.getDeclaredMethods()) {%>
<%  Class type = m.getReturnType();%>
<%  if (!type.isPrimitive()) {%>
public <%=type.getSimpleName()%> <%=m.getName()%> { return null; } // this line is the problem
<%  }%>
<%}%>       
}

此模板在generate方法中产生以下代码:

  public final String NL = nl == null ? (System.getProperties().getProperty("line.separator")) : nl;
  protected final String TEXT_1 = NL + "public class ";
  protected final String TEXT_2 = "Implementation implements ";
  protected final String TEXT_3 = " {";
  protected final String TEXT_4 = NL + "public ";
  protected final String TEXT_5 = " ";
  protected final String TEXT_6 = " { return null; }";
  protected final String TEXT_7 = NL + "\t\t" + NL + "}";
  protected final String TEXT_8 = NL;

  public String generate(Object argument)
  {
    final StringBuffer stringBuffer = new StringBuffer();
    Object o = (Object) argument;
    Class c = o.getClass();
    stringBuffer.append(TEXT_1);
    stringBuffer.append(c.getName());
    stringBuffer.append(TEXT_2);
    stringBuffer.append(c.getName());
    stringBuffer.append(TEXT_3);
    for (Method m : c.getDeclaredMethods()) {
        Class type = m.getReturnType();
        if (!type.isPrimitive()) {
    stringBuffer.append(TEXT_4);
    stringBuffer.append(type.getSimpleName());
    stringBuffer.append(TEXT_5);
    stringBuffer.append(m.getName());
    stringBuffer.append(TEXT_6);
        }
    }
    stringBuffer.append(TEXT_7);
    stringBuffer.append(TEXT_8);
    return stringBuffer.toString();
  }

有没有办法缩进stringBuffer.append()if 语句中的行?字符串方式是完成这项任务的正确方式吗?

谢谢。

4

1 回答 1

0

我会使用较新的 JET2 语法。您应该能够使用 New -> Other 创建一个新的 JET 转换。

至于高层发生的事情,您将拥有一个名为 main.jet 的模板,它将充当控制器。它本身不会创建任何文本内容,但会管理项目、文件夹和文件的生成。

我了解您希望使用类对象作为输入,但我建议您构建模板以使用 XML 文件作为输入。像这样的东西:

<root>
    <object name="A">
        <method name="m1" returns="void">
            <arg name="x" type="int" />
            <arg name="y" type="int" />
        </method>
        <method name="m2" returns="int">
            <arg name="a" type="Object" />
        </method>
        <method name="m3" returns="Object">
        </method>
    </object>
</root>

您可以看到,给定一个类,我们可以“轻松”创建这样的 XML 文档。

所以 main.jet 看起来像这样:

<%@taglib prefix="ws" id="org.eclipse.jet.workspaceTags" %>

<c:iterate select="/root/object" var="object"

    <c:set select="$object" name="impl" ><c:get select="$object/@name"/>Implementation</c:set>
    <c:set select="$object" name="interface" ><c:get select="$object/@name"/></c:set>

</c:iterate>


<c:iterate select="/root/object" var="object">

    <ws:file path="my project/src/a/b/c/{$object/@interface}.java" template="interface.jet" />
    <ws:file path="my project/src/a/b/c/{$object/@impl}.java" template="impl.jet" />

</c:iterate>

基本上,您正在迭代每个对象(您可以定义任意数量的对象),并且您正在构建实现​​和接口名称并将这些名称存储回模型中。
完成所有命名约定后,您可以遍历对象元素并使用 ws:file 标记将模板应用于模型。标签告诉使用哪个模板,然后指定要使用生成结果创建的文件名。

interface.jet 文件可能如下所示:

package a.b.c;

interface <c:get select="$object/@interface"/> { 
<c:iterate select="$object/method" var="method" > 
    <c:get select="$method/@returns"/> <c:get select="$method/@name"/>(int x, int y);  
</c:iterate>
}  

请注意,我已将包硬编码为 abc 您可以通过将属性添加到 XML 文件(可能是对象元素)并使用 c:get 标记将其插入源中来创建该变量。我还保留了 args 硬编码,但您可以使用另一个迭代标记来迭代模型中的嵌套元素以写出方法签名。

所以我会停下来看看这是否是你要找的。您可能想在评论中提出更多问题或发布更多问题。

于 2012-10-09T21:00:45.367 回答