1 18 19 package alt.jiapi.instrumentor; 20 21 import java.lang.reflect.Modifier ; 22 23 import org.apache.log4j.Category; 24 25 import alt.jiapi.Runtime; 26 import alt.jiapi.reflect.InstructionFactory; 27 import alt.jiapi.reflect.InstructionList; 28 import alt.jiapi.reflect.JiapiClass; 29 import alt.jiapi.reflect.JiapiMethod; 30 import alt.jiapi.reflect.Signature; 31 import alt.jiapi.reflect.MethodExistsException; 32 33 40 public class CreateMethodInstrumentor extends AbstractInstrumentor { 41 private static Category log = Runtime.getLogCategory(CreateMethodInstrumentor.class); 42 43 public static int FORWARD_ORIGINAL = 1; 44 public static int FORWARD_NEW = 2; 45 public static int FORWARD_BOTH = 3; 46 private static int DEFAULT = FORWARD_NEW; 47 48 private int modifiers; 49 private String returnType; 50 private String methodName; 51 private String [] parameterNames; 52 53 private int forwardMode = DEFAULT; 54 private boolean createReturn = true; 55 56 63 public CreateMethodInstrumentor(int modifiers, String methodName) { 64 this(modifiers, "void", methodName, new String [0]); 65 } 66 67 74 public CreateMethodInstrumentor(int modifiers, String returnType, 75 String methodName) { 76 this(modifiers, returnType, methodName, new String [0]); 77 } 78 79 87 public CreateMethodInstrumentor(int modifiers, String methodName, 88 String [] parameterNames) { 89 this(modifiers, "void", methodName, parameterNames); 90 } 91 92 98 public CreateMethodInstrumentor(JiapiMethod method) { 99 this(method.getModifiers(), method.getReturnType(), method.getName(), 100 method.getParameterTypeNames()); 101 } 102 103 112 public CreateMethodInstrumentor(int modifiers, String returnType, 113 String methodName, 114 String [] parameterNames) { 115 this.methodName = methodName; 116 this.modifiers = modifiers; 117 this.parameterNames = parameterNames; 118 this.returnType = returnType; 119 } 120 121 135 public void setForwardMode(int forwardMode) { 136 this.forwardMode = forwardMode; 137 } 138 139 147 public void setCreateReturn(boolean b) { 148 createReturn = b; 149 } 150 151 156 public void instrument(InstructionList il) { 157 JiapiClass clazz = getCurrentClass(); 158 159 if (Modifier.isInterface(clazz.getModifiers())) { 162 if (!Modifier.isPublic(modifiers)) { 163 log.info("Cannot create non public method " + 164 methodName + " to interface " + clazz.getName()); 165 166 forward(il); 168 return; 169 } 170 } 171 172 log.info("Creating method " + clazz.getName() + "." + methodName); 173 174 JiapiMethod method = null; 175 try { 176 Signature signature = new Signature(returnType, parameterNames); 177 method = clazz.addMethod((short)modifiers, methodName, signature); 178 } 179 catch (MethodExistsException mee) { 180 log.info("method " + clazz.getName() + "." + methodName + 181 " already exists"); 182 183 method = mee.getMethod(); 184 } 185 186 if (forwardMode == FORWARD_ORIGINAL) { 187 forward(il); 188 } 189 else if (forwardMode == FORWARD_NEW) { 190 forward(method.getInstructionList()); 191 } 192 else { 193 forward(il); 195 forward(method.getInstructionList()); 196 } 197 198 if (createReturn) { 199 InstructionFactory factory = method.getInstructionFactory(); 200 method.getInstructionList().add(factory.returnMethod(method)); 201 } 202 } 203 } 204 205 | Popular Tags |