我有一系列描述varius实体类型的XML文件。我想使用基于mixins的实现将这些XML文件转换为Java类(源代码,因此我可以检查它们是否已编译)。
一个例子:
描述村民的XML文件:
<?xml version="1.0" encoding="utf-8" ?>
<entity>
<id>1</id>
<gathers>
<rate>12</rate>
</gathers>
<moves>
<speed>4</speed>
</moves>
</entity>
应该成为以下课程:
public class Villager implements Gathers, Moves {
private final Gathers gathers;
private final Moves moves;
int getId() {
return 1;
}
@Override
public int getSpeed() {
return this.moves.getSpeed();
}
@Override
public int getRate() {
return this.gathers.getRate();
}
public Villager() {
super();
this.moves = new MovesMixin(4);
this.gathers = new GathersMixin(12);
}
}
我希望以一种易于扩展以涵盖新属性的方式执行此操作。
现有的软件包/工具是否可以执行此类操作?
包含模板的更新示例:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="1.0"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="entity">
/*
* DO NOT MODIFY
* This is an automatically generated class.
*/
package xslt.entities;
import xslt.*;
public strictfp final class <xsl:value-of select="typeName"/> implements <xsl:apply-templates select="moves" mode="implement"/><xsl:apply-templates select="gathers" mode="implement"/><xsl:apply-templates select="shoots" mode="implement"/>Entity {
<xsl:apply-templates select="moves" mode="mixin"/>
<xsl:apply-templates select="gathers" mode="mixin"/>
<xsl:apply-templates select="shoots" mode="mixin"/>
public <xsl:value-of select="typeName"/>() {
super();
}
}
</xsl:template>
<xsl:template match="moves" mode="implement">Moves, </xsl:template>
<xsl:template match="gathers" mode="implement">Gathers, </xsl:template>
<xsl:template match="shoots" mode="implement">Shoots, </xsl:template>
<xsl:template match="moves" mode="mixin">
private final Moves moves = new MovesMixin(<xsl:value-of select="speed"/>);
@Override
public int getSpeed() {
return this.moves.getSpeed();
}
</xsl:template>
<xsl:template match="gathers" mode="mixin">
private final Gathers gathers = new GathersMixin(<xsl:value-of select="rate"/>);
@Override
public int getRate() {
return this.gathers.getRate();
}
</xsl:template>
<xsl:template match="shoots" mode="mixin">
private final Shoots shoots = new ShootsMixin(<xsl:value-of select="range"/>);
@Override
public int getRange() {
return this.shoots.getRange();
}
</xsl:template>
</xsl:transform>
答案 0 :(得分:1)
查看AspectJ的Inter-type声明,它基本上允许您将一个方面中定义的新成员(字段,方法,构造函数)添加到现有类型。
http://www.eclipse.org/aspectj/doc/next/progguide/language-interType.html
它不是能理解你的XML描述符的东西,但肯定是在java中实现mixins的方法,所以也许你可以利用它。
答案 1 :(得分:0)
从XML生成java的方法很多。我的示例使用从ANT调用的XSLT。
├── build.xml
└── src
├── xml
│ └── entity.xml
└── xsl
└── java.xsl
<project name="Generate Java" default="generate">
<target name="generate">
<xslt style="src/xsl/java.xsl" basedir="src/xml" destdir="build/java" extension=".java"/>
</target>
<target name="clean">
<delete dir="build"/>
</target>
</project>
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output method="text"/>
<!--
==============================
Match the root tag
==============================
-->
<xsl:template match="entity">
public class Villager implements Gathers, Moves {
private final Gathers gathers;
private final Moves moves;
int getId() {
return <xsl:value-of select="id"/>;
}
@Override
public int getSpeed() {
return this.moves.getSpeed();
}
@Override
public int getRate() {
return this.gathers.getRate();
}
public Villager() {
super();
this.moves = new MovesMixin(<xsl:value-of select="moves/speed"/>);
this.gathers = new GathersMixin(<xsl:value-of select="gathers/rate"/>);
}
}
</xsl:template>
</xsl:stylesheet>
以下样式表增强功能演示了如何根据输入XML使源代码生成更具动态性。
注意:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output method="text"/>
<!--
==============================
Match the root tag
==============================
-->
<xsl:template match="entity">
public class Villager implements <xsl:apply-templates select="gathers|moves" mode="class-implements"/> {
private final Gathers gathers;
private final Moves moves;
int getId() {
return <xsl:value-of select="id"/>;
}
<xsl:apply-templates select="gathers|moves" mode="class-getters"/>
public Villager() {
super();
<xsl:apply-templates select="gathers|moves" mode="mixins"/>
}
}
</xsl:template>
<!--
==============================
Match the gather tag
==============================
-->
<xsl:template match="gathers" mode="class-implements">
<xsl:text>Gathers,</xsl:text>
</xsl:template>
<xsl:template match="gathers" mode="class-getters">
@Override
public int getRate() {
return this.gathers.getRate();
}
</xsl:template>
<xsl:template match="gathers" mode="mixins">
this.gathers = new GathersMixin(<xsl:value-of select="rate"/>);
</xsl:template>
<!--
==============================
Match the gather tag
==============================
-->
<xsl:template match="moves" mode="class-implements">
<xsl:text>Moves,</xsl:text>
</xsl:template>
<xsl:template match="moves" mode="class-getters">
@Override
public int getSpeed() {
return this.moves.getSpeed();
}
</xsl:template>
<xsl:template match="moves" mode="mixins">
this.moves = new MovesMixin(<xsl:value-of select="speed"/>);
</xsl:template>
</xsl:stylesheet>