package com.tinkerpop.frames; import java.beans.Introspector; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; import java.util.Map; import com.tinkerpop.blueprints.Vertex; import org.apache.commons.lang3.StringUtils; public class ClassUtilities { private static final String SET = "set"; private static final String GET = "get"; private static final String REMOVE = "remove"; private static final String ADD = "add"; private static final String IS = "is"; private static final String CAN = "can"; public static Method getGetterMethodForSetter(final Method setterMethod) { String propertyName = getBeanPropertyName(setterMethod); if (StringUtils.isBlank(propertyName)) return null; for (Method method : setterMethod.getDeclaringClass().getMethods()) { if (isGetMethod(method) && getBeanPropertyName(method).equals(propertyName)) { return method; } } return null; } public static Method getSetterMethodForGetter(final Method getterMethod) { String propertyName = getBeanPropertyName(getterMethod); if (StringUtils.isBlank(propertyName)) return null; for (Method method : getterMethod.getDeclaringClass().getMethods()) { if (isSetMethod(method) && getBeanPropertyName(method).equals(propertyName)) { return method; } } return null; } public static String getBeanPropertyName(final Method method) { String methodName = method.getName(); Class<?> returnType = method.getReturnType(); boolean returnTypeIsBoolean = (returnType == Boolean.class || returnType == Boolean.TYPE); String propertyName; if (methodName.startsWith(GET)) propertyName = Introspector.decapitalize(StringUtils.removeStart(methodName, GET)); else if (methodName.startsWith(SET)) propertyName = Introspector.decapitalize(StringUtils.removeStart(methodName, SET)); else if (returnTypeIsBoolean && methodName.startsWith(IS)) propertyName = Introspector.decapitalize(StringUtils.removeStart(methodName, IS)); else if (returnTypeIsBoolean && methodName.startsWith(CAN)) propertyName = Introspector.decapitalize(StringUtils.removeStart(methodName, CAN)); else propertyName = null; return propertyName; } public static boolean isGetMethod(final Method method) { Class<?> returnType = method.getReturnType(); return (method.getName().startsWith(GET) || (returnType == Boolean.class || returnType == Boolean.TYPE) && (method.getName().startsWith(IS) || method.getName().startsWith(CAN))); } public static boolean isSetMethod(final Method method) { return method.getName().startsWith(SET); } public static boolean isRemoveMethod(final Method method) { return method.getName().startsWith(REMOVE); } public static boolean acceptsIterable(final Method method) { return 1 == method.getParameterTypes().length && Iterable.class.isAssignableFrom(method.getParameterTypes()[0]); } public static boolean returnsIterable(final Method method) { return Iterable.class.isAssignableFrom(method.getReturnType()); } public static boolean returnsVertex(final Method method) { return Vertex.class.isAssignableFrom(method.getReturnType()); } public static boolean returnsMap(final Method method) { return Map.class.isAssignableFrom(method.getReturnType()); } public static boolean isAddMethod(final Method method) { return method.getName().startsWith(ADD); } public static Type getType(Type[] types, int pos) { if (pos >= types.length) { throw new RuntimeException("No type can be found at position " + pos); } return types[pos]; } public static Class<?> getActualType(Type genericType, int pos) { if (genericType == null) { return null; } if (!ParameterizedType.class.isAssignableFrom(genericType.getClass())) { if (genericType instanceof TypeVariable) { genericType = getType(((TypeVariable<?>) genericType).getBounds(), pos); } else if (genericType instanceof WildcardType) { WildcardType wildcardType = (WildcardType) genericType; Type[] bounds = wildcardType.getLowerBounds(); if (bounds.length == 0) { bounds = wildcardType.getUpperBounds(); } genericType = getType(bounds, pos); } Class<?> cls = (Class<?>) genericType; return cls.isArray() ? cls.getComponentType() : cls; } ParameterizedType paramType = (ParameterizedType) genericType; Type t = getType(paramType.getActualTypeArguments(), pos); return t instanceof Class ? (Class<?>) t : getActualType(t, pos); } @SuppressWarnings("rawtypes") public static Class getGenericClass(final Method method) { final Type returnType = method.getGenericReturnType(); return getActualType(returnType, 0); } }