View Javadoc

1   package org.sourceforge.jemm.weaver.transformation;
2   
3   import javassist.CannotCompileException;
4   import javassist.CtClass;
5   import javassist.CtMethod;
6   import javassist.Modifier;
7   
8   import org.sourceforge.jemm.client.Descriptor;
9   
10  /**
11   * Proxies all methods a begin and end call. Also detects synchronisation and
12   * adds in calls for begin and end Lock.
13   * 
14   * beginLock and endLock calls are only present if the method was declared
15   * synchronised.
16   * 
17   * Produces code similar to: jemmLCL.beginMethod(this); jemmLVL.beginLock(this);
18   * try { //original code } finally { jemmLVL.endLock(this);
19   * jemmLCL.endMethod(this); }
20   * 
21   * @author <a href="mailto:csuml@yahoo.co.uk">Paul Keeble</a>
22   * 
23   */
24  public class MethodProxyTransformation extends AbstractClassTransformation {
25  
26  	public void transform(CtClass clazz) throws TransformationException {
27  		try {
28  			String jemmOIF = ShadowTransformation.SHADOW_VARIABLE_NAME;
29  
30  			CtMethod[] methods = clazz.getDeclaredMethods();
31  			for (int i = 0; i < methods.length; ++i) {
32  				CtMethod m = methods[i];
33  				
34  				if(m.isEmpty())
35  					continue;
36  				
37  				String descriptor = getDescriptor(clazz,m);
38  				
39  				String begin = Modifier.isSynchronized(m.getModifiers()) ? jemmOIF
40  						+ ".entityEntered("+ descriptor +");" + jemmOIF + ".beginLock();"
41  						: jemmOIF + ".entityEntered("+ descriptor +");";
42  
43  				String end = Modifier.isSynchronized(m.getModifiers()) ? jemmOIF
44  						+ ".endLock();" + jemmOIF + ".entityExited("+descriptor+");"
45  						: jemmOIF + ".entityExited("+ descriptor+");";
46  				
47  
48  				m.insertBefore("{" + begin + "}");
49  				m.insertAfter("{" + end + "}");
50  
51  				if(Modifier.isSynchronized(m.getModifiers())) {
52  					int newModifiers = m.getModifiers() ^ Modifier.SYNCHRONIZED;
53  					m.setModifiers(newModifiers);
54  				}
55  
56  			}
57  		} catch (CannotCompileException e) {
58  			throw new TransformationException("Unknown compile error", e);
59  		}
60  	}
61  	
62  	String getDescriptor(CtClass clazz, CtMethod method) {
63  		String className = clazz.getName();
64  		String methodName = method.getName();
65  		String signature = method.getSignature();
66  		
67  		Descriptor d = new Descriptor(className,methodName,signature);
68  		return "\"" + d.getDescriptorString()+"\"";
69  	}
70  
71  	@Override
72  	public String[] dependentTransforms() {
73  		return new String[] {"InterfaceTransformation","ShadowTransformation"};
74  	}
75  }