在Eclipse中从XML生成Java代码 [英] Generating Java code from XML in 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屋!