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

com.jsftoolkit.utils.ClassUtils Maven / Gradle / Ivy

package com.jsftoolkit.utils;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import com.jsftoolkit.utils.Utils.MapBuilder;

import static com.jsftoolkit.utils.Utils.notNull;

/**
 * Utility methods for handling Classes.
 * 
 * @author noah
 * 
 */
public class ClassUtils {

	/**
	 * Map of primitive type classes to their wrapper.
	 */
	private static final Map FROM_PRIMITIVE = MapBuilder
			.putFirst((Class) boolean.class, (Class) Boolean.class).put(
					byte.class, Byte.class).put(short.class, Short.class).put(
					int.class, Integer.class).put(long.class, Long.class).put(
					float.class, Float.class).put(double.class, Double.class)
			.put(char.class, Character.class).put(void.class, Void.class)
			.getMap();

	/**
	 * Returns the wrapper for the given primitive type.
	 * 
	 * @param primitive
	 * @return the wrapper for the given class, or primitive if it is not a
	 *         primitive type.
	 */
	public static Class box(Class primitive) {
		if (primitive == null || !primitive.isPrimitive()) {
			return primitive;
		}
		return FROM_PRIMITIVE.get(primitive);
	}

	private static final Class[] PRIMITIVES = { boolean.class, byte.class,
			short.class, int.class, long.class, float.class, double.class,
			char.class, void.class };

	private static final Map FROM_NAME;

	static {
		FROM_NAME = new HashMap();
		for (Class clazz : PRIMITIVES) {
			FROM_NAME.put(clazz.getName(), clazz);
		}
	}

	/**
	 * 
	 * @param name
	 * @return the primitive class object with the given name.
	 */
	public static Class forPrimitive(String name) {
		return FROM_NAME.get(name);
	}

	@SuppressWarnings("unchecked")
	public static  T invoke(Object obj, String methodName, Object... args)
			throws InvocationTargetException {
		notNull(obj, "obj");
		notNull(methodName, "methodName");
		notNull(args, "args");

		// find the first method that will accept args
		for (Method method : obj.getClass().getMethods()) {
			Class[] types = method.getParameterTypes();
			if (methodName.equals(method.getName())
					&& types.length == args.length) {
				if (typesMatch(types, args)) {
					try {
						return (T) method.invoke(obj, args);
					} catch (InvocationTargetException e) {
						throw e;
					} catch (Exception e) {
						// illegal access and illegal argument are not expected
						throw new RuntimeException(e);
					}
				}
			}
		}
		return null;
	}

	/**
	 * 
	 * @param types
	 * @param args
	 * @return true if the class of each of the args can be assigned to the
	 *         corresponding type, or is null.
	 */
	public static boolean typesMatch(Class[] types, Object[] args) {
		if (types.length != args.length) {
			return false;
		}
		int i = 0;
		for (Class type : types) {
			if (args[i] != null && !type.isAssignableFrom(args[i].getClass())) {
				// type doesn't match, skip the method
				return false;
			}
			i++;
		}
		return true;
	}

	/**
	 * @param 
	 * @param className
	 *            the name of the class to create an instance of
	 * @param args
	 *            the parameters to the constructor. Matched using
	 *            {@link #typesMatch(Class[], Object[])}
	 * @return a new instance if the class can be loaded and a matching
	 *         constructor can be found, otherwise null.
	 * @throws InvocationTargetException
	 *             if the constructor invocation throws an exception
	 * @throws NullPointerException
	 *             if className or params is null
	 * @throws RuntimeException
	 *             if an {@link IllegalAccessException},
	 *             {@link IllegalArgumentException} or
	 *             {@link InstantiationException} are thrown
	 * 
	 */
	@SuppressWarnings("unchecked")
	public static  T instantiate(String className, Object... args)
			throws InvocationTargetException {
		notNull(className, "className");
		notNull(args, "args");
		try {
			Class clazz = Class.forName(className);
			for (Constructor c : clazz.getConstructors()) {
				if (typesMatch(c.getParameterTypes(), args)) {
					try {
						return (T) c.newInstance(args);
					} catch (InvocationTargetException e) {
						throw e;
					} catch (Exception e) {
						// illegal argument, instantiation, and illegal access
						// exceptions are not expected
						throw new RuntimeException(e);
					}
				}
			}
		} catch (ClassNotFoundException e) {
			// ignore and return null
		}
		return null;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy