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

org.pure4j.model.AbstractHandle Maven / Gradle / Ivy

Go to download

Parses Byte-code to check the purity semantics defined using pure4j-core annotations

The newest version!
package org.pure4j.model;

import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.LinkedHashSet;
import java.util.Set;

import org.pure4j.exception.MemberCantBeHydratedException;
import org.pure4j.exception.Pure4JException;


public abstract class AbstractHandle implements Handle {

	public static Set> hydrateClasses(Set classNames, ClassLoader cl) {
		Set> out = new LinkedHashSet>(classNames.size());
		for (String n : classNames) {
			out.add(hydrateClass(n, cl));
		}

		return out;
	}

	public static Set hydratePackages(Set packageNames, ClassLoader cl) {
		Set out = new LinkedHashSet(packageNames.size());
		for (PackageHandle n : packageNames) {
			out.add(n.hydrate(cl));
		}

		return out;
	}

	public static Set hydrateMembers(Set members, ClassLoader cl) {
		Set out = new LinkedHashSet(members.size());
		for (MemberHandle n : members) {
			out.add(n.hydrate(cl));
		}

		return out;
	}

	public static Class hydrateClass(String className, ClassLoader cl) {
		try {
			String name = className.replace("/", ".");
			name = name.endsWith(";") ? name.substring(0, name.length() - 1) : name;
			
			if (name.startsWith("[")) {
				int lastBracket = name.lastIndexOf("[");
				String shortName = name.substring(lastBracket+1);
				if (shortName.startsWith("L")) {
					cl.loadClass(shortName.substring(1));
				}
				Class arrayClass = Class.forName(name+";");
				return arrayClass;
			} else {
				Class c = cl.loadClass(name);
				return c;
			}
		} catch (ClassNotFoundException e) {
			throw new Pure4JException("Could not load class: ", e);
		}
	}

	public static Package hydratePackage(String name, String classInPackage, ClassLoader cl) {
		name = name.replace("/", ".");
		Package out = Package.getPackage(name);
		if (out == null) {
			try {
				Class c = hydrateClass(classInPackage, cl);
				out = c.getPackage();

				if (out == null) {
					throw new Pure4JException("Hydrated " + classInPackage + " but package " + name
							+ " still not available");
				}

			} catch (Exception e) {
				throw new Pure4JException("Couldn't instantiate package object for: " + name, e);
			}

		}
		return out;
	}

	public static Class[] hydrateParams(Type[] types, ClassLoader cl) {
		if ((types == null) || (types.length == 0)) {
			return new Class[0];
		}

		Class[] out = new Class[types.length];
		for (int i = 0; i < types.length; i++) {
			Class el = null;
			if (types[i].getSort() == Type.ARRAY) {
				int dimensions = types[i].getDimensions();
				el = loadElementType(types[i].getElementType(), cl);
				el = Array.newInstance(el, dimensions).getClass();
			} else {
				el = loadElementType(types[i], cl);
			}
			out[i] = el;
		}

		return out;
	}

	private static Class loadElementType(Type type, ClassLoader cl) {
		if (type == Type.BOOLEAN_TYPE) {
			return boolean.class;
		} else if (type == Type.BYTE_TYPE) {
			return byte.class;
		} else if (type == Type.CHAR_TYPE) {
			return char.class;
		} else if (type == Type.DOUBLE_TYPE) {
			return double.class;
		} else if (type == Type.FLOAT_TYPE) {
			return float.class;
		} else if (type == Type.INT_TYPE) {
			return int.class;
		} else if (type == Type.LONG_TYPE) {
			return long.class;
		} else if (type == Type.SHORT_TYPE) {
			return short.class;
		} else if (type == Type.VOID_TYPE) {
			return void.class;
		} else {
			return hydrateClass(type.getClassName(), cl);
		}
	}

	public static Method hydrateMethod(MethodHandle method, ClassLoader cl) {
		Type[] args = Type.getArgumentTypes(method.getDesc());
		Class c = hydrateClass(method.getClassName(), cl);
		Class[] params = hydrateParams(args, cl);
		Method m = getDeclaredMethod(method.getName(), c, params, cl);

		if (m == null) {
			throw new MemberCantBeHydratedException(method);
		}
		return m;

	}

	public static Method getDeclaredMethod(String name, Class c, Class[] params, ClassLoader cl) {
		Method m = null;
		
		if (c==null) {
			return null;
		}
		
		try {
			m = c.getDeclaredMethod(name, params);
		} catch (NoSuchMethodException e) {
		}

		if ((m == null) && (!c.isInterface())) {
			m = getDeclaredMethod(name, c.getSuperclass(), params, cl);
		}

		if (m == null) {
			for (Class intf : c.getInterfaces()) {
				if (m == null) {
					m = getDeclaredMethod(name, intf, params, cl);
				}
			}
		}

		return m;

	}

	public static Constructor hydrateConstructor(ConstructorHandle con, ClassLoader cl) {
		try {
			Type[] args = Type.getArgumentTypes(con.getDesc());
			Class c = hydrateClass(con.getClassName(), cl);
			Class[] params = hydrateParams(args, cl);
			Constructor co = c.getDeclaredConstructor(params);
			return co;
		} catch (NoSuchMethodException e) {
			throw new Pure4JException("Could not find constructor: ", e);
		}
	}

	public static Field hydrateField(FieldHandle field, ClassLoader cl) {
		Class c = hydrateClass(field.getClassName(), cl);
		Field f = hydrateFieldOn(c, field.getName());
		if (f==null) {	
			throw new MemberCantBeHydratedException(field);
		}
		return f;
	}
	
	private static Field hydrateFieldOn(Class c, String name) {
		if (c == null) {
			return null;
		}
		try {
			Field f = c.getDeclaredField(name);
			return f;
		} catch (NoSuchFieldException e) {
		}
		return hydrateFieldOn(c.getSuperclass(), name);
	}

	public static String convertClassName(Class c) {
		return Type.getInternalName(c);
	}

	public static String convertClassName(String name) {
		return name.replace(".", "/");
	}

	public static String convertPackageName(Package p) {
		return p.getName().replace(".", "/");
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy