公司不允许随便下载第三方jar包,但是公司lib库中的jar又非常老,更新需要申请,很多时候都是自己去写一些工具类,这次遇到xml处理的一些程序,于是自己写了一个工具类。这个比较粗糙,属于Test版本。
实体类注解@XmlEntity:
package com.cugxw.utils;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author cugxw
* @date 2012-10-11
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface XmlEntity {
/**
* Map namespace name of the XML.<br>
* If this value is "$Default$", the namespace name will be class namespace name.<br>
* If class namespace is unnamed, the XML namespace will be null. <br>
*/
String namespace() default "$Default$";
/**
* Map root name of the XML.<br>
* If this value is "$Default$", the XML root name will be simple class name.<br>
*/
String name() default "$Default$";
/**
* Map prefix of the elements.<br>
* If this value is "$Default$", all elements of the XML will have no prefix string.<br>
*/
String xmlPrefix() default "$Default$";
}
实体类field注解@XmlField
package com.cugxw.utils;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author cugxw
* @date 2012-10-11
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface XmlField {
/**
* Map the element name of the XML.
* If this value is "$Default$", the elements' name of the XML will be class field name.
*/
String name() default "$Default$";
}
Xml处理类,包含toXML和fromXML方法:
package com.cugxw.utils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.QName;
@SuppressWarnings("unchecked")
public class XmlHandler {
//Registed entity name
private Map regClassMap;
//Entity path, default src root directory.
private boolean useXmlAnnotation = false;
public XmlHandler()
{
this.regClassMap = new HashMap();
this.registClass(null);
}
public XmlHandler(String entityPath)
{
this.regClassMap = new HashMap();
this.registClass(entityPath);
}
public XmlHandler(String entityPath, boolean useXmlAnnotation)
{
this.regClassMap = new HashMap();
this.useXmlAnnotation = useXmlAnnotation;
this.registClass(entityPath);
}
/**
* Get all loaded classes, return them.
* @return
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
private List getLoadedClass() throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
ClassLoader curClassLoader = Thread.currentThread().getContextClassLoader();
Class loaderClass = curClassLoader.getClass();
/* Find all loaded classes in classloader */
while (!loaderClass.equals(ClassLoader.class)) {
loaderClass = loaderClass.getSuperclass();
}
/* Get the access to read private field */
Field loaderField = loaderClass.getDeclaredField("classes");
loaderField.setAccessible(true);
return (List) loaderField.get(curClassLoader);
}
private String getXmlEntityName(Class<Object> clazz) {
Object obj = clazz.getAnnotation(XmlEntity.class);
if (obj == null) {
return null;
}
return clazz.getAnnotation(XmlEntity.class).name();
}
public void registClassName(Class clazz) {
String className = clazz.getName();
if (this.useXmlAnnotation) {
String xmlEntityName = getXmlEntityName(clazz);
if (xmlEntityName != null && !"".equals(xmlEntityName)) {
this.regClassMap.put(clazz.getSimpleName(),
className);
System.out.println(className);
}
} else {
this.regClassMap.put(clazz.getSimpleName(),
className);
System.out.println(className);
}
}
/**
* Regist all loaded classes, put them into a map.
* @param regPath
*/
public void registClass(String regPath) {
try {
List classList = this.getLoadedClass();
int count = classList.size();
for(int i=0; i<count; i++) {
Object clazz = classList.get(i);
String className = ((Class)clazz).getName();
if (regPath == null || "".equals(regPath)) {
this.registClassName((Class)clazz);
} else {
if (className.startsWith(regPath)) {
this.registClassName((Class)clazz);
}
}
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
/**
* Get field value from one object by field name
* @param fieldName
* @param obj
* @return field value of the object;
*/
private Object getFieldValueByName(String fieldName, Object obj) throws Exception
{
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + fieldName.substring(1);
Method method = obj.getClass().getMethod(getter, new Class[] {});
Object value = method.invoke(obj, new Object[] {});
return value;
}
/**
* A sub task of addition sub element by calling recursion method
* @param pElement
* @param subElementName
* @param prefix
* @param textValue
* @return sub element
*/
private Element addSubElement(Element pElement, String subElementName,
String prefix, String textValue)
{
QName qname = QName.get(subElementName);
if(prefix != null && !"".equals(prefix))
{
qname = QName.get(prefix + ":" + subElementName);
}
Element node = pElement.addElement(qname);
if(textValue != null && !"".equals(textValue))
{
node.setText(this.nullToStr(textValue));
}
return node;
}
private String getXmlFieldName(Field field) {
String xmlFieldName = null;
if (this.useXmlAnnotation) {
XmlField xmlField = field.getAnnotation(XmlField.class);
if (xmlField != null) {
if (!"$Default$".equals(xmlField.name())) {
xmlFieldName = xmlField.name();
return xmlFieldName;
}
}
}
xmlFieldName = field.getName();
return xmlFieldName;
}
/**
* A sub task of create sub xml by Recursion method
* @param element
* @param prefix
* @param obj
*/
private void createSubXml(Element element, String prefix, Object obj) throws Exception
{
if(obj == null)
{
return;
}
Class objClass = obj.getClass();
Field[] fields = objClass.getDeclaredFields();
for(int i=0; i<fields.length; i++)
{
String fieldName = fields[i].getName();
String xmlFieldName = getXmlFieldName(fields[i]);
Object fieldVal = this.getFieldValueByName(fieldName, obj);
String fieldClassName = fields[i].getType().getSimpleName();
if(fieldClassName == null || "".equals(fieldClassName)
|| this.regClassMap == null)
{
continue;
}
String classFullName = (String) this.regClassMap.get(fieldClassName);
if(classFullName != null && !"".equals(classFullName))
{
Element subElement = this.addSubElement(element, xmlFieldName, prefix, null);
this.createSubXml(subElement, prefix, fieldVal);
}
else if(fieldVal != null && ("List".equals(fieldClassName) || "ArrayList".equals(fieldClassName)))
{
/* When sub class in a list object */
Element subElement = this.addSubElement(element, xmlFieldName, prefix, null);
Collection collection = (Collection) fieldVal;
for(Object aVal : collection)
{
Element grandSubEle = this.addSubElement(subElement, aVal.getClass().getSimpleName(), prefix, null);
this.createSubXml(grandSubEle, prefix, aVal);
}
}
else if(fieldVal != null && ("Set".equals(fieldClassName) || "HashSet".equals(fieldClassName)))
{
/* When sub class in a set object */
Element subElement = this.addSubElement(element, xmlFieldName, prefix, null);
Set set = (Set)fieldVal;
Iterator it = set.iterator();
while(it.hasNext())
{
Object aVal = it.next();
Element grandSubEle = this.addSubElement(subElement, aVal.getClass().getSimpleName(), prefix, null);
this.createSubXml(grandSubEle, prefix, aVal);
}
}
else if(fieldVal != null)
{
this.addSubElement(element, xmlFieldName, prefix, this.nullToStr(fieldVal));
}
}
}
/**
* Get QName by entity object
* @param obj entity object
* @return QName
*/
private QName getQName(Object obj) {
QName qname = null;
String namespace = null;
String prefix = null;
if (this.useXmlAnnotation) {
XmlEntity xmlEntity = obj.getClass().getAnnotation(XmlEntity.class);
if (xmlEntity != null) {
String elementName = obj.getClass().getSimpleName();
if (!"$Default$".equals(xmlEntity.name())) {
elementName = xmlEntity.name();
}
if (!"$Default$".equals(xmlEntity.namespace())) {
namespace = xmlEntity.namespace();
}
if (!"$Default$".equals(xmlEntity.xmlPrefix())) {
prefix = xmlEntity.xmlPrefix();
}
qname = QName.get(elementName, prefix, namespace);
return qname;
}
}
QName.get(obj.getClass().getSimpleName());
return qname;
}
/**
* Get xml data from an entity
* @param obj
* @param namespace
* @param prefix
* @return string data
*/
public String toXml(Object obj) throws Exception
{
if(obj != null)
{
QName qname = this.getQName(obj);
Element root = DocumentHelper.createElement(qname);
String prefix = qname.getNamespacePrefix();
if ("".equals(prefix)) {
prefix = null;
}
this.createSubXml(root, prefix, obj);
Document document = DocumentHelper.createDocument(root);
return document.asXML();
}
return null;
}
/**
* A sub work of parse sub xml via Recursion method
* @param obj
* @param element
*/
private void parseSubXml(Object obj, Element element)
{
/* The object and element must not be null */
if(obj == null || element == null)
{
return;
}
/* Get the all declared fields */
Field[] fields = obj.getClass().getDeclaredFields();
if(fields != null)
{
for(int i=0; i<fields.length; i++)
{
/* Get the field information */
Field aField = fields[i];
Class fieldClass = aField.getType();
String fieldClassName = fieldClass.getSimpleName();
String xmlFieldName = this.getXmlFieldName(aField);
if(this.regClassMap == null)
{
continue;
}
/* Get class name from registed class map if the class is registered */
String classFullName = (String) this.regClassMap.get(fieldClass.getSimpleName());
Element subEle = element.element(xmlFieldName);
// Make the field be accessible
fields[i].setAccessible(true);
Object value = null;
if(classFullName != null && !"".equals(classFullName))
{
/* Create an object of this sub class if it's a class which is registered */
try {
value = fieldClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
return;
} catch (IllegalAccessException e) {
e.printStackTrace();
return;
}
this.parseSubXml(value, subEle);
}
else if(subEle != null && ("List".equals(fieldClassName) || "ArrayList".equals(fieldClassName)))
{
/* When sub class in a list object */
List objList = new ArrayList();
List<Element> eleList = subEle.elements();
for(Element aEle : eleList)
{
if(aEle != null)
{
String fullPath = (String) this.regClassMap.get(aEle.getName());
Object aVal = null;
try {
aVal = Class.forName(fullPath).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
return;
} catch (IllegalAccessException e) {
e.printStackTrace();
return;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return;
}
this.parseSubXml(aVal, aEle);
objList.add(aVal);
}
}
value = objList;
}
else if(subEle != null && ("Set".equals(fieldClassName) || "HashSet".equals(fieldClassName)))
{
/* When sub class in a set object */
Set objSet = new HashSet();
List<Element> eleList = subEle.elements();
for(Element aEle : eleList)
{
if(aEle != null)
{
String fullPath = (String) this.regClassMap.get(aEle.getName());
Object aVal = null;
try {
aVal = Class.forName(fullPath).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
return;
} catch (IllegalAccessException e) {
e.printStackTrace();
return;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return;
}
this.parseSubXml(aVal, aEle);
objSet.add(aVal);
}
}
value = objSet;
}
else if(subEle != null)
{
// Get the common value if it's not a class which is registered
value = subEle.getText();
}
/*set the fields' value*/
if(value != null && !"".equals(value))
{
try {
fields[i].set(obj, value);
} catch (IllegalArgumentException e) {
e.printStackTrace();
return;
} catch (IllegalAccessException e) {
e.printStackTrace();
return;
}
}
}
}
}
/**
* Get a entity object from xml
* @param entityClass
* @param xml
* @return a entity object
* @throws DocumentException
*/
public Object fromXml(Class entityClass, String xml) throws Exception
{
/* Create a new object of the entity */
Object resObj = null;
/* Get the root of the xml */
Document document = null;
Element root = null;
document = DocumentHelper.parseText(xml);
root = document.getRootElement();
if(entityClass != null)
{
String xmlEntityName = this.getXmlEntityName(entityClass);
if(!xmlEntityName.equals(root.getName()))
{
return null;
}
/* Parse the XML */
resObj = entityClass.newInstance();
this.parseSubXml(resObj, root);
}
return resObj;
}
/**
* May be,we need to converse null to blank String
* @param obj
* @return string
*/
private String nullToStr(Object obj)
{
if(obj == null)
{
return "";
}
return obj.toString();
}
public boolean isUseXmlAnnotation() {
return useXmlAnnotation;
}
public void setUseXmlAnnotation(boolean useXmlAnnotation) {
this.useXmlAnnotation = useXmlAnnotation;
}
public void showRegMap() {
Set mSet = this.regClassMap.keySet();
for (Object clazzName : mSet) {
System.out.println(clazzName);
}
}
}