package org.eweb4j.util.xml;
import java.io.File;
import java.lang.annotation.Annotation;
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.Element;
import org.dom4j.io.SAXReader;
import org.eweb4j.util.ClassUtil;
import org.eweb4j.util.ReflectUtil;
import org.eweb4j.util.StringUtil;
import org.eweb4j.util.xml.tag.XmlTag;
import org.eweb4j.util.xml.tag.XmlTagType;
public class BeanXMLReader implements XMLReader {
private String beanName;
private File file;
private Hashtable<String, Class<?>> classes = new Hashtable<String, Class<?>>();
public void setClass(String key, Class<?> clazz) {
if (ClassUtil.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 = ClassUtil.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 File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public BeanXMLReader(File file) {
this.setFile(file);
}
public BeanXMLReader() {
}
@SuppressWarnings("unchecked")
public <T> List<T> read() throws Exception {
List<T> tList = new ArrayList<T>();
T t = null;
SAXReader reader = new SAXReader();
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;
List<?> list = doc.selectNodes("//" + BeanXMLConstant.ROOT_ELEMENT
+ "/" + sub);
for (Iterator<?> it = list.iterator(); it.hasNext();) {
Element bean = (Element) it.next();
// 进入递归
t = (T) this.readRecursion(bean);
tList.add(t);
}
return tList;
}
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 {
Attribute xmlBean = bean.attribute(BeanXMLConstant.CLASS_PROPERTY);
Class<T> clazz = null;
if (xmlBean != null) {
clazz = (Class<T>) Class.forName(xmlBean.getValue());
} else {
Element e = bean.element(BeanXMLConstant.CLASS_PROPERTY);
if (e != null)
clazz = (Class<T>) Class.forName(e.getText());
else
clazz = (Class<T>) this.classes.get(bean.getName());
}
T o = clazz.newInstance();
ReflectUtil ru = new ReflectUtil(o);
Field[] fields = ru.getFields();
for (Field f : fields) {
String n = f.getName();
Method m = ru.getMethod("set" + StringUtil.toUpCaseFirst(n));
if (m != null) {
Annotation[] annotation = f.getAnnotations();
if (annotation != null && annotation.length > 0) {
for (Annotation anno : annotation) {
XmlTag tag = (XmlTag) anno;
String type = tag.type();
String value = tag.value();
boolean canRead = tag.canRead();
if (canRead) {
if (XmlTagType.attriType.equals(type)) {
if ("clazz".equals(n)) {
n = "class";
}
Attribute a = bean.attribute(n);
if (a != null) {
m.invoke(o, a.getData());
}
} else if (XmlTagType.classType.equals(type)) {
Element el = bean.element(n);
if (el != null) {
if ("".equals(value) || value == null) {
Attribute a = el
.attribute(BeanXMLConstant.CLASS_PROPERTY);
if (a != null)
value = a.getValue();
else
value = this.classes.get(
el.getName()).getName();
}
Object object = Class.forName(value)
.newInstance();
// 递归
object = readRecursion(el);
m.invoke(o, object);
}
} else if (XmlTagType.listClassType.equals(type)) {
List<?> eList = bean.elements(n);
if (eList != null) {
List<Object> list = new ArrayList<Object>();
for (Iterator<?> it = eList.iterator(); it
.hasNext();) {
Element e = (Element) it.next();
if ("".equals(value)) {
Attribute a = e
.attribute(BeanXMLConstant.CLASS_PROPERTY);
if (a != null)
value = a.getValue();
else
value = this.classes.get(
e.getName()).getName();
}
Object object = Class.forName(value)
.newInstance();
// 递归
object = readRecursion(e);
list.add(object);
}
m.invoke(o, list);
}
} else if (XmlTagType.listElementType.equals(type)) {
List<?> eList = bean.elements(n);
if (eList != null) {
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 (XmlTagType.elementType.equals(type)) {
Element a = bean.element(n);
if (a != null) {
if ("clazz".equals(n)) {
n = "class";
}
if (a != null) {
m.invoke(o, a.getData());
}
}
} else if ("".equals(type)) {
Element a = bean.element(n);
if (a != null) {
if ("clazz".equals(n)) {
n = "class";
}
if (a != null) {
m.invoke(o, a.getData());
}
}
}
}
}
} else {
m.invoke(o, bean.element(n).getData());
}
}
}
return o;
}
}