Package org.jboss.aop.instrument

Source Code of org.jboss.aop.instrument.CallerTransformer$ConstructorDetail

/*     */ package org.jboss.aop.instrument;
/*     */
/*     */ import java.io.PrintStream;
/*     */ import java.util.Collection;
/*     */ import java.util.HashMap;
/*     */ import java.util.Iterator;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import javassist.CannotCompileException;
/*     */ import javassist.CtBehavior;
/*     */ import javassist.CtClass;
/*     */ import javassist.CtConstructor;
/*     */ import javassist.CtMethod;
/*     */ import javassist.Modifier;
/*     */ import javassist.NotFoundException;
/*     */ import javassist.expr.ExprEditor;
/*     */ import javassist.expr.MethodCall;
/*     */ import javassist.expr.NewExpr;
/*     */ import org.jboss.aop.AspectManager;
/*     */ import org.jboss.aop.ClassAdvisor;
/*     */ import org.jboss.aop.ConByConInfo;
/*     */ import org.jboss.aop.ConByMethodInfo;
/*     */ import org.jboss.aop.MethodByConInfo;
/*     */ import org.jboss.aop.MethodByMethodInfo;
/*     */ import org.jboss.aop.pointcut.Pointcut;
/*     */ import org.jboss.aop.util.Advisable;
/*     */ import org.jboss.aop.util.JavassistMethodHashing;
/*     */ import org.jboss.aop.util.logging.AOPLogger;
/*     */ import org.jboss.logging.Logger;
/*     */
/*     */ public abstract class CallerTransformer
/*     */ {
/*  56 */   private static final Logger logger = AOPLogger.getLogger(CallerTransformer.class);
/*     */
/*  58 */   public static final String CON_BY_CON_INFO_CLASS_NAME = ConByConInfo.class.getName();
/*  59 */   public static final String CON_BY_METHOD_INFO_CLASS_NAME = ConByMethodInfo.class.getName();
/*  60 */   public static final String METHOD_BY_CON_INFO_CLASS_NAME = MethodByConInfo.class.getName();
/*  61 */   public static final String METHOD_BY_METHOD_INFO_CLASS_NAME = MethodByMethodInfo.class.getName();
/*     */   Instrumentor instrumentor;
/*     */   boolean optimize;
/*     */   AspectManager manager;
/*     */   CallerInfoAdder callerInfoAdder;
/*     */
/*     */   protected CallerTransformer(Instrumentor instrumentor, AspectManager manager, boolean optimize, CallerInfoAdder callerInfoAdder)
/*     */   {
/*  77 */     this.instrumentor = instrumentor;
/*  78 */     this.optimize = optimize;
/*  79 */     this.manager = manager;
/*  80 */     this.callerInfoAdder = callerInfoAdder;
/*     */   }
/*     */
/*     */   protected abstract CallerExprEditor callerExprEditorFactory(ClassAdvisor paramClassAdvisor, CtClass paramCtClass);
/*     */
/*     */   public boolean applyCallerPointcuts(CtClass clazz, ClassAdvisor advisor) throws CannotCompileException {
/*  87 */     if ((!advisor.getManager().isWithin()) && (!advisor.getManager().isCall()) && (!advisor.getManager().isWithincode()))
/*     */     {
/*  89 */       if ((AspectManager.verbose) && (logger.isDebugEnabled())) logger.debug("There are no caller pointcuts!");
/*  90 */       return false;
/*     */     }
/*  92 */     CallerExprEditor expr = callerExprEditorFactory(advisor, clazz);
/*  93 */     CtMethod[] methods = clazz.getDeclaredMethods();
/*  94 */     for (int i = 0; i < methods.length; i++)
/*     */     {
/*  96 */       if (!Advisable.isAdvisable(methods[i]))
/*     */         continue;
/*  98 */       methods[i].instrument(expr);
/*     */     }
/*     */
/* 102 */     CtConstructor[] cons = clazz.getDeclaredConstructors();
/* 103 */     for (int i = 0; i < cons.length; i++)
/*     */     {
/* 105 */       cons[i].instrument(expr);
/*     */     }
/*     */
/* 108 */     return expr.appliedCallerBinding;
/*     */   }
/*     */
/*     */   private boolean isTargetConstructorAdvised(CtConstructor calledConstructor)
/*     */   {
/*     */     try
/*     */     {
/* 115 */       ClassAdvisor adv = this.manager.getTempClassAdvisor(calledConstructor.getDeclaringClass());
/* 116 */       return ConstructorExecutionTransformer.isAdvisableConstructor(calledConstructor, adv);
/*     */     }
/*     */     catch (Exception e) {
/*     */     }
/* 120 */     throw new RuntimeException(e);
/*     */   }
/*     */
/*     */   private static String getHashString(long hash)
/*     */   {
/* 127 */     if (hash < 0L)
/*     */     {
/* 129 */       return "_N_" + -1L * hash;
/*     */     }
/*     */
/* 133 */     return "_" + hash;
/*     */   }
/*     */
/*     */   protected static String getUniqueInvocationFieldname(long callingHash, String classname, long calledHash)
/*     */   {
/* 139 */     classname = classname.replace('.', '_');
/* 140 */     classname = classname.replace('/', '_');
/*     */
/* 142 */     return getHashString(callingHash) + classname + getHashString(calledHash);
/*     */   }
/*     */
/*     */   protected static String getConByConInfoName(long callingIndex, String classname, long calledHash)
/*     */   {
/* 147 */     return "aop$constructorCall_con_" + getUniqueInvocationFieldname(callingIndex, classname, calledHash);
/*     */   }
/*     */
/*     */   protected static String getConByMethodInfoName(long callingHash, String classname, long calledHash)
/*     */   {
/* 152 */     return "aop$constructorCall_" + getUniqueInvocationFieldname(callingHash, classname, calledHash);
/*     */   }
/*     */
/*     */   protected static String getMethodByConInfoName(int index, String classname, long calledHash)
/*     */   {
/* 157 */     return "aop$methodCall_con_" + getUniqueInvocationFieldname(index, classname, calledHash);
/*     */   }
/*     */
/*     */   protected static String getMethodByMethodInfoName(long callingHash, String classname, long calledHash)
/*     */   {
/* 162 */     return "aop$methodCall_" + getUniqueInvocationFieldname(callingHash, classname, calledHash);
/*     */   }
/*     */
/*     */   protected static String conByConInfoFromWeakReference(String localName, String infoName)
/*     */   {
/* 167 */     return TransformerCommon.infoFromWeakReference(CON_BY_CON_INFO_CLASS_NAME, localName, infoName);
/*     */   }
/*     */
/*     */   protected static String conByMethodInfoFromWeakReference(String localName, String infoName)
/*     */   {
/* 172 */     return TransformerCommon.infoFromWeakReference(CON_BY_METHOD_INFO_CLASS_NAME, localName, infoName);
/*     */   }
/*     */
/*     */   protected static String methodByMethodInfoFromWeakReference(String localName, String infoName)
/*     */   {
/* 177 */     return TransformerCommon.infoFromWeakReference(METHOD_BY_METHOD_INFO_CLASS_NAME, localName, infoName);
/*     */   }
/*     */
/*     */   protected static String methodByConInfoFromWeakReference(String localName, String infoName)
/*     */   {
/* 182 */     return TransformerCommon.infoFromWeakReference(METHOD_BY_CON_INFO_CLASS_NAME, localName, infoName);
/*     */   }
/*     */
/*     */   abstract class CallerExprEditor extends ExprEditor
/*     */   {
/*     */     CtClass callingClass;
/*     */     ClassAdvisor advisor;
/*     */     List constructors;
/* 284 */     public boolean appliedCallerBinding = false;
/*     */
/* 286 */     HashMap callerInfos = new HashMap();
/* 287 */     int invocationCounter = 0;
/*     */
/*     */     public CallerExprEditor(ClassAdvisor advisor, CtClass callingClass)
/*     */     {
/* 291 */       this.advisor = advisor;
/* 292 */       this.callingClass = callingClass;
/* 293 */       this.constructors = CallerTransformer.this.instrumentor.getConstructors(callingClass);
/*     */     }
/*     */
/*     */     private synchronized String getUniqueInvocationClassname(String classname)
/*     */     {
/* 298 */       return classname + "_" + ++this.invocationCounter + "_";
/*     */     }
/*     */
/*     */     protected String getOptimizedConCalledByMethodInvocationClassName(long callingHash, String classname, long calledHash)
/*     */     {
/* 303 */       return getUniqueInvocationClassname(classname) + "ConByMInvocation";
/*     */     }
/*     */
/*     */     protected String getOptimizedConCalledByConInvocationClassName(long callingIndex, String classname, long calledHash)
/*     */     {
/* 308 */       return getUniqueInvocationClassname(classname) + "ConByConInvocation";
/*     */     }
/*     */
/*     */     protected String getOptimizedMethodCalledByMethodClassName(long callingHash, String classname, long calledHash)
/*     */     {
/* 313 */       return getUniqueInvocationClassname(classname) + "MByMInvocation";
/*     */     }
/*     */
/*     */     protected String getOptimizedMethodCalledByConstructorClassName(int callingIndex, String classname, long calledHash)
/*     */     {
/* 318 */       return getUniqueInvocationClassname(classname) + "MByConInvocation";
/*     */     }
/*     */
/*     */     public void edit(MethodCall call) throws CannotCompileException
/*     */     {
/* 323 */       String classname = call.getClassName();
/* 324 */       String methodName = call.getMethodName();
/*     */       try
/*     */       {
/* 327 */         if ((ClassAdvisor.isWithoutAdvisement(methodName)) || (methodName.startsWith("_")) || (classname.startsWith("org.jboss.aop")) || (call.getMethodName().equals("class$")) || (!Instrumentor.isTransformable(this.callingClass)))
/*     */         {
/* 334 */           return;
/*     */         }
/*     */
/* 337 */         CtBehavior behavior = call.where();
/*     */
/* 339 */         boolean hasPointcut = false;
/*     */
/* 341 */         DeclareChecker.checkDeclares(CallerTransformer.this.manager, call, this.advisor);
/*     */
/* 344 */         Map pointcuts = CallerTransformer.this.manager.getPointcuts();
/* 345 */         synchronized (pointcuts)
/*     */         {
/* 347 */           Iterator it = pointcuts.values().iterator();
/* 348 */           while (it.hasNext())
/*     */           {
/* 350 */             Pointcut p = (Pointcut)it.next();
/* 351 */             if (p.matchesCall(this.advisor, call))
/*     */             {
/* 353 */               hasPointcut = true;
/* 354 */               break;
/*     */             }
/*     */
/* 358 */             if ((AspectManager.verbose) && (CallerTransformer.logger.isDebugEnabled())) CallerTransformer.logger.debug("MethodCall does not match: " + p.getExpr());
/*     */           }
/*     */         }
/*     */
/* 362 */         if (hasPointcut)
/*     */         {
/* 364 */           if ((behavior instanceof CtMethod))
/* 365 */             modifyMethod(call, classname);
/* 366 */           else if ((behavior instanceof CtConstructor)) modifyConstructor(call, classname);
/*     */         }
/*     */       }
/*     */       catch (Exception ex)
/*     */       {
/* 371 */         System.err.println("error getting:" + classname + ". '" + methodName + "'");
/* 372 */         ex.printStackTrace();
/* 373 */         throw new CannotCompileException(ex);
/*     */       }
/*     */     }
/*     */
/*     */     private void modifyConstructor(MethodCall call, String classname)
/*     */       throws NotFoundException, CannotCompileException
/*     */     {
/* 380 */       CallerTransformer.this.instrumentor.setupBasics(this.callingClass);
/* 381 */       CallerTransformer.ConstructorDetail cd = new CallerTransformer.ConstructorDetail(CallerTransformer.this, this, call, classname);
/* 382 */       setupConstructor(cd);
/* 383 */       replaceMethodCallInCon(cd);
/* 384 */       this.appliedCallerBinding = true;
/*     */     }
/*     */
/*     */     protected void replaceMethodCallInCon(CallerTransformer.ConstructorDetail cd)
/*     */       throws CannotCompileException, NotFoundException
/*     */     {
/* 391 */       String replaced = CallerTransformer.methodByConInfoFromWeakReference("info", cd.callerInfoField) + "if (info.getInterceptors() != (org.jboss.aop.advice.Interceptor[])null) { " + "$_ = ($r)aop$classAdvisor$aop.invokeConstructorCaller(info, this, $0, $args);" + "} else { " + "$_ = $proceed($$); " + "}";
/*     */
/* 399 */       cd.call.replace(replaced);
/*     */     }
/*     */
/*     */     private void modifyMethod(MethodCall call, String classname) throws NotFoundException, CannotCompileException
/*     */     {
/* 404 */       CallerTransformer.this.instrumentor.setupBasics(this.callingClass);
/* 405 */       CallerTransformer.MethodDetail md = new CallerTransformer.MethodDetail(CallerTransformer.this, this, call, classname);
/* 406 */       setupMethod(md);
/* 407 */       replaceMethodCallInMethod(md);
/* 408 */       this.appliedCallerBinding = true;
/*     */     }
/*     */
/*     */     protected void replaceMethodCallInMethod(CallerTransformer.MethodDetail md)
/*     */       throws NotFoundException, CannotCompileException
/*     */     {
/* 415 */       String callingObject = ", null";
/* 416 */       if (!Modifier.isStatic(md.where.getModifiers()))
/*     */       {
/* 418 */         callingObject = ", this";
/*     */       }
/* 420 */       String replaced = CallerTransformer.methodByMethodInfoFromWeakReference("info", md.callerInfoField) + "if (info.getInterceptors() != (org.jboss.aop.advice.Interceptor[])null) { " + "$_ = ($r)aop$classAdvisor$aop.invokeCaller(info" + callingObject + ", $0, $args);" + "} else { " + "$_ = $proceed($$); " + "}";
/*     */
/* 428 */       md.call.replace(replaced);
/*     */     }
/*     */
/*     */     public void edit(NewExpr call)
/*     */       throws CannotCompileException
/*     */     {
/*     */       try
/*     */       {
/* 436 */         String classname = call.getClassName();
/* 437 */         if ((classname.startsWith("org.jboss.aop")) || (!Instrumentor.isTransformable(this.callingClass)))
/*     */         {
/* 439 */           return;
/*     */         }
/*     */
/* 442 */         DeclareChecker.checkDeclares(CallerTransformer.this.manager, call, this.advisor);
/*     */
/* 444 */         boolean hasPointcut = false;
/*     */
/* 447 */         Map pointcuts = CallerTransformer.this.manager.getPointcuts();
/* 448 */         synchronized (pointcuts)
/*     */         {
/* 450 */           Iterator it = pointcuts.values().iterator();
/* 451 */           while (it.hasNext())
/*     */           {
/* 453 */             Pointcut p = (Pointcut)it.next();
/* 454 */             if (p.matchesCall(this.advisor, call))
/*     */             {
/* 456 */               hasPointcut = true;
/* 457 */               break;
/*     */             }
/*     */           }
/*     */         }
/* 461 */         if (hasPointcut)
/*     */         {
/* 463 */           CtBehavior behavior = call.where();
/* 464 */           if ((behavior instanceof CtMethod))
/* 465 */             modifyMethod(call, classname);
/* 466 */           else if ((behavior instanceof CtConstructor)) modifyConstructor(call, classname);
/*     */         }
/*     */       }
/*     */       catch (Exception ex)
/*     */       {
/* 471 */         CallerTransformer.logger.error(ex.getMessage());
/* 472 */         throw new CannotCompileException(ex);
/*     */       }
/*     */     }
/*     */
/*     */     private void modifyMethod(NewExpr call, String classname) throws Exception, NotFoundException, CannotCompileException
/*     */     {
/* 478 */       CallerTransformer.this.instrumentor.setupBasics(this.callingClass);
/* 479 */       CallerTransformer.ConByMethodDetail cd = new CallerTransformer.ConByMethodDetail(CallerTransformer.this, this, call, classname);
/* 480 */       setupMethod(cd);
/* 481 */       replaceConCallInMethod(cd);
/* 482 */       this.appliedCallerBinding = true;
/*     */     }
/*     */
/*     */     protected void replaceConCallInMethod(CallerTransformer.ConByMethodDetail cd)
/*     */       throws NotFoundException, CannotCompileException
/*     */     {
/* 489 */       String callingObject = "null";
/* 490 */       if (!Modifier.isStatic(cd.where.getModifiers()))
/*     */       {
/* 492 */         callingObject = "this";
/*     */       }
/*     */
/* 495 */       String replaced = CallerTransformer.conByMethodInfoFromWeakReference("info", cd.callerInfoField) + "if (info.getInterceptors() != (org.jboss.aop.advice.Interceptor[])null) { " + "java.lang.Object callingObject = " + callingObject + "; " + "$_ = ($r)aop$classAdvisor$aop.invokeConCalledByMethod(info, " + callingObject + ", $args);" + "} else { " + "$_ = $proceed($$); " + "}";
/*     */
/* 505 */       cd.call.replace(replaced);
/*     */     }
/*     */
/*     */     private void modifyConstructor(NewExpr call, String classname) throws Exception, NotFoundException, CannotCompileException
/*     */     {
/* 510 */       CallerTransformer.this.instrumentor.setupBasics(this.callingClass);
/* 511 */       CallerTransformer.ConByConDetail cd = new CallerTransformer.ConByConDetail(CallerTransformer.this, this, call, classname);
/* 512 */       setupConstructor(cd);
/* 513 */       replaceConCallInCon(cd);
/* 514 */       this.appliedCallerBinding = true;
/*     */     }
/*     */
/*     */     protected void replaceConCallInCon(CallerTransformer.ConByConDetail cd)
/*     */       throws CannotCompileException, NotFoundException
/*     */     {
/* 521 */       String replaced = CallerTransformer.conByConInfoFromWeakReference("info", cd.callerInfoField) + "if (info.getInterceptors() != (org.jboss.aop.advice.Interceptor[])null) { " + "$_ = ($r)aop$classAdvisor$aop.invokeConCalledByCon(info, this, $args);" + "} else { " + "$_ = $proceed($$); " + "}";
/*     */
/* 530 */       cd.call.replace(replaced);
/*     */     }
/*     */
/*     */     protected abstract void setupConstructor(CallerTransformer.ConstructorDetail paramConstructorDetail)
/*     */       throws NotFoundException, CannotCompileException;
/*     */
/*     */     protected abstract void setupMethod(CallerTransformer.MethodDetail paramMethodDetail)
/*     */       throws NotFoundException, CannotCompileException;
/*     */
/*     */     protected abstract void setupMethod(CallerTransformer.ConByMethodDetail paramConByMethodDetail)
/*     */       throws NotFoundException, CannotCompileException;
/*     */
/*     */     protected abstract void setupConstructor(CallerTransformer.ConByConDetail paramConByConDetail)
/*     */       throws NotFoundException, CannotCompileException;
/*     */   }
/*     */
/*     */   protected class ConByConDetail
/*     */   {
/*     */     NewExpr call;
/*     */     boolean isTgtConAdvised;
/*     */     CtConstructor con;
/*     */     int callingIndex;
/*     */     long calledHash;
/*     */     String callerInfoField;
/*     */     CtConstructor calledConstructor;
/*     */     String classname;
/*     */
/*     */     ConByConDetail(CallerTransformer.CallerExprEditor editor, NewExpr call, String classname)
/*     */       throws NotFoundException
/*     */     {
/* 268 */       this.call = call;
/* 269 */       this.con = ((CtConstructor)call.where());
/* 270 */       this.callingIndex = editor.constructors.indexOf(this.con);
/* 271 */       this.calledHash = JavassistMethodHashing.constructorHash(call.getConstructor());
/* 272 */       this.callerInfoField = CallerTransformer.getConByConInfoName(this.callingIndex, classname, this.calledHash);
/* 273 */       this.calledConstructor = call.getConstructor();
/* 274 */       this.classname = classname;
/* 275 */       this.isTgtConAdvised = CallerTransformer.this.isTargetConstructorAdvised(this.calledConstructor);
/*     */     }
/*     */   }
/*     */
/*     */   protected class ConByMethodDetail
/*     */   {
/*     */     NewExpr call;
/*     */     boolean isTgtConAdvised;
/*     */     CtMethod where;
/*     */     long callingHash;
/*     */     long calledHash;
/*     */     String callerInfoField;
/*     */     CtConstructor calledConstructor;
/*     */     String classname;
/*     */
/*     */     ConByMethodDetail(CallerTransformer.CallerExprEditor editor, NewExpr call, String classname)
/*     */       throws NotFoundException
/*     */     {
/* 244 */       this.call = call;
/* 245 */       this.where = ((CtMethod)call.where());
/* 246 */       this.callingHash = JavassistMethodHashing.methodHash(this.where);
/* 247 */       this.calledHash = JavassistMethodHashing.constructorHash(call.getConstructor());
/* 248 */       this.callerInfoField = CallerTransformer.getConByMethodInfoName(this.callingHash, classname, this.calledHash);
/* 249 */       this.calledConstructor = call.getConstructor();
/* 250 */       this.classname = classname;
/* 251 */       this.isTgtConAdvised = CallerTransformer.this.isTargetConstructorAdvised(this.calledConstructor);
/*     */     }
/*     */   }
/*     */
/*     */   protected class MethodDetail
/*     */   {
/*     */     MethodCall call;
/*     */     CtMethod where;
/*     */     long callingHash;
/*     */     long calledHash;
/*     */     String callerInfoField;
/*     */     CtMethod calledMethod;
/*     */     String classname;
/*     */
/*     */     MethodDetail(CallerTransformer.CallerExprEditor editor, MethodCall call, String classname)
/*     */       throws NotFoundException
/*     */     {
/* 220 */       this.call = call;
/* 221 */       this.where = ((CtMethod)call.where());
/* 222 */       this.callingHash = JavassistMethodHashing.methodHash(this.where);
/* 223 */       this.calledHash = JavassistMethodHashing.methodHash(call.getMethod());
/* 224 */       this.callerInfoField = CallerTransformer.getMethodByMethodInfoName(this.callingHash, classname, this.calledHash);
/* 225 */       this.calledMethod = call.getMethod();
/*     */
/* 227 */       this.classname = classname;
/*     */     }
/*     */   }
/*     */
/*     */   protected class ConstructorDetail
/*     */   {
/*     */     MethodCall call;
/*     */     CtConstructor con;
/*     */     int callingIndex;
/*     */     long calledHash;
/*     */     String callerInfoField;
/*     */     CtMethod calledMethod;
/*     */     String classname;
/*     */
/*     */     ConstructorDetail(CallerTransformer.CallerExprEditor editor, MethodCall call, String classname)
/*     */       throws NotFoundException
/*     */     {
/* 198 */       this.call = call;
/* 199 */       this.con = ((CtConstructor)call.where());
/* 200 */       this.callingIndex = editor.constructors.indexOf(this.con);
/* 201 */       this.calledHash = JavassistMethodHashing.methodHash(call.getMethod());
/* 202 */       this.callerInfoField = CallerTransformer.getMethodByConInfoName(this.callingIndex, classname, this.calledHash);
/* 203 */       this.calledMethod = call.getMethod();
/* 204 */       this.classname = classname;
/*     */     }
/*     */   }
/*     */ }

/* Location:           /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name:     org.jboss.aop.instrument.CallerTransformer
* JD-Core Version:    0.6.0
*/
TOP

Related Classes of org.jboss.aop.instrument.CallerTransformer$ConstructorDetail

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.