Discussions

EJB design: XML Binding with Castor

  1. XML Binding with Castor (1 messages)

    I'm trying to unmarshall an XML file:

    <?xml version="1.0" encoding="UTF-8"?>
    <billing nbr="1">
    <name>John Smith </name>
    <phone>416-429-8888</phone>
    <dob>1960-12-12</dob>
    </billing>

     into an Java object. But the output I am getting looks like this:



    As I need the date in "yyyy-MM-dd" format, I implemented the class DateHandler as follows:
    <!DOCTYPE databases PUBLIC
      "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
      "http://castor.exolab.org/mapping.dtd">
    <mapping>
      <class name="Person" auto-complete="true">
      <map-to xml="dob"/>
        <field name="dob" handler="DateHandler" type = "string" />
       </class>
    </mapping>

    and defaults handler source code is:
    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.GregorianCalendar;

    import org.exolab.castor.mapping.AbstractFieldHandler;
    import org.exolab.castor.mapping.ExtendedFieldHandler;
    import org.exolab.castor.mapping.FieldDescriptor;
    import org.exolab.castor.mapping.FieldHandler;
    import org.exolab.castor.mapping.GeneralizedFieldHandler;

    public class DateHandler extends GeneralizedFieldHandler {

    public final DateFormat format = new SimpleDateFormat("yyyy-MM-dd");

    public Object convertUponGet(Object value) {
    //System.out.println("A3");
    //System.out.println(value);
    //System.out.println(format.format(value));
    return format.format(value);
    }

    public Object convertUponSet (Object value) {
    //System.out.println("A1");
    String dateStr = (String) value;
    try {
    //System.out.println("A2");
    Date date1 = (Date) format.parse(dateStr);
    //System.out.println("date1 " + date1);
    //System.out.println(format.format(date1));
    return date1;
    } catch (ParseException e) {
    throw new RuntimeException(e);
    }
    }

    public Class getFieldType() {
    return java.util.Date.class;
    }
    }
  2. XML Binding with Castor[ Go to top ]

    hi,

    check out the documentation from castor mailing list on writing custom field handlers..

    -----------------------
    And the section 6.2 Create your own FieldHandler may include an example of the derivation of GeneralizedFieldHandler class.
    ---------------------------
    &lta name="6.2-Create-your-own-FieldHandler"&gt&lth3&gt6.2 Create your own FieldHandler&lt/h3&gt&lt/a&gt
                 
    &ltp&gt&ltspan class="bodyGrey"&gtSometimes to handle complex situations you'll need to create your own FieldHandler. Normally a FieldHandler deals with a specific class and field, however generic, reusable FieldHandlers can also be created by extending org.exolab.castor.mapping.GeneralizedFieldHandler (be sure to a Castor version &gt 0.9.4.1 !) or
    org.exolab.castor.mapping.AbstractFieldHandler.
    The FieldHandler can be specified on the &ltfield&gt element. &lt/span&gt&lt/p&gt
    &ltp&gt&ltspan class="bodyGrey"&gtLet's imagine one need to define a specialized date handler if the date format of the Castor's default date handler is not appropriate.
    One could define a new specialized date handler like the MMddYYYYDateHandler below.&lt/span&gt&lt/p&gt
                &lttable border="1" cellpadding="4"&gt
                &lttr&gt &ltth&gt MMddYYYYDateHandler.java &lt/th&gt &lt/tr&gt
                &lttr&gt &lttd bgcolor="#CCCCCC"&gt&ltspan class="bodyGrey" bgcolor="#CCCCCC"&gt
                 &ltspan class="bodyBlack"&gt
                &ltpre&gt
    import org.exolab.castor.mapping.GeneralizedFieldHandler;
    import java.text.SimpleDateFormat;
    import java.text.ParsePosition;
    public class MMddYYYYDateHandler extends GeneralizedFieldHandler {
      private static final SimpleDateFormat DateFormatter = new SimpleDateFormat("MM:dd:yyyy");
      static {
        DateFormatter.setLenient(false);
      }
      /**
       * This method is used to convert the value (from java.util.Date
       * to String) when the getValue method is called.
       * The getValue method will obtain the actual field value
       * from given 'parent' object. This convert method is then invoked
       * with the field's value. The value returned from this
       * method will be the actual value returned by getValue method.
       *
       * @param value the object value to convert after performing a get
       * operation
       * @return the converted value.
       */
      public Object convertUponGet(Object value) {
        return DateFormatter.format((java.util.Date) value);
      }


         
      /**
       * Returns the class type for the field that this GeneralizedFieldHandler
       * converts to and from. This should be the type that is used in the
       * object model.
       *
       * @return the class type of of the field
       */
      public Class getFieldType() {
        return java.util.Date.class;
      }
      /**
       * This method is used to convert the value (from String to
       * java.util.Date) when the setValue method is called.
       * The setValue method will call this method to obtain
       * the converted value. The converted value will then be used as
       * the value to set for the field.
       *
       * @param value the object value to convert before performing a set
       * operation
       * @return the converted value.
       */
      public Object convertUponSet(Object value) {
        return DateFormatter.parse((String) value, new ParsePosition(0));
      }
    }
    &lt/pre&gt&lt/span&gt &lt/span&gt&lt/td&gt &lt/tr&gt &lt/table&gt


    &ltp&gt&ltspan class="bodyGrey"&gtFor using this handler, a &ltfield&gt element should be defined like :
                    &ltspan class="bodyBlack"&gt&ltpre&gt
              &ltfield name="birthDate" type="string" handler="MMddYYYDateHandler"/&gt
              &lt/pre&gt&lt/span&gt
    The &ltspan class="bodyBlack"&gttype="string"&lt/span&gt defines the type that
    the MMddYYYDateHandler is expecting to receive. This special FieldHandler will convert the XML/string value into a Java/Date value
    and vice versa.&lt/span&gt&lt/p&gt
    &ltp&gt&ltspan class="bodyGrey"&gt
    The convertUponGet method is only be called during marshalling and validation
    (note that you can disable validation using [marshaller#setValidation(false)]),
    so the value will always be the instance from the object model and not
    from the XML.&ltbr&gt&ltbr&gt
    The convertUponGet method is also used when
    comparing values for reuseable objects for unmarshalling.
    If you are unmarshalling and you have setReuseObjects = true, simple
    values are compared to see if the value needs to be set, so an
    additional call might be done then as well.&ltbr&gt&ltbr&gt


    The convertUponSet method is only used during unmarshalling.
    The value from the XML file will be passed into convertUponSet during
    unmarshalling.
    &lt/span&gt&lt/p&gt



    ------------


    Bhagvan K
    http://www.architectcorner.com