package org.simpleframework.xml.reflect; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Constructor; import java.lang.reflect.Method; public class Reflection { public static String[] lookupParameterNames(AccessibleObject methodOrConstructor) { return lookupParameterNames(methodOrConstructor, true); } public static String[] lookupParameterNames(AccessibleObject methodOrCtor, boolean throwExceptionIfMissing) { Class<?>[] types = null; Class<?> declaringClass = null; String name = null; if (methodOrCtor instanceof Method) { Method method = (Method) methodOrCtor; types = method.getParameterTypes(); name = method.getName(); declaringClass = method.getDeclaringClass(); } else { Constructor<?> constructor = (Constructor<?>) methodOrCtor; types = constructor.getParameterTypes(); declaringClass = constructor.getDeclaringClass(); name = "<init>"; } if (types.length == 0) { return TypeCollector.EMPTY_NAMES; } InputStream content = getClassAsStream(declaringClass); if (content == null) { if (throwExceptionIfMissing) { throw new RuntimeException("Unable to get class bytes"); } else { return TypeCollector.EMPTY_NAMES; } } try { ClassReader reader = new ClassReader(content); TypeCollector visitor = new TypeCollector(name, types, throwExceptionIfMissing); reader.accept(visitor); return visitor.getParameterNamesForMethod(); } catch (IOException e) { if (throwExceptionIfMissing) { throw new RuntimeException( "IoException while reading class bytes", e); } else { return TypeCollector.EMPTY_NAMES; } } } private static InputStream getClassAsStream(Class<?> clazz) { ClassLoader classLoader = clazz.getClassLoader(); if (classLoader == null) { classLoader = ClassLoader.getSystemClassLoader(); } return getClassAsStream(classLoader, clazz.getName()); } private static InputStream getClassAsStream(ClassLoader classLoader, String className) { String name = className.replace('.', '/') + ".class"; // better pre-cache all methods otherwise this content will be loaded // multiple times InputStream asStream = classLoader.getResourceAsStream(name); if (asStream == null) { asStream = Reflection.class.getResourceAsStream(name); } return asStream; } }