com.gitee.qdbp.staticize.parse.ValueOf Maven / Gradle / Ivy
package com.gitee.qdbp.staticize.parse;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import com.gitee.qdbp.staticize.exception.TagException;
/**
* 计算标签值的工具类
* 调用目标类的静态方法valueOf()将参数转换为目标类型
* 为提高执行效率, 在根据Class获取valueOf()方法时作了缓存
*
* @author zhaohuihua
* @version 140521
*/
class ValueOf {
/** 方法名 **/
private static final String VALUE_OF_METHOD = "valueOf";
/** 缓存已经找到的方法对象 **/
// key=targetType:sourceType
private final Map valueOfMethods = new HashMap<>();
/** 查找失败的原因 **/
// key=targetType:sourceType, value=message
private final Map errorCauses = new HashMap<>();
/** 单实例 **/
public static final ValueOf instance = new ValueOf();
/**
* 调用目标类的静态方法valueOf(Object)将value转换为目标类型
*
* @param type 目标类
* @param value 参数值
* @return 目标类型的对象
* @throws TagException 转换失败
*/
@SuppressWarnings("unchecked")
public T eval(Class type, Object value) throws TagException {
// 参数值已经是目标类型了, 不需要转换
if (type.isAssignableFrom(value.getClass())) {
return (T) value;
}
if (type == String.class) {
return (T) String.valueOf(value);
}
// 获取目标类的ValueOf()方法
Method method = getValueOfMethod(type, value.getClass());
try {
// 调用ValueOf()静态方法
return (T) method.invoke(null, value);
} catch (Exception e) {
String fmt = "converting from %s to type %s error";
String src = value.getClass().getSimpleName();
String dest = type.getSimpleName();
throw new TagException(String.format(fmt, src, dest), e);
}
}
/**
* 获取目标类的ValueOf()方法
*
* @param targetType 目标类型
* @param sourceType 参数类型
* @return 方法对象
* @throws TagException 查找失败
*/
private Method getValueOfMethod(Class> targetType, Class> sourceType) throws TagException {
String key = targetType.getName() + ':' + sourceType.getName();
// 判断之前有没有失败的请求记录
String cause = errorCauses.get(key);
if (cause != null) {
throw new TagException(cause);
}
// 从缓存中获取方法
Method method = valueOfMethods.get(key);
if (method == null) {
try {
// 查找ValueOf()方法
method = findValueOfMethod(targetType, sourceType);
// 缓存起来
valueOfMethods.put(targetType.getName(), method);
} catch (TagException e) {
errorCauses.put(key, e.getMessage());
throw e;
}
}
return method;
}
/**
* 查找目标类的ValueOf()方法
*
* @param type 目标类
* @param value 参数类
* @return 方法对象
* @throws TagException 查找失败
*/
private static Method findValueOfMethod(Class> type, Class> value) throws TagException {
// 直接采用clazz.getMethod(name, types)的方式
// 会出现根据Integer找不到String.valueOf(Object)的情况
// 失败原因
String cause = "Unable to convert, method %s.%s(%s) does not found";
Method[] methods = type.getMethods();
for (Method method : methods) {
// 去掉方法名不符的方法
if (!VALUE_OF_METHOD.equals(method.getName())) {
continue;
}
// 去掉非静态方法
if (!Modifier.isStatic(method.getModifiers())) {
cause = "Unable to convert, %s.%s(%s) is not a static method";
continue;
}
// 去掉参数不是一个的
Class>[] types = method.getParameterTypes();
if (types.length != 1) {
cause = "Unable to convert, %s.%s(%s) param size not match";
continue;
}
// 去掉参数类型不符的
if (!types[0].isAssignableFrom(value)) {
cause = "Unable to convert, %s.%s(%s) param types not match";
continue;
}
// 去掉没有返回类型的
if (method.getReturnType() == void.class) {
cause = "Unable to convert, %s.%s(%s) has no return value";
continue;
}
// 去掉返回类型不符的
if (!type.isAssignableFrom(method.getReturnType())) {
cause = "Unable to convert, %s.%s(%s) return type does not match";
continue;
}
return method;
}
// 没有找到ValueOf()方法
String src = value.getSimpleName();
String dest = type.getSimpleName();
String msg = String.format(cause, dest, VALUE_OF_METHOD, src);
throw new TagException(msg);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy