2011-10-14 56 views
4

我試圖做到以下幾點:使用JET來生成代碼:代碼縮進

寫接收Class類型的對象作爲參數 一個JET模板。該對象應該表示一個Java接口。模板 生成實現該接口的類,即爲其定義的所有方法簽名提供方法 。生成的 類的名稱應爲XImplementation,其中X是參數 接口的名稱。生成的類中的方法什麼也不做,或者只有 返回常量值:0表示int和double,boolean表示false, 爲參考類型。您不需要考慮任何其他返回 類型。例如。對於下面的接口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; } 
} 

提示:一個類型 的不合格(簡單)名稱可以通過使用相應的 類對象上的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語句?而String方式是完成這項任務的正確方法嗎?

謝謝。

+0

如果這是家庭作業,它應該被標記爲這樣。 –

+0

@ferrarifan對不起。忘了這麼做。 – Jigglypuff

回答

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文檔。

所以主要。噴氣機將是這個樣子:

<%@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> 
} 

請注意,我硬編碼的包要A.B.C.您可以通過向XML文件添加屬性來創建該變量,可能是添加到對象元素,並使用c:get標記將其插入到源文件中。我也將參數保留爲硬編碼,但您可以使用另一個迭代標記遍歷模型中的嵌套元素以寫出方法簽名。

所以我會在那裏停下來看看這是你在找什麼。您可能想要在評論中提出更多問題或發佈更多問題。