Castor Doclet Tutorial
 
 Objective
 

The goal of this document is to describe the building of a project using Castor JDO, and how Castor-Doclet can ease this task.

 Prerequisites
 

In order to use Castor and Castor-Doclet, you will need some software packages :

 Development environment
 

Most experienced developers can skip this first two parts. You can use your favorite IDE to create the project, or use the following guidelines :

 Check the needed tools
 

Both java and ant must be properly installed. Set JAVA_HOME and ANT_HOME environment variables, then add JAVA_HOME/bin and ANT_HOME/bin to the PATH.

Check java installation by typing java -version and ant -version in a command line shell.

 Create project build file
 

Ant will be used for each build step, be it compile project, generate Castor mapping file or create database tables.

Create the following basic build file in an empty directory and execute it (ant):

 
<?xml version="1.0"?>
<project name="examples" default="init">
	<target name="init">
		<mkdir dir="src" />
		<mkdir dir="lib" />
		<mkdir dir="classes" />
		<mkdir dir="properties" />
		<mkdir dir="ddl" />
	</target>
</project>

More content will be added to this file later.

 Add project libraries
 

Add jdom.jar, castor-0.9.3.19.jar, castor-doclet.jar, jdbc-se2.0.jar, jta.jar and xerces.jar to the lib directory just created.

 The necessary Hello World !
 
 Create source code
 

Create a test subdirectory in src and a Test.java source file inside it :

 
package test;

public class Test {
  public static void main(String[] argv) {
    System.out.println("Hello World !");
  }
}
 Compile class
 

To compile the Test class, add a compile target and a classpath property to the build.xml :

 
<path id="classpath">
  <pathelement location="classes"/>
  <pathelement location="properties"/>
  <fileset dir="lib">
    <include name="*.jar"/>
  </fileset>
</path>

<target name="compile" depends="init">
	<javac srcdir="src" destdir="classes">
	  <classpath refid="classpath"/>
	</javac>
</target>

Compile the class with ant compile.

 Run
 

To run the Test class, use the java command or add a run target to the build.xml :

 
<target name="run" depends="compile">
	<java classname="test.Test" >
		<java classname="test.Test" >
		  <classpath refid="classpath"/>
		</java>
	</java>
</target>

Run with ant run.

 First persistent class
 

The basic project setup is finished, we can proceed with persistent classes (after all, this is not an ant tutorial).

 Create Java Bean
 

Castor persistent classes must respect the Javabean conventions. To ease object relational mapping, they should also have non functional primary keys : object ids, which will be generated with Castor key generators (MAX, SEQUENCE, ...).

Create a Person class with name, surname and OID properties.

 Add Castor-Doclet tags
 

Castor-Doclet uses javadoc tags to generate DDL and mapping file. See the Java Documentation for more information.

For the Person class, the following tags are needed :

 
package test;

/**
 * @table PERSON
 * @key-generator MAX 
 */
public class Person {
    public int getOID(){ return OID; }
    public void setOID(int OID){ this.OID = OID; }
    public String getFirstName(){ return firstName; }
    public void setFirstName(String firstName){ this.firstName = firstName; }
    public String getLastName(){ return lastName; }
    public void setLastName(String lastName){ this.lastName = lastName; }

    /**
     * @primary-key 
     */
    private int OID;

    /**
     * @sql-size 50 
     */
    private String firstName;

    /**
     * @sql-size 50 
     */
    private String lastName;
}

@table and @key-generator specify the table name and key generation strategy for @primary-key. As java String length is not fixed, the column size must be specified.

 Mapping and DDL generation
 

As always, the Castor mapping file and the DDL are generated using an ant target :

 
<target name="mapping" depends="compile">
	<javadoc packagenames="test.*"
       sourcepath="src"
       private="true"
       doclet="org.castor.doclet.ddl.DDL"
       docletpath="lib/jdom.jar;lib/castor-doclet.jar"
       additionalparam=" -J-DFILE=ddl/create.sql  -J-DDB_TYPE=db2 -J-DLOG=1">
	  <classpath refid="classpath"/>
	</javadoc>
	<javadoc packagenames="test.*"
       sourcepath="src"
       private="true"
       doclet="org.castor.doclet.jdo.JDO"
       docletpath="lib/jdom.jar;lib/castor-doclet.jar"
       additionalparam="-J-DFILE=properties/mapping.xml -J-DLOG=1">
	  <classpath refid="classpath"/>
	</javadoc>
</target>

Generate with ant mapping. Change DB_TYPE to oracle or sql92 to generate different DDLs.

 Test Persistence
 
 Build database
 

The database configuration is highly dependent on the RDBMS used. The example will use the lightweight HypersonicSQL.

Add the hsqldb.jar file to the lib directory and ant classpath property. Create a createdb target in ant :

 
<target name="createdb" depends="mapping">
  <sql
      driver="org.hsqldb.jdbcDriver"
      url="jdbc:hsqldb:testdb"
      userid="sa"
      password=""
      onerror="continue"
      src="ddl/create.sql">
	  <classpath refid="classpath"/>
	</sql>
</target>

Create database schema with ant createdb. On the first execution, the drop statement will fail, which is normal as the PERSON table does not exist.

 Configure Castor database file
 

Castor can use simple JDBC driver configuration or JNDI datasources in an application server.

Create a database.xml file in the properties directory :

 
<!DOCTYPE databases PUBLIC
	"-//EXOLAB/Castor JDO Configuration DTD Version 1.0//EN"
	"http://castor.exolab.org/jdo-conf.dtd">
<database name="default" engine="hsql" >
 <driver class-name="org.hsqldb.jdbcDriver"
          url="jdbc:hsqldb:testdb">
    <param name="user" value="sa" />
    <param name="password" value="" />
  </driver>
  <mapping href="mapping.xml" />
</database>
 Run Test
 

Modify the Test class to create a Person object in the database :

 
package test;

import java.io.PrintWriter;
import org.exolab.castor.util.Logger;
import org.exolab.castor.jdo.*;

public class Test {
    public void run() {
        Database db = null;
        try {
            PrintWriter writer = new Logger(System.out).setPrefix("test");
            JDO jdo = new JDO();
            jdo.setLogWriter(writer);
            jdo.setConfiguration(this.getClass()
            	.getResource("/database.xml").toString());
            jdo.setDatabaseName("default");

            db = jdo.getDatabase();
            db.begin();
            Person person = new Person();
            person.setFirstName("Obiwan");
            person.setLastName("Kenobi");

            db.create(person);
            db.commit();

        } catch (Exception e) {
            if (db != null) {
                try { db.rollback(); } catch (Exception e2) { }
            }
            e.printStackTrace();
        }
    }

    public static void main(String[] argv) {
        Test test = new Test();
        test.run();
    }
}

Then run test with ant run

 Conclusion
 

This tutorial only describe a very basic Castor-Doclet example. With Castor/Castor-Doclet you can handle inheritance, dependent classes, the different kind of relationships, unique indexes...

All those subjects will be covered in a future version of this document.