All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.cattleframework.utils.reflect.ReflectUtils Maven / Gradle / Ivy

There is a newer version: 1.0.1-M3
Show newest version
/*
 * Copyright (C) 2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.cattleframework.utils.reflect;

import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.cattleframework.exception.CattleException;
import org.cattleframework.exception.ExceptionWrapUtils;
import org.cattleframework.utils.auxiliary.DataConvertUtils;
import org.cattleframework.utils.reflect.constant.ClassType;

/**
 * 反射工具
 * 
 * @author orange
 *
 */
public final class ReflectUtils {

    private ReflectUtils() {
    }

    public static Field getField(Class clazz, String fieldName) {
	return getField(clazz, fieldName, true);
    }

    public static Field getField(Class clazz, String fieldName, boolean throwNotFound) {
	if (clazz == null) {
	    throw new CattleException("类为空");
	}
	if (StringUtils.isBlank(fieldName)) {
	    throw new CattleException("字段名为空");
	}
	Field field = null;
	try {
	    field = clazz.getDeclaredField(fieldName);
	} catch (SecurityException e) {
	    throw ExceptionWrapUtils.wrap(e);
	} catch (NoSuchFieldException e) {
	    if (clazz.getSuperclass() != Object.class) {
		field = getField(clazz.getSuperclass(), fieldName, false);
	    }
	}
	if (field == null && throwNotFound) {
	    throw new CattleException("在类'" + clazz.getName() + "'中没有找到字段'" + fieldName + "'");
	}
	return field;
    }

    public static void setFieldValue(Object obj, Field field, Object value) {
	if (obj == null) {
	    throw new CattleException("对象为空");
	}
	if (field == null) {
	    throw new CattleException("字段为空");
	}
	if (!field.trySetAccessible()) {
	    throw new CattleException("不能设置字段'" + field.getName() + "'的值");
	}
	try {
	    Object convertValue = null;
	    if (value != null) {
		ClassType type = getClassType(field.getType());
		convertValue = DataConvertUtils.convertValue(type,
			type == ClassType.Array ? field.getType().getComponentType()
				: (type == ClassType.Enum || type == ClassType.ClassObject ? field.getType() : null),
			value);
	    }
	    field.set(obj, convertValue);
	} catch (IllegalArgumentException | IllegalAccessException e) {
	    throw ExceptionWrapUtils.wrap(e);
	}
    }

    public static void setFieldValue(Object obj, String fieldName, Object value) {
	Field field = getField(obj.getClass(), fieldName);
	setFieldValue(obj, field, value);
    }

    public static ClassType getClassType(Class typeCls) {
	ClassType type = null;
	if (typeCls.isArray()) {
	    type = ClassType.Array;
	} else if (typeCls.isEnum()) {
	    type = ClassType.Enum;
	} else if (typeCls == Long.class || typeCls == long.class) {
	    type = ClassType.Long;
	} else if (typeCls == Integer.class || typeCls == int.class) {
	    type = ClassType.Int;
	} else if (typeCls == Double.class || typeCls == double.class) {
	    type = ClassType.Double;
	} else if (typeCls == String.class) {
	    type = ClassType.String;
	} else if (typeCls == Boolean.class || typeCls == boolean.class) {
	    type = ClassType.Boolean;
	} else if (typeCls == java.sql.Date.class) {
	    type = ClassType.SqlDate;
	} else if (typeCls == java.sql.Time.class) {
	    type = ClassType.Time;
	} else if (typeCls == java.sql.Timestamp.class) {
	    type = ClassType.Timestamp;
	} else if (typeCls == java.util.Date.class) {
	    type = ClassType.Date;
	} else if (List.class.isAssignableFrom(typeCls)) {
	    type = ClassType.List;
	} else if (Map.class.isAssignableFrom(typeCls)) {
	    type = ClassType.Map;
	} else if (typeCls == Byte.class || typeCls == byte.class) {
	    type = ClassType.Byte;
	} else if (typeCls == Character.class || typeCls == char.class) {
	    type = ClassType.Char;
	} else if (typeCls == Short.class || typeCls == short.class) {
	    type = ClassType.Short;
	} else if (typeCls == BigDecimal.class) {
	    type = ClassType.BigDecimal;
	} else if (typeCls == BigInteger.class) {
	    type = ClassType.BigInteger;
	} else if (typeCls == Class.class) {
	    type = ClassType.Class;
	} else if (typeCls == Object.class) {
	    type = ClassType.Object;
	} else {
	    type = ClassType.ClassObject;
	}
	return type;
    }

    public static Object setEnumValue(Class clazz, String value) {
	if (clazz == null) {
	    throw new CattleException("类为空");
	}
	if (!clazz.isEnum()) {
	    throw new CattleException("类'" + clazz.getCanonicalName() + "'不是枚举");
	}
	Method valuesMethod = getMethod(clazz, "values");
	Object values = invokeMethod(valuesMethod);
	int valuesSize = Array.getLength(values);
	boolean isFound = false;
	for (int i = 0; i < valuesSize; i++) {
	    String enumValue = Array.get(values, i).toString();
	    if (enumValue.equals(value)) {
		isFound = true;
		break;
	    }
	}
	if (!isFound) {
	    throw new CattleException("值'" + value + "'不属于枚举'" + clazz.getCanonicalName() + "'中的内容");
	}
	Method valueOfMethod = getMethod(clazz, "valueOf", String.class);
	return invokeMethod(valueOfMethod, value);
    }

    public static Method getMethod(Class clazz, String methodName, Class... parameterTypes) {
	return getMethod(clazz, methodName, true, parameterTypes);
    }

    private static Method getMethod(Class clazz, String methodName, boolean throwNotFound,
	    Class... parameterTypes) {
	if (clazz == null) {
	    throw new CattleException("类为空");
	}
	if (StringUtils.isBlank(methodName)) {
	    throw new CattleException("方法为空");
	}
	Method method = null;
	try {
	    method = clazz.getDeclaredMethod(methodName, parameterTypes);
	} catch (SecurityException e) {
	    throw ExceptionWrapUtils.wrap(e);
	} catch (NoSuchMethodException e) {
	    if (clazz.getSuperclass() != Object.class) {
		method = getMethod(clazz.getSuperclass(), methodName, false, parameterTypes);
	    }
	}
	if (method == null && throwNotFound) {
	    throw new CattleException("在类'" + clazz.getCanonicalName() + "'中没有找到方法'" + methodName + "'");
	}
	return method;
    }

    public static Method findSetMethod(Class clazz, String name) {
	if (clazz == null) {
	    throw new CattleException("类为空");
	}
	if (StringUtils.isBlank(name)) {
	    throw new CattleException("名称为空");
	}
	Method[] methods = clazz.getDeclaredMethods();
	String methodName = "set" + name.substring(0, 1).toUpperCase(Locale.ENGLISH) + name.substring(1);
	Method targetMethod = Arrays.stream(methods)
		.filter(method -> method.getName().equals(methodName) && method.getParameterCount() == 1).findFirst()
		.orElse(null);
	if (targetMethod == null) {
	    var methodName2 = "set" + name.toUpperCase(Locale.ENGLISH);
	    targetMethod = Arrays.stream(methods)
		    .filter(m -> m.getName().equals(methodName2) && m.getParameterCount() == 1).findFirst()
		    .orElse(null);
	}
	if (targetMethod == null && clazz.getSuperclass() != Object.class) {
	    targetMethod = findSetMethod(clazz.getSuperclass(), name);
	}
	return targetMethod;
    }

    public static Object invokeMethod(Method method, Object... args) {
	return invokeObjectMethod(method, null, args);
    }

    public static Object invokeObjectMethod(Method method, Object target, Object... args) {
	if (method == null) {
	    throw new CattleException("方法为空");
	}
	if (!method.trySetAccessible()) {
	    throw new CattleException("不能执行方法'" + method.getName() + "'");
	}
	try {
	    return method.invoke(target, args);
	} catch (IllegalArgumentException | IllegalAccessException e) {
	    throw ExceptionWrapUtils.wrap(e);
	} catch (InvocationTargetException e) {
	    if (e.getCause() != null) {
		throw ExceptionWrapUtils.wrap(e.getCause());
	    }
	    throw ExceptionWrapUtils.wrap(e);
	}
    }

    public static Object getFieldValue(Object obj, String fieldName) {
	Field field = getField(obj.getClass(), fieldName);
	return getFieldValue(obj, field);
    }

    public static Object getFieldValue(Object obj, Field field) {
	if (field == null) {
	    throw new CattleException("字段为空");
	}
	if (!field.trySetAccessible()) {
	    throw new CattleException("不能获取字段'" + field.getName() + "'的值");
	}
	try {
	    return field.get(obj);
	} catch (IllegalArgumentException | IllegalAccessException e) {
	    throw ExceptionWrapUtils.wrap(e);
	}
    }

    public static Set getFields(Class clazz) {
	Set fields = new HashSet();
	Field[] clsFields = clazz.getDeclaredFields();
	Arrays.stream(clsFields).forEach(clsField -> {
	    int mod = clsField.getModifiers();
	    if (!Modifier.isStatic(mod) && !Modifier.isFinal(mod)) {
		fields.add(clsField);
	    }
	});
	Class superclass = clazz.getSuperclass();
	if (superclass != null && superclass != Object.class) {
	    fields.addAll(getFields(clazz.getSuperclass()));
	}
	return fields;
    }

    public static  A getAnnotation(Class clazz, Class annotationClass) {
	A annotation = clazz.getAnnotation(annotationClass);
	if (annotation == null) {
	    if (Object.class != clazz.getSuperclass()) {
		annotation = getAnnotation(clazz.getSuperclass(), annotationClass);
	    }
	}
	return annotation;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy