1 8 package org.codehaus.aspectwerkz.expression; 9 10 import org.codehaus.aspectwerkz.expression.ast.ASTRoot; 11 import org.codehaus.aspectwerkz.expression.ast.ASTPointcutReference; 12 import org.codehaus.aspectwerkz.expression.ast.ASTArgParameter; 13 import org.codehaus.aspectwerkz.expression.ast.ASTArgs; 14 import org.codehaus.aspectwerkz.expression.ast.ASTThis; 15 import org.codehaus.aspectwerkz.expression.ast.ASTTarget; 16 import org.codehaus.aspectwerkz.expression.ast.Node; 17 import org.codehaus.aspectwerkz.expression.ast.ASTCflow; 18 import org.codehaus.aspectwerkz.util.Strings; 19 import org.codehaus.aspectwerkz.exception.DefinitionException; 20 import org.codehaus.aspectwerkz.reflect.ClassInfo; 21 import org.codehaus.aspectwerkz.reflect.ClassInfoHelper; 22 import org.codehaus.aspectwerkz.reflect.impl.asm.AsmClassInfo; 23 import org.codehaus.aspectwerkz.util.ContextClassLoader; 24 25 import java.util.Iterator ; 26 27 import gnu.trove.TIntIntHashMap; 28 import gnu.trove.TObjectIntHashMap; 29 30 38 public class ArgsIndexVisitor extends ExpressionVisitor { 39 40 44 private ClassLoader m_classLoader; 45 46 53 public static void updateContextForRuntimeInformation(final ExpressionInfo expressionInfo, 54 final ExpressionContext context, 55 final ClassLoader loader) { 56 ArgsIndexVisitor visitor = new ArgsIndexVisitor( 57 expressionInfo, expressionInfo.toString(), 58 expressionInfo.getNamespace(), 59 expressionInfo.getExpression().getASTRoot(), 60 loader 61 ); 62 visitor.match(context); 63 } 64 65 private ArgsIndexVisitor(final ExpressionInfo expressionInfo, 66 final String expression, 67 final String namespace, 68 final Node root, 69 final ClassLoader loader) { 70 super(expressionInfo, expression, namespace, root); 71 m_classLoader = loader; 72 } 73 74 76 public Object visit(ASTPointcutReference node, Object data) { 77 ExpressionContext context = (ExpressionContext) data; 79 ExpressionNamespace namespace = ExpressionNamespace.getNamespace(m_namespace); 80 ExpressionInfo expressionInfo = namespace.getExpressionInfo(node.getName()); 81 82 ArgsIndexVisitor referenced = new ArgsIndexVisitor( 83 expressionInfo, expressionInfo.toString(), 84 expressionInfo.getNamespace(), 85 expressionInfo.getExpression().getASTRoot(), 86 m_classLoader 87 ); 88 89 String targetSoFar = context.m_targetBoundedName; 91 String thisSoFar = context.m_thisBoundedName; 92 boolean targetWithRuntimeCheckSoFar = context.m_targetWithRuntimeCheck; 93 TObjectIntHashMap exprIndexToTargetIndexSoFar = (TObjectIntHashMap) context.m_exprIndexToTargetIndex.clone(); 94 95 context.resetRuntimeState(); 96 Boolean match = referenced.matchUndeterministic(context); 97 98 if (context.m_targetBoundedName == null) { 100 context.m_targetBoundedName = targetSoFar; 101 } else if (targetSoFar != null) { 102 if (node.jjtGetNumChildren() == 1) { 103 String referenceCallArg = ((ASTArgParameter) node.jjtGetChild(0)).getTypePattern().getPattern(); 104 if (!targetSoFar.equals(referenceCallArg)) { 105 throw new UnsupportedOperationException ("should not occur"); 106 } 107 } 108 } 109 if (context.m_thisBoundedName == null) { 110 context.m_thisBoundedName = thisSoFar; 111 } else if (thisSoFar != null) { 112 if (node.jjtGetNumChildren() == 1) { 113 String referenceCallArg = ((ASTArgParameter) node.jjtGetChild(0)).getTypePattern().getPattern(); 114 if (!thisSoFar.equals(referenceCallArg)) { 115 throw new UnsupportedOperationException ("should not occur"); 116 } 117 } 118 } 119 if (!context.m_targetWithRuntimeCheck) { 120 context.m_targetWithRuntimeCheck = targetWithRuntimeCheckSoFar; 122 } 123 if (context.m_exprIndexToTargetIndex.isEmpty()) { 124 context.m_exprIndexToTargetIndex = exprIndexToTargetIndexSoFar; 126 } else if (!exprIndexToTargetIndexSoFar.isEmpty()) { 127 throw new UnsupportedOperationException ("should not occur"); 129 } 130 131 132 TObjectIntHashMap exprToTargetArgIndexes = new TObjectIntHashMap(); 134 for (int i = 0; i < node.jjtGetNumChildren(); i++) { 135 String referenceCallArg = ((ASTArgParameter) node.jjtGetChild(i)).getTypePattern().getPattern(); 136 String referentArg = expressionInfo.getArgumentNameAtIndex(i); 137 if (referentArg.equals(context.m_targetBoundedName)) { 138 context.m_targetBoundedName = referenceCallArg; 139 assertIsInstanceOf( 140 expressionInfo.getArgumentType(referentArg), 141 m_expressionInfo.getArgumentType(referenceCallArg) 142 ); 143 } else if (referentArg.equals(context.m_thisBoundedName)) { 144 context.m_thisBoundedName = referenceCallArg; 145 assertIsInstanceOf( 146 expressionInfo.getArgumentType(referentArg), 147 m_expressionInfo.getArgumentType(referenceCallArg) 148 ); 149 } else { 150 int adviceArgIndex = i; 151 if (context.m_exprIndexToTargetIndex.containsKey(referentArg)) { 152 int targetArgIndex = context.m_exprIndexToTargetIndex.get(referentArg); 153 exprToTargetArgIndexes.put(referenceCallArg, targetArgIndex); 154 } 155 156 } 157 } 158 Object [] soFar = exprIndexToTargetIndexSoFar.keys(); 160 for (int i = 0; i < soFar.length; i++) { 161 String name = (String ) soFar[i]; 162 if (!exprToTargetArgIndexes.containsKey(name)) { 163 exprToTargetArgIndexes.put(name, exprIndexToTargetIndexSoFar.get(name)); 164 } 165 } 166 context.m_exprIndexToTargetIndex = exprToTargetArgIndexes; 167 return match; 168 } 169 170 public Object visit(ASTCflow node, Object data) { 171 ExpressionContext context = (ExpressionContext) data; 173 176 ExpressionInfo expressionInfo = new ExpressionInfo( 177 node.jjtGetChild(0), m_namespace 178 ); 179 expressionInfo.inheritPossibleArgumentFrom(m_expressionInfo); 180 181 ArgsIndexVisitor referenced = new ArgsIndexVisitor( 182 expressionInfo, "N/A", 183 m_namespace, 184 node.jjtGetChild(0), 185 m_classLoader 186 ); 187 188 String targetSoFar = context.m_targetBoundedName; 190 String thisSoFar = context.m_thisBoundedName; 191 boolean targetWithRuntimeCheckSoFar = context.m_targetWithRuntimeCheck; 192 TObjectIntHashMap exprIndexToTargetIndexSoFar = (TObjectIntHashMap) context.m_exprIndexToTargetIndex.clone(); 193 194 context.resetRuntimeState(); 195 Boolean match = referenced.matchUndeterministic(context); 196 197 if (context.m_targetBoundedName == null) { 199 context.m_targetBoundedName = targetSoFar; 200 } else if (targetSoFar != null) { 201 } 203 if (context.m_thisBoundedName == null) { 204 context.m_thisBoundedName = thisSoFar; 205 } else if (thisSoFar != null) { 206 } 208 if (!context.m_targetWithRuntimeCheck) { 209 context.m_targetWithRuntimeCheck = targetWithRuntimeCheckSoFar; 211 } 212 if (context.m_exprIndexToTargetIndex.isEmpty()) { 213 context.m_exprIndexToTargetIndex = exprIndexToTargetIndexSoFar; 215 } else if (!exprIndexToTargetIndexSoFar.isEmpty()) { 216 for (int i = 0; i < exprIndexToTargetIndexSoFar.keys().length; i++) { 218 Object o = exprIndexToTargetIndexSoFar.keys()[i]; 219 context.m_exprIndexToTargetIndex.put(o, exprIndexToTargetIndexSoFar.get(o)); 220 } 221 } 222 return match; 223 } 224 225 public Object visit(ASTArgs node, Object data) { 226 return super.visit(node, data); 227 } 228 229 public Object visit(ASTArgParameter node, Object data) { 230 Boolean match = (Boolean ) super.visit(node, data); 232 233 int pointcutArgIndex = -1; 235 if (node.getTypePattern().getPattern().indexOf(".") < 0) { 236 pointcutArgIndex = m_expressionInfo.getArgumentIndex(node.getTypePattern().getPattern()); 237 } 238 239 if (pointcutArgIndex >= 0 && Boolean.TRUE.equals(match)) { 241 ExpressionContext ctx = (ExpressionContext) data; 242 ctx.m_exprIndexToTargetIndex.put( 243 m_expressionInfo.getArgumentNameAtIndex(pointcutArgIndex), ctx.getCurrentTargetArgsIndex() 244 ); 245 } 246 return match; 247 } 248 249 public Object visit(ASTThis node, Object data) { 250 if (m_expressionInfo.getArgumentType(node.getIdentifier()) != null) { 252 ExpressionContext ctx = (ExpressionContext) data; 253 if (ctx.m_thisBoundedName == null) { 254 ctx.m_thisBoundedName = node.getIdentifier(); 255 } else if (ctx.m_thisBoundedName != node.getIdentifier()) { 256 throw new DefinitionException( 257 "this(..) seems to be bounded to different bounded entities in \"" 258 + m_expressionInfo.toString() + "\" in " + 259 m_expressionInfo.getNamespace() 260 + " : found " + ctx.m_targetBoundedName + " and " + 261 node.getIdentifier() 262 ); 263 } 264 } 265 return super.visit(node, data); 266 } 267 268 public Object visit(ASTTarget node, Object data) { 269 if (m_expressionInfo.getArgumentType(node.getIdentifier()) != null) { 271 ExpressionContext ctx = (ExpressionContext) data; 272 if (ctx.m_targetBoundedName == null) { 273 ctx.m_targetBoundedName = node.getIdentifier(); 274 } else if (ctx.m_targetBoundedName != node.getIdentifier()) { 275 throw new DefinitionException( 276 "target(..) seems to be bounded to different bounded entities in \"" 277 + m_expressionInfo.toString() + "\" in " + 278 m_expressionInfo.getNamespace() 279 + " : found " + ctx.m_targetBoundedName + " and " + 280 node.getIdentifier() 281 ); 282 } 283 } 284 Object match = super.visit(node, data); 286 if (match == null) { 287 ((ExpressionContext) data).m_targetWithRuntimeCheck = true; 288 } 289 return match; 290 } 291 292 299 private void assertIsInstanceOf(String className, String superClassName) { 300 if (className.equals(superClassName)) { 301 ; } else { 303 ClassInfo classInfo = AsmClassInfo.getClassInfo(className, m_classLoader); 306 boolean instanceOf = ClassInfoHelper.instanceOf(classInfo, superClassName); 307 if (!instanceOf) { 308 throw new DefinitionException( 309 "Attempt to reference a pointcut with incompatible object type: for \"" 310 + m_expression + "\" , " + className + " is not an instance of " + 311 superClassName + 312 "." 313 + " Error occured in " + m_namespace 314 ); 315 } 316 } 317 } 318 } | Popular Tags |