package org.netbeans.gradle.project.others; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Collections; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import org.netbeans.gradle.model.util.Exceptions; public final class ReflectionHelper { private static final Logger LOGGER = Logger.getLogger(ReflectionHelper.class.getName()); public static boolean isInstanceOf(Object obj, String requiredTypeName) { return isInstanceOfAny(obj, Collections.singleton(requiredTypeName)); } private static boolean isTypeOfAny(Class<?> type, Set<String> requiredTypeNames) { if (requiredTypeNames.contains(type.getName())) { return true; } for (Class<?> implementedIF: type.getInterfaces()) { if (requiredTypeNames.contains(implementedIF.getName())) { return true; } } Class<?> superclass = type.getSuperclass(); return superclass != null ? isTypeOfAny(superclass, requiredTypeNames) : false; } public static boolean isInstanceOfAny(Object obj, Set<String> requiredTypeNames) { if (obj == null) { return false; } return isTypeOfAny(obj.getClass(), requiredTypeNames); } private static boolean areParamsOk(Class<?>[] paramTypes, Map<Class<?>, Object> args) { for (Class<?> paramType: paramTypes) { if (!args.containsKey(paramType)) { return false; } } return true; } private static boolean isPublic(Member member) { return Modifier.isPublic(member.getModifiers()); } public static Object tryCreateInstance(Class<?> cl, Map<Class<?>, Object> args) { for (Constructor<?> constructor: cl.getConstructors()) { Class<?>[] paramTypes = constructor.getParameterTypes(); if (isPublic(constructor) && areParamsOk(paramTypes, args)) { Object[] passedArgs = new Object[paramTypes.length]; for (int i = 0; i < passedArgs.length; i++) { passedArgs[i] = args.get(paramTypes[i]); } try { return constructor.newInstance(passedArgs); } catch (InstantiationException | IllegalAccessException | IllegalArgumentException ex) { LOGGER.log(Level.WARNING, "Unexpected consturctor invocation error.", ex); } catch (InvocationTargetException ex) { throw Exceptions.throwUnchecked(ex.getCause()); } return null; } } return null; } public static Method tryGetMethod(Class<?> cl, String methodName, Class<?>... args) { try { return cl.getMethod(methodName, args); } catch (NoSuchMethodException ex) { return null; } } public static Object tryInvoke(Method method, Object obj, Object... args) { try { return method.invoke(obj, args); } catch (IllegalAccessException ex) { } catch (IllegalArgumentException ex) { LOGGER.log(Level.WARNING, "Unexpected IllegalArgumentException.", ex); } catch (InvocationTargetException ex) { throw Exceptions.throwUnchecked(ex.getCause()); } return null; } public static ClassFinder constClassFinder(final Class<?> type) { return new ClassFinder() { @Override public Class<?> tryGetClass() { return type; } }; } public static ClassFinder[] constClassFinders(Class<?>... types) { ClassFinder[] result = new ClassFinder[types.length]; for (int i = 0; i < result.length; i++) { result[i] = constClassFinder(types[i]); } return result; } }