Previous     Contents     DocHome    
iPlanet Trustbase Transaction Manager 3.0.1 Beta Developer Guide


 SymbolsABCDEFGHIJKLMNOPQRSTUVWXYZ 
Appendix A       The JAXHIT Class Generation Tool



What is JAXHIT?

The purpose of the classgen tool is to create a Java language binding for an XML DTD. This means that it will generate Java classes representing the structures defined in the DTD, with a correspondence of one Java class per element in the DTD. The resulting classes can be used to parse existing XML into a Java representation, or to create a new XML document by constructing it programmatically.


JAXHIT Operation

The JAXHIT tool takes information from two sources; the DTD file and a configuration file. The configuration file specifies all the options and parameters used in the code generation.


Command Line

jaxhit [-options] [<public Id> <DTD file>]

where options include:



-help

 

displays help

 

-config <file>

 

Specify the name of the configuration file

 

-cp <classpath>

 

Specify the classpath to use for compilation

 

-y

 

Do not confirm before overwriting existing files

 

-stub

 

Generate a stub service

 

-quiet

 

quiet output

 

-v

 

verbose output

 

-debug

 

debug output

 

The public id and DTD file must be specified in the config file or on the command line.


Configuration File Format

The configuration file for the class generator is an XML document. The Config element is the root element of the configuration document. It holds global settings for the generation. It contains the following attributes:


Name

 

Description

 

Default

 

Required

 

srcDir

 

The directory in which to keep the generated source files

 

-

 

No

 

libDir

 

The directory in which to keep the compiled classes

 

-

 

No

 

outputJar

 

The name of the output Jar file to create

 

-

 

No

 

basePackage

 

The root package under which all generated classes will be located

 

com.iplanet.trustbase.generated

 

No

 

baseDir

 

A root location from which all other file references are taken to be relative

 

Current directory

 

No

 

recurse

 

Whether to attempt to generate classes for all DTD files referenced as ENTITY inclusions from the top level DTD

 

false

 

No

 

force

 

Whether to generate classes that are already present on the system classpath

 

false

 

No

 

build

 

Whether to attempt to compile the generated classes

 

true

 

No

 

createService

 

Whether to generate the stub service

 

false

 

No

 

classPath

 

The semicolon seperated class path to be used when compiling the generated classes. As the compiler cannot pick up the system class path when the class generator is invoked with the java -jar <jarfile> syntax, the classpath must be specified here instead.

 

-

 

No

 

 


Content

The Config element can contain the following child elements:



Element

 

Occurrences

 

DTDFile

 

0 or more

 

DefaultElementBase

 

0 or 1

 

ElementBase

 

0 or more

 

ServiceConfig

 

0 or 1

 

 


DTDFile Element

This element specifies the location and public ID for a DTD


Attributes



Name

 

Description

 

Default

 

Required

 

file

 

The path to the DTD

 

-

 

Yes

 

publicId

 

The Public Id of the DTD

 

-

 

Yes

 

 


Content

The DTDFile element has no content.


ElementBase Element

This element specifies element-specific options used in the generation process.


Attributes



Name

 

Description

 

Default

 

Required

 

name

 

The name of the element to process

 

-

 

Yes

 

inherit

 

Whether to inherit values from the DefaultElementBase (if present)

 

true

 

No

 

methodPrefix

 

A string to prepend to the generated get/set/add/remove methods

 

-

 

No

 

 


Content

The ElementBase element can contain the following child elements:



Element

 

Occurrences

 

ExtendsClass

 

0 or 1

 

ImplementsInterface

 

0 or more

 

AdvancedOptions

 

0 or 1

 

AttributeType

 

0 or more

 


DefaultElementBase Element

This element specifies the default options used in the generation process.


Attributes



Name

 

Description

 

Default

 

Required

 

methodPrefix

 

A string to prepend to the generated get/set/add/remove methods

 

-

 

No

 


Content

The DefaultElementBase element can contain the following child elements:



Element

 

Occurrences

 

ExtendsClass

 

0 or 1

 

ImplementsInterface

 

0 or more

 

AdvancedOptions

 

0 or 1

 

AttributeType

 

0 or more

 


AdvancedOptions Element

This element specifies advanced options used in the generation process.


Attributes

The AdvancedOptions element has no attributes


Content

The AdvancedOptions element can contain the following child elements:



Element

 

Occurrences

 

PreParseFragment

 

0 or 1

 

PostParseFragment

 

0 or 1

 

ClassDoc

 

0 or 1

 


PreParseFragment Element

This element specifies Java code to be included in the generated class, and called prior to the parse of sub elements. Because the code is called within the SAX parse process, the only exception that the code may throw is org.xml.sax.SAXException


Attributes

The PreParseFragment element has no attributes


Content

The textual content is the Java code to be inserted


PostParseFragment Element

This element specifies Java code to be included in the generated class, and called after parsing of the sub elements. Because the code is called within the SAX parse process, the only exception that the code may throw is org.xml.sax.SAXException


Attributes

The PostParseFragment element has no attributes


Content

The textual content is the Java code to be inserted


ClassDoc Element

This element specifies text to be included in the Class JavaDoc for a generated class. Note that as text specified using this mechanism is included in a Javadoc comment, usage of "*/" and "/*" character combinations is likely to cause problems.


Attributes



Name

 

Description

 

Default

 

Required

 

file

 

The file name of a file containing the text to be used

 

-

 

No

 


Content

The ClassDoc element can also contain textual content. If the file attribute and the textual content are present, then the text will be appended to the file text before inclusion.

 


ImplementsInterface Element

This element specifies an interface for a generated class to implement.


Attributes



Name

 

Description

 

Default

 

Required

 

name

 

The fully qualified name of an interface

 

-

 

Yes

 


Content

The ImplementsInterface element has no content.

 


ExtendsClass Element

This element specifies a base class for a generated class to extend.


Attributes



Name

 

Description

 

Default

 

Required

 

name

 

The fully qualified name of a class

 

-

 

Yes

 


Content

The ExtendsClass element has no content.


AttributeType Element

By default, the accessor methods for attributes take and return the Java String type. This element allows an attribute's accessor methods to operate on a different type. The primitive types supported are:

  •       int

  •       long

  •       float

  •       double

  •       boolean

It is also possible to specify the fully qualified name of a class that has the following properties:

  •       a public constructor taking a single String argument, and throwing no caught exceptions

  •       an orthogonal toString() implementation.


Attributes



Name

 

Description

 

Default

 

Required

 

name

 

The name of the attribute

 

-

 

Yes

 

type

 

The type to use

 

-

 

Yes

 


Content

The AttributeType element has no content.


ServiceConfig Element

This element specifies options specific to the generation of the service stub. For each root element that the service is expected to process, there should be a corresponding RootElement child element.


Attributes



Name

 

Description

 

Default

 

Required

 

name

 

The friendly name of the service

 

-

 

No

 

className

 

The fully qualified class name of the service

 

-

 

Yes

 

RoutingAttribute

 

The name of the message attribute to use for routing

 

DocType

 

No

 


Content

The ServiceConfig element can contain the following child elements:



Element

 

Occurrences

 

RootElement

 

1 or more

 

 


RootElement Element

This element identifies a root element (i.e. a top level element) in the messaging scheme.


Attributes



Name

 

Description

 

Default

 

Required

 

name

 

The name of the root element

 

-

 

Yes

 

RoutingValue

 

A value that the RoutingAttribute may take. When the RoutingAttribute takes this value the message will be routed to the service.

 

The name of the root element

 

No

 


Content

The RootElement element has no content.

 


Example Config File

<!—- This config file causes the generated source to be retained in the "src" subdirectory of the current directory. The source is compiled and the generated classes are retained in "output.jar". A service stub is generated. -->

<Config

srcDir="src"

force="true"

outputJar="output.jar"

createService="true">

<-- Load the DTD "test.dtd" -->

<DTDFile file="jaxhit.dtd" publicId="-//classgen//generated"/>

<-- Specify that the class generated for the "TestMessage" element defined in the DTD should implement the interface "org.foo.test.Message" -->

<ElementBase name="TestMessage">

<ImplementsInterface name="org.foo.test.Message">

</ElementBase>

<-- Specify that the service stub should be "org.foo.Service". It accepts only one message type, that being "RootMessage"-->

<ServiceConfig name="MyService" className="org.foo.Service">

<RootElement name="TestMessage"/>

</ServiceConfig>

</Config>


The Generated Interface

There is a one to one mapping between elements in the DTD and generated classes. Each generated class implements the TbaseElement interface from the package com.iplanet.trustbase.xml.message, and those classes mapping to elements that have an ID attribute implement TbaseIdentifiedElement, from the same package.

In addition to the methods specified in the TbaseElement interface, the following methods are generated.


Attributes

Each attribute defined in the ATTLIST declaration for the element will have a get method and a set method generated. The method signatures will be

public String getAttr();

public void setAttr(String attr);

where "attr" is replaced by the name of the attribute. Any characters in the attribute name that are not a legal Java identifier part will be replaced by the underscore character '_'.

If the attribute is mapped to a Java type with the AttributeType configuration options, then the generated method signatures will reflect the type specified.


Content

For the purposes of generation, the content model of an element is considered to consist of two types of content. Singly addressable elements are those that can not be specified more than once. Elements that can be specified more than once are considered to be part of a group.

For example, the content model (A, B, C*) consists of the singly addressable elements A and B, and the group containing the element C.

For each singly addressable element, a get / set pair is produced:

public A getA();

public void setA(A a);

For each member of a group, the following methods are produced:

public void addC(C c);

public void removeC(C c);

public C[] getC();

 


Other methods

  •       Each generated class has a convenience construction method that takes input from a stream and returns an instance of the class if one can be constructed from the stream.
    public static <type> fromXML(Reader reader, boolean validate) throws SAXException,
    where <type> is the type of the class in which the method is defined, reader is a reader for the XML stream and validate is whether to validate during parse.

  •       public static <type> fromXML(Reader reader) throws SAXException
    This is the same as above, except that it does validation by default

  •       A copy method is provided that does a deep copy of the hierarchy.
    public TbaseElement copy();


Constructors

The generated classes have up to 4 constructors.

The default constructor

A constructor taking all the attributes of the element (excluding fixed attributes), if there are any

A constructor taking all the attributes and all the content of the element. Whether this constructor is generated depends on whether there are any groups ( * or +) in the content model. If noe (i.e. all the elements in the content are directly addressible), this constructor will be generated

The constructor used during the SAX parse process. This should not be used in user code.


Using the Generated Classes


Constructing instances of generated classes from XML

  1. If you have a complete document (complete with DOCTYPE declaration)
    Use com.iplanet.trustbase.xml.message.MessageBuilder.buildMessage(), passing in a Reader for the XML. This will return an instance of TbaseElement which you can cast to the correct type.

  2.       If you know in advance the type of the element you wish to read
    Use the static fromXML() method provided on the generated class you wish to construct. This will return an instance of the generated class

  3. If you do not know the type of the element in advance, and the XML does not have a DOCTYPE header
    Get an instance of MessageBuilder with one of the static getInstance() methods.
    Set the public Id by calling resolveEntity(publicId, null).
    Call the parse() method with a Reader for the XML. This will return an instance of a generated class which you can cast to the correct type.

  4. If you have no idea what you're trying to read (but it is well formed XML)
    Use com.iplanet.trustbase.xml.message.TbaseAnyElement.fromXML(), passing in a Reader. This will return an instance of TbaseAnyElement. The structure created by this method will not be typed in any way, by will contain all the data present in the document. Structures created in this manner can be reparsed into generated classes with the reParse() method, which takes the public Id of the DTD in which the element was defined. This method returns a TbaseElement which can be cast appropriately.


Outputting XML from generated classes

Call the toXMLString() method on any generated class. This will return a string representation of the XML structure. Note that the resulting XML will not have a DOCTYPE declaration. If you want to use the XML string as an entire document, you should insert the DOCTYPE declaration with the following format:

<DOCTYPE elementName PUBLIC "publicId" "systemId">

Where elementName is the name of the root element in the message, publicId is the public Id of the DTD (which can be obtained from the generated class using the publicId() method) and systemId is a URI that locates the DTD. The system Id need only be a valid identifier if the message is to be read by a non-Trustbase system.

 


FAQ

  1. How do I keep the generated source code?
    Specify the srcDir Attribute in the configuration file. All the generated source code will be retained in the specified directory

  2. Where is the source for my stub service?
    In the directory specified by srcDir. If you did not specify srcDir, then you will not have a stub service class.

  3. Why is the stub service class not compiled along with the other source files?
    The stub service is not useful by itself - you need to provide a meaningful implementation!

  4. Why do I need to supply a public ID?
    The public ID is used to generate a package name for the generated code. This is useful because it allows common elements to be represented by a single codebase.

  5. What does JAXHIT actually stand for?
    Java Architecture for XML Handling in Trustbase

  6. I want all but a few of the generated classes to implement a certain interface. Is there a way to override the settings in DefaultElementBase for these elements?
    Yes. For each element that should not inherit the settings in DefaultElementBase, create an ElementBase with the "inherit" attribute set to "false". Only the settings specified explicitly will be applied to the generated class.

  7. The compilation step fails. Why?
    There are a number of possible reasons for this. Most likely is a problem with the base interfaces and / or classes that you specified in the config file. If you are relying on the generated interface matching a certain pattern, make sure that this is in fact the case. Also, certain element or attribute names can cause conflicts with Object. For example, if you had an attribute called Class, the accessor method would be getClass() - clearly this will fail. This problem can be solved by using the methodPrefix attribute in the ElementBase config for the affected element, such that the generated method name becomes, for example, xGetClass().

  8. Attributes with enumerated values are supposed to have type-safe get / set methods. Why doesn't this appear to work?
    Because the default parser used with JAXP (Crimson) has a bug. Use the Xerces parser instead, using the following command line:


    java -Djavax.xml.parsers.SAXParserFactory=org.apache.xerces.jaxp.SAXPars erFactoryImpl -jar jaxhit.jar <options>


    and make sure that the Xerces jar is in the same place as jaxhit.jar.


Previous     Contents     DocHome    
Copyright © 2001 Sun Microsystems, Inc. Some preexisting portions Copyright © 2001 Netscape Communications Corp. All rights reserved.

Last Updated October 31, 2002