Reputation: 464
I would like to create an enum class using a file. I hope to make maintenance easier.
txt example:
//name of the enum instance and devided by a '-' are the parameter values:
JOHN-23
ANNA-19
xml example:
<friends>
<friend name="JOHN">
<age>23</age>
</friend>
<friend name="ANNA">
<age>19</age>
</friend>
</friends>
I would like to have an enum akting like this one:
enum Friends {
JOHN(23),
ANNA(19);
private int age;
Friends(int age) {
this.age = age;
}
}
Upvotes: 0
Views: 431
Reputation: 15173
Here an example how you can generate the enum with StAX in java:
package codegen;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
public class GenCode {
public static void main(String[] args) throws XMLStreamException, IOException {
URL xmlFile = GenCode.class.getResource("Friends.xml");
XMLInputFactory inFactory = XMLInputFactory.newFactory();
XMLStreamReader reader = inFactory.createXMLStreamReader(xmlFile.openStream());
try (FileWriter out = new FileWriter("generated/codegen/Friends.java")) {
out.write("package codegen;\n");
out.write("\n");
out.write("public enum Friends {\n");
String friendName = null;
boolean inAge = false;
String sep = "\t";
while (reader.hasNext()) {
switch (reader.next()) {
case XMLStreamReader.START_ELEMENT:
if (reader.getLocalName().equals("friend"))
friendName = reader.getAttributeValue(null, "name");
if (reader.getLocalName().equals("age"))
inAge = true;
break;
case XMLStreamReader.CHARACTERS:
if (inAge) {
out.write(sep + friendName + "_" + reader.getText());
sep = ",\n\t";
}
break;
case XMLStreamReader.END_ELEMENT:
if (reader.getLocalName().equals("age"))
inAge = false;
break;
}
}
out.write("\n}");
}
}
}
You might need to change some paths.
You have to compile this file, invoke it with java, which will create the Friends.java with the enum and then compile the rest.
Upvotes: 0
Reputation: 49331
You can do it with an XSLT transformation and call out to SAXON via a task in your build system.
e.g. applying this to your example XML will result in your example enum code
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="text" indent="no"/>
<xsl:variable name="classname"><xsl:sequence select="concat(upper-case(substring(/*/local-name(),1,1)), substring(/*/local-name(), 2), ' '[not(last())])"/> </xsl:variable>
<xsl:template match="/*">
enum <xsl:value-of select="$classname"/>
{<xsl:for-each select="*"><xsl:if test="position()!=1">,</xsl:if><xsl:text>
</xsl:text><xsl:value-of select="@name"/>(<xsl:for-each select="*"><xsl:if test="position()!=1">, </xsl:if><xsl:value-of select="text()"/></xsl:for-each>)</xsl:for-each>;
<xsl:for-each select="*[1]/*"> private int <xsl:value-of select="local-name()"/>;
</xsl:for-each><xsl:text>
</xsl:text><xsl:value-of select="$classname"/>(<xsl:for-each select="*[1]/*"><xsl:if test="position()!=1">, </xsl:if>int <xsl:value-of select="local-name()"/></xsl:for-each>)
{
<xsl:for-each select="*[1]/*"> this.<xsl:value-of select="local-name()"/> = <xsl:value-of select="local-name()"/>;
</xsl:for-each> }
}
</xsl:template>
</xsl:stylesheet>
However,
Upvotes: 1