View Javadoc

1   /*
2    *
3    */
4   package org.softevo.jdynpur.runtime;
5   
6   
7   import org.objectweb.asm.ClassAdapter;
8   import org.objectweb.asm.ClassVisitor;
9   import org.objectweb.asm.MethodVisitor;
10  import org.objectweb.asm.Opcodes;
11  import org.softevo.util.ObjectIdMapper;
12  import org.softevo.util.asm.FieldIdentifier;
13  import org.softevo.util.asm.MethodIdentifier;
14  import org.softevo.util.asm.MethodIdentifierMapGenerator;
15  
16  public class InstrumentingClassFileTransformer extends ClassAdapter implements Opcodes {
17  
18  	private MethodIdentifierMapGenerator identifierMapGenerator = null;
19  
20  	private String className = null;
21  
22  	private String superClassName = null;
23  
24  	private boolean isInterface = false;
25  
26  	private ObjectIdMapper<FieldIdentifier> fieldIdentifierMap;
27  
28  	private boolean traceParameterMutability;
29  
30  	public InstrumentingClassFileTransformer(ClassVisitor classVisitor, String className,
31  			MethodIdentifierMapGenerator identifierMapGenerator, ObjectIdMapper<FieldIdentifier> fieldIdentifierMap, 
32  			boolean traceParameterMutability) {
33  		super(classVisitor);
34  		this.identifierMapGenerator = identifierMapGenerator;
35  		this.className = className;
36  		this.fieldIdentifierMap = fieldIdentifierMap;
37  		this.traceParameterMutability = traceParameterMutability;
38  	}
39  
40  	@Override
41  	public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
42  		super.visit(version, access, name, signature, superName, interfaces);
43  		this.superClassName = superName;
44  		if ((access & ACC_INTERFACE) > 0) {
45  			isInterface = true;
46  		}
47  	}
48  
49  	@Override
50  	public MethodVisitor visitMethod(int access, String methodName, String desc, String signature, String[] exceptions) {
51  		MethodVisitor writingMethodVisitor;
52  		MethodStartEndTracingVisitor startEndVisitor;
53  		ArrayTracingVisitor arrayTracingVisitor;
54  		ObjectCreationTracingVisitor objectCreationVisitor;
55  		FieldWriteTracingVisitor fieldWriteVisitor;
56  		ConstructorPurityTracingVisitor constructorVisitor;
57  		ParameterTracingVisitor parameterTracingVisitor;
58  		int methodIdentifier;
59  
60  		if (!isInterface && ((access & ACC_ABSTRACT) == 0) && ((access & ACC_NATIVE) == 0)) {
61  			methodIdentifier = identifierMapGenerator.getIdentifier(className, methodName, desc, access);
62  			MethodIdentifier methodId = identifierMapGenerator.getMethodIdentifier(methodIdentifier);
63  			writingMethodVisitor = super.visitMethod(access, methodName, desc, signature, exceptions);
64  			startEndVisitor = new MethodStartEndTracingVisitor(writingMethodVisitor, access, className,methodName, desc,
65  					methodIdentifier);
66  			if  (traceParameterMutability) {
67  			  parameterTracingVisitor = new ParameterTracingVisitor(startEndVisitor, methodId, superClassName);
68  			  arrayTracingVisitor = new ArrayTracingVisitor(parameterTracingVisitor, access, desc);
69  			} else {
70  			  arrayTracingVisitor = new ArrayTracingVisitor(startEndVisitor, access, desc);
71  			}
72  			objectCreationVisitor = new ObjectCreationTracingVisitor(arrayTracingVisitor);
73  			fieldWriteVisitor = new FieldWriteTracingVisitor(objectCreationVisitor, methodName, className, superClassName, fieldIdentifierMap);
74  			constructorVisitor = new ConstructorPurityTracingVisitor(fieldWriteVisitor, methodName, className, superClassName);
75  			return constructorVisitor;
76  		} else {
77  			return super.visitMethod(access, methodName, desc, signature, exceptions);
78  		}
79  	}
80  
81  	public MethodIdentifierMapGenerator getIdentifierMapGenerator() {
82  		return identifierMapGenerator;
83  	}
84  
85  	public void setIdentifierMapGenerator(MethodIdentifierMapGenerator identifierMapGenerator) {
86  		this.identifierMapGenerator = identifierMapGenerator;
87  	}
88  
89  }