读书人

Castor (二) - 自定义映射

发布时间: 2012-07-26 12:01:08 作者: rapoo

Castor (二) -- 自定义映射

1.概述

?

Castor的自定义映射关系通过XML设置。

主要作用有

1)改变映射位置(node): attribute, element, text

2)改变映射名字(name...): attributeName, elementTagName

3)改变层级关系(location)

4)改变输出格式(handler): dateFormat...

5)改变属性获取和设置方式(get/setMethod, direct="true")

6)隐藏属性(auto-complete="true", transient="true")

?

2.源码

?

?Address.java Student.java 详见 Castor (一) -- 默认绑定?

?

LocalDateHandler.java

?

package com.siyuan.castor.handler;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import org.exolab.castor.mapping.FieldHandler;import org.exolab.castor.mapping.ValidityException;import com.siyuan.castor.Student;public class LocalDateHandler implements FieldHandler {private static final String LOCAL_DATE_FORMAT = "yyyy-MM-dd";public void checkValidity(Object object) throws ValidityException,IllegalStateException {}/** * @param object the owner of the field */public Object getValue(Object object) throws IllegalStateException {if (object instanceof Student) {Date date = ((Student) object).getBirthday();if (date != null) {DateFormat dateFmt = new SimpleDateFormat(LOCAL_DATE_FORMAT);return dateFmt.format(date);} else {return null;}}return null;}public Object newInstance(Object arg0) throws IllegalStateException {return null;}public void resetValue(Object arg0) throws IllegalStateException,IllegalArgumentException {}/** * @param object the owner of the field * @param dateString the field value in the xml source file */public void setValue(Object object, Object dateString)throws IllegalStateException, IllegalArgumentException {if (object instanceof Student) {DateFormat dateFmt = new SimpleDateFormat(LOCAL_DATE_FORMAT);try {Date date = dateFmt.parse((String) dateString);((Student) object).setBirthday(date);} catch (ParseException e) {throw new IllegalArgumentException(e);}}}}

?

?DivDateHandler.java

?

package com.siyuan.castor.handler;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import org.exolab.castor.mapping.GeneralizedFieldHandler;public class DivDateHandler extends GeneralizedFieldHandler {private static final String LOCAL_DATE_FORMAT = "yyyy-MM-dd";/** * automatically supports iterating over the items of a collection  * and passing them one-by-one to the convertUponGet *  * setCollectionIteration : could modify it */public DivDateHandler() {setCollectionIteration(false);}/** * @Override * @param value the object value to convert after                 *  performing a get operation * @return the converted value. */public Object convertUponGet(Object value) {if (value == null) return null;DateFormat dateFmt = new SimpleDateFormat(LOCAL_DATE_FORMAT);return dateFmt.format((Date) value);}/** * @Override * @param value the object value to convert before                 *  performing a set operation                 * @return the converted value. */public Object convertUponSet(Object value) {if (value == null) return null;DateFormat dateFmt = new SimpleDateFormat(LOCAL_DATE_FORMAT);Date date = null;try {date = dateFmt.parse((String) value);} catch (ParseException e) {throw new IllegalArgumentException(e);}return date;}/** * @Override * 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 Date.class;}}

?

ConfigureDateHandler.java

?

package com.siyuan.castor.handler;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Properties;import org.exolab.castor.mapping.ConfigurableFieldHandler;import org.exolab.castor.mapping.FieldHandler;import org.exolab.castor.mapping.ValidityException;import com.siyuan.castor.Student;public class ConfigureDateHandler implements FieldHandler,ConfigurableFieldHandler {private static final String DATE_FORMAT_PARAM_NAME = "date-format";private DateFormat dateFormat;public void checkValidity(Object arg0) throws ValidityException,IllegalStateException {}public Object getValue(Object object) throws IllegalStateException {if (object instanceof Student) {Date date = ((Student) object).getBirthday();if (date != null) {return dateFormat.format(date);} else {return null;}}return null;}public Object newInstance(Object arg0) throws IllegalStateException {return null;}public void resetValue(Object arg0) throws IllegalStateException,IllegalArgumentException {}public void setValue(Object object, Object dateString)throws IllegalStateException, IllegalArgumentException {if (object instanceof Student) {try {Date date = dateFormat.parse((String) dateString);((Student) object).setBirthday(date);} catch (ParseException e) {throw new IllegalArgumentException(e);}}}/** * @param params configure information in the xml */public void setConfiguration(Properties params) throws ValidityException {String pattern = params.getProperty(DATE_FORMAT_PARAM_NAME);if (pattern == null)throw new ValidityException("Required parameter \"" + DATE_FORMAT_PARAM_NAME + "\" is missing");try {dateFormat = new SimpleDateFormat(pattern);} catch (IllegalArgumentException e) {throw new ValidityException("Pattern \"" + pattern + "\" is not a valid date format.");}}}

?

Student.cst.xml

?

