package net.csdn.common.enhancer;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.AttributeInfo;
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.List;
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(CtField ctField, Class<? extends Annotation> annotationType, Map<String, MemberValue> members) {
if (ctField.hasAnnotation(annotationType)) return;
AnnotationsAttribute attr = new AnnotationsAttribute(ctField.getFieldInfo().getConstPool(), AnnotationsAttribute.visibleTag);
boolean isNewAttr = true;
List<AttributeInfo> attributeInfos = ctField.getFieldInfo().getAttributes();
for (AttributeInfo attributeInfo : attributeInfos) {
if (attributeInfo instanceof AnnotationsAttribute) {
attr = (AnnotationsAttribute) attributeInfo;
isNewAttr = false;
}
}
javassist.bytecode.annotation.Annotation[] annotations = attr.getAnnotations();
javassist.bytecode.annotation.Annotation annotation = new javassist.bytecode.annotation.Annotation(annotationType.getName(), attr.getConstPool());
for (javassist.bytecode.annotation.Annotation annotation1 : annotations) {
if (annotation1.getTypeName().equals(annotationType.getName())) {
annotation = annotation1;
break;
}
}
for (Map.Entry<String, MemberValue> member : members.entrySet()) {
try {
if (annotation.getMemberValue(member.getKey()) == null) {
annotation.addMemberValue(member.getKey(), member.getValue());
}
} catch (Exception e) {
e.printStackTrace();
annotation.addMemberValue(member.getKey(), member.getValue());
}
}
attr.addAnnotation(annotation);
if (isNewAttr) {
ctField.getFieldInfo().addAttribute(attr);
}
}
public static void createAnnotation(CtClass ctClass, Class<? extends Annotation> annotationType, Map<String, MemberValue> members) {
if (ctClass.hasAnnotation(annotationType)) return;
AnnotationsAttribute attr = new AnnotationsAttribute(ctClass.getClassFile().getConstPool(), AnnotationsAttribute.visibleTag);
boolean isNewAttr = true;
List<AttributeInfo> attributeInfos = ctClass.getClassFile2().getAttributes();
for (AttributeInfo attributeInfo : attributeInfos) {
if (attributeInfo instanceof AnnotationsAttribute) {
attr = (AnnotationsAttribute) attributeInfo;
isNewAttr = false;
}
}
javassist.bytecode.annotation.Annotation[] annotations = attr.getAnnotations();
javassist.bytecode.annotation.Annotation annotation = new javassist.bytecode.annotation.Annotation(annotationType.getName(), attr.getConstPool());
for (javassist.bytecode.annotation.Annotation annotation1 : annotations) {
if (annotation1.getTypeName().equals(annotationType.getName())) {
annotation = annotation1;
break;
}
}
for (Map.Entry<String, MemberValue> member : members.entrySet()) {
try {
if (annotation.getMemberValue(member.getKey()) == null) {
annotation.addMemberValue(member.getKey(), member.getValue());
}
} catch (Exception e) {
e.printStackTrace();
annotation.addMemberValue(member.getKey(), member.getValue());
}
}
attr.addAnnotation(annotation);
if (isNewAttr) {
ctClass.getClassFile().addAttribute(attr);
}
}
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);
return annotationsAttribute;
}
public static AnnotationsAttribute getAnnotations(CtMethod ctMethod) {
AnnotationsAttribute annotationsAttribute = (AnnotationsAttribute) ctMethod.getMethodInfo().getAttribute(AnnotationsAttribute.visibleTag);
return annotationsAttribute;
}
public static void createAnnotation(AnnotationsAttribute attribute, Class<? extends Annotation> annotationType) {
createAnnotation(attribute, annotationType, new HashMap<String, MemberValue>());
}
}