views:

280

answers:

7

Does anyone know what approach one can take to automatically generate Java source code, from for example an xml or json file, in eclipse?

One great example of what I am thinking of doing is what Google Android sdk does: they have an R class generated automatically from the resources.

Every time a resource file is saved in Eclipse R class is automatically regenerated.

UPDATE: Example: In the text (xml or json file) I have the following:

 <tags>
     <tag id="ALPHA">
         <description>The first alpha tag.</description>
         <value>231232</value>
     </tag>
     <tag id="BETA">
         <description>This is the beta tag.</description>
         <value>231232</value>
     </tag>

Then in my generated java class, say R I would have something like:

R.tags.ids.ALPHA //refers to an enum value for example
R.tags.values.ALPHA //refers to final int with avlue 231232
R.tags.descriptions.ALPHA //refers to the String with description

Thanks!

+4  A: 

The way I do it is that I have an XSLT file that simply transforms my xml-data (in my case a protocol specification) to java source code. This XSLT-transformation can easily be done in an ANT-task which could be included in the build-chain in eclipse.

Perhaps there is a plugin for this particular task.

Some useful links:

aioobe
+1  A: 

Take a look at XDoclet. Its an extensible open source code generation engine for Java.

EDIT: As bozho points out, XDoclet has mostly been replaced by annotations: Annotations vs. XDoclet

Do any java libraries use annotations for code generation?

dbyrne
XDoclet is obsolete
Bozho
What has replaced it?
dbyrne
annotations made XDoclet unneeded. It was very powerful in the pre-1.5 era, but now it isn't.
Bozho
Do note that I don't want to generate xml from my code; I want to generate Code from the xml or json.
drozzy
@drozzy you can generate code with both xdoclet and annotations
dbyrne
@drozzy You can convert your xml configuration into annotated source code, similar to the way you can replace a hibernate or spring xml configuration file with annotations.
dbyrne
Great, I am not familiar with hibernate or spring. Could you provide some resources as to where to start in generating Annotated source code from text/xml files?
drozzy
+1  A: 

From XML to JAVA and vice Versa I highly recommend JAXB.

You can generate Java source code from Schema's using JAXB 2.0 or greater. Or you can generate Schemas from Java.

You can also easily make JAXB generate/consume JSON using Jettison.

You can also have JAXB generate POJO's in a Martin Fowler Fluent Style or a whole bunch of different ways using its plugin system.

EDIT based on your comments: Have XSLT generate your JAXB POJO:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <xsl:output method="text" />
    <xsl:template match="/" priority="100">
    import javax.xml.bind.annotation.XmlRootElement;

    @XmlRootElement(name="Human")
    public class <xsl:value-of select="name(node())" /> {
        <xsl:apply-templates  select="child::node()" />
    }
    </xsl:template>
    <xsl:template match="/*/*">
        private String <xsl:value-of select="name()" />;
        public String get<xsl:value-of select="name()" /> {
            return <xsl:value-of select=" name()" />;
        }

        public void set<xsl:value-of select="name()" />(String value) {
            this.<xsl:value-of select="name()" /> = value;
        }
    </xsl:template>
</xsl:stylesheet>

If you process with this example XML:

<?xml version="1.0" encoding="UTF-8"?>
<Human>
    <EyeColor>brown</EyeColor>
    <HairColor>brown</HairColor>
</Human>

You get something like:

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="Human")
public class Human {


    private String EyeColor;
    public String getEyeColor {
        return EyeColor;
    }

    public void setEyeColor(String value) {
        this.EyeColor = value;
    }


    private String HairColor;
    public String getHairColor {
        return HairColor;
    }

    public void setHairColor(String value) {
        this.HairColor = value;
    }


}
Adam Gent
Thanks, but I am not only interested in the Schema of the Xml document, but the actual data contained within it. So if my xml document has a property with a given name I want the same property to be created in the java class file. I hope I am making some sense.
drozzy
Yes but it would not be hard to write a XSLT sheet to create a Java class with the correct JAXB annotations
Adam Gent
@drozzy: Added an XSLT example
Adam Gent
Thanks Adam, but how could I get the value (brown) from the above? E.g. Human.EyeColor.brown or Human.HairColor.brown? Do you know what I mean? This is what Android does with their R class, eg.: R.values.brown etc...
drozzy
I updated my question with an example.
drozzy
A: 

