Index: tutorial/source-generator/tutorial.html =================================================================== RCS file: tutorial/source-generator/tutorial.html diff -N tutorial/source-generator/tutorial.html --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ tutorial/source-generator/tutorial.html 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,945 @@ + + +
+ +
Page
+
+ Castor
+ XML Binding Tutorial
+ Date:
+ 28 Jan 2005
+
+
+
+
+
+
+
+
+
+
Table +of contents
+
+
1 Introduction 2
+2Overview 2
+3Binaries 2
+4Installation 3
+5SourceGen Tool 3
+5.1Usage 4
+5.2Steps to + generate code 4
+6Using generated code 6
+7Compile And Build 8
+8Custom Field Handler with binding 9
+9References 10
+
+
+
+
+
This +document is intended to explain the Castor XML-binding (SourceGen +tool) in brief, so that developer can understand the usage of Castor +SourceGen in short time. +
+
+
Castor +is the Open Source data binding framework for Java. Mainly it consist +of two feature Castor XML and Castor JDO,
+
+
Castor + XML - Java Object to and from XML-binding +
+
+
XML + – binding : +
+Source + code from XML Schema can be generated for Java Objects using + SourceGen tool. +
+Provides + easy way to un-marshal XML file to Java Object and marshal Java + Object to XML file. +
+Provides + the way to customize the source code generation by means of + binding-file. +
+No + need to use the DOM, SAX anymore.
+
+
+
XML + – mapping :
+Provides + the way to map the existing Java Objects to XML file by means of + mapping-file. +
+Provides + easy way to transform the Java Objects to XML file, vice versa.
+
+
+
Castor + JDO - Java Object to and from DataBase-binding +
+
+
+Castor JDO provides the +means to persist the Java Objects directly to DataBase. It maps the +Java Object to DataBase tables. One can avoid using JDBC API. Castor +JDO is similar technology like Sun’s JDO but they actually they +are very different.
+
+
This +tutorial explains about the XML – binding alone.
+
+
Castor +binaries are available at http://www.castor.org/download.html
+
+
Let’s +download the latest version from, +
++ftp://ftp.exolab.org/pub/castor/castor_0.9.6/ + +
+Then, +click and save castor-0.9.6-RC3.zip.
+
+
+
Unzip +the zip file in some folder lets call this folder CASTOR_HOME.
+
+
We +have to do some manual work before running the SourceGen tool,
+
+
Create + “lib” folder under CASTOR_HOME, say CASTOR_HOME\lib.
+Copy + all “*.jar” files lying in CASTOR_HOME to + CASTOR_HOME\lib.
+Create + “bin” folder under CASTOR_HOME, say CASTOR_HOME\bin.
+Copy + “SourceGen.bat” file lying in CASTOR_HOME to + CASTOR_HOME\bin.
+Modify + the SourceGen.bat as shown below, (modified part is shown in bold + letters)
+
+
+
+
+
Create + the “cp.bat” file in CASTOR_HOME\bin with following + line,
+
+
+
+
External + library on which Castor is dependent is comes with Castor source + distribution, either you can download the Castor Source + distribution OR download the following dependent library from + respective website. +
+
+
Castor + is depending on following external library,
++
+Xerces + and Apache serializer shipped with Xerces.
++Site +http://xml.apache.org/dist/xerces-j/
++download +Xerces-J-tools.2.5.0.zip from the above site and then copy -
++xercesImpl.jar and +xml-apis.jar file from zip to CASTOR_HOME\lib.
+
+
+
Jakarta + ORO +
++Site +http://jakarta.apache.org/site/binindex.cgi#oro
++download +jakarta-oro-2.0.8.zip from the above site and then copy -
++jakarta-oro-2.0.8.jar +file from zip to CASTOR_HOME\lib.
+
+
Jakarta + Regexp (Is shipped with Jakarta ORO.)
+
+
Jakarta + Common-Logging +
++Site +http://jakarta.apache.org/site/binindex.cgi#commons-logging
++download +commons-logging-1.0.4.zip from the above site and then copy -
++commons-logging.jar +file from zip to CASTOR_HOME\lib.
+
+
SourceGen + tool requires following jars in lib directory,
+castor-0.9.6-RC3-xml.jar
+castor-0.9.6-RC3.jar
+commons-logging.jar
+jakarta-oro-2.0.8.jar
+xercesImpl.jar
+
+
+
+
+

