ClassUtils.java :  » App » droidog » org » droidog » utils » Android Open Source

Android Open Source » App » droidog 
droidog » org » droidog » utils » ClassUtils.java
package org.droidog.utils;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * Class Utils
 * @author <a href="mailto:jfox.young@gmail.com">Young Yang</a>
 */

public class ClassUtils {

    public static final  Class[] EMPTY_CLASS_ARRAY = new Class[0];

    public static final char INNER_CLASS_SEPARATOR_CHAR = '$';

    private static Map<String, Class> primitiveStringToClass = new HashMap<String, Class>();

    static {
        primitiveStringToClass.put(boolean.class.getName(), Boolean.class);
        primitiveStringToClass.put(byte.class.getName(), Byte.class);
        primitiveStringToClass.put(char.class.getName(), Character.class);
        primitiveStringToClass.put(short.class.getName(), Short.class);
        primitiveStringToClass.put(int.class.getName(), Integer.class);
        primitiveStringToClass.put(long.class.getName(), Long.class);
        primitiveStringToClass.put(double.class.getName(), Double.class);
        primitiveStringToClass.put(float.class.getName(), Float.class);
    }

    private ClassUtils() {
    }

    public static Class[] getAllSuperclasses(Class cls) {
        if (cls == null) {
            return new Class[0];
        }
        List<Class> classList = new ArrayList<Class>();
        Class superClass = cls;
        while (superClass != null && !Object.class.equals(superClass) && !Class.class.equals(superClass)) { // java.lang.Object not treat as superclass 
            classList.add(superClass);
            superClass = superClass.getSuperclass();
        }
        return classList.toArray(new Class[classList.size()]);
    }

    public static Class[] getAllInterfaces(Class clazz) {
        if (clazz == null) {
            return new Class[0];
        }
        List<Class> classList = new ArrayList<Class>();
        while (clazz != null) {
            Class[] interfaces = clazz.getInterfaces();
            for (Class interf : interfaces) {
                if (!classList.contains(interf)) {
                    classList.add(interf);
                }
                Class[] superInterfaces = getAllInterfaces(interf);
                for (Class superIntf : superInterfaces ) {
                    if (!classList.contains(superIntf)) {
                        classList.add(superIntf);
                    }
                }
            }
            clazz = clazz.getSuperclass();
        }
        return classList.toArray(new Class[classList.size()]);
    }

    public static boolean isAssignable(Class clazz, Class toClass) {
        if (clazz == null || toClass == null) {
            return false;
        }
        if (clazz.equals(toClass)) {
            return true;
        }

        Class newClazz = clazz;
        Class newToClass = toClass;
        if(clazz.isPrimitive()) {
            newClazz = primitiveStringToClass.get(clazz.getName());
        }
        if(toClass.isPrimitive()){
            newToClass = primitiveStringToClass.get(toClass.getName());
        }
        return newToClass.isAssignableFrom(newClazz);
    }

    public static boolean isAssignable(Class[] classArray, Class[] toClassArray) {
        if (classArray == null || toClassArray == null) {
            return false;
        }
        if (classArray.length != toClassArray.length) {
            return false;
        }

        for (int i = 0; i < classArray.length; i++) {
            if (!isAssignable(classArray[i], toClassArray[i])) {
                return false;
            }
        }
        return true;
    }

    /**
     * if is primitive class, get it's concrete class object else use reflect
     * with a string paramter constructor
     *
     * @param clazz class
     * @param value value
     * @return Object
     * @throws NoSuchMethodException e
     * @throws InstantiationException e
     * @throws IllegalAccessException e
     * @throws java.lang.reflect.InvocationTargetException e
     */
    public static <T> T newObject(Class<T> clazz, String value)
            throws NoSuchMethodException, InstantiationException,
            IllegalAccessException, InvocationTargetException {
        Object obj;
        if (clazz.isArray()) { // array
            Class<?> elementClass = clazz.getComponentType();
            StringTokenizer st = new StringTokenizer(value);
            int length = st.countTokens();
            Object array = Array.newInstance(elementClass, length);
            for (int i = 0; st.hasMoreTokens(); i++) {
                Object param = newObject(elementClass, st.nextToken());
                Array.set(array, i, param);
            }
            obj = array;
        }
        else {
            Class<T> clz = clazz;
            if (clazz.isPrimitive()) {
                clz = primitiveStringToClass.get(clazz.getName());
            }
            if(clz.equals(String.class)){
                obj = value;
            }
            else if(clz.equals(Character.class)) {
                obj = new Character(value.charAt(0));
            }
            else {
                // use String constructor
                obj = clz.getConstructor(String.class).newInstance(value);
            }
        }
        return (T)obj;
    }

    public static boolean isInnerClass(Class cls) {
        return (cls == null) ? false : (cls.getName().indexOf(INNER_CLASS_SEPARATOR_CHAR) >= 0);
    }


    public static Class getClass(String className) throws ClassNotFoundException {
        Class clazz;
        if (isPrimitiveClass(className)) {
            return primitiveStringToClass.get(className);
        }
        else {
            clazz = Class.forName(className);
        }
        return clazz;
    }


    public static Class getClass(ClassLoader classLoader, String className) throws ClassNotFoundException {
        Class clazz;
        if (isPrimitiveClass(className)) {
            return primitiveStringToClass.get(className);
        }
        else {
            clazz = classLoader.loadClass(className);
        }
        return clazz;
    }

    /**
     * Get a method corresponds with the name and parameterTypes
     * @param clazz class
     * @param methodName method name
     * @param parameterTypes parameter types
     * @throws NoSuchMethodException if not found such method
     */
    public static Method getCompatibleMethod(Class clazz, String methodName, Class[] parameterTypes) throws NoSuchMethodException {
        Method theMethod = null;
        try {
            theMethod = clazz.getMethod(methodName, parameterTypes);
        }
        catch (NoSuchMethodException e) {
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                if (method.getName().equals(methodName)) {
                    if (isAssignable(parameterTypes, method.getParameterTypes())) {
                        if (theMethod == null) {
                            theMethod = method;
                        }
                        else {
                            // get the most suitable method
                            if (isAssignable(method.getParameterTypes(), theMethod.getParameterTypes())) {
                                theMethod = method;
                            }
                        }
                    }
                }
            }
            if (theMethod == null)
                throw e;
        }
        return theMethod;
    }

    public static Method getCompatibleMethod(Method[] methods, Class[] parameterTypes) throws NoSuchMethodException {
        if(methods.length == 0) {
            return null;
        }
        Method theMethod = null;
        for (Method method : methods) {
            if (isAssignable(parameterTypes, method.getParameterTypes())) {
                if (theMethod == null) {
                    theMethod = method;
                }
                else {
                    // get more suitable method
                    if (isAssignable(method.getParameterTypes(), theMethod.getParameterTypes())) {
                        theMethod = method;
                    }
                }
            }
        }
        if(theMethod == null) {
            throw new NoSuchMethodException("No such method: " + methods[0].getName() + "(" + Arrays.toString(parameterTypes) + ") in class: " + methods[0].getDeclaringClass());
        }
        return theMethod;
    }

    public static <T> Constructor<T> getConstructor(Class<T> clazz, Class[] expectedTypes) throws NoSuchMethodException {
        Constructor<T> constructor = null;
        if (expectedTypes == null) {
            expectedTypes = EMPTY_CLASS_ARRAY;
        }
        try {
            constructor = clazz.getConstructor(expectedTypes);
        }
        catch (NoSuchMethodException e) {
            Constructor[] constructors = clazz.getConstructors();
            for (Constructor constr : constructors) {
                if (isAssignable(expectedTypes, constr.getParameterTypes())) {
                    if (constructor == null) {
                        constructor = (Constructor<T>)constr;
                    }
                    else {
                        if (isAssignable(constr.getParameterTypes(), constructor.getParameterTypes())) {
                            constructor = (Constructor<T>)constr;
                        }
                    }
                }
            }
            if (constructor == null)
                throw e;
        }
        return constructor;
    }

    /**
     * Get all fields declared in this class, includes super class's
     *
     * @param clazz class
     * @param name field name
     * @throws NoSuchFieldException if not found such field
     */
    public static Field getDeclaredField(Class clazz, String name) throws NoSuchFieldException {
        Field field = null;
        Class[] superClasses = getAllSuperclasses(clazz);
        for(Class superClass : superClasses){
            try {
                field = superClass.getDeclaredField(name);
                break;
            }
            catch (NoSuchFieldException e) {
                // ignore
            }
        }
        if (field == null) {
            throw new NoSuchFieldException("No such declared field " + name + " in " + clazz);
        }
        return field;
    }

    /**
     * Get all declared Fields array, include declared in supper classes.
     * if a field is re-declared in sub-class, will ignore super class one
     *
     * @param clazz class
     */
    public static Field[] getAllDeclaredFields(Class clazz) {
        List<Field> declaredFields = new ArrayList<Field>();
        List<String> declaredFiledNames = new ArrayList<String>();

        Class[] superClasses = getAllSuperclasses(clazz);
        for(Class superClass : superClasses){
            Field[] fields = superClass.getDeclaredFields();
            for(Field field : fields){
                if(!declaredFiledNames.contains(field.getName())) {
                    declaredFields.add(field);
                    declaredFiledNames.add(field.getName());
                }
            }
        }
        return declaredFields.toArray(new Field[declaredFields.size()]);
    }

    /**
     * get the narrowest class from the given types
     *
     * @param types class array
     */
    public static Class getNarrowestClass(Class[] types) {
        if (types == null || types.length == 0) {
            throw new IllegalArgumentException("types is null or empty.");
        }
        Class clz = types[0];
        for (int i = 1; i < types.length; i++) {
            if (clz.isAssignableFrom(types[i])) {
                clz = types[i];
            }
            else if (!types[i].isAssignableFrom(clz)) {
                throw new IllegalArgumentException(types[i].getName() + " not has assignable relation with " + clz.getName());
            }
        }

        return clz;
    }

    public static boolean isPrimitiveClass(String primitiveClassName) {
        return primitiveStringToClass.containsKey(primitiveClassName);
    }

    public static boolean isPrimitiveClass(Class primitiveClass) {
        return primitiveStringToClass.containsKey(primitiveClass.getName());
    }

    public static boolean isPrimitiveWrapperClass(Class primitiveWrapperClass){
        return primitiveStringToClass.values().contains(primitiveWrapperClass);
    }

    public static void main(String[] args) throws Exception {
        String[] strArray = newObject((new String[0]).getClass(), "1 2 3");
        System.out.println(Arrays.toString(strArray));
        System.out.println(newObject(boolean.class,"true"));
        System.out.println(Arrays.toString(getAllSuperclasses(ClassUtils.class)));
    }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.