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.expression;
    9
    10  import org.codehaus.aspectwerkz.reflect.ClassInfo;
    11  import org.codehaus.aspectwerkz.reflect.ConstructorInfo;
    12  import org.codehaus.aspectwerkz.reflect.FieldInfo;
    13  import org.codehaus.aspectwerkz.reflect.MethodInfo;
    14  import org.codehaus.aspectwerkz.reflect.ReflectionInfo;
    15  import org.codehaus.aspectwerkz.reflect.StaticInitializationInfo;
    16
    17  import gnu.trove.TIntIntHashMap;
    18  import gnu.trove.TObjectIntHashMap;
    19
    20  /***
    21   * The expression context for AST evaluation.
    22   *
    23   * @author <a href="mailto:jboner@codehaus.org">Jonas BonŽr </a>
    24   * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
    25   */
    26  public class ExpressionContext {
    27      public static final int INFO_NOT_AVAILABLE = -1;
    28
    29      public static final int METHOD_INFO = 0;
    30
    31      public static final int CONSTRUCTOR_INFO = 1;
    32
    33      public static final int FIELD_INFO = 2;
    34
    35      public static final int CLASS_INFO = 3;
    36
    37      private static final int STATIC_INFO = 4;
    38
    39      private final int m_reflectionInfoType;
    40
    41      private final PointcutType m_pointcutType;
    42
    43      private final ReflectionInfo m_matchingReflectionInfo;
    44
    45      private final ReflectionInfo m_withinReflectionInfo;
    46
    47      private boolean m_inCflowSubAST = false;
    48
    49      private boolean m_cflowEvaluation = false;
    50
    51      private boolean m_hasBeenVisitingCflow = false;
    52
    53      private int m_currentTargetArgsIndex = 0;
    54
    55      /***
    56       * Expression to advised target (method / ctor) argument index map.
    57       * It depends on the matching context and the pointcut signature, as well as args(..)
    58       */
    59      public gnu.trove.TObjectIntHashMap m_exprIndexToTargetIndex = new TObjectIntHashMap();
    60
    61      /***
    62       * The variable name corresponding to the this(..) designator,
    63       * or null if nothing is bound (this(<type>) or no this(..))
    64       */
    65      public String m_thisBoundedName = null;
    66
    67      /***
    68       * The variable name corresponding to the target(..) designator,
    69       * or null if nothing is bound (target(<type>) or no target(..))
    70       */
    71      public String m_targetBoundedName = null;
    72
    73      /***
    74       * Set to true when we encounter a poincut using target(..) and when match cannot be done without a
    75       * runtime check with instance of.
    76       */
    77      public boolean m_targetWithRuntimeCheck = false;
    78
    79      /***
    80       * Creates a new expression context.
    81       *
    82       * @param pointcutType
    83       * @param reflectionInfo       - can be null f.e. with early evaluation of CALL pointcut
    84       * @param withinReflectionInfo
    85       */
    86      public ExpressionContext(final PointcutType pointcutType,
    87                               final ReflectionInfo reflectionInfo,
    88                               final ReflectionInfo withinReflectionInfo) {
    89          if (pointcutType == null) {
    90              throw new IllegalArgumentException("pointcut type can not be null");
    91          }
    92          m_pointcutType = pointcutType;
    93          m_matchingReflectionInfo = reflectionInfo;
    94          if (withinReflectionInfo != null) {
    95              m_withinReflectionInfo = withinReflectionInfo;
    96          } else {
    97              if (PointcutType.EXECUTION.equals(pointcutType)
    98                  || PointcutType.STATIC_INITIALIZATION.equals(pointcutType)
    99                  || PointcutType.WITHIN.equals(pointcutType)) {
    100                 m_withinReflectionInfo = m_matchingReflectionInfo;
    101             } else {
    102                 m_withinReflectionInfo = null;
    103             }
    104         }
    105         if (reflectionInfo instanceof MethodInfo) {
    106             m_reflectionInfoType = METHOD_INFO;
    107         } else if (reflectionInfo instanceof ConstructorInfo) {
    108             m_reflectionInfoType = CONSTRUCTOR_INFO;
    109         } else if (reflectionInfo instanceof FieldInfo) {
    110             m_reflectionInfoType = FIELD_INFO;
    111         } else if (reflectionInfo instanceof ClassInfo) {
    112             m_reflectionInfoType = CLASS_INFO;
    113         } else if (reflectionInfo instanceof StaticInitializationInfo) {
    114         	m_reflectionInfoType = STATIC_INFO;
    115         } else {
    116             m_reflectionInfoType = INFO_NOT_AVAILABLE;// used for early eval on CALL
    117         }
    118     }
    119
    120     public ReflectionInfo getReflectionInfo() {
    121         return m_matchingReflectionInfo;
    122     }
    123
    124     public ReflectionInfo getWithinReflectionInfo() {
    125         return m_withinReflectionInfo;
    126     }
    127
    128     public boolean hasExecutionPointcut() {
    129         return m_pointcutType.equals(PointcutType.EXECUTION);
    130     }
    131
    132     public boolean hasCallPointcut() {
    133         return m_pointcutType.equals(PointcutType.CALL);
    134     }
    135
    136     public boolean hasSetPointcut() {
    137         return m_pointcutType.equals(PointcutType.SET);
    138     }
    139
    140     public boolean hasGetPointcut() {
    141         return m_pointcutType.equals(PointcutType.GET);
    142     }
    143
    144     public boolean hasHandlerPointcut() {
    145         return m_pointcutType.equals(PointcutType.HANDLER);
    146     }
    147
    148     public boolean hasStaticInitializationPointcut() {
    149         return m_pointcutType.equals(PointcutType.STATIC_INITIALIZATION);
    150     }
    151
    152     public boolean hasWithinPointcut() {
    153         return m_pointcutType.equals(PointcutType.WITHIN);
    154     }
    155 //
    156 //    public boolean hasHasMethodPointcut() {
    157 //        return m_pointcutType.equals(PointcutType.HAS_METHOD);
    158 //    }
    159 //
    160 //    public boolean hasHasFieldPointcut() {
    161 //        return m_pointcutType.equals(PointcutType.HAS_FIELD);
    162 //    }
    163
    164     public boolean hasWithinReflectionInfo() {
    165         return m_withinReflectionInfo != null;
    166     }
    167
    168     public boolean hasMethodInfo() {
    169         return m_reflectionInfoType == METHOD_INFO;
    170     }
    171
    172     public boolean hasConstructorInfo() {
    173         return m_reflectionInfoType == CONSTRUCTOR_INFO;
    174     }
    175
    176     public boolean hasFieldInfo() {
    177         return m_reflectionInfoType == FIELD_INFO;
    178     }
    179
    180     public boolean hasClassInfo() {
    181         return m_reflectionInfoType == CLASS_INFO;
    182     }
    183
    184     public boolean hasReflectionInfo() {
    185         return m_reflectionInfoType != INFO_NOT_AVAILABLE;
    186     }
    187
    188     public void setInCflowSubAST(final boolean inCflowAST) {
    189         m_inCflowSubAST = inCflowAST;
    190     }
    191
    192     public boolean inCflowSubAST() {
    193         return m_inCflowSubAST;
    194     }
    195
    196     public void setHasBeenVisitingCflow(final boolean hasBeenVisitingCflow) {
    197         m_hasBeenVisitingCflow = hasBeenVisitingCflow;
    198     }
    199
    200     public boolean hasBeenVisitingCflow() {
    201         return m_hasBeenVisitingCflow;
    202     }
    203
    204     public boolean getCflowEvaluation() {
    205         return m_cflowEvaluation;
    206     }
    207
    208     public void setCflowEvaluation(boolean cflowEvaluation) {
    209         m_cflowEvaluation = cflowEvaluation;
    210     }
    211
    212     public int getCurrentTargetArgsIndex() {
    213         return m_currentTargetArgsIndex;
    214     }
    215
    216     public void setCurrentTargetArgsIndex(int argsIndex) {
    217         this.m_currentTargetArgsIndex = argsIndex;
    218     }
    219
    220     public boolean equals(Object o) {
    221         if (this == o) {
    222             return true;
    223         }
    224         if (!(o instanceof ExpressionContext)) {
    225             return false;
    226         }
    227         final ExpressionContext expressionContext = (ExpressionContext) o;
    228         if (m_reflectionInfoType != expressionContext.m_reflectionInfoType) {
    229             return false;
    230         }
    231         if (!m_matchingReflectionInfo.equals(expressionContext.m_matchingReflectionInfo)) {
    232             return false;
    233         }
    234         if (!m_pointcutType.equals(expressionContext.m_pointcutType)) {
    235             return false;
    236         }
    237         if ((m_withinReflectionInfo != null) ?
    238             (!m_withinReflectionInfo
    239                 .equals(expressionContext.m_withinReflectionInfo)) :
    240             (expressionContext.m_withinReflectionInfo != null)) {
    241             return false;
    242         }
    243         return true;
    244     }
    245
    246     public int hashCode() {
    247         int result;
    248         result = m_pointcutType.hashCode();
    249         result = (29 * result) + m_matchingReflectionInfo.hashCode();
    250         result = (29 * result) + ((m_withinReflectionInfo != null) ? m_withinReflectionInfo.hashCode() : 0);
    251         result = (29 * result) + m_reflectionInfoType;
    252         return result;
    253     }
    254
    255     public PointcutType getPointcutType() {
    256         return m_pointcutType;
    257     }
    258
    259     public void resetRuntimeState() {
    260         m_targetBoundedName = null;
    261         m_thisBoundedName = null;
    262         m_exprIndexToTargetIndex = new TObjectIntHashMap();
    263         m_targetWithRuntimeCheck = false;
    264     }
    265 }