+
+
SourceGen +-i xsdfilename [-package package-name] [-dest dest-dir] +
+[-line-separator +( unix | mac | win)] [-f ] [-h ] [-verbose ] [-nodesc ] +
+[-types +types] [-type-factory classname] [-nomarshall ] [-testable ] +
+[-sax1 +] [-binding-file filename] [-generateImportedSchemas ]
+
+
Do +not bother about all options of command. We require very few to start +with.
+
+
Let’s +get into process. Let’s generate source code from XML Schema +using SourceGen tool. Let’s create some directories for +execution of SourceGen tool.
+
+
+
1. +Please create the following directories,
+CASTOR_HOME\samples
+CASTOR_HOME\samples\src
+CASTOR_HOME\samples\classes
+CASTOR_HOME\samples\schema
+CASTOR_HOME\samples\xml
+
+
2. +Create the PurchaseOrder.xsd from the following content and place the +file under CASTOR_HOME\samples\schema. This PurchaseOrder contains +the date, customer, line items and shipper child elements. Please +refer PurchaseOrder.xsd shown below,
+PurchaseOrder.xml +is also sown for more clarity.
+
+
3. +Then execute the command,
+castor_home\bin>SourceGen +-i castor_home\samples\schema\purchaseorder.xsd +
+-dest +castor_home\samples\src +
+
+
+
Then +you will see some warning like below, +
+
+
Warning: +A class name generation conflict has occured between complexType +'complexType:customer' and element '/purchase-order/customer'. Please +use a Binding file to solve this problem.Continue anyway [not +recommended] (y|n|?)
+
+
4. +Just abort the process by CTL+C. We need to do something more. This +warning is generated because '/purchase-order/customer' element name +and 'complexType:customer' type name are same, Castor can not create +two classes with same name. Similarly if you notice “line-item” +and “shipper” element name and type name are same. So it +is naming conflict for Castor.
+
+
5. +We will have to customize the generated class names for either types +or elements to avoid the naming conflict. It is possible with binding +xml file. Create the -bindingpo.xml with the following content and +place the same in CASTOR_HOME\samples\schema folder.
+
+
You +might have understood that if we keep the Element name and Type name +different in schema we need not do this overwork. But better to know +how to do it!!
+
+
6. +Now execute the sourceGen command with one additional option as shown +below,
+
+
castor_home\bin>SourceGen +-i castor_home\samples\schema\purchaseorder.xsd +
+-dest +castor_home\samples\src +
+–binding-file +castor_home\samples\schema\bindingpo.xml +
+
+
7. +You will see the source code is generated under +castor_home\samples\src. We can add the package in the source by +using –package option in SourceGen command line Or adding +following element in bindingpo.xml, Please do either one step to add +the package name. Let’s add “org.openuri.easypo” +package name. Please delete the generated code from +castor_home\samples\src first.
+
+
+
8. +Now please refer the generated code e.g. PurchaseOrder.java. This is +the Java Class generated for <purchase-order> element. It has +got the setter and getter methods for <date>, <customer>, +<line-item> and <shipper> elements as shown below,
+setDate(..), + getDate()
+setCustomer(..), + getCustomer()
+setShipper(..), + getShipper()
+addLineItem(..), + getLineItem()
+And +some additional methods like marshal(..) and +unmarshal(..).marshal(..) and unmarshal(..) methods can be used to +write the data in Object to xml file and read the data from the xml +file to Object. That’s all. Its great na!!
+
+
9. +If you notice <price> element of <line-item> and +<per-kg-rate> element of <shipper> are generated as java +type java.math.BigDecimal. Please refer LineItemType.java and +ShipperType.java, We may not want to use BigDecimal in our +application. We can change this default behavior and can customize +the java type to prime type “double” by specifying same +in binding file. Please change the bindingpo.xml as shown below, and +generate the code again.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
10. +Now you can see the price in LineItemType.java and perKgRate in +ShipperType.java has changed to double. +
+
+
Tip: +More details on binding file can be find at,
+http://castor.exolab.org/sourcegen.html#Binding-File
+
+
Schema +for binding file available at,
+http://castor.exolab.org/binding.xsd + +
+OR
+castor_home\doc\binding.xsd
++
+
+
+
+
+
+
1. +Now let’s write the code to create new PurchaseOrder.xml using +the generated code
+and +code to read the PurchaseOrder.xml.
+
+
Please +create the POCreator.java and POReader.java with below content and +place the same in castor_home\samples\src directory.
+
+
+
+
+
+
+
+
+
Now +let’s compile the generated source and our source and execute.
+
+
1. +Please create the build.bat file under castor_home\samples folder to +set the environment, compile and execute the code, from the below +content,
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
2. +castor-0.9.6-RC3-xml.jar is required for compiling the generated +code, and others are required to execute the code.
+
+
3. +You can see the PurchaseOrder.xml is created under +castor_home\samples\xml.
+
+
Castor +configuration can also be set from castor.properties file. This file +must be available in classpath. +
+e.g, +castor.properties file
+
+
#if +set true generated xml file will be well formated +
+org.exolab.castor.indent=true
+#if +set to true XML will be validated during marshalling and +un-marshaling
+org.exolab.castor.validation=true
+#if +set true debug mode is enabled +
+org.exolab.castor.debug=false
+
+
Tip: +For more details, please refer castor.properties present in +castor-0.9.6-RC3-xml.jar.
+
+
+
Many +times we need to handle the field value before get OR set methods. +Let’s see how it can be done with Castor.
+
+
1. +Our task is to put the formatted date in XML file. I guess you might +not have liked the format of date in PurchaseOrder.xml in above +example. So lets try to change the same in “"yyyy/MM/dd +HH:mm:ss"” format.
+
+
For +this we need do write the Class which implements interface +“org.exolab.castor.mapping.FieldHandler”. +
+
+
2. +Please add the following content in binding file.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
3. +Please create PODateHandler.java file from below content. Place the +same in castor_home\samples\src fodler.
+package
+ org.openuri.easypo; import
+ org.exolab.castor.mapping.FieldHandler; import
+ org.exolab.castor.mapping.ValidityException; import
+ java.text.ParseException; import
+ java.text.SimpleDateFormat; import
+ java.util.Date; public
+ class PODateHandler implements FieldHandler { private
+ static final String FORMAT = "yyyy/MM/dd HH:mm:ss"; public
+ PODateHandler() { super(); }//end
+ of PODateHandler()
+ public
+ Object getValue( Object object ) throws
+ IllegalStateException { PurchaseOrder
+ root = (PurchaseOrder)object; Date
+ value = root.getDate(); if
+ (value == null) return null;
+ SimpleDateFormat
+ formatter = new SimpleDateFormat(FORMAT); Date
+ date = (Date)value; return
+ formatter.format(date); }
+ //end of getValue() public
+ void setValue( Object object, Object value ) throws
+ IllegalStateException, IllegalArgumentException { PurchaseOrder
+ root = (PurchaseOrder)object;
+ SimpleDateFormat
+ formatter = new SimpleDateFormat(FORMAT); Date
+ date = null; try
+ { date
+ = formatter.parse((String)value); }
+ catch(ParseException
+ px) { throw
+ new IllegalArgumentException(px.getMessage()); }
+ root.setDate(date); }//end
+ of setValue() //just
+ add the below methods without botheration, they are present in
+ interface.
+ public
+ Object newInstance( Object parent ) throws
+ IllegalStateException { //--
+ Since it's marked as a string...just return null, //--
+ it's not needed. return
+ null; }//end
+ of newInstance() public
+ void resetValue( Object object ) throws
+ IllegalStateException, IllegalArgumentException {
+ ((PurchaseOrder)object).setDate(null); }//end
+ of resetValue() /**
+ @deprecated No longer supported */ public
+ void checkValidity( Object object ) throws
+ ValidityException, IllegalStateException { //
+ do nothing }//end
+ of checkValidity }//end
+ of PODateHandler()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Please +generate the source code again to make get effect of PODateHandler. +
+
+
4. +Please run the build.cmd to compile and execute the code.
+
+
5. +You can see the date has been input in new format. Castor by default +generates the attribute xsi:types=”java.lang.String” for +this date element. We have to live with this as of now. If we remove +the same, We can not execute the POReader. Keep this in mind.
+
+
Now +come on explore more on your own. +
+Castor + provides the ANT TASK to generate the source from schema, try using. + I am sorry I did not try it.
+I + guess GeneralizedFieldHandler is not supported for binding file. I + tried. Please refer link B. below. +
+
+
+
+
+
+
---------------------------XXXX +END OF DOCUMENT XXXX---------------------------
+
+
+
+
This document is intended to explain the Castor XML-binding (SourceGen tool) in brief, + so that developer can understand the usage of Castor SourceGen in short time.
+Castor is an open source data binding framework for Java. It consist of two + independent tools, namely Castor XML and Castor JDO.
+ +Castor JDO provides the means to persist the Java objects directly to DataBase. It maps the + Java Object to DataBase tables. One can avoid using JDBC API. Castor JDO is similar technology like + Sun's JDO but they actually they are very different.
This tutorial covers XML-binding alone.
+ +Castor binaries are available at Castor's downlod site.
+ +Let's download the latest version from here. Then, + click and save castor-0.9.6.zip.
+ +Unzip the zip file in some folder lets call this folder CASTOR_HOME.
+ +We have to do some manual work before running the SourceGen tool:
+ +


Do not bother about all options of command. We require very few to start with.
+ +Let's get into process. Let's generate source code from XML Schema using SourceGen + tool. Let's create some directories for execution of SourceGen tool.
+Please create the following directories:
+ +Create PurchaseOrder.xsd from the following content and place the file under + CASTOR_HOME\samples\schema. This PurchaseOrder contains the date, customer, line items and shipper child + elements. Please refer PurchaseOrder.xsd shown below, PurchaseOrder.xml is also shown for more + clarity.
+ +3. Then execute the command,
+ +
+castor_home\bin>SourceGen -i castor_home\samples\schema\purchaseorder.xsd \\
+ -dest castor_home\samples\src
+
+
+ IMG SRC="tutorial_html_m1aeec92f.gif" ALIGN="LEFT" HSPACE="12"/>
Then you will see some warning like below,
+ +Warning: A class name generation conflict has occured between complexType
+ 'complexType:customer' and element '/purchase-order/customer'. Please
+ use a Binding file to solve this problem.Continue anyway [not recommended] (y|n|?)
Just abort the process by CTL+C. We need to do something more. This warning is generated + because '/purchase-order/customer' element name and 'complexType:customer' type name are + same, Castor can not create two classes with same name. Similarly if you notice + "line-item" and "shipper" element name and type name are same. + So it is naming conflict for Castor.
+ +We will have to customize the generated class names for either types or elements to avoid + the naming conflict. It is possible with binding xml file. Create the -bindingpo.xml with the + following content and place the same in CASTOR_HOME\samples\schema folder.
+ +
You might have understood that if we keep the Element name and Type name different in + schema we need not do this overwork. But better to know how to do it!!
+ +Now execute the sourceGen command with one additional option as shown below,
+ +You will see the source code is generated under castor_home\samples\src. We can add the + package in the source by using -package option in SourceGen command line Or adding + following element in bindingpo.xml, Please do either one step to add the package name. + Let"s add "org.openuri.easypo" package name. Please delete the generated + code from castor_home\samples\src first.
+ +
Now please refer to the generated code e.g. PurchaseOrder.java. This is the Java Class + generated for <purchase-order> element. It has got the setter and getter methods + for <date>, <customer>, <line-item> and <shipper> elements as + shown below:
+ +And some additional methods like marshal(..) and unmarshal(..).marshal(..) and + unmarshal(..) methods can be used to write the data in Object to xml file and read + the data from the xml file to Object. That"s all.
+ +If you notice <price> element of <line-item> and <per-kg-rate> + element of <shipper> are generated as java type java.math.BigDecimal. Please + refer LineItemType.java and ShipperType.java, We may not want to use BigDecimal + in our application. We can change this default behavior and can customize + the java type to prime type "double" by specifying same + in binding file. Please change the bindingpo.xml as shown below, and generate + the code again.
+ +
Now you can see the price in LineItemType.java and perKgRate in ShipperType.java + has changed to double.
+ +More detail on the binding file can be found + here, + and the XML chema for the binding file is available + here.
+ +Now let?s write the code to create new PurchaseOrder.xml using the generated code + and code to read the PurchaseOrder.xml.
+ +Please create the POCreator.java and POReader.java with below content and place the + same in castor_home\samples\src directory.
+ +

Now let?s compile the generated source and our source and execute.
+ +Please create the build.bat file under castor_home\samples folder to set the + environment, compile and execute the code, from the below content,
+ +
castor-0.9.6-RC3-xml.jar is required for compiling the generated code, and + others are required to execute the code.
+ +You can see the PurchaseOrder.xml is created under castor_home\samples\xml.
+ +Castor configuration can also be set from castor.properties file. This file must + be available in classpath.
+ +
+#if set true generated xml file will be well formated
+org.exolab.castor.indent=true
+#if set to true XML will be validated during marshalling and un-marshaling
+org.exolab.castor.validation=true
+#if set true debug mode is enabled
+org.exolab.castor.debug=false
+
+
+ Tip:For more details, please refer castor.properties present in castor-0.9.6-RC3-xml.jar.
+ +Many times we need to handle the field value before get OR set methods. Let?s + see how it can be done with Castor.
+ +Our task is to put the formatted date in XML file. I guess you might not have + liked the format of date in PurchaseOrder.xml in above example. So lets try + to change the same in ?"yyyy/MM/dd HH:mm:ss"? format.
+ +For this we need do write the Class which implements interface + ?org.exolab.castor.mapping.FieldHandler?.
+ +Please add the following content in binding file.
+ +
Please create PODateHandler.java file from below content. Place the same in + castor_home\samples\src fodler.
+ +
+package org.openuri.easypo;
+
+import org.exolab.castor.mapping.FieldHandler;
+import org.exolab.castor.mapping.ValidityException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+public class PODateHandler implements FieldHandler {
+
+ private static final String FORMAT = "yyyy/MM/dd HH:mm:ss";
+
+ public PODateHandler() {
+ super();
+ }//end of PODateHandler()
+
+ public Object getValue( Object object )
+ throws IllegalStateException
+ {
+ PurchaseOrder root = (PurchaseOrder)object;
+ Date value = root.getDate();
+ if (value == null) return null;
+ SimpleDateFormat formatter = new SimpleDateFormat(FORMAT);
+ Date date = (Date)value;
+ return formatter.format(date);
+ } //end of getValue()
+
+ public void setValue( Object object, Object value )
+ throws IllegalStateException, IllegalArgumentException
+ {
+ PurchaseOrder root = (PurchaseOrder)object;
+ SimpleDateFormat formatter = new SimpleDateFormat(FORMAT);
+ Date date = null;
+ try {
+ date = formatter.parse((String)value);
+ }
+ catch(ParseException px) {
+ throw new IllegalArgumentException(px.getMessage());
+ }
+ root.setDate(date);
+ }//end of setValue()
+
+ //just add the below methods without botheration, they are present in interface.
+ public Object newInstance( Object parent )
+ throws IllegalStateException
+ {
+ //-- Since it's marked as a string...just return null,
+ //-- it's not needed.
+ return null;
+ }//end of newInstance()
+
+ public void resetValue( Object object )
+ throws IllegalStateException, IllegalArgumentException
+ {
+ ((PurchaseOrder)object).setDate(null);
+ }//end of resetValue()
+
+ /** @deprecated No longer supported */
+ public void checkValidity( Object object )
+ throws ValidityException, IllegalStateException
+ {
+ // do nothing
+ }//end of checkValidity
+}//endof PODateHandler()
+
+
+ Please generate the source code again to make get effect of PODateHandler.
+ +Please run the build.cmd to compile and execute the code.
+ +You can see the date has been input in new format. Castor by default generates + the attribute xsi:types="java.lang.String" for this date element. We have + to live with this as of now. If we remove the same, We can not execute the POReader. + Keep this in mind.
+ +Now come on explore more on your own.
+ +