Package org.jboss.aop.instrument

Source Code of org.jboss.aop.instrument.ConstructorExecutionTransformer$ConstructorTransformation

/*     */ package org.jboss.aop.instrument;
/*     */
/*     */ 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.CodeConverter;
/*     */ import javassist.CtClass;
/*     */ import javassist.CtConstructor;
/*     */ import javassist.CtField.Initializer;
/*     */ import javassist.CtMember;
/*     */ import javassist.CtMethod;
/*     */ import javassist.CtNewMethod;
/*     */ import javassist.NotFoundException;
/*     */ import javassist.bytecode.MethodInfo;
/*     */ import javassist.bytecode.SignatureAttribute;
/*     */ import org.jboss.aop.AspectManager;
/*     */ import org.jboss.aop.ClassAdvisor;
/*     */ import org.jboss.aop.pointcut.Pointcut;
/*     */ import org.jboss.aop.util.logging.AOPLogger;
/*     */ import org.jboss.logging.Logger;
/*     */
/*     */ public abstract class ConstructorExecutionTransformer
/*     */   implements CodeConversionObserver
/*     */ {
/*  55 */   private static final Logger logger = AOPLogger.getLogger(ConstructorExecutionTransformer.class);
/*     */   protected static final String CONSTRUCTOR_INFO_CLASS_NAME = "org.jboss.aop.ConstructorInfo";
/*     */   protected Instrumentor instrumentor;
/*     */   protected Codifier codifier;
/*     */   private JoinpointClassifier classifier;
/*  63 */   private static final WrapperTransformer wrapper = new WrapperTransformer(new String[] { "wrapperStatus", "constructorsWrapped" });
/*     */   protected static final int CONSTRUCTOR_STATUS = 0;
/*     */   private static final int ALL_CONSTRUCTORS_STATUS = 1;
/*     */
/*     */   protected ConstructorExecutionTransformer(Instrumentor instrumentor)
/*     */   {
/*  70 */     this.instrumentor = instrumentor;
/*  71 */     this.codifier = new Codifier();
/*  72 */     this.classifier = instrumentor.joinpointClassifier;
/*     */   }
/*     */
/*     */   protected Instrumentor getInstrumentor()
/*     */   {
/*  78 */     return this.instrumentor;
/*     */   }
/*     */
/*     */   protected WrapperTransformer getWrapper()
/*     */   {
/*  83 */     return wrapper;
/*     */   }
/*     */
/*     */   public static String constructorFactory(String className)
/*     */   {
/*  88 */     if (className.indexOf('.') >= 0) throw new RuntimeException("constructorFactory() takes a simple class name: " + className);
/*  89 */     return className + "_new_" + "$aop";
/*     */   }
/*     */
/*     */   protected String addConstructorInfoField(int modifiers, CtClass addTo, String infoName)
/*     */     throws NotFoundException, CannotCompileException
/*     */   {
/*  97 */     return addConstructorInfoField(modifiers, addTo, infoName, null);
/*     */   }
/*     */
/*     */   protected String addConstructorInfoField(int modifiers, CtClass addTo, String infoName, CtField.Initializer init)
/*     */     throws NotFoundException, CannotCompileException
/*     */   {
/* 107 */     if (this.instrumentor.getClassPool() != null)
/*     */     {
/*     */       try
/*     */       {
/* 111 */         addTo.getDeclaredField(infoName);
/* 112 */         return infoName;
/*     */       }
/*     */       catch (NotFoundException e)
/*     */       {
/* 117 */         TransformerCommon.addInfoField(this.instrumentor, "org.jboss.aop.ConstructorInfo", infoName, modifiers, addTo, addInfoAsWeakReference(), init);
/*     */       }
/*     */     }
/* 120 */     return infoName;
/*     */   }
/*     */
/*     */   protected boolean addInfoAsWeakReference()
/*     */   {
/* 125 */     return true;
/*     */   }
/*     */
/*     */   public static String getConstructorInfoFieldName(String classname, int index)
/*     */   {
/* 130 */     if (classname.indexOf('.') >= 0) throw new RuntimeException("Simple name should be used: " + classname);
/* 131 */     return "aop$constructorInfo_" + index;
/*     */   }
/*     */
/*     */   protected static String constructorInfoFromWeakReference(String localName, String ctorInfoName)
/*     */   {
/* 136 */     return TransformerCommon.infoFromWeakReference("org.jboss.aop.ConstructorInfo", localName, ctorInfoName);
/*     */   }
/*     */
/*     */   public boolean transform(CtClass clazz, ClassAdvisor classAdvisor)
/*     */     throws Exception
/*     */   {
/* 148 */     List constructors = this.instrumentor.getConstructors(clazz);
/* 149 */     boolean wrappersGenerated = false;
/* 150 */     boolean oneOrMoreWrapped = false;
/* 151 */     int i = 0;
/* 152 */     boolean dynamicallyWrapped = false;
/* 153 */     boolean notDynamicallyWrapped = false;
/* 154 */     CtConstructor firstConstructor = null;
/* 155 */     if (!constructors.isEmpty())
/*     */     {
/* 157 */       firstConstructor = (CtConstructor)constructors.get(0);
/*     */     }
/* 159 */     if (constructors.size() > 0)
/*     */     {
/* 161 */       for (Iterator iterator = constructors.iterator(); iterator.hasNext(); i++)
/*     */       {
/* 163 */         CtConstructor constructor = (CtConstructor)iterator.next();
/*     */
/* 165 */         JoinpointClassification classification = this.classifier.classifyConstructorExecution(constructor, classAdvisor);
/*     */
/* 167 */         if ((classification == JoinpointClassification.NOT_INSTRUMENTED) && (!oneOrMoreWrapped))
/*     */         {
/*     */           continue;
/*     */         }
/*     */
/* 172 */         if (!wrappersGenerated)
/*     */         {
/* 175 */           buildConstructorWrappers(clazz, classAdvisor);
/* 176 */           wrappersGenerated = true;
/* 177 */           wrapper.prepareForWrapping(firstConstructor, 1);
/*     */         }
/*     */
/* 180 */         if (classification.equals(JoinpointClassification.WRAPPED))
/*     */         {
/* 182 */           if (!oneOrMoreWrapped)
/*     */           {
/* 184 */             for (int j = 0; j < i; j++)
/*     */             {
/* 186 */               setEmptyWrapperCodeLater((CtConstructor)constructors.get(j));
/*     */             }
/* 188 */             oneOrMoreWrapped = true;
/*     */           }
/* 190 */           wrap(clazz, constructor, i);
/* 191 */           dynamicallyWrapped = (dynamicallyWrapped) || (classification.equals(JoinpointClassification.DYNAMICALY_WRAPPED));
/* 192 */           notDynamicallyWrapped = (notDynamicallyWrapped) || (!classification.equals(JoinpointClassification.DYNAMICALY_WRAPPED));
/*     */         } else {
/* 194 */           if (!oneOrMoreWrapped)
/*     */             continue;
/* 196 */           setEmptyWrapperCodeLater(constructor);
/*     */         }
/*     */       }
/*     */     }
/*     */
/* 201 */     if (oneOrMoreWrapped)
/*     */     {
/* 203 */       wrapAllConstructors(clazz, firstConstructor, null);
/*     */     }
/* 205 */     if ((dynamicallyWrapped) && (!notDynamicallyWrapped))
/*     */     {
/* 207 */       this.instrumentor.dynamicTransformationObserver.constructorDynamicalyWrapped();
/*     */     }
/* 209 */     return wrappersGenerated;
/*     */   }
/*     */
/*     */   private void wrapAllConstructors(CtClass clazz, CtConstructor firstConstructor, List constructors)
/*     */     throws NotFoundException, CannotCompileException
/*     */   {
/* 229 */     wrapper.wrap(firstConstructor, 1);
/* 230 */     if (constructors == null)
/*     */     {
/* 232 */       return;
/*     */     }
/* 234 */     for (Iterator i = constructors.iterator(); i.hasNext(); )
/*     */     {
/* 236 */       CtConstructor constructor = (CtConstructor)i.next();
/* 237 */       if (!wrapper.isWrapped(constructor, 0))
/*     */       {
/* 239 */         setEmptyWrapperCodeLater(constructor);
/*     */       }
/*     */     }
/* 242 */     this.instrumentor.converter.replaceNew(clazz, clazz, constructorFactory(clazz.getSimpleName()));
/*     */   }
/*     */
/*     */   public void wrap(CtClass clazz, Collection constructorIndexes)
/*     */     throws Exception
/*     */   {
/* 253 */     List constructors = this.instrumentor.getConstructors(clazz);
/*     */
/* 255 */     CtConstructor firstConstructor = (CtConstructor)constructors.get(0);
/* 256 */     if (wrapper.isNotPrepared(firstConstructor, 1))
/*     */     {
/* 258 */       return;
/*     */     }
/*     */
/* 261 */     for (Iterator iterator = constructorIndexes.iterator(); iterator.hasNext(); )
/*     */     {
/* 263 */       int constructorIndex = ((Integer)iterator.next()).intValue();
/* 264 */       CtConstructor constructor = (CtConstructor)constructors.get(constructorIndex);
/* 265 */       wrap(clazz, constructor, constructorIndex);
/*     */     }
/*     */
/* 269 */     if (!wrapper.isWrapped(firstConstructor, 1))
/*     */     {
/* 271 */       wrapAllConstructors(clazz, firstConstructor, constructors);
/*     */     }
/*     */   }
/*     */
/*     */   private void wrap(CtClass clazz, CtConstructor constructor, int constructorIndex)
/*     */     throws NotFoundException, Exception, CannotCompileException
/*     */   {
/* 284 */     if (wrapper.isNotPrepared(constructor, 0))
/*     */     {
/* 286 */       return;
/*     */     }
/*     */
/* 289 */     wrapper.wrap(constructor, 0);
/*     */
/* 291 */     CtMethod wrapperMethod = clazz.getDeclaredMethod(constructorFactory(clazz.getSimpleName()), constructor.getParameterTypes());
/* 292 */     setTemporaryWrapperCode(constructor.getDeclaringClass(), wrapperMethod);
/* 293 */     ConstructorTransformation trans = new ConstructorTransformation(clazz, constructor, wrapperMethod, constructorIndex);
/* 294 */     createWrapper(trans);
/*     */   }
/*     */
/*     */   public void unwrap(CtClass clazz, Collection constructorIndexes)
/*     */     throws NotFoundException
/*     */   {
/* 305 */     List constructors = this.instrumentor.getConstructors(clazz);
/*     */
/* 307 */     if (wrapper.isNotPrepared((CtMember)constructors.get(0), 1))
/*     */     {
/* 309 */       return;
/*     */     }
/* 311 */     for (Iterator iterator = constructorIndexes.iterator(); iterator.hasNext(); )
/*     */     {
/* 313 */       int constructorIndex = ((Integer)iterator.next()).intValue();
/* 314 */       CtConstructor constructor = (CtConstructor)constructors.get(constructorIndex);
/* 315 */       if (wrapper.isNotPrepared(constructor, 0))
/*     */       {
/*     */         continue;
/*     */       }
/*     */
/* 320 */       wrapper.unwrap(constructor, 0);
/*     */
/* 323 */       setEmptyWrapperCode(constructor);
/*     */     }
/*     */   }
/*     */
/*     */   public void codeConverted()
/*     */     throws CannotCompileException
/*     */   {
/* 332 */     this.codifier.codifyPending();
/*     */   }
/*     */
/*     */   public boolean replaceConstructorAccess(ClassAdvisor sourceAdvisor, CtClass source) throws NotFoundException
/*     */   {
/* 337 */     if (!isAnyConstructorAdvised(source, sourceAdvisor))
/*     */     {
/* 339 */       return false;
/*     */     }
/* 341 */     this.instrumentor.converter.replaceNew(source, source, constructorFactory(source.getSimpleName()));
/* 342 */     return true;
/*     */   }
/*     */
/*     */   protected void buildConstructorWrappers(CtClass clazz, ClassAdvisor advisor)
/*     */     throws Exception
/*     */   {
/* 349 */     this.instrumentor.setupBasics(clazz);
/* 350 */     List constructors = this.instrumentor.getConstructors(clazz);
/*     */
/* 352 */     Iterator it = constructors.iterator();
/* 353 */     for (int index = 0; it.hasNext(); index++)
/*     */     {
/* 356 */       CtConstructor constructor = (CtConstructor)it.next();
/* 357 */       int mod = 8;
/* 358 */       if ((constructor.getModifiers() & 0x1) != 0)
/*     */       {
/* 360 */         mod |= 1;
/*     */       }
/* 362 */       else if ((constructor.getModifiers() & 0x4) != 0)
/*     */       {
/* 364 */         mod |= 4;
/*     */       }
/* 366 */       else if ((constructor.getModifiers() & 0x2) != 0)
/*     */       {
/* 368 */         mod |= 2;
/*     */       }
/*     */       else
/*     */       {
/* 372 */         mod |= 1;
/*     */       }
/*     */
/* 375 */       initialiseWrapper(mod, constructor, index);
/* 376 */       generateConstructorInfoField(clazz, constructor, index);
/*     */     }
/*     */   }
/*     */
/*     */   protected void generateConstructorInfoField(CtClass clazz, CtConstructor constructor, int index) throws CannotCompileException, NotFoundException
/*     */   {
/* 382 */     String name = getConstructorInfoFieldName(clazz.getSimpleName(), index);
/* 383 */     addConstructorInfoField(10, clazz, name);
/*     */   }
/*     */
/*     */   protected void setTemporaryWrapperCode(CtClass type, CtMethod wrapperMethod)
/*     */   {
/* 394 */     String code = "{   return null;}";
/*     */     try
/*     */     {
/* 399 */       wrapperMethod.setBody(code);
/*     */     }
/*     */     catch (CannotCompileException e)
/*     */     {
/* 403 */       logger.error("Cannot compile " + code);
/* 404 */       throw new RuntimeException(e);
/*     */     }
/*     */   }
/*     */
/*     */   protected void setEmptyWrapperCode(CtConstructor constructor)
/*     */     throws NotFoundException
/*     */   {
/* 416 */     CtMethod wrapperMethod = getWrapperMethod(constructor);
/* 417 */     String code = "{     return new " + constructor.getDeclaringClass().getName() + "($$); " + "}";
/*     */     try
/*     */     {
/* 423 */       wrapperMethod.setBody(code);
/*     */     }
/*     */     catch (CannotCompileException e)
/*     */     {
/* 427 */       logger.error("Cannot compile " + code);
/* 428 */       throw new RuntimeException(e);
/*     */     }
/*     */   }
/*     */
/*     */   protected void setEmptyWrapperCodeLater(CtConstructor constructor)
/*     */     throws NotFoundException
/*     */   {
/* 441 */     CtMethod wrapperMethod = getWrapperMethod(constructor);
/* 442 */     String code = "{     return new " + constructor.getDeclaringClass().getName() + "($$); " + "}";
/*     */
/* 446 */     this.codifier.addPendingCode(wrapperMethod, code);
/*     */   }
/*     */
/*     */   protected boolean isAnyConstructorAdvised(CtClass clazz, ClassAdvisor advisor)
/*     */     throws NotFoundException
/*     */   {
/* 459 */     CtConstructor[] constructors = clazz.getDeclaredConstructors();
/* 460 */     for (int i = 0; i < constructors.length; i++)
/*     */     {
/* 462 */       JoinpointClassification classification = this.classifier.classifyConstructorExecution(constructors[i], advisor);
/* 463 */       if (classification.equals(JoinpointClassification.WRAPPED))
/* 464 */         return true;
/*     */     }
/* 466 */     return false;
/*     */   }
/*     */
/*     */   public static boolean isAdvisableConstructor(CtConstructor con, ClassAdvisor advisor)
/*     */     throws NotFoundException
/*     */   {
/* 472 */     Map pointcuts = advisor.getManager().getPointcuts();
/* 473 */     synchronized (pointcuts)
/*     */     {
/* 475 */       Iterator it = pointcuts.values().iterator();
/* 476 */       while (it.hasNext())
/*     */       {
/* 478 */         Pointcut pointcut = (Pointcut)it.next();
/* 479 */         if (pointcut.matchesExecution(advisor, con))
/*     */         {
/* 481 */           return true;
/*     */         }
/*     */       }
/*     */     }
/* 485 */     return false;
/*     */   }
/*     */
/*     */   protected abstract void createWrapper(ConstructorTransformation paramConstructorTransformation) throws CannotCompileException, NotFoundException;
/*     */
/*     */   protected void initialiseWrapper(int mod, CtConstructor constructor, int index) throws NotFoundException, CannotCompileException {
/* 492 */     CtClass clazz = constructor.getDeclaringClass();
/* 493 */     CtClass[] exceptions = constructor.getExceptionTypes();
/* 494 */     String name = clazz.getSimpleName();
/* 495 */     CtClass type = constructor.getDeclaringClass();
/*     */
/* 497 */     CtMethod wmethod = CtNewMethod.make(type, constructorFactory(name), constructor.getParameterTypes(), exceptions, null, clazz);
/* 498 */     wmethod.setModifiers(mod);
/* 499 */     setTemporaryWrapperCode(type, wmethod);
/* 500 */     clazz.addMethod(wmethod);
/*     */
/* 503 */     MethodInfo constructorInfo = constructor.getMethodInfo2();
/* 504 */     SignatureAttribute attribute = (SignatureAttribute)constructorInfo.getAttribute("Signature");
/* 505 */     if (attribute != null)
/*     */     {
/* 507 */       MethodInfo wrapperInfo = wmethod.getMethodInfo2();
/* 508 */       wrapperInfo.addAttribute(attribute.copy(wrapperInfo.getConstPool(), new HashMap()));
/*     */     }
/*     */
/* 512 */     getWrapper().prepareForWrapping(constructor, 0);
/*     */   }
/*     */
/*     */   protected CtMethod getWrapperMethod(CtConstructor constructor) throws NotFoundException
/*     */   {
/* 517 */     CtClass clazz = constructor.getDeclaringClass();
/* 518 */     return clazz.getDeclaredMethod(constructorFactory(clazz.getSimpleName()), constructor.getParameterTypes());
/*     */   }
/*     */
/*     */   protected class ConstructorTransformation {
/*     */     CtClass clazz;
/*     */     CtConstructor constructor;
/*     */     CtMethod wrapperMethod;
/*     */     int index;
/*     */
/*     */     public ConstructorTransformation(CtClass clazz, CtConstructor constructor, CtMethod wrapper, int index) {
/* 532 */       this.clazz = clazz;
/* 533 */       this.constructor = constructor;
/* 534 */       this.wrapperMethod = wrapper;
/* 535 */       this.index = index;
/*     */     }
/*     */
/*     */     public CtMethod getWrapperMethod()
/*     */     {
/* 540 */       return this.wrapperMethod;
/*     */     }
/*     */
/*     */     public void setWrapperMethod(CtMethod wrapperMethod)
/*     */     {
/* 545 */       this.wrapperMethod = wrapperMethod;
/*     */     }
/*     */
/*     */     public CtClass getClazz()
/*     */     {
/* 550 */       return this.clazz;
/*     */     }
/*     */
/*     */     public CtConstructor getConstructor()
/*     */     {
/* 555 */       return this.constructor;
/*     */     }
/*     */
/*     */     public int getIndex()
/*     */     {
/* 560 */       return this.index;
/*     */     }
/*     */
/*     */     public String getClassName()
/*     */     {
/* 565 */       return this.clazz.getName();
/*     */     }
/*     */
/*     */     public String getSimpleName()
/*     */     {
/* 570 */       return this.clazz.getSimpleName();
/*     */     }
/*     */   }
/*     */ }

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

Related Classes of org.jboss.aop.instrument.ConstructorExecutionTransformer$ConstructorTransformation

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.