/**
*
*/
package de.tutorials;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.commons.EmptyVisitor;
import com.sun.org.apache.bcel.internal.Repository;
import com.sun.org.apache.bcel.internal.classfile.LocalVariable;
import com.sun.org.apache.bcel.internal.classfile.LocalVariableTable;
/**
* @author Thomas.Darimont
*
*/
public class ParameterNamesViaReflection {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
Method method = ParameterNamesViaReflection.class
.getMethod("someOperation", new Class<?>[] { String.class,
Integer.class });
printParameterInfoFor(method); //Reflection + Annotations
System.out.println("####");
printParameterInfoFor1(method); // BCEL
System.out.println("####");
printParameterInfoFor2(method); //ASM
}
private static void printParameterInfoFor2(final Method method) {
try {
new ClassReader(method.getDeclaringClass().getName()).accept(
new EmptyVisitor() {
@Override
public MethodVisitor visitMethod(int access,
String name, String desc, String signature,
String[] exceptions) {
if (name.equals(method.getName())) {
org.objectweb.asm.commons.Method asmMethod = org.objectweb.asm.commons.Method
.getMethod(method.toString());
if (Arrays.equals(org.objectweb.asm.Type
.getArgumentTypes(desc), asmMethod
.getArgumentTypes())) {
return new EmptyVisitor() {
int currentArgumentCount;
@Override
public void visitLocalVariable(
String name, String desc,
String signature, Label start,
Label end, int index) {
if (currentArgumentCount++ < method
.getParameterTypes().length) {
System.out.println(name + " "
+ desc);
}
}
};
}
}
return null;
}
}, 0);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @param method
*/
private static void printParameterInfoFor1(Method method) {
com.sun.org.apache.bcel.internal.classfile.Method bcelMethod = Repository
.lookupClass(method.getDeclaringClass()).getMethod(method);
LocalVariableTable localVariableTable = bcelMethod
.getLocalVariableTable();
for (int currentLocalVariableIndex = 0; currentLocalVariableIndex < localVariableTable
.getTableLength(); currentLocalVariableIndex++) {
LocalVariable localVariable = localVariableTable
.getLocalVariable(currentLocalVariableIndex);
if (localVariable.getStartPC() == 0) {
System.out.println(localVariable.getName() + " "
+ localVariable.getSignature());
}
}
}
/**
* @param method
*/
private static void printParameterInfoFor(Method method) {
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
for (int parameterIndex = 0; parameterIndex < parameterAnnotations.length; parameterIndex++) {
Class<?> parameterType = method.getParameterTypes()[parameterIndex];
Named namedAnnotation = null;
for (Annotation annotation : parameterAnnotations[parameterIndex]) {
if (annotation.annotationType().equals(Named.class)) {
namedAnnotation = (Named) annotation;
break;
}
}
System.out
.println(String
.format(
"The parameter at index: %s of Method: %s with parameter type: %s is named by: %s",
parameterIndex, method, parameterType,
namedAnnotation.value()));
}
}
public static void someOperation(@Named("firstArgument")
String firstArgument, @Named("secondArgument")
Integer secondArgument) {
int i = 0;
Object o = "";
}
public static void someOperation(@Named("firstArgument")
String firstArgument) {
int j = 0;
Object u = "";
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
static @interface Named {
String value() default "";
}
}