
com.eg.agent.compile.visitor.EventClassVisitor Maven / Gradle / Ivy
package com.eg.agent.compile.visitor;
import com.eg.agent.compile.InstrumentationContext;
import com.eg.agent.compile.EGLogger;
import com.eg.objectweb.asm.ClassAdapter;
import com.eg.objectweb.asm.ClassVisitor;
import com.eg.objectweb.asm.MethodVisitor;
import com.eg.objectweb.asm.commons.GeneratorAdapter;
import com.eg.objectweb.asm.commons.Method;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author janakiraman.k
*
*/
public abstract class EventClassVisitor extends ClassAdapter {
protected final Set baseClasses;
private final Map methodVisitors = new HashMap();
protected String superName;
protected boolean instrument = false;
protected final InstrumentationContext context;
protected final EGLogger log;
private Pattern androidPackagePattern = Pattern.compile("^android[x]{0,1}/.*");
protected final Map baseClassPatterns;
public EventClassVisitor(ClassVisitor cv, InstrumentationContext context, EGLogger log, Set baseClasses, Map methodMappings) {
super(cv);
this.context = context;
this.log = log;
this.baseClasses = Collections.unmodifiableSet(baseClasses);
java.util.Map.Entry entry;
for (Iterator i$ = methodMappings.entrySet().iterator(); i$.hasNext(); methodVisitors.put(entry.getKey(), new MethodVisitorFactory((Method) entry.getValue())))
entry = (java.util.Map.Entry) i$.next();
this.baseClassPatterns = new HashMap();
for (String pattern : baseClasses) {
this.baseClassPatterns.put(pattern, Pattern.compile(pattern));
}
}
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
super.visit(version, access, name, signature, superName, interfaces);
this.superName = superName;
this.instrument = this.shouldInstrumentClass(name, superName);
if (this.instrument) {
this.context.markModified();
}
}
protected boolean shouldInstrumentClass(String className, String superName) {
if (!this.androidPackagePattern.matcher(className.toLowerCase()).matches()) {
if(this.baseClasses.contains(superName)) {
return true;
}
for (Pattern baseClassPattern : this.baseClassPatterns.values()) {
Matcher matcher = baseClassPattern.matcher(superName);
if (!matcher.matches()) continue;
return true;
}
}
return false;
}
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
if (!this.instrument) {
return mv;
}
Method method = new Method(name, desc);
MethodVisitorFactory v = (MethodVisitorFactory) this.methodVisitors.get(method);
if (v != null) {
this.methodVisitors.remove(method);
return v.createMethodVisitor(access, method, mv, false);
}
return mv;
}
public void visitEnd() {
if (!this.instrument) {
return;
}
MethodVisitor mv;
for (Iterator i$ = methodVisitors.entrySet().iterator(); i$.hasNext(); mv.visitEnd()) {
java.util.Map.Entry entry = (java.util.Map.Entry) i$.next();
mv = super.visitMethod(4, ((Method) entry.getKey()).getName(), ((Method) entry.getKey()).getDescriptor(), null, null);
mv = ((MethodVisitorFactory) entry.getValue()).createMethodVisitor(4, (Method) entry.getKey(), mv, true);
mv.visitCode();
mv.visitInsn(177);
mv.visitMaxs(0, 0);
}
super.visitEnd();
}
protected abstract void injectCodeIntoMethod(GeneratorAdapter paramGeneratorAdapter, Method paramMethod1, Method paramMethod2);
protected class MethodVisitorFactory {
final Method monitorMethod;
public MethodVisitorFactory(Method monitorMethod) {
this.monitorMethod = monitorMethod;
}
public MethodVisitor createMethodVisitor(int access, final Method method, MethodVisitor mv, final boolean callSuper) {
return new GeneratorAdapter(access, method, mv) {
public void visitCode() {
super.visitCode();
if (callSuper) {
loadThis();
for (int i = 0; i < method.getArgumentTypes().length; i++) {
loadArg(i);
}
visitMethodInsn(183, EventClassVisitor.this.superName, method.getName(), method.getDescriptor());
}
EventClassVisitor.this.injectCodeIntoMethod(this, method, EventClassVisitor.MethodVisitorFactory.this.monitorMethod);
}
};
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy