package org.jcommons.file.xml; import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.jcommons.common.ClassUtils; import org.jcommons.common.ReflectUtils; @SuppressWarnings("all") public class BeanXMLReader implements XMLReader { private String rootElementName; private String beanName; private File file; private Hashtable<String, Class<?>> classes = new Hashtable<String, Class<?>>(); public void setClass(Class<?> clazz) { this.setClass(this.beanName, clazz); } public void setClass(String key, Class<?> clazz) { if (ClassUtils.isPojo(clazz)) { Field[] fields = clazz.getDeclaredFields(); for (Field f : fields) { if (List.class.isAssignableFrom(f.getType())) { ParameterizedType pt = (ParameterizedType) f .getGenericType(); Type type = pt.getActualTypeArguments()[0]; Class<?> cls = ClassUtils.getPojoClass(type.toString() .replace("class ", "")); setClass(f.getName(), cls); } else { setClass(f.getName(), f.getType()); } } this.classes.put(key, clazz); } } public void setBeanName(String beanName) { this.beanName = beanName; } public void setRootElementName(String name) { this.rootElementName = name; } public File getFile() { return file; } public void setFile(File file) { this.file = file; } public BeanXMLReader(File file) { this.setFile(file); } public BeanXMLReader() { } public String toXml() throws Exception { return createDoc(new ArrayList<Object>()).asXML(); } public <T> List<T> read() throws Exception { List<T> tList = new ArrayList<T>(); createDoc(tList); return tList; } private <T> Document createDoc(List<T> tList) throws DocumentException, Exception { SAXReader reader = new SAXReader(); T t; Document doc = reader.read(this.file); // 列出beans下的所有bean元素节点 String sub; if (this.beanName == null || this.beanName.trim().length() == 0) sub = BeanXMLConstant.SUBROOT_ELEMENT; else sub = this.beanName; if (this.rootElementName == null || this.rootElementName.trim().length() == 0) this.rootElementName = BeanXMLConstant.ROOT_ELEMENT; List<?> list = doc.selectNodes("//" + this.rootElementName + "/" + sub); for (Iterator<?> it = list.iterator(); it.hasNext();) { Element bean = (Element) it.next(); // 进入递归 t = (T) this.readRecursion(bean); tList.add(t); } return doc; } public <T> T readOne() throws Exception { T t = null; List<T> list = this.read(); if (list != null) { t = list.get(0); } return t; } @SuppressWarnings("unchecked") private <T> T readRecursion(Element bean) throws Exception { Class<T> clazz = (Class<T>) this.classes.get(bean.getName()); T o = clazz.newInstance(); ReflectUtils ru = new ReflectUtils(o); Field[] fields = ru.getFields(); for (Field f : fields) { String n = f.getName(); Method m = ru.getSetter(n); if (m == null) continue; Skip skip = f.getAnnotation(Skip.class); if (skip != null) continue; AttrTag attrTag = f.getAnnotation(AttrTag.class); Writeonly writeonly = f.getAnnotation(Writeonly.class); if (writeonly != null) continue; if (attrTag != null) { if ("clazz".equals(n)) n = "class"; Attribute a = bean.attribute(n); if (a != null) m.invoke(o, a.getData()); } else if (ClassUtils.isPojo(f.getType())) { Element el = bean.element(n); if (el == null) continue; String cls = this.classes.get(el.getName()).getName(); Object object = Thread.currentThread().getContextClassLoader().loadClass(cls).newInstance(); // 递归 object = readRecursion(el); m.invoke(o, object); } else if (ClassUtils.isListClass(f)) { List<?> eList = bean.elements(n); if (eList == null) continue; List<Object> list = new ArrayList<Object>(); for (Iterator<?> it = eList.iterator(); it.hasNext();) { Element e = (Element) it.next(); // 递归 list.add(readRecursion(e)); } m.invoke(o, list); } else if (ClassUtils.isListString(f)) { List<?> eList = bean.elements(n); if (eList == null) continue; List<String> list = new ArrayList<String>(); for (Iterator<?> it = eList.iterator(); it.hasNext();) { Element e = (Element) it.next(); list.add(e.getText()); } m.invoke(o, list); } else { if ("clazz".equals(n)) n = "class"; Element a = bean.element(n); if (a == null) continue; m.invoke(o, String.valueOf(a.getData())); } } return o; } }