`
orange5458
  • 浏览: 347491 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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" class="com.siyuan.castor.handler.ConfigureDateHandler">
		<param name="date-format" 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 string
		location="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文件

 

分享到:
评论
1 楼 孙大圣123 2016-03-29  
大神,你分享的castor dtd文件中没有field-handler元素,是因为版本问题么?

相关推荐

    Castor Plug-in for Eclipse 图解使用教程

    Castor Plug-in for Eclipse 插件的使用总结,全部以截图的方式一步一步向下引导。从安装开始,到使用其产生类。这是我的学习文档,写的比较的简单,多是一些图。目的就是为了让自己以后忘了的时候,能够一眼就看懂...

    castor-1.2系列.rar

    castor-1.2.jar castor-1.2-anttasks.jar castor-1.2-codegen.jar castor-1.2-ddlgen.jar castor-1.2-jdo.jar castor-1.2-xml-schema.jar castor-1.2-xml.jar

    castor-1.2-xml-schema castor转化XML需要的jar包

    Castor 项目采用 BSD 类型的证书,因此可在任何类型的应用程序(包括完整版权的项目)中使用。 Castor 实际上仅仅有 XML 数据绑定,它还支持 SQL 和 LDAP 绑定

    castor-1.0-xml.jar

    org.castor.util.IdentityMap org.castor.util.IdentitySet org.exolab.javasource.JEnum org.exolab.javasource.JType org.exolab.castor.util.List org.exolab.javasource.Header org.exolab.javasource.JClass ...

    castor-xml-1.3.2.jar

    Unmarshall与Marshall使用的castor-xml-1.3.2.jar包

    castor-core-1.3.2

    Unmarshall与Marshall使用的jar包

    castor-1.2-examples

    castor-1.2-examples

    castor-1.2.zip

    castor-1.2.zip

    castor-1.2-doc.zip

    castor-1.2-doc.zip

    castor-0.9.5.2.jar

    castor-0.9.5.2.jar

    castor-0.9.9.1.jar

    Castor的jar包 对XML的序列号更容易些!

    castor实现xsd生成javabean所需jar

    java -classpath D:\xsd/castor-1.2-anttasks.jar;D:\xsd/castor-1.2-codegen.jar;D:\xsd/commons-logging-1.1.jar;D:\xsd/castor-1.2-ddlgen.jar;D:\xsd/castor-1.2-jdo.jar;D:\xsd/castor-1.2-xml-schema.jar;D:\...

    Java 对象XML解析器castor-0.9

    要实现的是O/R映射功能。它主要API和数据接口为:JDO-like, SQL, OQL, JDBC, LDAP, XML, DSML。它支持分布式目录事务处理和时间;提供处理XML、Directory、XADirectory的类库,提供从XML到JAVA类的转换机制。

    castor-0.9.5.3-xml.jar

    castor-0.9.5.3-xml.jar,java和xml互相转换所使用的JAR

    castor1-2(java and xml 数据绑定过程所需数据包)

    利用该包内提供的java类,可以进行java读取解析xml文件,并对文件进行操作

    castor-1.2-codegen castor代码生成需要的jar包

    Castor 项目采用 BSD 类型的证书,因此可在任何类型的应用程序(包括完整版权的项目)中使用。 Castor 实际上仅仅有 XML 数据绑定,它还支持 SQL 和 LDAP 绑定

    castor-1.2解析XML

    是个不错的XML解析工具。...二、作为数据存储文件。 其中作为数据存储文件有很多优点,比如,数据更加规范,数据校验等。 2、这个工具的功能:能够把xml文件存储的数据和pojo对象进行映射。我们暂且把这种叫做:OXM。

    castor R/M映射神器

    Castor是ExoLab Group下面的一个开放源代码的项目,它主要实现的是O/R映射功能。它主要API和数据接口为:JDO-like, SQL, OQL, JDBC, LDAP, XML, DSML。它支持分布式目录事务处理和时间;提供处理XML、Directory、...

    com.springsource.org.exolab.castor.xml-1.2.0.jar

    jar包,官方版本,自测可用

Global site tag (gtag.js) - Google Analytics