Zeus is set up to allow applications to call the source generator,
and therefore does not provide a static entry point for source
generation within the API. Because that's a common task,
though, a class within the samples (remember running the build
program with the "samples" argument?) does allow easy
class generation. If your classpath is set up like I showed you
previously, all you need to do is create a new directory called
"output". The samples program puts generated classes in
there by default (programmatically, you can change that option). So,
with an output directory in
place, run the following command:
I have spaced things out for clarity. I've specified the file
to generate source from, the package to put the source within, and
that generation should occur quietly (without
spitting out any debugging information). Generation from a schema is
very similar. Since Zeus uses the final version of the XML Schema
recommendation, you need to use a newer version of the XML Schema
shown back in the Castor section; Example 15-6
updates that schema to a current version.
Example 15-6. Updating the Castor XML Schema
<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.homespuntapes.com">
<element name="catalog">
<complexType>
<sequence>
<element ref="item" minOccurs="1" maxOccurs="unbounded" />
</sequence>
</complexType>
</element>
<element name="item">
<complexType>
<sequence>
<element name="title" type="string" />
<element name="teacher" type="string" />
<element name="guest" type="string" minOccurs="0" maxOccurs="unbounded" />
<element name="description" type="string" />
</sequence>
<attribute name="id" type="string" />
<attribute name="level">
<simpleType>
<restriction base="integer">
<enumeration value="1" />
<enumeration value="2" />
<enumeration value="3" />
<enumeration value="4" />
<enumeration value="5" />
</restriction>
</simpleType>
</attribute>
</complexType>
</element>
</schema>
Once you've got that, use the following command for class
generation:
C:\javaxml2\build>java samples.TestSchemaBinder
-file=c:\javaxml2\ch14\xml\zeus\catalog.xsd
-package=javaxml2.zeus
-quiet=true
You'll get identical output using either a DTD or a schema.
WARNING:
This is a slight overstatement. Actually, you will get identical output if you can represent the constraints in the DTD and XML Schema identically. In this example, the schema defines "level" as an integer, while the DTD must define it as PCDATA. The result is that using a schema, you get a typed level (a Java int), and using a DTD, you get a String. I've used the DTD version throughout this section, to show you that option.
Within the output directory, you'll find a
javaxml2 directory, and then a
zeus directory (matching up to
the package hierarchy). You can take a look at the source files
generated within.
Right off, you should notice that Zeus produces an interface (for
example, Catalog.java) and a
default implementation of that interface (for example, CatalogImpl.java). The reasoning behind this,
as opposed to the concrete classes that Castor generates, is that you
may want to have your own custom classes, perhaps already in
existence, that implement the Catalog interface.
You can therefore use your own implementation, but get the benefits
of class generation. I commonly see developers using Zeus to generate
classes and then creating their own implementation of the generated
interfaces as Enterprise JavaBeans (EJBs). These EJBs are then
persisted using Zeus, which is a piece of cake (as I'll show
you in the next section). Without providing for user-defined
implementations, this behavior would require modifying the generated
source code, which could break marshalling and unmarshalling.
Another notable difference you should be aware of is the method
names. For example, here's the Item
interface (trimmed down to its simplest form):
package javaxml2.zeus;
public interface Item {
public Title getTitle( );
public void setTitle(Title title);
public Teacher getTeacher( );
public void setTeacher(Teacher teacher);
public java.util.List getGuestList( );
public void setGuestList(java.util.List guestList);
public void addGuest(Guest guest);
public void removeGuest(Guest guest);
public Description getDescription( );
public void setDescription(Description description);
public String getLevel( );
public void setLevel(String level);
public String getId( );
public void setId(String id);
}
Notice that the JavaBeans naming is used, and elements that can
appear multiple times are returned as Java 2 Collections classes. In
any case, take a look at this source, and then compile it:
javac -d . output/javaxml2/zeus/*.java
Now you're ready to look at marshalling and unmarshalling using
Zeus.