You could have a look at the Eclipse modeling project's model to text components.

Fabian Steeg
Thanks, but first of all I don't know what is does exactly. It seems like it's converting java code to text, whereas I need it the other way - given text (xml or json) create a java class with constants whose values are given in the text file.
drozzy
@drozzy The first step would be to get some sort of model by parsing the input format, e.g. you could parse your XML with JDOM, and from that generate the Java source files with JET (see http://www.eclipse.org/articles/Article-JET/jet_tutorial1.html). Another option would be to use XML with EMF and use Xpand to generate your Java files from the EMF model (http://www.openarchitectureware.org/pub/documentation/4.3.1/html/contents/xsd_tutorial.html).
Fabian Steeg
Thanks, but JET tutorial is not very clear as to what exactly JET does. Also what is EMF?
drozzy
With JET you define a template for the code you want to generate. From that, JET will generate a class that will create your code, allowing you to pass your model to that class. EMF is the Eclipse Modeling Framework: http://eclipse.org/modeling/emf
Fabian Steeg
A: 

Well Eclipse Modelling Framework (EMF) is meant for the application you are looking forward to. I assume you have a model and you want to convert it into code. Very specific hint I can give is JET (Java Emitter template) you can refer here for more details.

Also the newer framework XPand introduced by eclipse,

Revolving around the abstract syntax-development components are model-transformation tech- nologies. 1. model-to-text (Java Emitter Templates [JET] and Xpand) 2. model-to-model (QVT and ATL)

Here model refers to XML-XSLT / UML (Rational rose) model.

Chaitannya
I can't find the "XPand" framework. Could you provide a link?
drozzy
+3  A: 

I'm adding another answer based on your comments and also because I don't really recommend doing this outside of Google Android Resource SDK. Google is basically using a hierarchy of static classes (singletons) for their resources. You need to make your XSLT generate static member variables instead of getters and setters.

I basically took my old answer and changed it to static for all member variables. You have to be very careful doing this because I have seen so many bugs with incorrect use of the "static" modifier.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
    <xsl:output method="text" />
    <xsl:template match="/" priority="100">
    public class <xsl:value-of select="name(node())" /> {
        <xsl:apply-templates  select="child::node()" />
    }
    </xsl:template>
    <xsl:template match="/*/*">
        public static String <xsl:value-of select="name()" />;
        public static String get<xsl:value-of select="name()" /> {
            return <xsl:value-of select=" name()" />;
        }

        public void static set<xsl:value-of select="name()" />(String value) {
            <xsl:value-of select="name()" /> = value;
        }
    </xsl:template>
</xsl:stylesheet>

If you process with this example XML:

<?xml version="1.0" encoding="UTF-8"?>
<Human>
    <EyeColor>brown</EyeColor>
    <HairColor>brown</HairColor>
</Human>

You get something like: public class Human {

    public static String EyeColor;

    public static String getEyeColor {
        return EyeColor;
    }

    public static void setEyeColor(String value) {
        this.EyeColor = value;
    }


    public static String HairColor;
    public static String getHairColor {
        return HairColor;
    }

    public static void setHairColor(String value) {
        this.HairColor = value;
    }


}
Adam Gent
Why do I need the getter-setter methods at all if it's public? Why not general Final static members?
drozzy
Because you need them if you want to use serialization tools (like JAXB) that automatically read and populate the fields.Otherwise you do not need them. Infact some tools allow you to use member variables instead of getters/setters.
Adam Gent
Is there a way to hook this up in eclipse so it's down automatically, whenever I save an xml file, for example?
drozzy
A: 

Yes you can do it using xml file.Create your own xml file template then using preferences-java-code template-import choose that file and you can use that template.

Rupeshit