package org.netbeans.gradle.model.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
public final class ReflectionUtils {
private static final Object[] EMPTY_ARR = new Object[0];
public static String updateTypeName(Class<?> defaultPackage, String typeName) {
if (typeName.indexOf('.') >= 0) {
return typeName;
}
return defaultPackage.getPackage().getName() + "." + typeName;
}
public static Method getAccessibleMethod(Class<?> type, String methodName, Class<?>... parameterTypes) throws NoSuchMethodException {
for (Method method: type.getMethods()) {
if (!Modifier.isPublic(method.getModifiers())) {
continue;
}
if (!Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
continue;
}
if (!methodName.equals(method.getName())) {
continue;
}
if (!Arrays.equals(parameterTypes, method.getParameterTypes())) {
continue;
}
return method;
}
Method method = type.getMethod(methodName, parameterTypes);
method.setAccessible(true);
return method;
}
private static Object callParameterLessMethodSimple(Object obj, String methodName) throws NoSuchMethodException {
try {
Method method = getAccessibleMethod(obj.getClass(), methodName);
return method.invoke(obj);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException(ex);
}
}
private static Object callParameterLessMethodDyn(Object obj, String methodName) throws NoSuchMethodException {
try {
Object dynObj = callParameterLessMethodSimple(obj, "getAsDynamicObject");
Method invokeMethod = getAccessibleMethod(dynObj.getClass(), "invokeMethod", String.class, Object[].class);
Object result = invokeMethod.invoke(dynObj, methodName, EMPTY_ARR);
return result;
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException(ex);
}
}
private static Object callParameterLessMethodSimpleFirst(Object obj, String methodName) {
try {
return callParameterLessMethodSimple(obj, methodName);
} catch (NoSuchMethodException ex) {
try {
return callParameterLessMethodDyn(obj, methodName);
} catch (NoSuchMethodException ex2) {
throw new RuntimeException(ex);
}
}
}
private static Object callParameterLessMethodDynFirst(Object obj, String methodName) {
try {
return callParameterLessMethodDyn(obj, methodName);
} catch (NoSuchMethodException ex) {
try {
return callParameterLessMethodSimple(obj, methodName);
} catch (NoSuchMethodException ex2) {
throw new RuntimeException(ex);
}
}
}
private static String getGetterOfProperty(String prefix, String propertyName) {
StringBuilder methodName = new StringBuilder(propertyName.length() + prefix.length());
methodName.append(prefix);
methodName.append(Character.toUpperCase(propertyName.charAt(0)));
methodName.append(propertyName.substring(1));
return methodName.toString();
}
private static Object getPropertySimpleFirst(Object obj, String prefix, String propertyName) {
String methodName = getGetterOfProperty(prefix, propertyName);
return callParameterLessMethodSimpleFirst(obj, methodName);
}
private static Object getPropertyDynFirst(Object obj, String prefix, String propertyName) {
String methodName = getGetterOfProperty(prefix, propertyName);
return callParameterLessMethodDynFirst(obj, methodName);
}
public static Object getNonBoolProperty(Object obj, String propertyName) {
return getPropertySimpleFirst(obj, "get", propertyName);
}
public static boolean getBoolProperty(Object obj, String propertyName) {
return (Boolean)getPropertySimpleFirst(obj, "is", propertyName);
}
public static Object getNonBoolPropertyDyn(Object obj, String propertyName) {
return getPropertyDynFirst(obj, "get", propertyName);
}
public static boolean getBoolPropertyDyn(Object obj, String propertyName) {
return (Boolean)getPropertyDynFirst(obj, "is", propertyName);
}
public static String getStringProperty(Object obj, String propertyName) {
Object result = getNonBoolProperty(obj, propertyName);
return result != null ? result.toString() : null;
}
public static boolean isPublic(Member member) {
int modifiers = member.getModifiers();
return (modifiers & Modifier.PUBLIC) != 0;
}
public static Method tryGetPublicMethod(
Class<?> type,
String methodName,
Class<?> returnType,
Class<?>... argTypes) {
try {
Method method = getAccessibleMethod(type, methodName, argTypes);
if (!isPublic(method)) {
return null;
}
if (!returnType.isAssignableFrom(method.getReturnType())) {
return null;
}
if (Modifier.isAbstract(method.getModifiers())) {
return null;
}
return method;
} catch (NoSuchMethodException ex) {
return null;
}
}
private ReflectionUtils() {
throw new AssertionError();
}
}