Hi!

Today I downloaded and played with JAXB 1.0 beta. Guess what? It does the
samek thing as XGG, except it's based on XML Schema and not DTD. JAXB now
has an Ant task <xjc> that can generate java classes from a schema (just
like XGG does). These classes can be thought of as classes that can be used
to build a type-safe DOM tree, the JAXB terminology is "content tree".

I successfully ran xjc on ejb-jar_2_1.xsd (I had to do some small
modifications before I succeeded) and it spits out one class for each XML
element type. Neat! Here is the class that represents the root element of
the content tree, <ejb-jar>:

package xdoclet.plugins.com.sun.java.xml.ns.j2ee;

public interface EjbJar {
    java.util.List getDisplayName();
    java.util.List getDescription();
    xdoclet.plugins.com.sun.java.xml.ns.j2ee.RelationshipsType
getRelationships();
    void
setRelationships(xdoclet.plugins.com.sun.java.xml.ns.j2ee.RelationshipsType
value);
    java.util.List getDeploymentExtension();
    java.util.List getIcon();
    java.math.BigDecimal getVersion();
    void setVersion(java.math.BigDecimal value);
    xdoclet.plugins.com.sun.java.xml.ns.j2ee.AssemblyDescriptorType
getAssemblyDescriptor();
    void
setAssemblyDescriptor(xdoclet.plugins.com.sun.java.xml.ns.j2ee.AssemblyDescr
iptorType value);
    String getEjbClientJar();
    void setEjbClientJar(String value);
    xdoclet.plugins.com.sun.java.xml.ns.j2ee.EnterpriseBeansType
getEnterpriseBeans();
    void
setEnterpriseBeans(xdoclet.plugins.com.sun.java.xml.ns.j2ee.EnterpriseBeansT
ype value);
}

The JAXB framework provides a simple way (perfect for our needs) to
serialise a content tree back to an XML document:

    EjbJar ejbJar =
xdoclet.plugins.com.sun.java.xml.ns.j2ee.ObjectFactory.createEjbJar();
    // build the tree
    ...
    // output the tree
    JAXBContext jc = JAXBContext.newInstance(
"xdoclet.plugins.com.sun.java.xml.ns.j2ee.EjbJar" );
    Marshaller m = jc.createMarshaller();
    m.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE );
    m.marshal( ejbJar, System.out );

It don't get simpler than this :-) So what's left for XDoclet (or rather the
ejb-jar plugin) is to construct the content tree based on data in the
classes and the @tags. That could be done like this:

public class EjbJarPlugin extends JAXBPlugin {
    public Object createContentTree() {
        EjbJar ejbJar = ObjectFactory.createEjbJar();
        PopulatorFactory.createEjbJarPopulator().populate(ejbJar);
    }
}

public class EjbPopulator {
    private void populate(EjbJar ejbJar) {
    // create, populate and add <display-name>
    DisplayName displayName = ObjectFactory.createDisplayName();
    PopulatorFactory.createDisplayNamePopulator().populate(ejbJar);
    ejbJar.getDisplayName().add(displayName);

    // etc.
}

So what we need to do is to write a Populator class for each of the JAXB
generated classes. We can geberate quick-start implementations of these
Populator classes that can be hand-edited. The classes that need to be
hand-edited are basically those that correspond to elements that have
attributes or values, which is usually leaf nodes. For EJB2.1 There is about
30 classes.

Each of the populator classes would then extract data from the classes using
the XJavadoc API.

The approach is similar to the initial proposal with XGG, except that it's
now a push model rather than a pull model. We're pushing data into the
content tree. I the XGG approach it was the content tree classes themselves
that pulled the data from xjavadoc.

There are many available tools that can convert the old DTDs into XML Schema
(.xsd files).

About versioning: We'll have one set of classes per version of the
DTD/Schema. That means that there will be e.g. EjbJar classes in different
packages, one for each version of the DTD/Schema the element occurs in.
However, we don't want to write a new set of populators each time we get a
new version for a schema.

This can be solved by post-processing the JAXB generated interfaces to
extend a common interface. These interfaces will have a "union" of all
methods for all versions, and the JAXB generated interfaces should also be
post-processed to implement additional methods and just throw
UnsupportedOperationException. All this can be done automatically with help
of Xjavadoc's code-mutation capabilities (which we'll have to improve a
bit).

Then the populators will always treat JAXB classes as this common interface,
and call descendant populators based on the version of the Schema we're
running against.

If we go for this approach, we won't need Velocity at all for XML
generation. Velocity will only be used for generation of other kinds of
files (.java, .properties, etc.)

How does this sound to you?

Aslak



-------------------------------------------------------
This SF.net email is sponsored by: ApacheCon, November 18-21 in
Las Vegas (supported by COMDEX), the only Apache event to be
fully supported by the ASF. http://www.apachecon.com
_______________________________________________
Xdoclet-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/xdoclet-devel

Reply via email to