在Eclipse中从XML生成Java代码 [英] Generating Java code from XML in Eclipse

查看:92
本文介绍了在Eclipse中从XML生成Java代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理一个项目,它将有几个非常相似的Java类,我想从XML文件生成。我想要做的是更改Eclipse构建过程以执行以下操作:




  • 编译代码生成器

  • 运行代码生成器,将XML转换为Java

  • 编译项​​目的其余部分



我可以手动完成所有操作,但我希望能够让Eclipse为我做所有这些。



示例



我想要获取一个如下所示的源XML文件:

 <命令列表> 
< command name =DATE/>
< command name =GROUP>
< capabilityREADER/>
<参数groupname/>
< / command>
< command name =ARTICLE>
< capabilityREADER/>
< argumentmessage-idoptional =true/>
< / command>
< / command-list>

并让它给我类似于以下内容(在适当的单独的文件中):

  public class Date extends命令{
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(尝试不可用的功能: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命令{
public ResponseCode execute(){
服务器srv = getServer();
if(srv.hasCapability(Capabilities.READER)== false){
Log.debug(尝试不可用的功能:READER);
}
String messageId = getArgument(messageId);
String command =ARTICLE;
if(messageId!= null)command + =+ messageId;
srv.send(command);
return srv.getResponse();
}
}


解决方案

正是模型到文本(M2T)项目中的JET组件所做的。实际上,您甚至可以使用JET创建项目.classpath和所需的任何其他文件。



Jet模板如下。请注意,这些模板必须完全按照所示命名。



/templates/main.jet

 <%@ taglib prefix =wsid =org.eclipse.jet.workspaceTags%> 
<% - com.lacqui.command.xform的主入口点 - %>

<% -
让c:迭代标签设置XPath上下文对象。
为了与JET 0.9.x或更早版本的100%兼容性,请删除此语句
- %>
< c:setVariable var =org.eclipse.jet.taglib.control.iterateSetsContextselect =true()/>

< c:setVariable select =/ command-listvar =command-list/>

---遍历输入模型,执行计算并存储
---结果作为模型注释通过c:set tag

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

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

- 从命令名称中导出类名

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

< c:iterate select =$ command / argumentvar =argument>

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

< / c:iterate>

< / c:iterate>

---遍历注释模型,执行文本生成动作
---如ws:file,ws:folder和ws:project

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

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

< ws:file template =templates / class.jetpath ={$ command-list / @ project} / src / {$ command-list / @ commandDir} / {$ command /@classname}.javareplace =true/>

< / c:iterate>

/templates/classpath.jet

 <?xml version =1.0encoding =UTF-8?> 
< classpath>
< classpathentry kind =srcpath =src/>
< classpathentry kind =conpath =org.eclipse.jdt.launching.JRE_CONTAINER/>
< classpathentry kind =outputpath =bin/>
< / classpath>

/templates/project.jet

 <?xml version =1.0encoding =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 / capabilityvar =capability>

if(srv.hasCapability(Capabilities。< c:get select =$ capabilities / @ name/>)== false){
Log.debug( - 可用功能:< c:get select =$ capabilities / @ name/>);
}
< / c:iterate>
< c:iterate select =$ command / argumentvar =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 / @命名 /> 中);
}
< / c:if>
< / c:iterate>

String command =GROUP;
< c:iterate select =$ command / argumentvar =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-idoptional =false/>
< argument name =message-idoptional =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(尝试不可用的功能: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(尝试不可用的功能:LOGGER);
}

if(srv.hasCapability(Capabilities.AUTHENTICATOR)== false){
Log.debug(尝试不可用的功能: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();
}
}


I am working on a project that will have several Java classes that are very similar to each other, and that I would like to generate from XML files. What I would like to be able to do is change the Eclipse build process to do something like this:

  • Compile the code generator
  • Run the code generator, converting the XML to Java
  • Compile the rest of the project

I could do this all manually but I would prefer to be able to have Eclipse do it all for me.

Example

I want to be able to take a source XML file that looks like this:

<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>

and have it give me something similar to the following (in separate files as appropriate):

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();
    }
}

解决方案

This is exactly what the JET component in the Model to Text (M2T) project was made for. In fact, you can even create the project, .classpath and any other files you need with JET.

Jet templates are as follows. Note that these templates must be named exactly as shown.

/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();
    }
}

and using this model:

<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>

gives a complete java project named com.lacqui.commands containing three java files:

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();
    }
}

and this:

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();
    }
}

这篇关于在Eclipse中从XML生成Java代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