4

私は次のことをしようとしています:

クラス型のオブジェクトを引数として受け取るJETテンプレートを記述します。オブジェクトはJavaインターフェースを表す必要があります。テンプレートは、インターフェイスを実装するクラスを生成します。つまり、テンプレートが定義するすべてのメソッドシグネチャのメソッドを提供します。生成されるクラスの名前はXImplementationである必要があります。ここで、Xは引数インターフェイスの名前です。生成されたクラスのメソッドは、何もしないか、定数値のみを返します。intとdoubleの場合は0、ブール値の場合は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か?それは正しい概念ですか?

その場合、私は1つの特定の側面で問題を抱えています。これは私がこれまでに思いついた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もハードコーディングしたままにしましたが、別のiterateタグを使用して、モデル内のネストされた要素を反復処理し、メソッドのシグネチャを書き出すことができます。

だから私はここで立ち止まって、これがあなたが探していたものであるかどうかを確認します。コメントでもっと質問したり、質問を投稿したりすることもできます。

于 2012-10-09T21:00:45.367 に答える