package com.flysoft.fuse4j.support.xbean;/*** IBeanToXml 接口實(shí)現(xiàn)將任意對(duì)象轉(zhuǎn)換為數(shù)據(jù)島或XML的方法。* flysoft company.* @author Dingli.* 2008 Apr 22, 2008 5:56:26 PM*/public interface IBeanToXml{/*** 將一個(gè)類解析成 XML 格式。* @param object 要進(jìn)行解析的類。* @param encoding 使用的字符集。* @return 返回解析后的 XML 字符串。*/public String parseBeanToXml(Object object, String encoding);/*** 將一個(gè)類解析成數(shù)據(jù)島格式。* @param id 數(shù)據(jù)島的ID。* @param object 要解析的對(duì)象。* @param encoding 使用的字符集。* @return 返回解析后的數(shù)據(jù)島字符串。*/public String parseBeanToDataIsland(String id, Object object, String encoding);}
package com.flysoft.fuse4j.support.xbean;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.math.BigDecimal;import java.math.BigInteger;import java.text.SimpleDateFormat;import java.util.Collection;import java.util.Date;import java.util.Iterator;import java.util.Map;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.dom4j.Document;import org.dom4j.DocumentFactory;import org.dom4j.Element;/*** BeanToXmlParser 類實(shí)現(xiàn)將任意對(duì)象轉(zhuǎn)換為數(shù)據(jù)島或XML,但對(duì)象不能循環(huán)引用自身。* flysoft company.* @author Dingli.* 2008 Apr 22, 2008 5:41:07 PM*/public class BeanToXmlParser implements IBeanToXml{//log4j日志記錄器。private static final Log logger = LogFactory.getLog(BeanToXmlParser.class);//簡(jiǎn)單日期格式化對(duì)象。private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");/*** 構(gòu)建默認(rèn)的 BeanToXmlParser 對(duì)象。*/public BeanToXmlParser(){}/** (non-Javadoc)* @see com.flysoft.fuse4j.support.xbean.IBeanToXml#parseBeanToXml(java.lang.Object, java.lang.String)*/public String parseBeanToXml(Object object, String encoding){try{//應(yīng)為遞歸可能很消耗資源,先進(jìn)行垃圾回收。System.gc();//傳入的對(duì)象必須不能為空。if(object != null){//獲取傳入對(duì)象的全類名。String classPath = object.getClass().getName();//獲取傳入對(duì)象的類名。String className = classPath.substring(classPath.lastIndexOf(".") + 1);//構(gòu)建文檔工廠類對(duì)象。DocumentFactory documentFactory = DocumentFactory.getInstance();//構(gòu)建文檔類對(duì)象。Document document = documentFactory.createDocument(encoding.toUpperCase());//添加根節(jié)點(diǎn)。document.addElement(className);//獲取文檔根節(jié)點(diǎn)。Element rootNode = document.getRootElement();//添加根元素的 "class" 屬性。rootNode.addAttribute("class", classPath);//插入根元素。insertElement(rootNode, className.toLowerCase(), object);//返回表示該文檔的 XML 字符串。return document.asXML();}else{return null;}}catch(Exception ex){logger.error("Parse object to xml string fail", ex);return null;}}/** (non-Javadoc)* @see com.flysoft.fuse4j.support.xbean.IBeanToXml#parseBeanToDataIsland(java.lang.String, java.lang.Object, java.lang.String)*/public String parseBeanToDataIsland(String id, Object object, String encoding){StringBuffer stringBuffer = new StringBuffer();stringBuffer.append("<xml id=\"{id}\">");stringBuffer.append(parseBeanToXml(object, encoding));stringBuffer.append("</xml>");return stringBuffer.toString().replaceAll("[{]id[}]", id);}/*** 插入節(jié)點(diǎn)到父節(jié)點(diǎn)元素。* @param parentNode 父節(jié)點(diǎn)元素。* @param nodeName 要插入的節(jié)點(diǎn)名。* @param object 要插入的節(jié)點(diǎn)對(duì)象。*/private void insertElement(Element parentNode, String nodeName, Object object){//如果傳入的對(duì)象為空,則轉(zhuǎn)換為空字符串。object = (object == null)? "": object;//父元素節(jié)點(diǎn)和傳入的對(duì)象均不能為空。if(parentNode != null){//表示當(dāng)前元素節(jié)點(diǎn)。Element currentNode = null;//獲取傳入對(duì)象的全類名。String classPath = object.getClass().getName();//獲取傳入對(duì)象的類名。String className = classPath.substring(classPath.lastIndexOf(".") + 1).toLowerCase();//傳入的對(duì)象為基本數(shù)據(jù)類型。if(isBaseDataType(object.getClass())){//如果節(jié)點(diǎn)名不為空,添加的元素名為節(jié)點(diǎn)名,否則為傳入類的類名。currentNode = parentNode.addElement((nodeName != null && !nodeName.equals(""))? nodeName: className);//添加子節(jié)點(diǎn)的值。currentNode.addText((object instanceof Date)? BeanToXmlParser.simpleDateFormat.format(object): object.toString());}//傳入的對(duì)象為集合類型。else if(object instanceof Collection){//插入集合中的對(duì)象到元素。insertElementFromCollection(parentNode, object);}//傳入的對(duì)象為Map類型。else if(object instanceof Map){//插入Map中的對(duì)象到元素。insertElementFromMap(parentNode, object);}//其他類類型(自定義類型)。else{//插入自定義的對(duì)象到元素。insertElementFromOtherObject(parentNode, object);}}}/*** 插入節(jié)點(diǎn)到父節(jié)點(diǎn)元素。* @param parentNode 父節(jié)點(diǎn)元素。* @param object 要插入的節(jié)點(diǎn)對(duì)象。*/private void insertElement(Element parentNode, Object object){insertElement(parentNode, null, object);}/*** 獲取自定義對(duì)象中的元素做為節(jié)點(diǎn)插入父節(jié)點(diǎn)。* @param parentNode 父節(jié)點(diǎn)。* @param object 要獲取元素的對(duì)象。*/private void insertElementFromOtherObject(Element parentNode, Object object){//表示當(dāng)前元素節(jié)點(diǎn)。Element currentNode = null;//表示字段名。String fieldName = null;//表示類中的getter方法名。String methodName = null;//表示通過(guò)getter方法取得的對(duì)象。Object fieldObject = null;//返回類所定義的字段。Field[] fields = object.getClass().getDeclaredFields();//遍歷所有類字段對(duì)象。for(int i = 0; i < fields.length; i++){//獲取單個(gè)字段對(duì)象。Field field = fields[i];//獲取字段名。fieldName = field.getName();//獲取以getter起始的方法名。methodName = "get" + Character.toUpperCase(fieldName.charAt(0))+ fieldName.substring(1);try{//獲取所有的方法對(duì)象。Method method = object.getClass().getMethod(methodName, null);//判斷getter方法是否為public。if(Modifier.isPublic(method.getModifiers())){//判斷從getter方法獲取的對(duì)象是否為空。if((fieldObject = method.invoke(object, null)) != null && !isBaseDataType(fieldObject.getClass())){//用字段名為節(jié)點(diǎn)名添加一個(gè)節(jié)點(diǎn)元素到指定的父節(jié)點(diǎn)。currentNode = parentNode.addElement(fieldName);//添加該節(jié)點(diǎn)元素的"class"屬性。currentNode.addAttribute("class", fieldObject.getClass().getName());//添加節(jié)點(diǎn)元素到當(dāng)前新插入的節(jié)點(diǎn)下。insertElement(currentNode, fieldName, fieldObject);}else{//添加節(jié)點(diǎn)元素節(jié)點(diǎn)到父節(jié)點(diǎn)下。insertElement(parentNode, fieldName, fieldObject);}}}catch(NoSuchMethodException nex){}catch(Exception ex){logger.error("Get class field fail", ex);}}}/*** 獲取Map中的元素做為節(jié)點(diǎn)插入父節(jié)點(diǎn)。* @param parentNode 父節(jié)點(diǎn)。* @param object 要獲取元素的對(duì)象。*/private void insertElementFromMap(Element parentNode, Object object){//獲取傳入對(duì)象的全類名(包括包名)。String classPath = null;//獲取傳入對(duì)象的類名(不包括包名)。String className = null;//表示Map的鍵。Object key = null;//表示Map的值。Object value = null;//表示當(dāng)前元素節(jié)點(diǎn)。Element currentNode = null;//轉(zhuǎn)換Object為Map類型。Map map = (Map)object;//判斷傳入的對(duì)象是否為空。if(map != null){//遍歷所有鍵集合。for(Iterator keyIterator = map.keySet().iterator(); keyIterator.hasNext();){//判斷取得的Map中的鍵是否為空。if((key = keyIterator.next()) != null){//判斷子元素是否不為空。if((value = map.get(key)) != null){//判斷子元素是否不為基本數(shù)據(jù)類型。if(!isBaseDataType(value.getClass())){//獲取傳入對(duì)象的全類名(包括包名)。classPath = value.getClass().getName();//獲取傳入對(duì)象的類名(不包括包名)。className = classPath.substring(classPath.lastIndexOf(".") + 1);//添加元素到當(dāng)前元素。currentNode = parentNode.addElement(className);//添加元素的class屬性。currentNode.addAttribute("class", classPath);//插入到當(dāng)前元素。insertElement(currentNode, value);}else{//插入到父元素。insertElement(parentNode, key.toString(), value);}}}}}}/*** 獲取集合中的元素做為節(jié)點(diǎn)插入父節(jié)點(diǎn)。* @param parentNode 父節(jié)點(diǎn)。* @param object 要獲取元素的對(duì)象。*/private void insertElementFromCollection(Element parentNode, Object object){//表示當(dāng)前元素節(jié)點(diǎn)。Element currentNode = null;//獲取傳入對(duì)象的全類名(包括包名)。String classPath = null;//獲取傳入對(duì)象的類名(不包括包名)。String className = null;//轉(zhuǎn)換為集合接口對(duì)象。Collection collection = (Collection)object;//集合的子元素。Object subObject = null;//集合對(duì)象不能為空。if(collection != null){//遍歷所有的集合元素。for(Iterator iterator = collection.iterator(); iterator.hasNext();){//判斷獲取的集合的子元素是否為空。if((subObject = iterator.next()) != null){//判斷子元素是否不為一個(gè)基本數(shù)據(jù)類型。if(!isBaseDataType(subObject.getClass())){//獲取傳入對(duì)象的全類名(包括包名)。classPath = subObject.getClass().getName();//獲取傳入對(duì)象的類名(不包括包名)。className = classPath.substring(classPath.lastIndexOf(".") + 1);//添加元素到當(dāng)前元素。currentNode = parentNode.addElement(className);//添加元素的class屬性。currentNode.addAttribute("class", classPath);//插入到當(dāng)前元素。insertElement(currentNode, subObject);}else{//插入到父元素。insertElement(parentNode, subObject);}}}}}/*** 判斷一個(gè)類是否為基本數(shù)據(jù)類型。* @param clazz 要判斷的類。* @return true 表示為基本數(shù)據(jù)類型。*/private boolean isBaseDataType(Class clazz){return(clazz.equals(String.class) ||clazz.equals(Integer.class)||clazz.equals(Byte.class) ||clazz.equals(Long.class) ||clazz.equals(Double.class) ||clazz.equals(Float.class) ||clazz.equals(Character.class) ||clazz.equals(Short.class) ||clazz.equals(BigDecimal.class) ||clazz.equals(BigInteger.class) ||clazz.equals(Boolean.class) ||clazz.equals(Date.class) ||clazz.isPrimitive());}}
public class MainClass{public static void main(String[] args) throws Exception{try{List rootList = new ArrayList();List subList = new ArrayList();rootList.add("name");rootList.add(new Integer(100));rootList.add(new Float(100.1F));rootList.add(new Double(100.01D));subList.add(new Integer(100));subList.add(new Float(100.1F));subList.add(new Double(100.01D));rootList.add(subList);//java 類到 xml 文檔的解析器。BeanToXmlParser beanToXmlParser = new BeanToXmlParser();//轉(zhuǎn)換為 xml 字符串。System.out.println(beanToXmlParser.parseBeanToXml(rootList));}catch(Exception ex){ex.printStackTrace();}}}
聯(lián)系客服