2012-08-10 109 views
4

我正在研究一個項目,該項目將具有多個彼此非常類似的Java類,並且我希望從XML文件生成這些類。我希望能夠做的是改變Eclipse構建過程中做這樣的事情:在Eclipse中從XML生成Java代碼

  • 編譯代碼生成器
  • 運行代碼生成器,將XML轉換成Java
  • 編譯休息的項目

我可以手動完成這一切,但我更希望能夠讓Eclipse爲我做這一切。

我希望能夠把看起來像這樣的一個源XML文件:

<command-list> 
    <command name="DATE" /> 
    <command name="GROUP"> 
     <capability "READER" /> 
     <argument "groupname" /> 
    </command> 
    <command name="ARTICLE"> 
     <capability "READER" /> 
     <argument "message-id" optional="true" /> 
    </command> 
</command-list> 

,並把它給了我類似下面的內容(在單獨的文件作爲適當的):

public class Date extends Command { 
    public ResponseCode execute() { 
     Server srv = getServer(); 
     srv.send("DATE"); 
     return srv.getResponse(); 
    } 
} 

public class Group extends Command { 
    public ResponseCode execute() { 
     Server srv = getServer(); 
     if (srv.hasCapability(Capabilities.READER) == false) { 
      Log.debug("Attempting non-available capability: READER"); 
     } 
     String groupname = getArgument("groupname"); 
     if (groupname == null) { 
      throw new InvalidArgumentException("Require groupname"); 
     } 
     String command = "GROUP"; 
     if (groupname != null) command += " " + groupname; 
     srv.send(command); 
     return srv.getResponse(); 
    } 
} 

public class Article extends Command { 
    public ResponseCode execute() { 
     Server srv = getServer(); 
     if (srv.hasCapability(Capabilities.READER) == false) { 
      Log.debug("Attempting non-available capability: READER"); 
     } 
     String messageId = getArgument("messageId"); 
     String command = "ARTICLE"; 
     if (messageId != null) command += " " + messageId; 
     srv.send(command); 
     return srv.getResponse(); 
    } 
} 
+1

你爲什麼不只是編寫一個批處理文件/ shell腳本來完成這一切的嗎?一行兩個參數 - >完成!我這樣問是因爲我個人不知道你會如何(如果可能的話)在eclipse中做這件事,而且看起來你在這裏很容易使用。 – thatidiotguy 2012-08-10 15:32:33

+0

我希望它成爲構建過程的一部分,以便如果我更改我的模板或XML,它將重新生成 – 2012-08-10 18:18:26

+0

@thatidiotguy您可以將ant腳本作爲項目屬性的一部分集成到構建過程中,它位於「構建器」下。我不知道是否有批處理/ shell腳本支持,但我也沒有看過。 – 2012-08-15 17:07:12

回答

3

這正是模型到文本(M2T)項目中的JET組件所做的。實際上,您甚至可以使用JET創建項目,.classpath和任何其他需要的文件。

Jet模板如下。請注意,這些模板必須完全按照所示進行命名。

/templates/main.jet

<%@taglib prefix="ws" id="org.eclipse.jet.workspaceTags" %> 
<%-- Main entry point for com.lacqui.command.xform --%> 

<%-- 
    Let c:iterate tags set the XPath context object. 
    For 100% compatibility with JET 0.9.x or earlier, remove this statement 
--%> 
<c:setVariable var="org.eclipse.jet.taglib.control.iterateSetsContext" select="true()"/> 

    <c:setVariable select="/command-list" var="command-list" /> 

    --- traverse input model, performing calculations and storing 
    --- the results as model annotations via c:set tag 

    <c:set select="$command-list" name="project">com.lacqui.commands</c:set> 
    <c:set select="$command-list" name="commandPkg">com.lacqui.commands</c:set> 
    <c:set select="$command-list" name="commandDir"><c:get select="translate($command-list/@commandPkg,'.','/')" /></c:set> 

    <c:iterate select="$command-list/command" var="command" > 

      - Derive the class name from the name of the command 

     <c:set select="$command" name="classname"><c:get select="camelCase($command/@name)" />Command</c:set> 

     <c:iterate select="$command/argument" var="argument"> 

      <c:if test="not($argument/@optional)"> 
       <c:set select="$argument" name="optional">false</c:set> 
      </c:if> 

     </c:iterate> 

    </c:iterate> 

    --- traverse annotated model, performing text generation actions 
    --- such as ws:file, ws:folder and ws:project 

    <ws:project name="{$command-list/@project}" /> 
    <ws:file template="templates/project.jet" path="{$command-list/@project}/.project" /> 
    <ws:file template="templates/classpath.jet" path="{$command-list/@project}/.classpath"/> 

    <c:iterate select="$command-list/command" var="command" > 

     <ws:file template="templates/class.jet" path="{$command-list/@project}/src/{$command-list/@commandDir}/{$command/@classname}.java" replace="true"/> 

    </c:iterate> 

/templates/classpath.jet

<?xml version="1.0" encoding="UTF-8"?> 
<classpath> 
    <classpathentry kind="src" path="src"/> 
    <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> 
    <classpathentry kind="output" path="bin"/> 
