2012-08-10 303 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