1 22 package org.jboss.aop.instrument; 23 24 import java.util.ArrayList ; 25 26 import org.jboss.aop.util.JavassistMethodHashing; 27 28 import javassist.CannotCompileException; 29 import javassist.CtClass; 30 import javassist.CtField; 31 import javassist.CtMethod; 32 import javassist.Modifier; 33 import javassist.NotFoundException; 34 import javassist.expr.FieldAccess; 35 36 42 public class GeneratedAdvisorFieldAccessTransformer extends FieldAccessTransformer 43 { 44 45 public GeneratedAdvisorFieldAccessTransformer(Instrumentor instrumentor) 46 { 47 super(instrumentor); 48 } 49 50 protected void doBuildFieldWrappers(CtClass clazz, CtField field, int index, JoinpointClassification classificationGet, JoinpointClassification classificationSet) throws NotFoundException, CannotCompileException 51 { 52 instrumentor.setupBasics(clazz); 53 boolean wrappedGet = classificationGet.equals(JoinpointClassification.WRAPPED); 54 boolean wrappedSet = classificationSet.equals(JoinpointClassification.WRAPPED); 55 int mod = field.getModifiers(); 56 57 buildWrapperPlaceHolders(clazz, 63 field, 64 isPrepared(classificationGet), 65 isPrepared(classificationSet), 66 mod); 67 68 try 69 { 70 if (isPrepared(classificationGet)) 71 { 72 addFieldReadInfoFieldToGeneratedAdvisor(field, index); 73 wrapper.prepareForWrapping(field, GET_INDEX); 75 } 76 77 if (isPrepared(classificationSet)) 78 { 79 addFieldWriteInfoFieldToGeneratedAdvisor(field, index); 80 wrapper.prepareForWrapping(field, SET_INDEX); 82 } 83 } 84 catch (Exception e) 85 { 86 throw new CannotCompileException(e); 87 } 88 89 if (wrappedGet) 91 { 92 wrapper.wrap(field, GET_INDEX); 93 if (classificationGet.equals(JoinpointClassification.DYNAMICALY_WRAPPED)) 94 { 95 instrumentor.dynamicTransformationObserver.fieldReadDynamicalyWrapped(field); 96 } 97 } 98 if (wrappedSet) 99 { 100 wrapper.wrap(field, SET_INDEX); 101 if (classificationSet.equals(JoinpointClassification.DYNAMICALY_WRAPPED)) 102 { 103 instrumentor.dynamicTransformationObserver.fieldWriteDynamicalyWrapped(field); 104 } 105 } 106 107 replaceFieldAccessInternally(clazz, field, wrappedGet, wrappedSet, index); 109 buildWrappers(clazz, field, wrappedGet, wrappedSet, index); 110 } 111 112 protected String addFieldReadInfoFieldToGeneratedAdvisor(CtField field, int index)throws NotFoundException, CannotCompileException 113 { 114 CtClass genadvisor = getGenadvisor(); 115 String finame = addFieldReadInfoFieldWithAccessors( 116 Modifier.PROTECTED, 117 genadvisor, 118 field); 119 120 addReadJoinPoint(field, finame, index); 121 122 long wrapperHash = JavassistMethodHashing.methodHash( 123 field.getDeclaringClass().getDeclaredMethod(fieldRead(field.getName()))); 124 ((GeneratedAdvisorInstrumentor)instrumentor).initialiseFieldReadInfoField(finame, index, field.getName(), wrapperHash); 125 return finame; 126 } 127 128 protected boolean addInfoAsWeakReference() 129 { 130 return false; 131 } 132 133 private void addReadJoinPoint(CtField field, String finame, int index) throws CannotCompileException, NotFoundException 134 { 135 CtClass joinpoint = createReadJoinPointClass(field, finame, index); 136 CtClass genadvisor = ((GeneratedAdvisorInstrumentor)instrumentor).getGenadvisor(); 137 CtField jpfield = new CtField( 138 joinpoint, 139 FieldJoinPointGenerator.getInfoFieldName(field.getName(), true), 140 genadvisor); 141 jpfield.setModifiers(Modifier.PROTECTED); 142 genadvisor.addField(jpfield); 143 } 144 145 private CtClass createReadJoinPointClass(CtField field, String finame, int index) throws CannotCompileException, NotFoundException 146 { 147 return FieldJoinPointGenerator.createReadJoinpointBaseClass((GeneratedAdvisorInstrumentor)instrumentor, 148 field.getDeclaringClass(), 149 field, 150 finame, 151 index); 152 } 153 154 protected String addFieldWriteInfoFieldToGeneratedAdvisor(CtField field, int index)throws NotFoundException, CannotCompileException 155 { 156 CtClass genadvisor = getGenadvisor(); 157 158 String finame = addFieldWriteInfoField( 159 Modifier.PROTECTED, 160 genadvisor, 161 field); 162 163 addWriteJoinPoint(field, finame, index); 164 165 long wrapperHash = JavassistMethodHashing.methodHash( 166 field.getDeclaringClass().getDeclaredMethod(fieldWrite(field.getName()))); 167 ((GeneratedAdvisorInstrumentor)instrumentor).initialiseFieldWriteInfoField(finame, index, field.getName(), wrapperHash); 168 169 return finame; 170 } 171 172 private void addWriteJoinPoint(CtField field, String finame, int index) throws CannotCompileException, NotFoundException 173 { 174 CtClass joinpoint = createWriteJoinPointClass(field, finame, index); 175 CtClass genadvisor = ((GeneratedAdvisorInstrumentor)instrumentor).getGenadvisor(); 176 CtField jpfield = new CtField( 177 joinpoint, 178 FieldJoinPointGenerator.getInfoFieldName(field.getName(), false), 179 genadvisor); 180 jpfield.setModifiers(Modifier.PROTECTED); 181 genadvisor.addField(jpfield); 182 } 183 184 private CtClass createWriteJoinPointClass(CtField field, String finame, int index) throws CannotCompileException, NotFoundException 185 { 186 return FieldJoinPointGenerator.createWriteJoinpointBaseClass((GeneratedAdvisorInstrumentor)instrumentor, 187 field.getDeclaringClass(), 188 field, 189 finame, 190 index); 191 } 192 193 protected void buildWrapperPlaceHolders(CtClass clazz, CtField field, boolean doGet, boolean doSet, int mod) 194 throws NotFoundException, CannotCompileException 195 { 196 super.buildWrapperPlaceHolders(clazz, field, doGet, doSet, getStaticModifiers(field)); 197 198 CtClass genadvisor = getGenadvisor(); 199 if (doGet) 200 { 201 CtMethod rmethod = super.buildReadWrapperPlaceHolder( 202 genadvisor, 203 field, 204 advisorFieldRead(genadvisor, field.getName()), 205 Modifier.PROTECTED); 206 207 } 208 if (doSet) 209 { 210 CtMethod wmethod = super.buildWriteWrapperPlaceHolder( 211 genadvisor, 212 field, 213 advisorFieldWrite(genadvisor, field.getName()), 214 Modifier.PROTECTED); 215 216 } 217 } 218 219 public static String advisorFieldRead(CtClass genadvisor, String fieldName) 220 { 221 return genadvisor.getSimpleName() + "$" + fieldRead(fieldName); 222 } 223 224 public static String advisorFieldWrite(CtClass genadvisor, String fieldName) 225 { 226 return genadvisor.getSimpleName() + "$" + fieldWrite(fieldName); 227 } 228 229 protected String getWrapperBody(CtClass clazz, CtField field, boolean get, int fieldIndex) throws NotFoundException, CannotCompileException 230 { 231 if (get) 232 { 233 return getMainReadWrapperBody(clazz, field, fieldIndex); 234 } 235 return getMainWriteWrapperBody(clazz, field, fieldIndex); 236 } 237 238 protected void replaceFieldAccessInternally(CtClass clazz, CtField field, boolean doGet, boolean doSet, int index) throws CannotCompileException 239 { 240 GeneratedAdvisorFieldAccessExprEditor expr = new GeneratedAdvisorFieldAccessExprEditor(clazz, field, doGet, doSet, index); 241 clazz.instrument(expr); 242 } 243 244 private CtClass getGenadvisor() 245 { 246 return ((GeneratedAdvisorInstrumentor)instrumentor).getGenadvisor(); 247 } 248 249 private CtClass getGenInstanceAdvisor() 250 { 251 return ((GeneratedAdvisorInstrumentor)instrumentor).getGenInstanceadvisor(); 252 } 253 254 private String getAdvisorReadWrapperBody(CtClass clazz, CtField field, int index) 255 throws NotFoundException, CannotCompileException 256 { 257 boolean isStatic = Modifier.isStatic(field.getModifiers()); 258 String code = null; 259 String infoName = FieldJoinPointGenerator.getInfoFieldName(field.getName(), true); 260 String generatorName = FieldJoinPointGenerator.getJoinPointGeneratorFieldName(field.getName(), true); 261 if (isStatic) 262 { 263 code = 264 "{" + 265 " if (" + infoName + " == null && " + generatorName + " != null)" + 266 " {" + 267 " " + generatorName + "." + JoinPointGenerator.GENERATE_JOINPOINT_CLASS + "();" + 268 " }" + 269 " if (" + infoName + " == null)" + 270 " { " + 271 " return " + clazz.getName() + "." + field.getName() + ";" + 272 " }" + 273 " else" + 274 " {" + 275 " " + MethodExecutionTransformer.getAopReturnStr(false) + infoName + "." + JoinPointGenerator.INVOKE_JOINPOINT + "();" + 276 " }" + 277 "}"; 278 } 279 else 280 { 281 code = 282 "{" + 283 " if (" + infoName + " == null && " + generatorName + " != null)" + 284 " {" + 285 " " + generatorName + "." + JoinPointGenerator.GENERATE_JOINPOINT_CLASS + "();" + 286 " }" + 287 " if (" + infoName + " == null)" + 288 " { " + 289 " return ((" + clazz.getName() + ")$1)." + field.getName() + ";" + 290 " }" + 291 " else" + 292 " {" + 293 " " + MethodExecutionTransformer.getAopReturnStr(false) + infoName + "." + JoinPointGenerator.INVOKE_JOINPOINT + "((" + clazz.getName() + ")$1);" + 294 " }" + 295 "}"; 296 } 297 298 return code; 299 } 300 301 private String getAdvisorWriteWrapperBody(CtClass clazz, CtField field, int index) 302 throws NotFoundException, CannotCompileException 303 { 304 boolean isStatic = Modifier.isStatic(field.getModifiers()); 305 String code = null; 306 String infoName = FieldJoinPointGenerator.getInfoFieldName(field.getName(), false); 307 String generatorName = FieldJoinPointGenerator.getJoinPointGeneratorFieldName(field.getName(), false); 308 if (isStatic) 309 { 310 code = 311 "{" + 312 " if (" + infoName + " == null && " + generatorName + " != null)" + 313 " {" + 314 " " + generatorName + "." + JoinPointGenerator.GENERATE_JOINPOINT_CLASS + "();" + 315 " }" + 316 " if (" + infoName + " == null)" + 317 " { " + 318 " " + clazz.getName() + "." + field.getName() + " = $2;" + 319 " }" + 320 " else" + 321 " {" + 322 " " + infoName + "." + JoinPointGenerator.INVOKE_JOINPOINT + "($2);" + 323 " }" + 324 "}"; 325 } 326 else 327 { 328 code = 329 "{" + 330 " if (" + infoName + " == null && " + generatorName + " != null)" + 331 " {" + 332 " " + generatorName + "." + JoinPointGenerator.GENERATE_JOINPOINT_CLASS + "();" + 333 " }" + 334 " if (" + infoName + " == null)" + 335 " { " + 336 " ((" + clazz.getName() + ")$1)." + field.getName() + " = $2;" + 337 " }" + 338 " else" + 339 " {" + 340 " " + MethodExecutionTransformer.getAopReturnStr(false) + infoName + "." + JoinPointGenerator.INVOKE_JOINPOINT + "((" + clazz.getName() + ")$1, $2);" + 341 " }" + 342 "}"; 343 } 344 345 return code; 346 } 347 348 349 private String getMainReadWrapperBody(CtClass clazz, CtField field, int index) 350 throws NotFoundException, CannotCompileException 351 { 352 boolean isStatic = Modifier.isStatic(field.getModifiers()); 354 355 String code; 356 String advisor = isStatic ? 357 "((" + GeneratedAdvisorInstrumentor.getAdvisorFQN(clazz) + ")" + Instrumentor.HELPER_FIELD_NAME + ")" : 358 "((" + GeneratedAdvisorInstrumentor.getAdvisorFQN(clazz) + ")((" + clazz.getName() + ")$1)." + GeneratedAdvisorInstrumentor.GET_CURRENT_ADVISOR + ")"; 359 360 return "return " + advisor + "." + advisorFieldRead(getGenadvisor(), field.getName()) + "($$);"; 361 } 362 363 private String getMainWriteWrapperBody(CtClass clazz, CtField field, int index) 364 throws NotFoundException, CannotCompileException 365 { 366 boolean isStatic = Modifier.isStatic(field.getModifiers()); 368 369 String code; 370 String advisor = isStatic ? 371 "((" + GeneratedAdvisorInstrumentor.getAdvisorFQN(clazz) + ")" + Instrumentor.HELPER_FIELD_NAME + ")" : 372 "((" + GeneratedAdvisorInstrumentor.getAdvisorFQN(clazz) + ")((" + clazz.getName() + ")$1)." + GeneratedAdvisorInstrumentor.GET_CURRENT_ADVISOR + ")"; 373 374 return advisor + "." + advisorFieldWrite(getGenadvisor(), field.getName()) + "($$);"; 375 } 376 377 378 379 private void buildWrappers(CtClass clazz, CtField field, boolean doGet, boolean doSet, int index) throws NotFoundException, CannotCompileException 380 { 381 if (doGet) 382 { 383 String code = getAdvisorReadWrapperBody(clazz, field, index); 385 CtMethod method = getGenadvisor().getDeclaredMethod(advisorFieldRead(getGenadvisor(), field.getName())); 386 try 387 { 388 method.setBody(code); 389 } 390 catch (CannotCompileException e) 391 { 392 throw new RuntimeException ("Field " + field + " code: " + code + " in Method " + method, e); 393 } 394 395 String mcode = getMainReadWrapperBody(clazz, field, index); 397 CtMethod mmethod = clazz.getDeclaredMethod(fieldRead(field.getName())); 398 399 mmethod.setBody(mcode); 400 } 401 if (doSet) 402 { 403 String code = getAdvisorWriteWrapperBody(clazz, field, index); 405 CtMethod method = getGenadvisor().getDeclaredMethod(advisorFieldWrite(getGenadvisor(), field.getName())); 406 try 407 { 408 method.setBody(code); 409 } 410 catch (CannotCompileException e) 411 { 412 throw new RuntimeException ("Field " + field + " code: " + code + " in Method " + method, e); 413 } 414 415 String mcode = getMainWriteWrapperBody(clazz, field, index); 417 CtMethod mmethod = clazz.getDeclaredMethod(fieldWrite(field.getName())); 418 419 mmethod.setBody(mcode); 420 } 421 } 422 423 private ArrayList pendingFieldWriteInfos = new ArrayList (); 424 private ArrayList pendingFieldReadInfos = new ArrayList (); 425 426 private class PendingFieldInfo 427 { 428 CtField field; 429 int index; 430 public PendingFieldInfo(CtField field, int index) 431 { 432 this.field = field; 433 this.index = index; 434 } 435 public CtField getField() 436 { 437 return field; 438 } 439 public int getIndex() 440 { 441 return index; 442 } 443 } 444 445 protected class GeneratedAdvisorFieldAccessExprEditor extends FieldAccessExprEditor 446 { 447 public GeneratedAdvisorFieldAccessExprEditor(CtClass clazz, CtField field, boolean doGet, boolean doSet, int index) 448 { 449 super(clazz, field, doGet, doSet, index); 450 } 451 452 protected void replaceRead(FieldAccess fieldAccess) throws CannotCompileException 453 { 454 if (fieldAccess.isStatic()) 455 { 456 String code = 457 " { " + 458 " $_ = ($r)" + fieldRead(field.getName()) + "(null);" + 459 " } " + 460 ""; 461 fieldAccess.replace(code); 462 } 463 else 464 { 465 String code = 466 " { " + 467 " $_ = ($r)" + fieldRead(field.getName()) + "($0);" + 468 " } " + 469 ""; 470 fieldAccess.replace(code); 471 } 472 } 473 474 protected void replaceWrite(FieldAccess fieldAccess) throws CannotCompileException 475 { 476 String fieldWrite = fieldWrite(field.getName()); 477 if (fieldAccess.isStatic()) 478 { 479 String code = 480 " { " + 481 " " + fieldWrite + "(null, $1);" + 482 " } " + 483 ""; 484 fieldAccess.replace(code); 485 } 486 else 487 { 488 String code = 489 " { " + 490 " " + fieldWrite + "($0, $1);" + 491 " } " + 492 ""; 493 fieldAccess.replace(code); 494 } 495 } 496 } 497 498 } 499 | Popular Tags |