</classpath> 

/templates/project.jet

<?xml version="1.0" encoding="UTF-8"?> 
<projectDescription> 
    <name><c:get select="$command-list/@project" /></name> 
    <comment></comment> 
    <projects> 
    </projects> 
    <buildSpec> 
     <buildCommand> 
      <name>org.eclipse.jdt.core.javabuilder</name> 
      <arguments> 
      </arguments> 
     </buildCommand> 
    </buildSpec> 
    <natures> 
     <nature>org.eclipse.jdt.core.javanature</nature> 
    </natures> 
</projectDescription> 

/templates/class.jet

package <c:get select="$command-list/@commandPkg" />; 

public class <c:get select="$command/@classname" /> extends Command { 
    public ResponseCode execute() { 
     Server srv = getServer(); 
<c:iterate select="$command/capability" var="capability"> 

     if (srv.hasCapability(Capabilities.<c:get select="$capability/@name"/>) == false) { 
      Log.debug("Attempting non-available capability: <c:get select="$capability/@name"/>"); 
     } 
</c:iterate>   
<c:iterate select="$command/argument" var="argument"> 

     String <c:get select="$argument/@name"/> = getArgument("<c:get select="$argument/@name"/>"); 
<c:if test="$argument/@optional = 'false'" > 
     if (<c:get select="$argument/@name"/> == null) { 
      throw new InvalidArgumentException("Require <c:get select="$argument/@name"/>"); 
     } 
</c:if> 
</c:iterate>   

     String command = "GROUP"; 
<c:iterate select="$command/argument" var="argument"> 
     if (<c:get select="$argument/@name"/> != null) command += " -<c:get select="$argument/@name"/> " + <c:get select="$argument/@name"/>; 
</c:iterate>  

     srv.send(command); 
     return srv.getResponse(); 
    } 
} 

,並利用該模型:

<command-list> 
    <command name="DATE" /> 
    <command name="GROUP"> 
     <capability name="LOGGER" /> 
     <capability name="AUTHENTICATOR" /> 
     <argument name="groupname" /> 
    </command> 
    <command name="ARTICLE"> 
     <capability name="READER" /> 
     <argument name="article-id" optional="false" /> 
     <argument name="message-id" optional="true" /> 
    </command> 
</command-list> 

給人命名包含三個Java文件com.lacqui.commands一個完整的Java項目:

package com.lacqui.commands; 

public class ArticleCommand extends Command { 
    public ResponseCode execute() { 
     Server srv = getServer(); 

     if (srv.hasCapability(Capabilities.READER) == false) { 
      Log.debug("Attempting non-available capability: READER"); 
     } 

     String article-id = getArgument("article-id"); 
     if (article-id == null) { 
      throw new InvalidArgumentException("Require article-id"); 
     } 

     String message-id = getArgument("message-id"); 

     String command = "GROUP"; 
     if (article-id != null) command += " -article-id " + article-id; 
     if (message-id != null) command += " -message-id " + message-id; 

     srv.send(command); 
     return srv.getResponse(); 
    } 
} 

這:

package com.lacqui.commands; 

public class GroupCommand extends Command { 
    public ResponseCode execute() { 
     Server srv = getServer(); 

     if (srv.hasCapability(Capabilities.LOGGER) == false) { 
      Log.debug("Attempting non-available capability: LOGGER"); 
     } 

     if (srv.hasCapability(Capabilities.AUTHENTICATOR) == false) { 
      Log.debug("Attempting non-available capability: AUTHENTICATOR"); 
     } 

     String groupname = getArgument("groupname"); 
     if (groupname == null) { 
      throw new InvalidArgumentException("Require groupname"); 
     } 

     String command = "GROUP"; 
     if (groupname != null) command += " -groupname " + groupname; 

     srv.send(command); 
     return srv.getResponse(); 
    } 
} 
+0

我不想將XML用作運行時數據格式 - 我正在使用它來簡化我的源文件生成。 – 2012-08-14 13:02:38

+0

JET是一個開發時工具,可以在Eclipse項目中生成代碼,JSP,HTML,屬性文件,Eclipse「點資源」等(可能在創建和配置這些項目之後)。該資源生成是由模型驅動的,通常是XML,但可以是任何格式,並且該模型在運行時完全不使用。所以JET對你來說確實是一個很好的方法。 在您的問題中發佈示例類,我可以發佈您可能用於生成該類的模板。 – 2012-08-14 15:38:00

+0

我在我的問題中有幾個例子。 – 2012-08-14 22:55:10

-1

您要使用的是您的項目屬性中的「Builders」選項。在這裏,您可以設置您的項目,在編譯其餘項目之前,使用'ant'腳本編譯和執行代碼生成器(其他類型的構建器也可用)。

我認爲這些文章更好的解釋:

http://www.eclipsezone.com/eclipse/forums/t65486.html

http://help.eclipse.org/juno/index.jsp?topic=%2Forg.eclipse.platform.doc.user%2FgettingStarted%2Fqs-93_project_builder.htm

+0

我可以得到downvote的原因嗎? – 2012-08-17 12:54:02