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

com.almondtools.picklock.Converter Maven / Gradle / Ivy

package com.almondtools.picklock;

import static com.almondtools.picklock.SignatureUtil.findTargetTypeName;
import static com.almondtools.picklock.SignatureUtil.isBooleanGetter;
import static com.almondtools.picklock.SignatureUtil.isGetter;
import static com.almondtools.picklock.SignatureUtil.isSetter;
import static com.almondtools.picklock.SignatureUtil.propertyOf;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class Converter {

	private static final int GETTER = 0;
	private static final int SETTER = 1;

	private Map properties;

	public Converter() {
		properties = new LinkedHashMap();
	}

	public void addGetter(Method method) {
		Method[] methods = fetchMethods(method);
		methods[GETTER] = method;
	}

	public void addSetter(Method method) {
		Method[] methods = fetchMethods(method);
		methods[SETTER] = method;
	}

	private Method[] fetchMethods(Method method) {
		String name = propertyOf(method);
		Method[] methods = properties.get(name);
		if (methods == null) {
			methods = new Method[2];
			properties.put(name, methods);
		}
		return methods;
	}

	public List getReadWritablePropertyPairs() {
		List propertyPairs = new ArrayList();
		for (Method[] pair : properties.values()) {
			if (pair[0] != null && pair[1] != null) {
				propertyPairs.add(pair);
			}
		}
		return propertyPairs;
	}

	public static String[] determineNeededConversions(Annotation[][] parameterAnnotations, Class[] parameterTypes) {
		String[] convert = new String[parameterAnnotations.length];
		for (int i = 0; i < parameterAnnotations.length; i++) {
			convert[i] = findTargetTypeName(parameterAnnotations[i], parameterTypes[i]);
		}
		return convert;
	}

	public static Object[] convertArguments(Class[] targetTypes, Class[] methodTypes, Object... args) throws InstantiationException, IllegalAccessException, NoSuchMethodException,
		IllegalArgumentException, InvocationTargetException, SecurityException {
		if (args == null) {
			args = new Object[0];
		}
		Object[] converted = new Object[args.length];
		Class[] targetArgumentTypes = targetTypes;
		Class[] methodArgumentTypes = methodTypes;
		for (int i = 0; i < args.length; i++) {
			converted[i] = convertArgument(targetArgumentTypes[i], methodArgumentTypes[i], args[i]);
		}
		return converted;
	}

	public static Object convertArgument(Class targetType, Class methodType, Object arg) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
		if (targetType.equals(methodType)) {
			return arg;
		} else {
			return convert(arg, methodType, targetType);
		}
	}

	public static Object convertResult(Class targetType, Class methodType, Object result) throws NoSuchMethodException {
		if (targetType.isAssignableFrom(methodType)) {
			return result;
		} else if (result == null) {
			return null;
		} else {
			return ObjectAccess.unlock(result).features(targetType);
		}
	}

	public static boolean isConverted(Method method) {
		if (method.getAnnotation(Convert.class) != null) {
			return true;
		}
		Annotation[][] parameterAnnotations = method.getParameterAnnotations();
		Class[] parameterTypes = method.getParameterTypes();
		for (int i = 0; i < parameterTypes.length; i++) {
			Class parameterType = parameterTypes[i];
			Annotation[] annotations = parameterAnnotations[i];
			if (findTargetTypeName(annotations, parameterType) != null) {
				return true;
			}
		}
		return false;
	}

	public static Object convert(Object object, Class clazz, Class accessibleClass) throws InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException,
		InvocationTargetException, SecurityException {
		if (object instanceof Proxy) {
			InvocationHandler invocationHandler = Proxy.getInvocationHandler((Proxy) object);
			if (invocationHandler instanceof ObjectAccess) {
				return ((ObjectAccess) invocationHandler).getObject();
			}
		}
		Object converted = createBaseObject(clazz, accessibleClass);
		Object accessible = ObjectAccess.unlock(converted).features(accessibleClass);
		for (Method[] getSetPair : findProperties(accessibleClass)) {
			Method get = getSetPair[0];
			get.setAccessible(true);
			Method set = getSetPair[1];
			set.setAccessible(true);
			Object value = get.invoke(object);
			set.invoke(accessible, value);
		}
		return converted;
	}

	private static Object createBaseObject(Class clazz, Class accessibleClass) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
		Constructor constructor = clazz.getDeclaredConstructor();
		constructor.setAccessible(true);
		return constructor.newInstance();
	}

	private static List findProperties(Class accessibleClass) {
		Converter converter = new Converter();
		for (Method method : accessibleClass.getDeclaredMethods()) {
			if (isSetter(method)) {
				converter.addSetter(method);
			} else if (isGetter(method) || isBooleanGetter(method)) {
				converter.addGetter(method);
			}
		}
		return converter.getReadWritablePropertyPairs();
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy