View Javadoc

    1   /***************************************************************************************
    2    * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved.                 *
    3    * http://aspectwerkz.codehaus.org                                                    *
    4    * ---------------------------------------------------------------------------------- *
    5    * The software in this package is published under the terms of the LGPL license      *
    6    * a copy of which has been included with this distribution in the license.txt file.  *
    7    **************************************************************************************/
    8   package org.codehaus.aspectwerkz.intercept;
    9
    10  import java.util.ArrayList;
    11  import java.util.List;
    12  import java.lang.reflect.Field;
    13
    14  import gnu.trove.TIntObjectHashMap;
    15  import org.codehaus.aspectwerkz.reflect.ClassInfo;
    16  import org.codehaus.aspectwerkz.reflect.ReflectionInfo;
    17  import org.codehaus.aspectwerkz.reflect.impl.asm.AsmClassInfo;
    18  import org.codehaus.aspectwerkz.reflect.impl.java.JavaClassInfo;
    19  import org.codehaus.aspectwerkz.expression.PointcutType;
    20  import org.codehaus.aspectwerkz.expression.ExpressionContext;
    21  import org.codehaus.aspectwerkz.expression.ExpressionInfo;
    22  import org.codehaus.aspectwerkz.transform.inlining.AsmHelper;
    23  import org.codehaus.aspectwerkz.transform.inlining.EmittedJoinPoint;
    24  import org.codehaus.aspectwerkz.transform.TransformationConstants;
    25  import org.codehaus.aspectwerkz.joinpoint.management.JoinPointType;
    26
    27  /***
    28   * Implementation of the <code>Advisable</code> mixin.
    29   *
    30   * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
    31   * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
    32   */
    33  public class AdvisableImpl implements Advisable {
    34
    35      private static final String EXPRESSION_NAMESPACE = "___AW_ADVISABLE_AW___";
    36
    37      public static final ClassInfo CLASS_INFO;
    38      public static final AroundAdvice[] EMPTY_AROUND_ADVICE_ARRAY = new AroundAdvice[0];
    39      public static final BeforeAdvice[] EMPTY_BEFORE_ADVICE_ARRAY = new BeforeAdvice[0];
    40      public static final AfterAdvice[] EMPTY_AFTER_ADVICE_ARRAY = new AfterAdvice[0];
    41      public static final AfterReturningAdvice[] EMPTY_AFTER_RETURNING_ADVICE_ARRAY = new AfterReturningAdvice[0];
    42      public static final AfterThrowingAdvice[] EMPTY_AFTER_THROWING_ADVICE_ARRAY = new AfterThrowingAdvice[0];
    43
    44      static {
    45          final Class clazz = AdvisableImpl.class;
    46          try {
    47              CLASS_INFO = AsmClassInfo.getClassInfo(clazz.getName(), clazz.getClassLoader());
    48          } catch (Exception e) {
    49              throw new Error("could not create class info for [" + clazz.getName() + ']');
    50          }
    51      }
    52
    53      private final Advisable m_targetInstance;
    54      private final TIntObjectHashMap m_emittedJoinPoints;
    55
    56      private final TIntObjectHashMap m_aroundAdvice = new TIntObjectHashMap();
    57      private final TIntObjectHashMap m_beforeAdvice = new TIntObjectHashMap();
    58      private final TIntObjectHashMap m_afterAdvice = new TIntObjectHashMap();
    59      private final TIntObjectHashMap m_afterReturningAdvice = new TIntObjectHashMap();
    60      private final TIntObjectHashMap m_afterThrowingAdvice = new TIntObjectHashMap();
    61
    62      /***
    63       * Creates a new mixin impl.
    64       *
    65       * @param targetInstance the target for this mixin instance (perInstance deployed)
    66       */
    67      public AdvisableImpl(final Object targetInstance) {
    68          if (!(targetInstance instanceof Advisable)) {
    69              throw new RuntimeException(
    70                      "advisable mixin applied to target class that does not implement the Advisable interface"
    71              );
    72          }
    73          m_targetInstance = (Advisable) targetInstance;
    74
    75          try {
    76              Field f = targetInstance.getClass().getDeclaredField("aw$emittedJoinPoints");
    77              f.setAccessible(true);
    78              m_emittedJoinPoints = (TIntObjectHashMap) f.get(null);
    79          } catch (Exception e) {
    80              throw new RuntimeException(
    81                      "advisable mixin applied to target class cannot access reflective information: " + e.toString()
    82              );
    83          }
    84      }
    85
    86      /***
    87       * @param pointcut
    88       * @param advice
    89       */
    90      public void aw_addAdvice(final String pointcut, final Advice advice) {
    91          addAdvice(pointcut, advice);
    92      }
    93
    94      /***
    95       * @param pointcut
    96       * @param adviceClass
    97       */
    98      public void aw_removeAdvice(final String pointcut, final Class adviceClass) {
    99          removeAdvice(pointcut, adviceClass);
    100     }
    101
    102     /***
    103      * @param joinPointIndex
    104      * @return
    105      */
    106     public AroundAdvice[] aw$getAroundAdvice(final int joinPointIndex) {
    107         Object advice = m_aroundAdvice.get(joinPointIndex);
    108         if (advice == null) {
    109             return EMPTY_AROUND_ADVICE_ARRAY;
    110         } else {
    111             return (AroundAdvice[]) advice;
    112         }
    113     }
    114
    115     /***
    116      * @param joinPointIndex
    117      * @return
    118      */
    119     public BeforeAdvice[] aw$getBeforeAdvice(final int joinPointIndex) {
    120         Object advice = m_beforeAdvice.get(joinPointIndex);
    121         if (advice == null) {
    122             return EMPTY_BEFORE_ADVICE_ARRAY;
    123         } else {
    124             return (BeforeAdvice[]) advice;
    125         }
    126     }
    127
    128     /***
    129      * @param joinPointIndex
    130      * @return
    131      */
    132     public AfterAdvice[] aw$getAfterAdvice(final int joinPointIndex) {
    133         Object advice = m_afterAdvice.get(joinPointIndex);
    134         if (advice == null) {
    135             return EMPTY_AFTER_ADVICE_ARRAY;
    136         } else {
    137             return (AfterAdvice[]) advice;
    138         }
    139     }
    140
    141     /***
    142      * @param joinPointIndex
    143      * @return
    144      */
    145     public AfterReturningAdvice[] aw$getAfterReturningAdvice(final int joinPointIndex) {
    146         Object advice = m_afterReturningAdvice.get(joinPointIndex);
    147         if (advice == null) {
    148             return EMPTY_AFTER_RETURNING_ADVICE_ARRAY;
    149         } else {
    150             return (AfterReturningAdvice[]) advice;
    151         }
    152     }
    153
    154     /***
    155      * @param joinPointIndex
    156      * @return
    157      */
    158     public AfterThrowingAdvice[] aw$getAfterThrowingAdvice(final int joinPointIndex) {
    159         Object advice = m_afterThrowingAdvice.get(joinPointIndex);
    160         if (advice == null) {
    161             return EMPTY_AFTER_THROWING_ADVICE_ARRAY;
    162         } else {
    163             return (AfterThrowingAdvice[]) advice;
    164         }
    165     }
    166
    167     /***
    168      * @param pointcut
    169      * @param advice
    170      */
    171     private void addAdvice(final String pointcut,
    172                            final Advice advice) {
    173         ExpressionInfo expressionInfo = new ExpressionInfo(pointcut, EXPRESSION_NAMESPACE);
    174         Object[] emittedJoinPoints = m_emittedJoinPoints.getValues();
    175         for (int i = 0; i < emittedJoinPoints.length; i++) {
    176             EmittedJoinPoint emittedJoinPoint = (EmittedJoinPoint) emittedJoinPoints[i];
    177             if (match(expressionInfo, PointcutType.EXECUTION, emittedJoinPoint)
    178                 || match(expressionInfo, PointcutType.CALL, emittedJoinPoint)
    179                 || match(expressionInfo, PointcutType.HANDLER, emittedJoinPoint)
    180                 || match(expressionInfo, PointcutType.GET, emittedJoinPoint)
    181                 || match(expressionInfo, PointcutType.SET, emittedJoinPoint)
    182                 //note: STATIC INIT is useless since the class is already loaded to manipulate the instance
    183             ) {
    184                 int hash = emittedJoinPoint.getJoinPointClassName().hashCode();
    185                 addAroundAdvice(advice, hash);
    186                 addBeforeAdvice(advice, hash);
    187                 addAfterAdvice(advice, hash);
    188                 addAfterReturningAdvice(advice, hash);
    189                 addAfterThrowingAdvice(advice, hash);
    190             }
    191         }
    192     }
    193
    194     /***
    195      * @param pointcut
    196      * @param adviceClass
    197      */
    198     private void removeAdvice(final String pointcut,
    199                               final Class adviceClass) {
    200         ExpressionInfo expressionInfo = new ExpressionInfo(pointcut, EXPRESSION_NAMESPACE);
    201         Object[] emittedJoinPoints = m_emittedJoinPoints.getValues();
    202         for (int i = 0; i < emittedJoinPoints.length; i++) {
    203             EmittedJoinPoint emittedJoinPoint = (EmittedJoinPoint) emittedJoinPoints[i];
    204             if (match(expressionInfo, PointcutType.EXECUTION, emittedJoinPoint)
    205                 || match(expressionInfo, PointcutType.CALL, emittedJoinPoint)
    206                 || match(expressionInfo, PointcutType.HANDLER, emittedJoinPoint)
    207                 || match(expressionInfo, PointcutType.GET, emittedJoinPoint)
    208                 || match(expressionInfo, PointcutType.SET, emittedJoinPoint)
    209                 //note: STATIC INIT is useless since the class is already loaded to manipulate the instance
    210             ) {
    211                 int hash = emittedJoinPoint.getJoinPointClassName().hashCode();
    212                 removeAroundAdvice(adviceClass, hash);
    213                 removeBeforeAdvice(adviceClass, hash);
    214                 removeAfterAdvice(adviceClass, hash);
    215                 removeAfterReturningAdvice(adviceClass, hash);
    216                 removeAfterThrowingAdvice(adviceClass, hash);
    217             }
    218         }
    219     }
    220
    221     /***
    222      * @param advice
    223      * @param joinPointHash
    224      */
    225     private void addAroundAdvice(final Advice advice, int joinPointHash) {
    226         if (advice instanceof AroundAdvice) {
    227             AroundAdvice aroundAdvice = (AroundAdvice) advice;
    228             AroundAdvice[] advices;
    229             AroundAdvice[] olds = aw$getAroundAdvice(joinPointHash);
    230             if (olds != null) {
    231                 advices = new AroundAdvice[olds.length + 1];
    232                 System.arraycopy(olds, 0, advices, 0, olds.length);
    233                 advices[advices.length - 1] = aroundAdvice;
    234             } else {
    235                 advices = new AroundAdvice[]{aroundAdvice};
    236             }
    237             m_aroundAdvice.put(joinPointHash, advices);
    238         }
    239     }
    240
    241     /***
    242      * @param advice
    243      * @param joinPointHash
    244      */
    245     private void addBeforeAdvice(final Advice advice, int joinPointHash) {
    246         if (advice instanceof BeforeAdvice) {
    247             BeforeAdvice beforeAdvice = (BeforeAdvice) advice;
    248             BeforeAdvice[] advices;
    249             BeforeAdvice[] olds = aw$getBeforeAdvice(joinPointHash);
    250             if (olds != null) {
    251                 advices = new BeforeAdvice[olds.length + 1];
    252                 System.arraycopy(olds, 0, advices, 0, olds.length);
    253                 advices[advices.length - 1] = beforeAdvice;
    254             } else {
    255                 advices = new BeforeAdvice[]{beforeAdvice};
    256             }
    257             m_beforeAdvice.put(joinPointHash, advices);
    258         }
    259     }
    260
    261     /***
    262      * @param advice
    263      * @param joinPointHash
    264      */
    265     private void addAfterAdvice(final Advice advice, int joinPointHash) {
    266         if (advice instanceof AfterAdvice) {
    267             AfterAdvice afterFinallyAdvice = (AfterAdvice) advice;
    268             AfterAdvice[] advices;
    269             AfterAdvice[] olds = aw$getAfterAdvice(joinPointHash);
    270             if (olds != null) {
    271                 advices = new AfterAdvice[olds.length + 1];
    272                 System.arraycopy(olds, 0, advices, 0, olds.length);
    273                 advices[advices.length - 1] = afterFinallyAdvice;
    274             } else {
    275                 advices = new AfterAdvice[]{afterFinallyAdvice};
    276             }
    277             m_afterAdvice.put(joinPointHash, advices);
    278         }
    279     }
    280
    281     /***
    282      * @param advice
    283      * @param joinPointHash
    284      */
    285     private void addAfterReturningAdvice(final Advice advice, int joinPointHash) {
    286         if (advice instanceof AfterReturningAdvice) {
    287             AfterReturningAdvice afterReturningAdvice = (AfterReturningAdvice) advice;
    288             AfterReturningAdvice[] advices;
    289             AfterReturningAdvice[] olds = aw$getAfterReturningAdvice(joinPointHash);
    290             if (olds != null) {
    291                 advices = new AfterReturningAdvice[olds.length + 1];
    292                 System.arraycopy(olds, 0, advices, 0, olds.length);
    293                 advices[advices.length - 1] = afterReturningAdvice;
    294             } else {
    295                 advices = new AfterReturningAdvice[]{afterReturningAdvice};
    296             }
    297             m_afterReturningAdvice.put(joinPointHash, advices);
    298         }
    299     }
    300
    301     /***
    302      * @param advice
    303      * @param joinPointHash
    304      */
    305     private void addAfterThrowingAdvice(final Advice advice, int joinPointHash) {
    306         if (advice instanceof AfterThrowingAdvice) {
    307             AfterThrowingAdvice afterThrowingAdvice = (AfterThrowingAdvice) advice;
    308             AfterThrowingAdvice[] advices;
    309             AfterThrowingAdvice[] olds = aw$getAfterThrowingAdvice(joinPointHash);
    310             if (olds != null) {
    311                 advices = new AfterThrowingAdvice[olds.length + 1];
    312                 System.arraycopy(olds, 0, advices, 0, olds.length);
    313                 advices[advices.length - 1] = afterThrowingAdvice;
    314             } else {
    315                 advices = new AfterThrowingAdvice[]{afterThrowingAdvice};
    316             }
    317             m_afterThrowingAdvice.put(joinPointHash, advices);
    318         }
    319     }
    320
    321     /***
    322      * @param adviceClass
    323      * @param joinPointHash
    324      */
    325     private void removeAroundAdvice(final Class adviceClass, int joinPointHash) {
    326         if (isAroundAdvice(adviceClass)) {
    327             AroundAdvice[] oldArray = aw$getAroundAdvice(joinPointHash);
    328             if (oldArray.length == 0) {
    329             } else if (oldArray.length == 1) {
    330                 m_aroundAdvice.put(joinPointHash, EMPTY_AROUND_ADVICE_ARRAY);
    331             } else {
    332                 List newArrayList = new ArrayList();
    333                 for (int i = 0; i < oldArray.length; i++) {
    334                     AroundAdvice aroundAdvice = oldArray[i];
    335                     if (!aroundAdvice.getClass().equals(adviceClass)) {
    336                         newArrayList.add(aroundAdvice);
    337                     }
    338                 }
    339                 m_aroundAdvice.put(
    340                         joinPointHash,
    341                         (AroundAdvice[]) newArrayList.toArray(new AroundAdvice[newArrayList.size()])
    342                 );
    343             }
    344         }
    345     }
    346
    347     /***
    348      * @param adviceClass
    349      * @param joinPointHash
    350      */
    351     private void removeBeforeAdvice(final Class adviceClass, int joinPointHash) {
    352         if (isBeforeAdvice(adviceClass)) {
    353             BeforeAdvice[] oldArray = aw$getBeforeAdvice(joinPointHash);
    354             if (oldArray.length == 0) {
    355             } else if (oldArray.length == 1) {
    356                 m_beforeAdvice.put(joinPointHash, EMPTY_BEFORE_ADVICE_ARRAY);
    357             } else {
    358                 List newArrayList = new ArrayList();
    359                 for (int i = 0; i < oldArray.length; i++) {
    360                     BeforeAdvice beforeAdvice = oldArray[i];
    361                     if (!beforeAdvice.getClass().equals(adviceClass)) {
    362                         newArrayList.add(beforeAdvice);
    363                     }
    364                 }
    365                 m_beforeAdvice.put(
    366                         joinPointHash,
    367                         (BeforeAdvice[]) newArrayList.toArray(new BeforeAdvice[newArrayList.size()])
    368                 );
    369             }
    370         }
    371     }
    372
    373     /***
    374      * @param adviceClass
    375      * @param joinPointHash
    376      */
    377     private void removeAfterAdvice(final Class adviceClass, int joinPointHash) {
    378         if (isAfterAdvice(adviceClass)) {
    379             AfterAdvice[] oldArray = aw$getAfterAdvice(joinPointHash);
    380             if (oldArray.length == 0) {
    381             } else if (oldArray.length == 1) {
    382                 m_afterAdvice.put(joinPointHash, EMPTY_AFTER_ADVICE_ARRAY);
    383             } else {
    384                 List newArrayList = new ArrayList();
    385                 for (int i = 0; i < oldArray.length; i++) {
    386                     AfterAdvice afterAdvice = oldArray[i];
    387                     if (!afterAdvice.getClass().equals(adviceClass)) {
    388                         newArrayList.add(afterAdvice);
    389                     }
    390                 }
    391                 m_afterAdvice.put(
    392                         joinPointHash,
    393                         (AfterAdvice[]) newArrayList.toArray(new AfterAdvice[newArrayList.size()])
    394                 );
    395             }
    396         }
    397     }
    398
    399     /***
    400      * @param adviceClass
    401      * @param joinPointHash
    402      */
    403     private void removeAfterReturningAdvice(final Class adviceClass, int joinPointHash) {
    404         if (isAfterReturningAdvice(adviceClass)) {
    405             AfterReturningAdvice[] oldArray = aw$getAfterReturningAdvice(joinPointHash);
    406             if (oldArray.length == 0) {
    407             } else if (oldArray.length == 1) {
    408                 m_afterReturningAdvice.put(joinPointHash, EMPTY_AFTER_RETURNING_ADVICE_ARRAY);
    409             } else {
    410                 List newArrayList = new ArrayList();
    411                 for (int i = 0; i < oldArray.length; i++) {
    412                     AfterReturningAdvice afterReturningAdvice = oldArray[i];
    413                     if (!afterReturningAdvice.getClass().equals(adviceClass)) {
    414                         newArrayList.add(afterReturningAdvice);
    415                     }
    416                 }
    417                 m_afterReturningAdvice.put(
    418                         joinPointHash,
    419                         (AfterReturningAdvice[]) newArrayList.toArray(new AfterReturningAdvice[newArrayList.size()])
    420                 );
    421             }
    422         }
    423     }
    424
    425     /***
    426      * @param adviceClass
    427      * @param joinPointHash
    428      */
    429     private void removeAfterThrowingAdvice(final Class adviceClass, int joinPointHash) {
    430         if (isAfterThrowingAdvice(adviceClass)) {
    431             AfterThrowingAdvice[] oldArray = aw$getAfterThrowingAdvice(joinPointHash);
    432             if (oldArray.length == 0) {
    433             } else if (oldArray.length == 1) {
    434                 m_afterThrowingAdvice.put(joinPointHash, EMPTY_AFTER_THROWING_ADVICE_ARRAY);
    435             } else {
    436                 List newArrayList = new ArrayList();
    437                 for (int i = 0; i < oldArray.length; i++) {
    438                     AfterThrowingAdvice advice = oldArray[i];
    439                     if (!advice.getClass().equals(adviceClass)) {
    440                         newArrayList.add(advice);
    441                     }
    442                 }
    443                 m_afterThrowingAdvice.put(
    444                         joinPointHash,
    445                         (AfterThrowingAdvice[]) newArrayList.toArray(new AfterThrowingAdvice[newArrayList.size()])
    446                 );
    447             }
    448         }
    449     }
    450
    451     private boolean isAroundAdvice(final Class adviceClass) {
    452         if (adviceClass == AroundAdvice.class) {
    453             return true;
    454         }
    455         Class[] interfaces = adviceClass.getInterfaces();
    456         for (int i = 0; i < interfaces.length; i++) {
    457             Class anInterface = interfaces[i];
    458             if (anInterface == AroundAdvice.class) {
    459                 return true;
    460             }
    461         }
    462         return false;
    463     }
    464
    465     private boolean isBeforeAdvice(final Class adviceClass) {
    466         if (adviceClass == BeforeAdvice.class) {
    467             return true;
    468         }
    469         Class[] interfaces = adviceClass.getInterfaces();
    470         for (int i = 0; i < interfaces.length; i++) {
    471             Class anInterface = interfaces[i];
    472             if (anInterface == BeforeAdvice.class) {
    473                 return true;
    474             }
    475         }
    476         return false;
    477     }
    478
    479     private boolean isAfterAdvice(final Class adviceClass) {
    480         if (adviceClass == AfterAdvice.class) {
    481             return true;
    482         }
    483         Class[] interfaces = adviceClass.getInterfaces();
    484         for (int i = 0; i < interfaces.length; i++) {
    485             Class anInterface = interfaces[i];
    486             if (anInterface == AfterAdvice.class) {
    487                 return true;
    488             }
    489         }
    490         return false;
    491     }
    492
    493     private boolean isAfterReturningAdvice(final Class adviceClass) {
    494         if (adviceClass == AfterReturningAdvice.class) {
    495             return true;
    496         }
    497         Class[] interfaces = adviceClass.getInterfaces();
    498         for (int i = 0; i < interfaces.length; i++) {
    499             Class anInterface = interfaces[i];
    500             if (anInterface == AfterReturningAdvice.class) {
    501                 return true;
    502             }
    503         }
    504         return false;
    505     }
    506
    507     private boolean isAfterThrowingAdvice(final Class adviceClass) {
    508         if (adviceClass == AfterThrowingAdvice.class) {
    509             return true;
    510         }
    511         Class[] interfaces = adviceClass.getInterfaces();
    512         for (int i = 0; i < interfaces.length; i++) {
    513             Class anInterface = interfaces[i];
    514             if (anInterface == AfterThrowingAdvice.class) {
    515                 return true;
    516             }
    517         }
    518         return false;
    519     }
    520
    521     /***
    522      * Match the given expression for the given pointcut type against the given emittedJoinPoint
    523      *
    524      * @param expression
    525      * @param pointcutType
    526      * @param emittedJoinPoint
    527      * @return
    528      */
    529     private boolean match(ExpressionInfo expression, PointcutType pointcutType, EmittedJoinPoint emittedJoinPoint) {
    530         ClassInfo callerClassInfo = JavaClassInfo.getClassInfo(m_targetInstance.getClass());
    531         ClassInfo calleeClassInfo = AsmClassInfo.getClassInfo(emittedJoinPoint.getCalleeClassName(), m_targetInstance.getClass().getClassLoader());
    532
    533         // early match
    534         if (!expression.getAdvisedClassFilterExpression().match(new ExpressionContext(pointcutType, calleeClassInfo, callerClassInfo))) {
    535             return false;
    536         }
    537
    538         // create the callee info
    539         final ReflectionInfo reflectionInfo;
    540         final PointcutType joinPointType;
    541         switch (emittedJoinPoint.getJoinPointType()) {
    542             case JoinPointType.STATIC_INITIALIZATION_INT:
    543                 reflectionInfo = calleeClassInfo.staticInitializer();
    544                 joinPointType = PointcutType.STATIC_INITIALIZATION;
    545                 break;
    546             case JoinPointType.METHOD_EXECUTION_INT:
    547                 reflectionInfo = calleeClassInfo.getMethod(emittedJoinPoint.getJoinPointHash());
    548                 joinPointType = PointcutType.EXECUTION;
    549                 break;
    550             case JoinPointType.METHOD_CALL_INT:
    551                 reflectionInfo = calleeClassInfo.getMethod(emittedJoinPoint.getJoinPointHash());
    552                 joinPointType = PointcutType.CALL;
    553                 break;
    554             case JoinPointType.FIELD_GET_INT:
    555                 reflectionInfo = calleeClassInfo.getField(emittedJoinPoint.getJoinPointHash());
    556                 joinPointType = PointcutType.GET;
    557                 break;
    558             case JoinPointType.FIELD_SET_INT:
    559                 reflectionInfo = calleeClassInfo.getField(emittedJoinPoint.getJoinPointHash());
    560                 joinPointType = PointcutType.SET;
    561                 break;
    562             case JoinPointType.CONSTRUCTOR_EXECUTION_INT:
    563                 reflectionInfo = calleeClassInfo.getConstructor(emittedJoinPoint.getJoinPointHash());
    564                 joinPointType = PointcutType.EXECUTION;
    565                 break;
    566             case JoinPointType.CONSTRUCTOR_CALL_INT:
    567                 reflectionInfo = calleeClassInfo.getConstructor(emittedJoinPoint.getJoinPointHash());
    568                 joinPointType = PointcutType.CALL;
    569                 break;
    570             case JoinPointType.HANDLER_INT:
    571                 reflectionInfo = calleeClassInfo;
    572                 joinPointType = PointcutType.HANDLER;
    573                 break;
    574             default:
    575                 throw new RuntimeException("Joinpoint type not supported: " + emittedJoinPoint.getJoinPointType());
    576         }
    577
    578         // create the caller info
    579         final ReflectionInfo withinInfo;
    580         if (TransformationConstants.CLINIT_METHOD_NAME.equals(emittedJoinPoint.getCallerMethodName())) {
    581             withinInfo = callerClassInfo.staticInitializer();
    582         } else if (TransformationConstants.INIT_METHOD_NAME.equals(emittedJoinPoint.getCallerMethodName())) {
    583             withinInfo = callerClassInfo.getConstructor(AsmHelper.calculateConstructorHash(
    584                     emittedJoinPoint.getCallerMethodDesc()
    585             ));
    586         } else {
    587             withinInfo =
    588                     callerClassInfo.getMethod(AsmHelper.calculateMethodHash(emittedJoinPoint.getCallerMethodName(),
    589                                                                             emittedJoinPoint.getCallerMethodDesc())
    590                     );
    591         }
    592
    593         // check pointcutType vs joinPointType
    594         if (pointcutType != PointcutType.WITHIN && pointcutType != joinPointType) {
    595             return false;
    596         }
    597
    598         return expression.getExpression().match(new ExpressionContext(pointcutType, reflectionInfo, withinInfo));
    599     }
    600 }