package net.csdn.enhancer;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.NotFoundException;
import javassist.bytecode.AnnotationsAttribute;
import javassist.bytecode.ConstPool;
import javassist.bytecode.SignatureAttribute;
import javassist.bytecode.annotation.Annotation;
import javassist.bytecode.annotation.ArrayMemberValue;
import javassist.bytecode.annotation.EnumMemberValue;
import javassist.bytecode.annotation.StringMemberValue;
import net.csdn.annotation.association.ManyToManyHint;
import org.apache.commons.lang.StringUtils;
import java.lang.reflect.Modifier;
/**
* User: WilliamZhu
* Date: 12-7-25
* Time: 下午7:14
*/
public class AssociatedHelper {
public static CtField findAssociatedField(CtClass ctClass, String targetClassName) throws Exception {
CtClass other = ctClass.getClassPool().get(targetClassName);
CtField[] ctFields = other.getDeclaredFields();
for (CtField otherField : ctFields) {
if (Modifier.isFinal(otherField.getModifiers()) || Modifier.isStatic(otherField.getModifiers()))
continue;
String wow = findAssociatedClassName(otherField);
if (ctClass.getName().equals(wow) && EnhancerHelper.hasAnnotationWithPrefix(other, "javax.persistence.")) {
return otherField;
}
}
return null;
}
public static String findAssociatedFieldName(CtClass ctClass, String targetClassName) throws Exception {
CtField ctField = findAssociatedField(ctClass, targetClassName);
if (ctField != null) return ctField.getName();
return null;
}
public static CtClass findAssociatedClass(ClassPool classPool, CtField ctField) {
try {
return classPool.get(findAssociatedClassName(ctField));
} catch (NotFoundException e) {
e.printStackTrace();
}
return null;
}
public static String findAssociatedClassName(CtField ctField) {
SignatureAttribute.ObjectType objectType = EnhancerHelper.getFieldSignature(ctField);
String className = EnhancerHelper.findFieldGenericType(objectType);
if (StringUtils.isEmpty(className)) {
try {
return ctField.getType().getName();
} catch (NotFoundException e) {
e.printStackTrace();
}
}
return className;
}
public static void setCascadeWithDefault(CtField ctField, String type) {
setCascade(ctField, type, "PERSIST");
}
public static void setCascade(CtField ctField, String type, String... persistTypes) {
//默认设置为cascade = CascadeType.PERSIST
AnnotationsAttribute annotationsAttribute = EnhancerHelper.getAnnotations(ctField);
Annotation annotation = annotationsAttribute.getAnnotation("javax.persistence." + type);
ArrayMemberValue cascade = (ArrayMemberValue) annotation.getMemberValue("cascade");
if (cascade == null || cascade.getValue().length == 0) {
EnumMemberValue[] enumMemberValue = new EnumMemberValue[persistTypes.length];
int i = 0;
for (String persistType : persistTypes) {
EnumMemberValue emb = new EnumMemberValue(ctField.getFieldInfo2().getConstPool());
emb.setType("javax.persistence.CascadeType");
emb.setValue(persistType);
enumMemberValue[i++] = emb;
}
ArrayMemberValue arrayMemberValue = new ArrayMemberValue(ctField.getFieldInfo2().getConstPool());
arrayMemberValue.setValue(enumMemberValue);
annotation.addMemberValue("cascade", arrayMemberValue);
annotationsAttribute.addAnnotation(annotation);
}
}
public static void setManyToManyHint(CtField ctField) {
AnnotationsAttribute annotationsAttribute = EnhancerHelper.getAnnotations(ctField);
EnhancerHelper.createAnnotation(annotationsAttribute, ManyToManyHint.class);
}
public static void setMappedBy(CtField ctField, String mappedByFieldName, String type) {
AnnotationsAttribute annotationsAttribute = EnhancerHelper.getAnnotations(ctField);
ConstPool constPool = ctField.getFieldInfo2().getConstPool();
Annotation annotation = annotationsAttribute.getAnnotation("javax.persistence." + type);
StringMemberValue mappedBy = (StringMemberValue) annotation.getMemberValue("mappedBy");
if (mappedBy == null || StringUtils.isEmpty(mappedBy.getValue())) {
annotation.addMemberValue("mappedBy", new StringMemberValue(mappedByFieldName, constPool));
annotationsAttribute.addAnnotation(annotation);
}
}
}