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

com.centit.support.algorithm.ReflectionOpt Maven / Gradle / Ivy

There is a newer version: 5.3.2302
Show newest version
package com.centit.support.algorithm;

import com.centit.support.file.FileType;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 *  提供一些反射方面缺失功能的封装.
 *  @author codefan
 */
@SuppressWarnings("unused")
public abstract class ReflectionOpt  {

    private ReflectionOpt() {
        throw new IllegalAccessError("Utility class");
    }

    protected static final Logger logger = LoggerFactory.getLogger(ReflectionOpt.class);

    /*
     * 循环向上转型,获取对象的DeclaredField.
     *
     * @throws NoSuchFieldException 如果没有该Field时抛出.
     */
    public static Field getDeclaredField(Object object, String propertyName) throws NoSuchFieldException {
        assert(object != null);
        assert(propertyName != null && !propertyName.isEmpty());

        return getDeclaredField(object.getClass(), propertyName);
    }

    /*
     * 循环向上转型,获取对象的DeclaredField.
     *
     * @throws NoSuchFieldException 如果没有该Field时抛出.
     */
    public static Field getDeclaredField(Class clazz, String propertyName) throws NoSuchFieldException {
        assert(clazz != null);
        assert(propertyName != null && !propertyName.isEmpty());
        //Assert.notNull(object);
        //Assert.hasText(propertyName);
        for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
            try {
                Field f = superClass.getDeclaredField(propertyName);
                if(f!=null)
                    return f;
            } catch (NoSuchFieldException e) {
                logger.debug(e.getMessage());
                // Field不在当前类定义,继续向上转型
            }
        }
        throw new NoSuchFieldException("No such field: " + clazz.getName() + '.' + propertyName);
    }

    /*
     * 获得对象的属性值
     * @param object
     * @param field
     * @return
     * @throws NoSuchFieldException
     */
    public static Object forceGetFieldValue(Object object,Field field ) {
        assert(object != null);

        boolean accessible = field.isAccessible();
        field.setAccessible(true);

        Object result = null;
        try {
            result = field.get(object);
        } catch (IllegalAccessException e) {
            logger.info("error wont' happen."+ e.getMessage());
        }
        field.setAccessible(accessible);
        return result;
    }


    /*
     * 获得get field value by getter
     */
    public static Object getFieldValue(Object obj,  String fieldName) {
        Method md=null;
        try {
            md = obj.getClass().getMethod("get" + StringUtils.capitalize(fieldName));
        }catch (NoSuchMethodException noGet ){
            try {
                md = obj.getClass().getMethod("is" + StringUtils.capitalize(fieldName));
            }catch (Exception e ){
                logger.error(noGet.getMessage() + e.getMessage());
            }
        }catch (Exception e) {
            logger.error(e.getMessage());
        }

        if(md==null){
            try{
                return forceGetProperty(obj, fieldName);
            }catch (Exception e) {
                logger.error(e.getMessage());
            }
        }else{
            try{
                return md.invoke(obj);
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        }
        return null;
    }

    public static boolean setFieldValue(Object object, String fieldName, Object newValue, Class paramType) {
        Class relParamType = (paramType!=null)?paramType:(newValue!=null?newValue.getClass():null);
        boolean hasSetValue=false;
        if(relParamType != null) {
            try {
                Method md = object.getClass().getMethod("set" + StringUtils.capitalize(fieldName), relParamType);
                md.invoke(object, newValue);
                hasSetValue = true;
            } catch (NoSuchMethodException noSet) {
                logger.error(noSet.getMessage(), noSet);
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        }
        if(!hasSetValue){
            try{
                forceSetProperty(object, fieldName, newValue);
                hasSetValue = true;
            }catch (Exception e) {
                logger.error(e.getMessage());
            }
        }
        return hasSetValue;
    }

    public static boolean setFieldValue(Object object, String fieldName, Object newValue) {
            return setFieldValue(object, fieldName, newValue, null);
    }
    /*
     * 获得get field value by getter
     */
    public static Object getFieldValue(Object obj,  Field field) {
        try {
            return field.get(obj);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }


    /*
     * 获取对象变量值,忽略private,protected修饰符的限制.
     *
     * @throws NoSuchFieldException 如果没有该Field时抛出.
     */
    public static Object forceGetProperty(Object object, String propertyName) throws NoSuchFieldException {
        assert(object != null);
        assert(propertyName != null && !propertyName.isEmpty());

        Field field = getDeclaredField(object, propertyName);
/*        if(field==null){
            log.debug("property not found. (没有找到对应的属性) 对象:" + object.toString() +" 属性 :"+ propertyName);
            return null;
        }*/
        return  forceGetFieldValue(object,field);
    }

    /*
     * 设置对象变量值,忽略private,protected修饰符的限制.
     *
     * @throws NoSuchFieldException 如果没有该Field时抛出.
     */
    public static void forceSetProperty(Object object, String propertyName, Object newValue)
            throws NoSuchFieldException {
        assert(object != null);
        assert(propertyName != null && !propertyName.isEmpty());

        Field field = getDeclaredField(object, propertyName);
/*        if(field==null){
            log.debug("property not found. (没有找到对应的属性) 对象:" + object.toString() +" 属性 :"+ propertyName);
            return;
        }*/
        boolean accessible = field.isAccessible();
        if(!accessible) {
            field.setAccessible(true);
        }
        try {
            field.set(object, newValue);
        } catch (IllegalAccessException e) {
            logger.error("Error won't happen."+e.getMessage(), e);
        }
        if(!accessible) {
            field.setAccessible(accessible);
        }
    }

    /*
     * 调用对象函数,忽略private,protected修饰符的限制.
     *
     * @throws NoSuchMethodException 如果没有该Method时抛出.
     */
    public static Object invokePrivateMethod(Object object, String methodName, Object... params)
            throws NoSuchMethodException {
        assert(object != null);
        assert(methodName != null && !methodName.isEmpty());

        Class[] types = new Class[params.length];
        for (int i = 0; i < params.length; i++) {
            types[i] = params[i].getClass();
        }

        Class clazz = object.getClass();
        Method method = null;
        for (Class superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
            try {
                method = superClass.getDeclaredMethod(methodName, types);
                break;
            } catch (NoSuchMethodException e) {
                logger.debug("方法不在当前类定义,继续向上转型");
                // 方法不在当前类定义,继续向上转型
            }
        }

        if (method == null)
            throw new NoSuchMethodException("No Such Method:" + clazz.getSimpleName() + methodName);

        boolean accessible = method.isAccessible();
        method.setAccessible(true);
        Object result = null;
        try {
            result = method.invoke(object, params);
        } catch (Exception e) {
            //ReflectionUtils.handleReflectionException(e);
            logger.error(e.getMessage() );
            logger.error(e.getMessage(),e);//e.printStackTrace();
        }
        method.setAccessible(accessible);
        return result;
    }

    /*
     * 取得Field列表.
     */
    public static Field[] getFields(Object object) {
        return object.getClass().getDeclaredFields();
    }

    /*
     * 按Filed的类型取得Field列表.
     */
    public static List getFieldsByType(Object object, Class type) {
        List list = new ArrayList<>();
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (type.isAssignableFrom(field.getType())) {
                list.add(field);
            }
        }
        return list;
    }

    /*
     * 按FiledName获得Field的类型.
     */
    public static Class getPropertyType(Class type, String name) throws NoSuchFieldException {
        return getDeclaredField(type, name).getType();
    }



    /*
     * 获得field的getter函数名称.
     */
    public static String methodNameToField(String methodName) {
        if(methodName== null)
            return null;
        int sl = methodName.length();

        if( sl > 3 && (methodName.startsWith("get") || methodName.startsWith("set") ))
            return methodName.substring(3,4).toLowerCase() + methodName.substring(4);

        if( sl > 2 && methodName.startsWith("is"))
            return methodName.substring(2,3).toLowerCase() + methodName.substring(3);

        return methodName;
    }
    /*
     * 获得field的getter函数,如果找不到该方法,返回null.
     */
    public static Method getGetterMethod(Class classType, Class propertyType, String fieldName) {
        try {
            String getFuncName = (boolean.class.equals(propertyType) || Boolean.class.isAssignableFrom(propertyType))?
                  "is" + StringUtils.capitalize(fieldName) : "get" + StringUtils.capitalize(fieldName);
            Method md = classType.getMethod(getFuncName);
            if(propertyType.isAssignableFrom( md.getReturnType()))
                return md;
            else
                return null;
        } catch (NoSuchMethodException e) {
            logger.error(e.getMessage());
            return null;
        }
    }

    /*
     * 获得field的getter函数,如果找不到该方法,返回null.
     */
    public static Method getGetterMethod(Class classType,  String fieldName) {
        try {
            Method md = classType.getMethod("get" + StringUtils.capitalize(fieldName));
            if(void.class.equals(md.getReturnType()))
                return null;
            else
                return md;
        } catch (NoSuchMethodException e) {
            logger.error(e.getMessage());
            return null;
        }
    }

    /*
     * 获得field的getter函数,如果找不到该方法,返回null.
     */
    public static Method getSetterMethod(Class classType, Class propertyType, String fieldName) {
        try {
            return classType.getMethod("set" + StringUtils.capitalize(fieldName), propertyType);
        } catch (NoSuchMethodException e) {
            logger.error(e.getMessage());
            return null;
        }
    }

    /*
     * 获得 对象的 属性
     * @param sourceObj
     * @param expression
     * @return
     */
    public static Object attainExpressionValue(Object sourceObj , String expression){
        if(sourceObj==null || StringUtils.isBlank(expression))
            return null;
        if(".".equals(expression))
            return sourceObj;

        int nPos = expression.indexOf('.');
        String fieldValue;
        String restExpression=".";
        if(nPos>0){
            fieldValue = expression.substring(0,nPos).trim();
            if(expression.length()>nPos+1)
                restExpression = expression.substring(nPos+1);
        }else
            fieldValue = expression.trim();

        int nAarrayInd = -1;
        nPos = fieldValue.indexOf('[');
        if(nPos>0){
            String sArrayInd = fieldValue.substring(nPos+1,fieldValue.length()-1);
            if(StringRegularOpt.isNumber(sArrayInd))
                nAarrayInd = Double.valueOf(sArrayInd).intValue();
            fieldValue = fieldValue.substring(0,nPos);
        }

        Object retObj;
        if(sourceObj instanceof Map ){
            @SuppressWarnings("unchecked")
            Map objMap = (Map) sourceObj;
            retObj = objMap.get(fieldValue);
        }else{
            //如果是一个标量则不应该再有属性,所以统一返回null
            if(ReflectionOpt.isScalarType(sourceObj.getClass())){
                return null;
            }else
                retObj = ReflectionOpt.getFieldValue(sourceObj,fieldValue);
        }

        if(retObj==null)
            return null;

        if(retObj instanceof Collection){
            Collection objlist = (Collection) retObj;
            int objSize = objlist.size();
            if(objSize<1)
                return null;

            if(nAarrayInd>=0){
                if( nAarrayInd =0){
                if(nAarrayInd  classType,  String fieldName) {
        try {
            return classType.getMethod("is" + StringUtils.capitalize(fieldName));
        } catch (NoSuchMethodException e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }
    /*
     * 获取所有getMethod方法
     */
    public static List getAllGetterMethod(Class type) {
        try {
            Method[] mths =  type.getMethods();
            List getMths = new ArrayList();
            for (Method mth : mths)
                if( ( mth.getName().startsWith("get") ||  mth.getName().startsWith("is") )
                        && ! mth.getName().equals("getClass")
                        && ! void.class.equals(mth.getReturnType())
                        //&& ! mth.getReturnType().getName().equals("void")
                        && mth.getGenericParameterTypes().length < 1 )
                    getMths.add(mth);
            return getMths;

        } catch (SecurityException e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }

    /*
     * 获取所有setMethod方法
     */
    public static List getAllSetterMethod(Class type) {
        try {
            Method[] mths =  type.getMethods();
            List setMths = new ArrayList();
            for (Method mth : mths) {
                String methodName = mth.getName();
                if(  methodName.startsWith("set")
                    &&  methodName.length()>=4
                        //&& mth.getReturnType().getName().equals("void")
                        && mth.getGenericParameterTypes().length == 1 ) {
                    setMths.add(mth);
                }
            }
            return setMths;

        } catch (SecurityException e) {
            logger.error(e.getMessage(), e);
        }
        return null;
    }

    /*
     * 调用对象的无参数函数
     */
    public static void  invokeNoParamFunc(Object demander,String smethod) {
        try {
            //"copyNotNullProperty"
            Method setV = demander.getClass().getMethod(smethod);
            //Class rt = d.getReturnType();
/*            if(setV == null)
                return;    */
            setV.invoke(demander);
        } catch (NoSuchMethodException | SecurityException
                | IllegalAccessException | InvocationTargetException e) {
            logger.error(e.getMessage(), e);
        }
    }

    /*
     * 调用相同类型的类之间的二元操作
     */
    public static   void  invokeBinaryOpt(T demander,String smethod,T param) {
        try {
            //"copyNotNullProperty"
            Method setV = demander.getClass().getMethod(smethod ,demander.getClass());
            //Class rt = d.getReturnType();
/*            if(setV == null)
                return;    */
            setV.invoke(demander,param);
        } catch (NoSuchMethodException | SecurityException | IllegalArgumentException
                | IllegalAccessException | InvocationTargetException e) {
            logger.error(e.getMessage(), e);
        }
    }

    /**
     * @param clazz The class to introspect
     * @return the first generic declaration, or Object.class if cannot be determined
     */
    public static Class getSuperClassGenricType(Class clazz) {
        return getSuperClassGenricType(clazz, 0);
    }

    /**
     * @param clazz
     *            clazz The class to introspect
     * @param index
     *            the Index of the generic declaration,start from 0.
     * @return the index generic declaration, or Object.class if
     *         cannot be determined
     */
    public static Class getSuperClassGenricType(Class clazz, int index) {

        Type genType = clazz.getGenericSuperclass();

        if (!(genType instanceof ParameterizedType)) {
            logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
            return Object.class;
        }

        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

        if (index >= params.length || index < 0) {
            logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "
                    + params.length);
            return Object.class;
        }
        if (!(params[index] instanceof Class)) {
            logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
            return Object.class;
        }
        return (Class) params[index];
    }


    /** isPrimitiveType
     * 判断一个类型是否是基础类型 int boolean void float double char
     * 或者单值类型 String Date Integer Float Double,  scalar
     * @param tp isPrimitiveType
     * @return isPrimitiveType
     */
    public static boolean isPrimitiveType(Class  tp){
        return tp.isPrimitive() || tp.getName().startsWith("java.lang.");
    }
    /** isScalarType
     * 判断一个类型是否是基础类型 int boolean void float double char
     * 或者单值类型 String Date Integer Float Double,  scalar
     * @param tp isScalarType
     * @return isScalarType
     */
    public static boolean isScalarType(Class  tp){
        if(tp.isPrimitive())
            return true;
        String tpName = tp.getName();
        if(tpName.startsWith("java.lang."))
            return true;
        if(tpName.startsWith("java.sql."))
            return true;
        if( java.util.Date.class.isAssignableFrom(tp))// "java.util.Date".equals(tp.getName()))
            return true;
        if( java.util.UUID.class.isAssignableFrom(tp))// "java.util.UUID".equals(tp.getName()))
            return true;

        return false;
    }

    public static boolean isNumberType(Class  tp){
        return java.lang.Number.class.isAssignableFrom(tp);
                //tp.getSuperclass().equals(Number.class) || tp.equals(Number.class);
    }
    /**
     * 判断一个对象是否是 数组[]、Collection(List)
     * @param obj 对象
     * @return 否是 数组[]
     */
    public static boolean isArray(Object obj){
        Class  tp = obj.getClass();
        if(tp.isArray())
            return true;
        //if(obj instanceof Object[])
        //    return true;
        if(obj instanceof Collection)
            return true;
        return false;
    }

    /**
     * 判断一个类型是否是 数组[]、Collection(List)
     * @param tp 类型
     * @return 否是 数组[]
     */
    public static boolean isArrayType(Class  tp){
        if(tp.isArray())
            return true;
        if(Collection.class.isAssignableFrom(tp))
            return true;
        return false;
    }

    /*
     *  得到当前方法的名字
     */
    public static String getCurrentMethodName(){
        return Thread.currentThread().getStackTrace()[1].getMethodName();
    }


    /*
     * 类 clazz 必需有一个无参数的默认构造函数
     * 这个Map需要和属性严格匹配,如果需要更灵活的匹配可以 使用OBNL
     *  或者转换为JSONString在用JSON转化为对象
     * @param clazz
     * @param properties
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws IllegalArgumentException
     */
    public  T createObjectFromMap( Class clazz, Map properties)
            throws InstantiationException, IllegalAccessException,
            IllegalArgumentException, InvocationTargetException{
        T obj = (T) clazz.newInstance();
        try {
            Method[] mths =  clazz.getMethods();
            for (Method mth : mths){
                Type[] paramTypes = mth.getGenericParameterTypes();
                String methodName = mth.getName();
                if(  methodName.startsWith("set")
                        &&  methodName.length()>=4
                        && paramTypes.length == 1 ){
                    Object value = properties.get(methodName.substring(3,4).toLowerCase() + methodName.substring(4));
                    if(value!=null){
                        mth.invoke(obj,value);
                    }
                }
            }
        } catch (SecurityException e) {
            logger.error(e.getMessage(), e);
        }
        return obj;
    }


    public static String getJavaTypeName(Class type) {

        String typeName = type.getTypeName();
        if(typeName.indexOf('.')<1) {
            return typeName;
        } else if(typeName.startsWith("java.lang.")
                || "java.util.Date".equals(typeName)
                || "java.sql.Clob".equals(typeName)
                || "java.sql.Blob".equals(typeName)
                || "java.util.UUID".equals(typeName)
                || "java.math.BigDecimal".equals(typeName)
                || "java.math.BigInteger".equals(typeName)) {
            return FileType.getFileExtName(typeName);
        } else if(typeName.startsWith("java.sql.")) {
            return "sql" + FileType.getFileExtName(typeName);
        } else {
            return typeName;
        }
    }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy