Package net.sourceforge.javautil.common

Source Code of net.sourceforge.javautil.common.ReflectionUtil

package net.sourceforge.javautil.common;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sourceforge.javautil.common.coersion.CoersionContext;
import net.sourceforge.javautil.common.coersion.CoersionException;
import net.sourceforge.javautil.common.context.Context;
import net.sourceforge.javautil.common.exception.ThrowableManagerRegistry;
import net.sourceforge.javautil.common.io.IVirtualDirectory;
import net.sourceforge.javautil.common.io.IVirtualFile;
import net.sourceforge.javautil.common.io.impl.ISystemArtifact;
import net.sourceforge.javautil.common.io.impl.SystemDirectory;
import net.sourceforge.javautil.common.io.impl.SystemFile;
import net.sourceforge.javautil.common.reflection.ReflectionContext;
import net.sourceforge.javautil.common.reflection.cache.ClassCache;
import net.sourceforge.javautil.common.reflection.cache.ClassDescriptor;
import net.sourceforge.javautil.common.reflection.cache.ClassField;

/**
* Utilities/methods for dealing with reflection.
*
* @author ponder
* @author $Author: ponderator $
* @version $Id: ReflectionUtil.java 2722 2011-01-16 05:38:59Z ponderator $
*/
public class ReflectionUtil {
 
  /**
   * @param type The type in question
   * @param index The index of the possible parameterized type
   * @return The concrete class (minimum/base) for the generic type, or null if it could not be determined or was not declared
   */
  public static Class<?> getConcreteGeneric (Type type, int index) {
    if (type instanceof ParameterizedType) {
      ParameterizedType pt = (ParameterizedType) type;
      if (pt.getActualTypeArguments().length <= index) return null;
      return pt.getActualTypeArguments()[index] instanceof ParameterizedType ?
        getConcreteGeneric(pt.getRawType(), 0) : getConcreteGeneric(pt.getActualTypeArguments()[index], 0);
    } else if (type instanceof WildcardType) {
      WildcardType wt = (WildcardType) type;
      return wt.getUpperBounds().length <= index ? null : getConcreteGeneric(wt.getUpperBounds()[index], 0);
    } else if (type instanceof TypeVariable) {
      TypeVariable tt = (TypeVariable) type;
      return tt.getBounds().length <= index ? null : getConcreteGeneric(tt.getBounds()[index], 0);
    } else if (type instanceof GenericArrayType) {
      GenericArrayType gat = (GenericArrayType) type;
      return getConcreteGeneric(gat.getGenericComponentType(), index);
    } else if (type instanceof Class) {
      return (Class) type;
    }
    return null;
  }
 
  /**
   * @param parameters The parameters for a method or constructor invocation
   * @return The classes for each parameter, if a parameter is null, the type will be Object
   */
  public static Class[] getClassesFor (Object... parameters) {
    Class[] types = new Class[parameters.length];
    for (int p=0; p<parameters.length; p++) {
      types[p] = parameters[p] == null ? Object.class : parameters[p].getClass();
    }
    return types;
  }
 
  /**
   * @param type The type from which to extract a super class set
   * @return A unique set of super-classes (including the passed type) for this type in order of bottom-top hierarchy
   */
  public static Set<Class<?>> extractSuperclasses (Class<?> type) {
    return new RecursiveOperation<Class<?>, Set<Class<?>>>(type) {
     
      @Override protected Class<?>[] evaluate(Class<?> instance, Set<Class<?>> result) {
        result.add(instance);
        return instance.getSuperclass() == null ? new Class[0] : new Class[] { instance.getSuperclass() };
      }
     
    }.execute(new LinkedHashSet<Class<?>>());
  }
 
  /**
   * @param type The type from which to extract all unique interfaces
   * @return A unique set of interfaces (including the passed type of an interface) declared in order of bottom-top hierarchy
   */
  public static Set<Class<?>> extractInterfaces (Class<?> type) {
    return new RecursiveOperation<Class<?>, Set<Class<?>>>(type) {
     
      @Override protected Class<?>[] evaluate(Class<?> instance, Set<Class<?>> result) {
        if (instance.isInterface()) result.add(instance);
        return instance.getInterfaces();
      }
     
    }.execute(new LinkedHashSet<Class<?>>());
  }
 
  /**
   * @param name The name of the class
   * @return The class
   */
  public static Class getClass (String name) {
    return getClass(name, Thread.currentThread().getContextClassLoader());
  }
 
  /**
   * @param name The name of the class
   * @param loader The {@link ClassLoader} to use to load the class
   * @return The class
   */
  public static Class getClass (String name, ClassLoader loader) {
    try {
      return ReflectionContext.getReflectionManager().getClass(name, false, loader);
    } catch (ClassNotFoundException e) {
      throw new RuntimeException(e);
    }
  }
 
  /**
   * @param <T> The type of object that will be created
   * @param clazz The class to make a new instance of
   * @param types The parameter type list of the constructor to use
   * @param parameters The arguments to pass to the constructor
   * @return The new instance
   */
  public static <T> T newInstance (Class<T> clazz, Class[] types, Object... parameters) {
    try {
      return ReflectionContext.getReflectionManager().instantiate(clazz, types, parameters);
    } catch (IllegalArgumentException e) {
      throw new RuntimeException(e);
    } catch (InstantiationException e) {
      throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
      throw new RuntimeException(e);
    } catch (InvocationTargetException e) {
      throw new RuntimeException(e);
    } catch (NoSuchMethodException e) {
      throw new RuntimeException(e);
    }
  }
 
  /**
   * @param object The object to invoke the method on
   * @param name The name of the method
   * @return What is returned by the method
   */
  public static Object invokeMethod (Object object, String name) {
    return invokeMethod(object.getClass(), name, object);
  }
 
  /**
   * @param clazz The class to invoke this static method on
   * @param name The name of the static method
   * @return What is returned by the method
   */
  public static Object invokeMethod (Class clazz, String name) {
    return invokeMethod(clazz, name, (Object) null);
  }
 
  /**
   * @param clazz The class for method lookup
   * @param name The name of the method to invoke
   * @param target The object to invoke the method on
   * @return What is returned by the method
   */
  public static Object invokeMethod (Class clazz, String name, Object target) {
    return invokeMethod(clazz, name, target, Object.class);
  }
 
  /**
   * @param <T> The type expected to be returned
   * @param object The object to invoke the method on
   * @param name The name of the method
   * @param returnType The class of the type
   * @return What is returned by the method
   */
  public static <T> T invokeMethod (Object object, String name, Class<T> returnType) {
    return invokeMethod(object.getClass(), name, object, returnType);
  }
 
  /**
   * @param <T> The type expected to be returned
   * @param clazz The class for method lookup
   * @param name The name of the method
   * @param target The object to invoke the method on
   * @param returnType The class of the type
   * @return What is returned by the method
   */
  public static <T> T invokeMethod (Class clazz, String name, Object target, Class<T> returnType) {
    return invokeMethod(clazz, name, target, returnType, new Class[0]);
  }
 
  /**
   * @param <T> The type expected to be returned
   * @param object The object to invoke the method on
   * @param name The name of the method
   * @param returnType The class of the type
   * @param types The list of argument types
   * @param parameters The arguments to be passed to the method invocation
   * @return What is returned by the method
   */
  public static <T> T invokeMethod (Object object, String name, Class<T> returnType, Class[] types, Object... parameters) {
    return invokeMethod(object.getClass(), name, object, returnType, types, parameters);
  }
 
  /**
   * @param <T> The type expected to be returned
   * @param clazz The class for method lookup
   * @param name The name of the method
   * @param target The object to invoke the method on
   * @param returnType The class of the type
   * @param types The list of argument types
   * @param parameters The arguments to be passed to the method invocation
   * @return What is returned by the method
   */
  public static <T> T invokeMethod (Class clazz, String name, Object target, Class<T> returnType, Class[] types, Object... parameters) {
    try {
      return target == null ?
        (T) ReflectionContext.getReflectionManager().invoke(clazz, name, types, parameters) :
        (T) ReflectionContext.getReflectionManager().invoke(target, name, types, parameters);
    } catch (IllegalArgumentException e) {
      throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
      throw new RuntimeException(e);
    } catch (InvocationTargetException e) {
      throw new RuntimeException(e);
    } catch (NoSuchMethodException e) {
      throw new RuntimeException(e);
    }
  }
 
  /**
   * Facility, will wrap {@link ClassNotFoundException}'s
   * into {@link RuntimeException}'s.
   *
   * @param fqn The fully qualified class name
   * @return The class loaded
   */
  public static Class<?> forName (String fqn) {
    try {
      return ReflectionContext.getReflectionManager().getClass(fqn, false, Thread.currentThread().getContextClassLoader());
    } catch (ClassNotFoundException e) {
      throw new RuntimeException(e);
    }
  }
 
  /**
   * Assumes the use of the current thread-level class loader.
   *
   * @see #classExists(ClassLoader, String)
   */
  public static boolean classExists (String fqn) { return classExists(Thread.currentThread().getContextClassLoader(), fqn); }
 
  /**
   * @param loader The class loader to use to attempt loading the class
   * @param fqn The fully qualified class name
   * @return True if the class can be loaded by the current thread level CL, otherwise false
   */
  public static boolean classExists (ClassLoader loader, String fqn) {
    try {
      ReflectionContext.getReflectionManager().getClass(fqn, false, loader);
      return true;
    } catch (ClassNotFoundException e) {
      return false;
    }
  }
 
  /**
   * This will use {@link #coerce(Class, String)} to attempt to
   * convert a particular string to the type specified.
   *
   * @param types The types of classes expected
   * @param args The string array of arguments to coerce
   * @return An array of objects representing the coerced arguments
   */
  public static Object[] coerce (Class[] types, String[] args) {
    if (types.length == 1 && types[0] == String[].class) return args;
    Object[] coerced = new Object[types.length];
    for (int i=0; i<types.length; i++) {
      if (i >= args.length) coerced[i] = null;
      else coerced[i] = coerceString(types[i], args[i]);
    }
    return coerced;
  }
 
  /**
   * @param type The type to coerce to
   * @param arg The argument to coerce
   * @return The coerced object
   *
   * @throws IllegalArgumentException
   */
  public static <T> T coerce (Class<T> type, Object arg) {
    if (arg == null) {
      if (type.isPrimitive()) { return (T) getPrimitiveDefault(type); }
      return null;
    }
    return CoersionContext.get().coerce(arg, type);
  }
 
  /**
   * @param type The primitive type
   * @return The default value for the primitive type
   */
  public static Object getPrimitiveDefault (Class type) {
    if (type == boolean.class || type == Boolean.class) return Boolean.FALSE;
    else if (type == int.class || type == Integer.class) return new Integer(0);
    else if (type == float.class || type == Float.class) return new Float(0);
    else if (type == double.class || type == Double.class) return new Double(0);
    else if (type == byte.class || type == Byte.class) return new Byte((byte)0);
    else if (type == char.class || type == Character.class) return new Character((char)0);
    else if (type == short.class || type == Short.class) return new Short((short)0);
    else if (type == long.class || type == Long.class) return new Long(0);
    else if (type == void.class || type == Void.class) return null;
   
    throw new IllegalArgumentException("Not a primitive type: " + type);
  }
 
  /**
   * @param primitiveType The primitive class
   * @param type The type to validate
   * @return True if the type is the boxed type of the primitive passed
   */
  public static boolean isPrimitiveBoxedType (Class primitiveType, Class type) {
    if (primitiveType == int.class && type == Integer.class) return true;
    if (primitiveType == long.class && type == Long.class) return true;
    if (primitiveType == short.class && type == Short.class) return true;
    if (primitiveType == byte.class && type == Byte.class) return true;
    if (primitiveType == boolean.class && type == Boolean.class) return true;
    if (primitiveType == char.class && type == Character.class) return true;
    if (primitiveType == float.class && type == Float.class) return true;
    if (primitiveType == double.class && type == Double.class) return true;
    if (primitiveType == void.class && type == Void.class) return true;
   
    return false;
  }
 
  /**
   * @param type The type in question (must be a primitive)
   * @return The equivalent boxed type
   */
  public static Class getBoxedType (Class type) {
    if (type == int.class) return Integer.class;
    if (type == long.class) return Long.class;
    if (type == short.class) return Short.class;
    if (type == byte.class) return Byte.class;
    if (type == boolean.class) return Boolean.class;
    if (type == char.class) return Character.class;
    if (type == float.class) return Float.class;
    if (type == double.class) return Double.class;
    if (type == void.class) return Void.class;
   
    throw new IllegalArgumentException("Not a primitive type: " + type);
  }

  /**
   * @param type The type in question (must be a boxed primitive)
   * @return The equivalent primitive type
   */
  public static Class getPrimitiveType (Class type) {
    if (type == Integer.class) return int.class;
    if (type == Long.class) return long.class;
    if (type == Short.class) return short.class;
    if (type == Byte.class) return byte.class;
    if (type == Boolean.class) return boolean.class;
    if (type == Character.class) return char.class;
    if (type == Float.class) return float.class;
    if (type == Double.class) return double.class;
   
    throw new IllegalArgumentException("Not a primitive type: " + type);
  }
 
  /**
   * @param type The type in question
   * @return True if the type is a primitive boxed type
   */
  public static boolean isBoxedType (Class type) {
    return type == Integer.class ||
      type == Long.class ||
      type == Short.class ||
      type == Byte.class ||
      type == Boolean.class ||
      type == Character.class ||
      type == Float.class ||
      type == Double.class;
  }
 
  /**
   * This will use the {@link CoersionContext} to coerce the string into the specified type.
   *
   * @throws IllegalArgumentException
   */
  public static Object coerceString (Class type, String arg) {
    return Context.get(CoersionContext.class).getProvider().coerce(arg, type);
  }
 
  /**
   * Facility, wraps {@link InstantiationException} and {@link IllegalAccessException}
   * in a {@link RuntimeException}. This will only use the no-arg constructor.
   *
   * @param type The class/type to create a new instance
   * @return A new instance of the class
   */
  public static Object instantiate (Class type) {
    try {
      return ReflectionContext.getReflectionManager().instantiate(type);
    } catch (InstantiationException e) {
      throw new RuntimeException(e);
    } catch (InvocationTargetException e) {
      throw new RuntimeException(e);
    } catch (NoSuchMethodException e) {
      throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
      throw new RuntimeException(e);
    }
  }
 
  /**
   * This will assume no instance is needed. The method passed must be a static method.
   *
   * @see #callWithOptionalParameters(Method, Object, Object...)
   */
  public static Object callStaticWithOptionalParameters (Method method, Object... parameters) {
    return callWithOptionalParameters(method, null, parameters);
  }
 
  /**
   * This will assume no instance is needed. The method passed must be a static method.
   *
   * @see #call(Method, Object, Object...)
   */
  public static Object callStatic (Method method, Object... parameters) {
    return call(method, null, parameters);
  }
 
  /**
   * This will shorten the argument array if the amount of parameters accepted by
   * the method is less that the arguments provided.
   *
   * @see #call(Method, Object, Object...)
   */
  public static Object callWithOptionalParameters (Method method, Object instance, Object... parameters) {
    Object[] pars = new Object[method.getParameterTypes().length];
    System.arraycopy(parameters, 0, pars, 0, pars.length);
    return call(method, instance, pars);
  }
 
  /**
   * @param method The method to invoke
   * @param instance The instance to invoke the method on, null if the method is static
   * @param parameters The parameters to pass to the method
   * @return The value returned by the method, null if null returned or void
   */
  public static Object call (Method method, Object instance, Object... parameters) {
    try {
      return ReflectionContext.getReflectionManager().invoke(instance, method, parameters);
    } catch (IllegalArgumentException e) {
      throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
      throw new RuntimeException(e);
    } catch (InvocationTargetException e) {
      throw new RuntimeException(e);
    }
  }
 

}
TOP

Related Classes of net.sourceforge.javautil.common.ReflectionUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.