package net.csdn.enhancer;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.BadBytecode;
import javassist.bytecode.SignatureAttribute;
import javassist.bytecode.annotation.MemberValue;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
* User: WilliamZhu
* Date: 12-7-12
* Time: 下午1:35
*/
public class EnhancerHelper {
public static String findFieldGenericType(SignatureAttribute.ObjectType fieldSignatureType) {
try {
Field field = fieldSignatureType.getClass().getDeclaredField("arguments");
field.setAccessible(true);
SignatureAttribute.TypeArgument[] arguments = (SignatureAttribute.TypeArgument[]) field.get(fieldSignatureType);
return arguments[0].toString();
} catch (Exception e) {
}
return null;
}
public static SignatureAttribute.ObjectType getFieldSignature(CtField field) {
if (field == null)
throw new IllegalArgumentException("Null method/constructor");
SignatureAttribute signature = (SignatureAttribute) field.getFieldInfo2().getAttribute(SignatureAttribute.tag);
if (signature == null)
return null;
String sig = signature.getSignature();
try {
return SignatureAttribute.toFieldSignature(sig);
} catch (BadBytecode e) {
throw new IllegalStateException(e);
}
}
public static void createAnnotation(AnnotationsAttribute attribute, Class<? extends Annotation> annotationType, Map<String, MemberValue> members) {
javassist.bytecode.annotation.Annotation annotation = new javassist.bytecode.annotation.Annotation(annotationType.getName(), attribute.getConstPool());
for (Map.Entry<String, MemberValue> member : members.entrySet()) {
annotation.addMemberValue(member.getKey(), member.getValue());
}
attribute.addAnnotation(annotation);
}
public static boolean hasAnnotation(CtClass ctClass, String annotation) throws ClassNotFoundException {
for (Object object : ctClass.getAvailableAnnotations()) {
Annotation ann = (Annotation) object;
if (ann.annotationType().getName().equals(annotation)) {
return true;
}
}
return false;
}
public static boolean hasAnnotationWithPrefix(CtClass ctClass, String annotationPrefix) throws ClassNotFoundException {
for (Object object : ctClass.getAvailableAnnotations()) {
Annotation ann = (Annotation) object;
if (ann.annotationType().getName().startsWith(annotationPrefix)) {
return true;
}
}
return false;
}
public static boolean hasAnnotation(CtField ctField, String annotation) throws ClassNotFoundException {
for (Object object : ctField.getAvailableAnnotations()) {
Annotation ann = (Annotation) object;
if (ann.annotationType().getName().equals(annotation)) {
return true;
}
}
return false;
}
public static boolean hasAnnotation(CtMethod ctMethod, String annotation) throws ClassNotFoundException {
for (Object object : ctMethod.getAvailableAnnotations()) {
Annotation ann = (Annotation) object;
if (ann.annotationType().getName().equals(annotation)) {
return true;
}
}
return false;
}
public static AnnotationsAttribute getAnnotations(CtClass ctClass) {
AnnotationsAttribute annotationsAttribute = (AnnotationsAttribute) ctClass.getClassFile().getAttribute(AnnotationsAttribute.visibleTag);
if (annotationsAttribute == null) {
annotationsAttribute = new AnnotationsAttribute(ctClass.getClassFile().getConstPool(), AnnotationsAttribute.visibleTag);
ctClass.getClassFile().addAttribute(annotationsAttribute);
}
return annotationsAttribute;
}
public static AnnotationsAttribute getAnnotations(CtField ctField) {
AnnotationsAttribute annotationsAttribute = (AnnotationsAttribute) ctField.getFieldInfo().getAttribute(AnnotationsAttribute.visibleTag);
if (annotationsAttribute == null) {
annotationsAttribute = new AnnotationsAttribute(ctField.getFieldInfo().getConstPool(), AnnotationsAttribute.visibleTag);
ctField.getFieldInfo().addAttribute(annotationsAttribute);
}
return annotationsAttribute;
}
public static AnnotationsAttribute getAnnotations(CtMethod ctMethod) {
AnnotationsAttribute annotationsAttribute = (AnnotationsAttribute) ctMethod.getMethodInfo().getAttribute(AnnotationsAttribute.visibleTag);
if (annotationsAttribute == null) {
annotationsAttribute = new AnnotationsAttribute(ctMethod.getMethodInfo().getConstPool(), AnnotationsAttribute.visibleTag);
ctMethod.getMethodInfo().addAttribute(annotationsAttribute);
}
return annotationsAttribute;
}
// public static void modifyAnnotation(AnnotationsAttribute attribute, Annotation annotation, String key, MemberValue memberValue) {
//
// Method[] methods = annotation.getClass().getDeclaredMethods();
// Map<String, MemberValue> memberValueMap = new HashMap<String, MemberValue>();
// for (Method method : methods) {
// if (method.getName().equals(key)) {
// memberValueMap.put(key, memberValue);
// } else {
// Object obj = ReflectHelper.method(annotation, method.getName());
// if (obj == null) continue;
// MemberValue temp = createMemberValue(attribute.getConstPool(), method.getReturnType(), obj);
// memberValueMap.put(method.getName(), temp);
// }
// }
// createAnnotation(attribute, annotation.annotationType(), memberValueMap);
//
// }
public static void createAnnotation(AnnotationsAttribute attribute, Class<? extends Annotation> annotationType) {
createAnnotation(attribute, annotationType, new HashMap<String, MemberValue>());
}
// public static MemberValue createMemberValue(ConstPool cp, Class type, Object obj)
//
// {
// if (type == Boolean.class) {
// BooleanMemberValue booleanMemberValue = new BooleanMemberValue(cp);
// booleanMemberValue.setValue((Boolean) obj);
// return booleanMemberValue;
// } else if (type == Byte.class)
// return new ByteMemberValue(cp);
// else if (type == Character.class)
// return new CharMemberValue(cp);
// else if (type == Short.class)
// return new ShortMemberValue(cp);
// else if (type == Integer.class)
// return new IntegerMemberValue(cp);
// else if (type == Long.class)
// return new LongMemberValue(cp);
// else if (type == Float.class)
// return new FloatMemberValue(cp);
// else if (type == Double.class)
// return new DoubleMemberValue(cp);
// else if (type == Class.class)
// return new ClassMemberValue(cp);
// else if (type == String.class)
// return new StringMemberValue(cp);
// else if (type.isArray()) {
// Class arrayType = type.getComponentType();
// MemberValue member = createMemberValue(cp, arrayType);
// return new ArrayMemberValue(member, cp);
// } else if (type.isInterface()) {
//// Annotation info = new Annotation(cp, type);
//// return new AnnotationMemberValue(info, cp);
// return null;
// } else {
// // treat as enum. I know this is not typed,
// // but JBoss has an Annotation Compiler for JDK 1.4
// // and I want it to work with that. - Bill Burke
// EnumMemberValue emv = new EnumMemberValue(cp);
// emv.setType(type.getName());
// emv.setValue(obj.toString());
// return emv;
// }
// }
}