<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Object Mapping DTD Version 1.0//EN""http://castor.exolab.org/mapping.dtd"><mapping><description>Used for com.siyuan.castor.Student</description><!-- <include href=""></include> --> <!-- <field-handler /> --><field-handler name="localDateHandler" value="yyyy-MM-dd"/></field-handler><!-- verify-constructable="false" used with the set-method="%1-9%"make it able to omit the no-parameter constructor --><class name="com.siyuan.castor.Student" auto-complete="true"><description>com.siyuan.castor.Student</description><map-to xml="Person"/><!-- type="java.lang.String" handler="" required="true" direct="true" transient="true" set-method="%1-9%" get-method="getName" type="string" //can not omit the no-parameter constructor--><field name="name"><description>property name</description>      <bind-xml name="stuName" node="attribute"/>   </field><!-- type="string" handler="com.siyuan.castor.handler.DivDateHandler" type="string" handler="com.siyuan.castor.handler.LocalDateHandler" //type could not be omitted and must be stringlocation="birthday/birthday1"--><field name="birthday" type="string" handler="localDateHandler">      <bind-xml name="birth" node="attribute"/>   </field>   <field name="friends" collection="set" type="com.siyuan.castor.Student" get-method="getFriends" set-method="addFriend">      <bind-xml name="friend" node="element"/>   </field>      <field name="subjects" collection="arraylist" type="string" get-method="getSubjects" set-method="addSubject">      <bind-xml name="subjects" node="element"/>   </field>      <field name="teachers" collection="map">      <bind-xml name="teachers" node="element">      <class name="org.exolab.castor.mapping.MapItem">      <field name="key" type="java.lang.String">      <bind-xml name="name" node="attribute"/>      </field>      <field name="value" type="java.lang.String">      <bind-xml name="subject" node="attribute"/>      </field>      </class>      </bind-xml>   </field>   </class><!-- not used for XML mapping<key-generator /> --></mapping> 

?

CastorDIYTest.java

?

package com.siyuan.castor.test;import java.io.IOException;import java.io.InputStream;import java.io.StringReader;import java.io.StringWriter;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Arrays;import java.util.Date;import java.util.HashMap;import java.util.HashSet;import java.util.List;import java.util.Map;import java.util.Set;import org.exolab.castor.mapping.Mapping;import org.exolab.castor.mapping.MappingException;import org.exolab.castor.xml.MarshalException;import org.exolab.castor.xml.Marshaller;import org.exolab.castor.xml.Unmarshaller;import org.exolab.castor.xml.ValidationException;import org.xml.sax.InputSource;import com.siyuan.castor.Address;import com.siyuan.castor.Student;public class CastorDIYTest {/** * @param args * @throws ValidationException  * @throws MarshalException  * @throws ValidationException  * @throws MarshalException  */public static void main(String[] args) throws MarshalException, ValidationException{Student stuSrc = new Student();stuSrc.setAge(22);stuSrc.setName("SingleMan");stuSrc.setMale(true);Address address = new Address();address.setStreet("Renmin Road");stuSrc.setAddress(address);DateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd");try {Date birthday = dateFmt.parse("1988-11-21");stuSrc.setBirthday(birthday);} catch (ParseException e) {e.printStackTrace();}Student girl = new Student();girl.setAge(20);stuSrc.setGirlFriend(girl);Set<Student> students = new HashSet<Student>();Student stu1 = new Student();stu1.setAge(21);students.add(stu1);Student stu2 = new Student();stu2.setAge(23);students.add(stu2);stuSrc.addFriend(stu1);stuSrc.addFriend(stu2);stuSrc.addSubject("English");stuSrc.addSubject("Math");stuSrc.addSubject("Chinese");Map<String, String> teachers = new HashMap<String, String>();teachers.put("English", "teacher a");teachers.put("Math", "teacher b");teachers.put("Chinese", "teacher c");stuSrc.setTeachers(teachers);Mapping mapping = new Mapping();try {InputStream mappingFileIn = Student.class.getResourceAsStream("/com/siyuan/castor/Student.cst.xml");mapping.loadMapping(new InputSource(mappingFileIn));StringWriter result = new StringWriter();Marshaller marshaller = new Marshaller();marshaller.setMapping(mapping);marshaller.setWriter(result);marshaller.marshal(stuSrc);System.out.println(result);System.out.println("=================================================================");Unmarshaller unmarshaller = new Unmarshaller(mapping);Student stuDist = (Student) unmarshaller.unmarshal(new StringReader(result.toString()));System.out.println(stuDist);} catch (MappingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}

?

3. 输出结果

?

<?xml version="1.0" encoding="UTF-8"?><Person stuName="SingleMan" birth="1988-11-21" male="true" age="22"><friend male="false" age="23"/><friend male="false" age="21"/><subjects>English</subjects><subjects>Math</subjects><subjects>Chinese</subjects><teachers name="English" subject="teacher a"/><teachers name="Math" subject="teacher b"/><teachers name="Chinese" subject="teacher c"/><girl-friend male="false" age="20"/><address><street>Renmin Road</street></address></Person>=================================================================Student[name=SingleMan,age=22,male=true,birthday=Mon Nov 21 00:00:00 CST 1988,address=Address[street=Renmin Road],girlFriend=Student[name=null,age=20,male=false,birthday=null,address=null,girlFriend=null,friends=[],subjects=[],teachers={}],friends=[Student[name=null,age=23,male=false,birthday=null,address=null,girlFriend=null,friends=[],subjects=[],teachers={}], Student[name=null,age=21,male=false,birthday=null,address=null,girlFriend=null,friends=[],subjects=[],teachers={}]],subjects=[English, Math, Chinese],teachers={English=teacher a, Math=teacher b, Chinese=teacher c}]

?

?

4.参考资料

?

http://www.castor.org/xml-mapping.html

?

http://www.castor.org/xml-fieldhandlers.html#Use-ConfigurableFieldHandler-for-more-flexibility

?

附件为mapping文件对应的DTD和XSD文件

?

读书人网 >开源软件

热点推荐