1、忽略掉xml标签的大小写。
2、调用setter方法,将xml元素属性注入到BEAN。
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Attribute;
import org.dom4j.DocumentException;
import org.dom4j.Element;
public class ElementWrapper {
protected Log logger = LogFactory.getLog(getClass());
/** 基本类型到包装类型的映射 **/
private static Map<Class, Class> wrapperClassMap = new HashMap<Class, Class>(){{
put(boolean.class, Boolean.class);
put(int.class, Integer.class);
put(double.class, Double.class);
put(long.class, Long.class);
put(short.class, Short.class);
put(float.class, Float.class);
put(byte.class, Byte.class);
put(char.class, Character.class);
}};
/**
*<pre>
* 调用 targetBean 的普通setter方法,将configElement中的属性值反射到 targetBean 中
* 注意: Element 中属性的名称必须在 targetBean 中有seter方法,且不区分大小写
*</pre>
* @param targetBean 目标 Bean
* @param configElement 标签对象
* @author 陈修恒 2011-3-21
* @throws DocumentException
*/
protected void invokeNode (Object targetBean, Element configElement) throws DocumentException {
if (logger.isDebugEnabled()) {
logger.debug("开始调用:" + targetBean.getClass().getSimpleName() + "#setter方法");
}
/** 获取这个节点的所有setter方法 */
Map<String, Method> methodMap = new HashMap<String, Method>();
Method[] methods = targetBean.getClass().getMethods();
for (Method method : methods) {
if (method.getName().indexOf("set")==0
&& method.getParameterTypes().length == 1) {
methodMap.put(
method.getName().toLowerCase().substring(3),
method);
}
}
/** 调用set,属性写入 */
for (Attribute attribute : (List<Attribute>)configElement.attributes()) {
String methodName = attribute.getName().toLowerCase();
String value = attribute.getValue();
Method method = methodMap.get(methodName);
/** 如果有属性的配置为 isXXX,去掉前面的is */
if (method == null
&& 0 == methodName.indexOf("is")) {
method = methodMap.get(methodName.substring(2));
}
if (method != null
&& value != null
&& value.length() != 0) {
/** 参数类型 */
Class<?> paramType = method.getParameterTypes()[0];
try {
Object param = null;
if (paramType.equals(char.class)) {
param = value.charAt(0);
} else if (paramType.equals(String.class)){
param = value;
} else {
if (paramType.isPrimitive()) { // 是基本类型,获取他的包装类型
paramType = wrapperClassMap.get(paramType);
}
/** 调用本类型的String构造函数 */
Constructor<?> cons = paramType.getConstructor(String.class);
param = cons.newInstance(value);
}
/** 调用setter (String) 方法 */
method.invoke(targetBean, param);
if (logger.isDebugEnabled()) {
logger.debug("成功调用:"+ getMethodInfo(targetBean, method)+", 参数:"+ param);
}
/** 将该方法删除 */
methodMap.remove(method.getName().toLowerCase().substring(3));
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new DocumentException(e.getMessage());
}
} else if (logger.isDebugEnabled()) {
logger.debug(targetBean.getClass().getSimpleName() + "不存在setter方法, 属性名:" + methodName);
}
}
if (!methodMap.isEmpty() && logger.isDebugEnabled()) {
for (Method m : methodMap.values()) {
String methodInfo = getMethodInfo(targetBean, m);
logger.debug(
"没有调用:" + methodInfo
);
}
}
}
/**
*<pre>
*
*</pre>
* @param targetBean
* @param m
* @return
* @author 陈修恒 2011-3-30
*/
private String getMethodInfo(Object targetBean, Method m) {
String methodString = m.toString();
int setIndex = methodString.lastIndexOf(".set");
String methodInfo = targetBean.getClass().getSimpleName() +
"#"+methodString.substring(setIndex+1);
return methodInfo;
}
/**
*<pre>
* 将 Element 配置的属性名,全改成小写
*</pre>
* @param el
* @return
* @author 陈修恒 2011-3-28
*/
public Map<String, String> attributes(Element el) {
Map<String, String> map = new HashMap<String, String>();
for (Attribute attri : (Collection<Attribute>)el.attributes()) {
map.put(attri.getName().toLowerCase(), attri.getValue());
}
return map;
}
/**
*<pre>
* 获取子标签列表
*</pre>
* @param rootElement 父标签
* @param elementName 子标签名称
* @return
* @author 陈修恒 2011-3-28
*/
public List<Element> elements (Element rootElement, String elementName) {
List<Element> elementRst = new ArrayList<Element>();
/** 获取父节点下的所有子节点 */
List<Element> elements = rootElement.elements();
/** 帅选出名称与指定名称相同的标签,忽略大小写 */
for (Element element : elements) {
if(elementName.equalsIgnoreCase(element.getName())) {
elementRst.add(element);
}
}
return elementRst;
}
/**
*<pre>
* 获取子标签列表
*</pre>
* @param rootElement 父标签
* @param elementName 子标签名称
* @return
* @author 陈修恒 2011-3-28
*/
public Element element (Element rootElement, String elementName) {
List<Element> elementRst = elements(rootElement, elementName);
if (elementRst.isEmpty()) {
return null;
} else {
return elementRst.get(0);
}
}
}