panda.aop.asm.ClassY Maven / Gradle / Ivy
package panda.aop.asm;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import panda.aop.AopCallback;
import panda.aop.MethodInterceptor;
import panda.asm.ClassWriter;
import panda.asm.MethodVisitor;
import panda.asm.Opcodes;
import panda.asm.Type;
/**
* @author wendal([email protected])
*/
class ClassY implements Opcodes {
ClassWriter cw;
String myName;
String enhancedSuperName;
Method[] methodArray;
Constructor>[] constructors;
private Class> superClass;
ClassY(Class> klass, String myName, Method[] methodArray, Constructor>[] constructors) {
this.myName = myName.replace('.', '/');
this.enhancedSuperName = klass.getName().replace('.', '/');
this.cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.visit(AsmClassAgent.CLASS_LEVEL, ACC_PUBLIC, this.myName, null, enhancedSuperName,
getParentInterfaces(klass));
this.methodArray = methodArray;
this.constructors = constructors;
this.superClass = klass;
}
String[] getParentInterfaces(Class> xClass) {
Class>[] its = xClass.getInterfaces();
if (its == null || its.length == 0)
return new String[] { AopCallback.class.getName().replace('.', '/') };
else {
String[] iii = new String[its.length + 1];
for (int i = 0; i < its.length; i++)
iii[i] = its[i].getName().replace('.', '/');
iii[its.length] = AopCallback.class.getName().replace('.', '/');
return iii;
}
}
String[] convertExp(Class>[] expClasses) {
if (expClasses.length == 0)
return null;
String[] results = new String[expClasses.length];
for (int i = 0; i < results.length; i++)
results[i] = expClasses[i].getName().replace('.', '/');
return results;
}
int getAccess(int modify) {
if (Modifier.isProtected(modify))
return ACC_PROTECTED;
if (Modifier.isPublic(modify))
return ACC_PUBLIC;
return 0x00;
}
static int findMethodIndex(String name, String desc, Method[] methods) {
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
if (Type.getMethodDescriptor(method).equals(desc) && method.getName().equals(name))
return i;
}
return -1;// 是否应该抛出异常呢?应该不可能发生的
}
void addConstructors() {
for (Constructor> constructor : constructors) {
String[] expClasses = convertExp(constructor.getExceptionTypes());
String desc = Type.getConstructorDescriptor(constructor);
int access = getAccess(constructor.getModifiers());
MethodVisitor mv = cw.visitMethod(access, "", desc, null, expClasses);
new ChangeToChildConstructorMethodAdapter(mv, desc, access, enhancedSuperName).visitCode();
}
}
byte[] toByteArray() {
addField();
addConstructors();
addAopMethods();
enhandMethod();
cw.visitSource(superClass.getSimpleName() + ".java", null);
return cw.toByteArray();
}
private void enhandMethod() {
for (Method method : methodArray) {
String methodName = method.getName();
String methodDesc = Type.getMethodDescriptor(method);
int methodAccess = getAccess(method.getModifiers());
MethodVisitor mv = cw.visitMethod(methodAccess, methodName, methodDesc, null,
convertExp(method.getExceptionTypes()));
int methodIndex = findMethodIndex(methodName, methodDesc, methodArray);
AopMethodAdapter adapter = new AopMethodAdapter(mv, methodAccess, methodName, methodDesc, methodIndex,
myName, enhancedSuperName);
adapter.visitCode();
adapter.visitAttribute();
}
}
private void addAopMethods() {
new AopInvokeAdpter(methodArray, cw.visitMethod(ACC_PUBLIC, "_aop_invoke",
"(I[Ljava/lang/Object;)Ljava/lang/Object;", null, null), ACC_PUBLIC, "invoke",
"(I[Ljava/lang/Object;)Ljava/lang/Object;", 0, myName, enhancedSuperName).visitCode();
}
static final String MI_CLS_PATH = MethodInterceptor.class.getName().replace('.', '/');
private void addField() {
cw.visitField(ACC_PRIVATE + ACC_STATIC, AsmClassAgent.MethodArray_FieldName, "[Ljava/lang/reflect/Method;",
null, null).visitEnd();
cw.visitField(ACC_PRIVATE + ACC_STATIC, AsmClassAgent.MethodInterceptorList_FieldName, "[Ljava/util/List;",
"[Ljava/util/List;", null).visitEnd();
}
static byte[] enhandClass(Class kclass, String myName, Method[] methodArray, Constructor>[] constructors) {
return new ClassY(kclass, myName, methodArray, constructors).toByteArray();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy