package org.restler.spring.mvc; import org.objectweb.asm.ClassReader; import org.restler.client.RestlerException; import org.restler.spring.mvc.asm.ClassUtils; import org.restler.spring.mvc.asm.ParameterNameDiscoveringVisitor; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.HashMap; import java.util.Map; public class ParameterNameDiscoverer { public String[] getParameterNames(Method method) { String[] result = getParameterNamesDefault(method); if(result == null) { result = getParameterNamesFromLocalVariableTable(method); } return result; } private String[] getParameterNamesDefault(Method method) { Parameter[] parameters = method.getParameters(); String[] parameterNames = new String[parameters.length]; for (int i = 0; i < parameters.length; i++) { Parameter param = parameters[i]; if (!param.isNamePresent()) { return null; } parameterNames[i] = param.getName(); } return parameterNames; } private String[] getParameterNamesFromLocalVariableTable(Method method) { Class<?> declaringClass = method.getDeclaringClass(); Map<Member, String[]> map = inspectClass(declaringClass); if (map != null) { return map.get(method); } return null; } private Map<Member, String[]> inspectClass(Class<?> clazz) { try(InputStream inputStream = clazz.getResourceAsStream(ClassUtils.getClassFileName(clazz))) { if (inputStream == null) { return null; } ClassReader classReader = new ClassReader(inputStream); Map<Member, String[]> map = new HashMap<>(32); classReader.accept(new ParameterNameDiscoveringVisitor(clazz, map), 0); return map; } catch (IOException e) { throw new RestlerException("Can't read class from stream.", e); } catch(IllegalArgumentException e) { throw new RestlerException("Illegal argument.", e); } } }