1 4 package com.tc.aspectwerkz.expression; 5 6 import com.tc.aspectwerkz.exception.DefinitionException; 7 import com.tc.aspectwerkz.expression.ast.ASTArgParameter; 8 import com.tc.aspectwerkz.expression.ast.ASTArgs; 9 import com.tc.aspectwerkz.expression.ast.ASTCflow; 10 import com.tc.aspectwerkz.expression.ast.ASTPointcutReference; 11 import com.tc.aspectwerkz.expression.ast.ASTTarget; 12 import com.tc.aspectwerkz.expression.ast.ASTThis; 13 import com.tc.aspectwerkz.expression.ast.Node; 14 import com.tc.aspectwerkz.reflect.impl.asm.AsmClassInfo; 15 import com.tc.aspectwerkz.reflect.ClassInfoHelper; 16 import com.tc.aspectwerkz.reflect.ClassInfo; 17 18 import java.util.HashMap ; 19 import java.util.Iterator ; 20 import java.util.Map ; 21 22 30 public class ArgsIndexVisitor extends ExpressionVisitor { 31 32 36 private ClassLoader m_classLoader; 37 38 45 public static void updateContextForRuntimeInformation(final ExpressionInfo expressionInfo, 46 final ExpressionContext context, 47 final ClassLoader loader) { 48 ArgsIndexVisitor visitor = new ArgsIndexVisitor( 49 expressionInfo, expressionInfo.toString(), 50 expressionInfo.getNamespace(), 51 expressionInfo.getExpression().getASTRoot(), 52 loader 53 ); 54 visitor.match(context); 55 } 56 57 private ArgsIndexVisitor(final ExpressionInfo expressionInfo, 58 final String expression, 59 final String namespace, 60 final Node root, 61 final ClassLoader loader) { 62 super(expressionInfo, expression, namespace, root); 63 m_classLoader = loader; 64 } 65 66 68 public Object visit(ASTPointcutReference node, Object data) { 69 ExpressionContext context = (ExpressionContext) data; 71 ExpressionNamespace namespace = ExpressionNamespace.getNamespace(m_namespace); 72 ExpressionInfo expressionInfo = namespace.getExpressionInfo(node.getName()); 73 74 ArgsIndexVisitor referenced = new ArgsIndexVisitor( 75 expressionInfo, expressionInfo.toString(), 76 expressionInfo.getNamespace(), 77 expressionInfo.getExpression().getASTRoot(), 78 m_classLoader 79 ); 80 81 String targetSoFar = context.m_targetBoundedName; 83 String thisSoFar = context.m_thisBoundedName; 84 boolean targetWithRuntimeCheckSoFar = context.m_targetWithRuntimeCheck; 85 HashMap exprIndexToTargetIndexSoFar = (HashMap ) context.m_exprIndexToTargetIndex.clone(); 86 87 context.resetRuntimeState(); 88 Boolean match = referenced.matchUndeterministic(context); 89 90 if (context.m_targetBoundedName == null) { 92 context.m_targetBoundedName = targetSoFar; 93 } else if (targetSoFar != null) { 94 if (node.jjtGetNumChildren() == 1) { 95 String referenceCallArg = ((ASTArgParameter) node.jjtGetChild(0)).getTypePattern().getPattern(); 96 if (!targetSoFar.equals(referenceCallArg)) { 97 throw new UnsupportedOperationException ("should not occur"); 98 } 99 } 100 } 101 if (context.m_thisBoundedName == null) { 102 context.m_thisBoundedName = thisSoFar; 103 } else if (thisSoFar != null) { 104 if (node.jjtGetNumChildren() == 1) { 105 String referenceCallArg = ((ASTArgParameter) node.jjtGetChild(0)).getTypePattern().getPattern(); 106 if (!thisSoFar.equals(referenceCallArg)) { 107 throw new UnsupportedOperationException ("should not occur"); 108 } 109 } 110 } 111 if (!context.m_targetWithRuntimeCheck) { 112 context.m_targetWithRuntimeCheck = targetWithRuntimeCheckSoFar; 114 } 115 if (context.m_exprIndexToTargetIndex.isEmpty()) { 116 context.m_exprIndexToTargetIndex = exprIndexToTargetIndexSoFar; 118 } else if (!exprIndexToTargetIndexSoFar.isEmpty()) { 119 throw new UnsupportedOperationException ("should not occur"); 121 } 122 123 HashMap exprToTargetArgIndexes = new HashMap (); 125 for (int i = 0; i < node.jjtGetNumChildren(); i++) { 126 String referenceCallArg = ((ASTArgParameter) node.jjtGetChild(i)).getTypePattern().getPattern(); 127 String referentArg = expressionInfo.getArgumentNameAtIndex(i); 128 if (referentArg.equals(context.m_targetBoundedName)) { 129 context.m_targetBoundedName = referenceCallArg; 130 assertIsInstanceOf( 131 expressionInfo.getArgumentType(referentArg), 132 m_expressionInfo.getArgumentType(referenceCallArg) 133 ); 134 } else if (referentArg.equals(context.m_thisBoundedName)) { 135 context.m_thisBoundedName = referenceCallArg; 136 assertIsInstanceOf( 137 expressionInfo.getArgumentType(referentArg), 138 m_expressionInfo.getArgumentType(referenceCallArg) 139 ); 140 } else { 141 if (context.m_exprIndexToTargetIndex.containsKey(referentArg)) { 143 Object targetArgIndex = context.m_exprIndexToTargetIndex.get(referentArg); 144 exprToTargetArgIndexes.put(referenceCallArg, targetArgIndex); 145 } 146 147 } 148 } 149 for (Iterator it = exprIndexToTargetIndexSoFar.entrySet().iterator(); it.hasNext();) { 158 Map.Entry e = (Map.Entry ) it.next(); 159 Object key = e.getKey(); 160 if (!exprToTargetArgIndexes.containsKey(key)) { 161 exprToTargetArgIndexes.put(key, e.getValue()); 162 } 163 } 164 165 context.m_exprIndexToTargetIndex = exprToTargetArgIndexes; 166 return match; 167 } 168 169 public Object visit(ASTCflow node, Object data) { 170 ExpressionContext context = (ExpressionContext) data; 172 175 ExpressionInfo expressionInfo = new ExpressionInfo( 176 node.jjtGetChild(0), m_namespace 177 ); 178 expressionInfo.inheritPossibleArgumentFrom(m_expressionInfo); 179 180 ArgsIndexVisitor referenced = new ArgsIndexVisitor( 181 expressionInfo, "N/A", 182 m_namespace, 183 node.jjtGetChild(0), 184 m_classLoader 185 ); 186 187 String targetSoFar = context.m_targetBoundedName; 189 String thisSoFar = context.m_thisBoundedName; 190 boolean targetWithRuntimeCheckSoFar = context.m_targetWithRuntimeCheck; 191 HashMap exprIndexToTargetIndexSoFar = (HashMap ) context.m_exprIndexToTargetIndex.clone(); 192 193 context.resetRuntimeState(); 194 Boolean match = referenced.matchUndeterministic(context); 195 196 if (context.m_targetBoundedName == null) { 198 context.m_targetBoundedName = targetSoFar; 199 } else if (targetSoFar != null) { 200 } 202 if (context.m_thisBoundedName == null) { 203 context.m_thisBoundedName = thisSoFar; 204 } else if (thisSoFar != null) { 205 } 207 if (!context.m_targetWithRuntimeCheck) { 208 context.m_targetWithRuntimeCheck = targetWithRuntimeCheckSoFar; 210 } 211 if (context.m_exprIndexToTargetIndex.isEmpty()) { 212 context.m_exprIndexToTargetIndex = exprIndexToTargetIndexSoFar; 214 } else if (!exprIndexToTargetIndexSoFar.isEmpty()) { 215 for (Iterator it = exprIndexToTargetIndexSoFar.entrySet().iterator(); it.hasNext();) { 221 Map.Entry e = (Map.Entry ) it.next(); 222 context.m_exprIndexToTargetIndex.put(e.getKey(), e.getValue()); 223 } 224 } 225 return match; 226 } 227 228 public Object visit(ASTArgs node, Object data) { 229 return super.visit(node, data); 230 } 231 232 public Object visit(ASTArgParameter node, Object data) { 233 Boolean match = (Boolean ) super.visit(node, data); 235 236 int pointcutArgIndex = -1; 238 if (node.getTypePattern().getPattern().indexOf(".") < 0) { 239 pointcutArgIndex = m_expressionInfo.getArgumentIndex(node.getTypePattern().getPattern()); 240 } 241 242 if (pointcutArgIndex >= 0 && Boolean.TRUE.equals(match)) { 244 ExpressionContext ctx = (ExpressionContext) data; 245 ctx.m_exprIndexToTargetIndex.put( 246 m_expressionInfo.getArgumentNameAtIndex(pointcutArgIndex), 247 new Integer (ctx.getCurrentTargetArgsIndex())); 248 } 249 return match; 250 } 251 252 public Object visit(ASTThis node, Object data) { 253 if (m_expressionInfo.getArgumentType(node.getIdentifier()) != null) { 255 ExpressionContext ctx = (ExpressionContext) data; 256 if (ctx.m_thisBoundedName == null) { 257 ctx.m_thisBoundedName = node.getIdentifier(); 258 } else if (ctx.m_thisBoundedName != node.getIdentifier()) { 259 throw new DefinitionException( 260 "this(..) seems to be bounded to different bounded entities in \"" 261 + m_expressionInfo.toString() + "\" in " + 262 m_expressionInfo.getNamespace() 263 + " : found " + ctx.m_targetBoundedName + " and " + 264 node.getIdentifier() 265 ); 266 } 267 } 268 return super.visit(node, data); 269 } 270 271 public Object visit(ASTTarget node, Object data) { 272 if (m_expressionInfo.getArgumentType(node.getIdentifier()) != null) { 274 ExpressionContext ctx = (ExpressionContext) data; 275 if (ctx.m_targetBoundedName == null) { 276 ctx.m_targetBoundedName = node.getIdentifier(); 277 } else if (ctx.m_targetBoundedName != node.getIdentifier()) { 278 throw new DefinitionException( 279 "target(..) seems to be bounded to different bounded entities in \"" 280 + m_expressionInfo.toString() + "\" in " + 281 m_expressionInfo.getNamespace() 282 + " : found " + ctx.m_targetBoundedName + " and " + 283 node.getIdentifier() 284 ); 285 } 286 } 287 Object match = super.visit(node, data); 289 if (match == null) { 290 ((ExpressionContext) data).m_targetWithRuntimeCheck = true; 291 } 292 return match; 293 } 294 295 302 private void assertIsInstanceOf(String className, String superClassName) { 303 if (!className.equals(superClassName)) { 304 ClassInfo classInfo = AsmClassInfo.getClassInfo(className, m_classLoader); 307 boolean instanceOf = ClassInfoHelper.instanceOf(classInfo, superClassName); 308 if (!instanceOf) { 309 throw new DefinitionException( 310 "Attempt to reference a pointcut with incompatible object type: for \"" 311 + m_expression + "\" , " + className + " is not an instance of " + 312 superClassName + 313 "." 314 + " Error occured in " + m_namespace 315 ); 316 } 317 } 318 } 319 } | Popular Tags |