import java.io.IOException;
import java.io.StringReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.codehaus.jackson.map.util.BeanUtil;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.dom.DOMDocumentFactory;
import org.dom4j.dom.DOMElement;
import org.dom4j.io.SAXReader;
/**
* @Description:
* class description
* Revision History:
* DATE AUTHOR VERSION DESCRIPTION
*
* 用于pojo 转换为xml字符串 的工具类
* @createDate 2013-10-14
* @since gdcams V01.00.000
*/
public class XmlUtils {
@SuppressWarnings("rawtypes")
public static String pojoToXml(Object obj,String rootName) throws SecurityException, NoSuchFieldException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Document document=DOMDocumentFactory.getInstance().createDocument();
if(obj!=null ){
if(isArray(obj)){
Element root=getElement(obj, rootName);
for(Object pojo:(Object[])obj){
root.add(pojoToElelment(pojo,null));
}
document.setRootElement(root);
}else if(isCollection(obj)){
Element root=getElement(obj, rootName);
for(Object pojo:(Collection) obj){
root.add(pojoToElelment(pojo,null));
}
document.setRootElement(root);
}else{
document.setRootElement(pojoToElelment(obj,rootName));
}
}
return document.asXML();
}
/**
* @param xml
* @param pojoClass
* @param name
* @return
* @throws DocumentException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws NoSuchFieldException
* @throws SecurityException
*/
@SuppressWarnings("unchecked")
public static <T> List<T> xmlToPojo(String xml,Class<T> pojoClass,String name) throws DocumentException, InstantiationException, IllegalAccessException, SecurityException, NoSuchFieldException, InvocationTargetException, NoSuchMethodException {
SAXReader saxReader=new SAXReader();
Document document=saxReader.read(new StringReader(xml));
name=getName(pojoClass, name);
if(document.getRootElement().getName().equals(name)){
List<T> result=new ArrayList<T>();
result.add(elementToPojo(document.getRootElement(), pojoClass));
return result;
}
List<Element> data=document.getRootElement().elements(name);
List<T> result=new ArrayList<T>();
for(Element ele:data){
result.add(elementToPojo(ele, pojoClass));
}
return result;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static <T> T elementToPojo(Element ele,Class<T> pojoClass) throws InstantiationException, IllegalAccessException, SecurityException, NoSuchFieldException, InvocationTargetException, NoSuchMethodException{
if(ele==null)
return null;
T pojo=pojoClass.newInstance();
for(String name : getPropertyNames(pojo)){
Field field=pojoClass.getDeclaredField(name);
Class cls=field.getType();
String pName=getName(cls, name);
Annotation ann=null;
if(field.getAnnotation(Value.class)!=null){
Object value=ConvertUtils.convert(ele.getText(), cls);
PropertyUtils.setProperty(pojo, name,value);
}else if(field.getAnnotation(Attribute.class) !=null){
org.dom4j.Attribute atr=ele.attribute(name);
if(atr!=null){
Object value=ConvertUtils.convert(atr.getValue(), cls);
PropertyUtils.setProperty(pojo, name,value);
}
}else if((ann=field.getAnnotation(CollectionOrArray.class)) !=null){
Element ee=ele.element(pName) ;
if(ee!=null){
Class _cls=((CollectionOrArray)ann).cls();
List<Element> es=ee.elements(getName(_cls,""));
List data=new ArrayList();
for(Element e: es){
data.add(elementToPojo(e, _cls));
}
if(cls.isArray()){
PropertyUtils.setProperty(pojo, name,data.toArray());
}else{
PropertyUtils.setProperty(pojo, name,data);
}
}
}else if( (ann=field.getAnnotation(ValueList.class)) !=null){
Class _cls=((ValueList)ann).cls();
List data=new ArrayList();
List<Element> es=ele.elements(getName(_cls,""));
for(Element e: es){
data.add(elementToPojo(e, _cls));
}
PropertyUtils.setProperty(pojo, name,data);
}else if(isBaseType(cls)){
Object value=ConvertUtils.convert(ele.elementText(name), cls);
PropertyUtils.setProperty(pojo, name,value);
}else {
Object value=elementToPojo(ele.element(pName), cls);
PropertyUtils.setProperty(pojo, name,value);
}
}
return pojo;
}
/**具体的pojo 转换为xml 元素
* @param pojo
* @param pName
* @return
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
@SuppressWarnings("rawtypes")
private static Element pojoToElelment(Object pojo,String pName) throws SecurityException, NoSuchFieldException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{
if(pojo==null )
return null;
pName=getName(pojo,pName);
Class cls=pojo.getClass(); //获取元素类型
Element ele = getElement(pojo,pName); //获取元素
for(String name : getPropertyNames(pojo)){ //遍历所有属性
Object _pojo=PropertyUtils.getProperty(pojo, name);
Field field=cls.getDeclaredField(name);
if(_pojo==null ){ //如果该属性为空 不设置此属性相关信息
continue;
}else if( field.getAnnotation(Disabled.class) !=null){//如果该属性设置注解 Disabled 不设置此属性相关信息
continue;
}else if( field.getAnnotation(Value.class) !=null ){//注解Value 转换为 text
ele.setText(String.valueOf(_pojo));
}else if( field.getAnnotation(Attribute.class) !=null ){
ele.addAttribute(name,String.valueOf(_pojo));
}else if( field.getAnnotation(ValueList.class) !=null){
for(Object obj:(Collection)_pojo){
addElement(ele,pojoToElelment(obj,null));
}
}else if( field.getAnnotation(CollectionOrArray.class) !=null){
Element _ele=getElement(_pojo, name);
addElement(ele,_ele);
if(isArray(_pojo)){
for(Object obj:(Object[])_pojo){
addElement(_ele,pojoToElelment(obj,null));
}
}else if(isCollection(_pojo)){
for(Object obj:(Collection)_pojo){
addElement(_ele,pojoToElelment(obj,null));
}
}
}else if(isBaseType(_pojo)){
addElement(ele,getElement(_pojo, name));
} else{
addElement(ele,pojoToElelment(_pojo,name));
}
}
return ele;
}
private static String getName(Object pojo,String pName){
return getName(pojo.getClass(),pName);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
private static String getName(Class pojoClass,String pName){
if(pName==null||pName.trim().length()==0){//不设置元素名称 取类名为默认名称
Annotation ann=pojoClass.getAnnotation(Name.class);
Name name=(Name)ann;
if(name!=null && name.value()!=null && name.value().trim().length()!=0){
return name.value();
}
return pojoClass.getSimpleName();
}
return pName;
}
/**元素增加子元素 增加了为空判断 使其不会报错
* @param parent
* @param child
* @return
*/
private static Element addElement (Element parent,Element child){
if(parent==null )
return parent;
if(child==null)
return parent;
parent.add(child);
return parent;
}
/**判断对象是否基本类型 (包括 number string date)
* @param pojo
* @return
*/
public static boolean isBaseType(Object pojo){
if(pojo==null)
return false;
return pojo.getClass().isPrimitive() || pojo instanceof Number || pojo instanceof String || pojo instanceof Date;
}
@SuppressWarnings("rawtypes")
public static boolean isBaseType(Class pojoClass){
if(pojoClass==null)
return false;
return pojoClass.isPrimitive() || Number.class.equals(pojoClass.getSuperclass()) || String.class.equals(pojoClass) || Date.class.equals(pojoClass);
}
/**判断对象是否是集合或数组类型
* @param pojo
* @return
*/
public static boolean isCollectionOrArray(Object pojo){
if(pojo==null)
return false;
return isCollection(pojo) || isArray(pojo);
}
/**判断对象是否是集合类型
* @param pojo
* @return
*/
public static boolean isCollection(Object pojo){
if(pojo==null)
return false;
return (pojo instanceof Collection) ;
}
/**判断对象是否是数组类型
* @param pojo
* @return
*/
public static boolean isArray(Object pojo){
if(pojo==null)
return false;
return pojo.getClass().isArray() ;
}
/**根据pojo 与 名称 创建xml元素 不设置元素名称 取类名为默认名称
* @param pojo
* @param name
* @return
*/
private static Element getElement(Object pojo,String name){
if(pojo==null)
return null;
if(name==null)
name=pojo.getClass().getSimpleName();
Element ele=new DOMElement(name);
if(isBaseType(pojo)){
if(pojo!=null)
ele.setText(String.valueOf(pojo));
}
return ele;
}
public static java.util.Map describe(Object pojo){
if(pojo==null)
return new HashMap(0);
try {
Map<String,Object> map= BeanUtils.describe(pojo);
map.remove("class");
return map;
} catch (Exception e) {
return new HashMap(0);
}
}
public static Collection<String> getPropertyNames(Object pojo){
return describe(pojo).keySet();
}
}
public @interface Attribute {
}
public @interface CollectionOrArray {
Class cls();
}
public @interface Disabled {
}
public @interface Name {
String value();
}
public @interface Value {
}
public @interface ValueList {
Class cls();
}