package edu.ucsd.arcum.util; import java.lang.reflect.*; import com.google.common.base.Function; import com.google.inject.TypeLiteral; public class Accessor { public static <R, D> Function<R, D> getFunction(Class<R> range, Class<D> domain, String methodName) { try { final Method method = range.getMethod(methodName); return new Function<R, D>() { public D apply(R from) { try { return (D)method.invoke(from); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } }; } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } public static <R, D> Function<R, D> getFunction(TypeLiteral<R> range, TypeLiteral<D> domain, String methodName) { // The raw type contains the actual method; we provide the TypeLiterals // only to allow Functions to be created with more specific types Class<?> rawRange = getRawType(range.getType()); Class<?> rawDomain = getRawType(domain.getType()); return (Function<R, D>)getFunction(rawRange, rawDomain, methodName); } private static Class<?> getRawType(Type type) { // Copied implementation from com.google.inject.TypeLiteral#getRawType, 2006 Google if (type instanceof Class<?>) { return (Class<?>)type; } else if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType)type; return (Class<?>)parameterizedType.getRawType(); } else if (type instanceof GenericArrayType) { return Object[].class; } return null; } }