| 1 8 package org.codehaus.aspectwerkz.expression; 9 10 import org.codehaus.aspectwerkz.annotation.AnnotationInfo; 11 import org.codehaus.aspectwerkz.expression.ast.ASTAnd; 12 import org.codehaus.aspectwerkz.expression.ast.ASTAttribute; 13 import org.codehaus.aspectwerkz.expression.ast.ASTCall; 14 import org.codehaus.aspectwerkz.expression.ast.ASTCflow; 15 import org.codehaus.aspectwerkz.expression.ast.ASTCflowBelow; 16 import org.codehaus.aspectwerkz.expression.ast.ASTClassPattern; 17 import org.codehaus.aspectwerkz.expression.ast.ASTConstructorPattern; 18 import org.codehaus.aspectwerkz.expression.ast.ASTExecution; 19 import org.codehaus.aspectwerkz.expression.ast.ASTExpression; 20 import org.codehaus.aspectwerkz.expression.ast.ASTFieldPattern; 21 import org.codehaus.aspectwerkz.expression.ast.ASTGet; 22 import org.codehaus.aspectwerkz.expression.ast.ASTHandler; 23 import org.codehaus.aspectwerkz.expression.ast.ASTMethodPattern; 24 import org.codehaus.aspectwerkz.expression.ast.ASTModifier; 25 import org.codehaus.aspectwerkz.expression.ast.ASTNot; 26 import org.codehaus.aspectwerkz.expression.ast.ASTOr; 27 import org.codehaus.aspectwerkz.expression.ast.ASTParameter; 28 import org.codehaus.aspectwerkz.expression.ast.ASTPointcutReference; 29 import org.codehaus.aspectwerkz.expression.ast.ASTRoot; 30 import org.codehaus.aspectwerkz.expression.ast.ASTSet; 31 import org.codehaus.aspectwerkz.expression.ast.ASTStaticInitialization; 32 import org.codehaus.aspectwerkz.expression.ast.ASTWithin; 33 import org.codehaus.aspectwerkz.expression.ast.ASTWithinCode; 34 import org.codehaus.aspectwerkz.expression.ast.ExpressionParserVisitor; 35 import org.codehaus.aspectwerkz.expression.ast.Node; 36 import org.codehaus.aspectwerkz.expression.ast.SimpleNode; 37 import org.codehaus.aspectwerkz.expression.ast.ASTArgs; 38 import org.codehaus.aspectwerkz.expression.ast.ASTArgParameter; 39 import org.codehaus.aspectwerkz.expression.regexp.TypePattern; 40 import org.codehaus.aspectwerkz.reflect.ClassInfo; 41 import org.codehaus.aspectwerkz.reflect.ConstructorInfo; 42 import org.codehaus.aspectwerkz.reflect.FieldInfo; 43 import org.codehaus.aspectwerkz.reflect.MemberInfo; 44 import org.codehaus.aspectwerkz.reflect.MethodInfo; 45 import org.codehaus.aspectwerkz.reflect.ReflectionInfo; 46 import org.codehaus.aspectwerkz.reflect.ClassInfoHelper; 47 import org.codehaus.aspectwerkz.reflect.StaticInitializationInfo; 48 49 import java.lang.reflect.Modifier ; 50 import java.util.ArrayList ; 51 import java.util.Iterator ; 52 import java.util.List ; 53 54 import org.codehaus.aspectwerkz.expression.ast.ASTHasField; 55 import org.codehaus.aspectwerkz.expression.ast.ASTHasMethod; 56 import org.codehaus.aspectwerkz.expression.ast.ASTTarget; 57 import org.codehaus.aspectwerkz.expression.ast.ASTThis; 58 import org.codehaus.aspectwerkz.util.Util; 59 60 69 public class ExpressionVisitor implements ExpressionParserVisitor { 70 71 protected Node m_root; 72 protected String m_expression; 73 protected String m_namespace; 74 75 78 protected ExpressionInfo m_expressionInfo; 79 80 88 public ExpressionVisitor(final ExpressionInfo expressionInfo, 89 final String expression, 90 final String namespace, 91 final Node root) { 92 m_expressionInfo = expressionInfo; 93 m_expression = expression; 94 m_namespace = namespace; 95 m_root = root; 96 } 97 98 106 public boolean match(final ExpressionContext context) { 107 Boolean match = ((Boolean ) visit(m_root, context)); 108 return (match != null) ? match.booleanValue() : true; 112 } 113 114 protected Boolean matchUndeterministic(final ExpressionContext context) { 115 Boolean match = ((Boolean ) visit(m_root, context)); 116 return match; 117 } 118 119 public Object visit(Node node, Object data) { 121 return node.jjtGetChild(0).jjtAccept(this, data); 122 } 123 124 public Object visit(SimpleNode node, Object data) { 125 return node.jjtGetChild(0).jjtAccept(this, data); 126 } 127 128 public Object visit(ASTRoot node, Object data) { 129 return node.jjtGetChild(0).jjtAccept(this, data); 130 } 131 132 public Object visit(ASTExpression node, Object data) { 133 return node.jjtGetChild(0).jjtAccept(this, data); 134 } 135 136 public Object visit(ASTOr node, Object data) { 138 Boolean matchL = (Boolean ) node.jjtGetChild(0).jjtAccept(this, data); 140 Boolean matchR = (Boolean ) node.jjtGetChild(1).jjtAccept(this, data); 141 Boolean intermediate = Undeterministic.or(matchL, matchR); 142 for (int i = 2; i < node.jjtGetNumChildren(); i++) { 143 Boolean matchNext = (Boolean ) node.jjtGetChild(i).jjtAccept(this, data); 144 intermediate = Undeterministic.or(intermediate, matchNext); 145 } 146 return intermediate; 147 } 148 149 public Object visit(ASTAnd node, Object data) { 150 Boolean matchL = (Boolean ) node.jjtGetChild(0).jjtAccept(this, data); 152 Boolean matchR = (Boolean ) node.jjtGetChild(1).jjtAccept(this, data); 153 Boolean intermediate = Undeterministic.and(matchL, matchR); 154 for (int i = 2; i < node.jjtGetNumChildren(); i++) { 155 Boolean matchNext = (Boolean ) node.jjtGetChild(i).jjtAccept(this, data); 156 intermediate = Undeterministic.and(intermediate, matchNext); 157 } 158 return intermediate; 159 } 160 161 public Object visit(ASTNot node, Object data) { 162 Boolean match = (Boolean ) node.jjtGetChild(0).jjtAccept(this, data); 163 return Undeterministic.not(match); 164 } 165 166 public Object visit(ASTPointcutReference node, Object data) { 168 ExpressionContext context = (ExpressionContext) data; 169 ExpressionNamespace namespace = ExpressionNamespace.getNamespace(m_namespace); 170 ExpressionVisitor expression = namespace.getExpression(node.getName()); 171 return expression.matchUndeterministic(context); 172 } 173 174 public Object visit(ASTExecution node, Object data) { 175 ExpressionContext context = (ExpressionContext) data; 176 if (context.hasExecutionPointcut() && (context.hasMethodInfo() || context.hasConstructorInfo())) { 177 return visitAnnotatedNode(node, context.getReflectionInfo()); 178 } else { 179 return Boolean.FALSE; 180 } 181 } 182 183 public Object visit(ASTCall node, Object data) { 184 ExpressionContext context = (ExpressionContext) data; 185 if (context.hasCallPointcut() && (context.hasMethodInfo() || context.hasConstructorInfo())) { 186 return visitAnnotatedNode(node, context.getReflectionInfo()); 187 } else { 188 return Boolean.FALSE; 189 } 190 } 191 192 public Object visit(ASTSet node, Object data) { 193 ExpressionContext context = (ExpressionContext) data; 194 if (context.hasSetPointcut() && context.hasFieldInfo()) { 195 return visitAnnotatedNode(node, context.getReflectionInfo()); 196 } else { 197 return Boolean.FALSE; 198 } 199 } 200 201 public Object visit(ASTGet node, Object data) { 202 ExpressionContext context = (ExpressionContext) data; 203 if (context.hasGetPointcut() && context.hasFieldInfo()) { 204 return visitAnnotatedNode(node, context.getReflectionInfo()); 205 } else { 206 return Boolean.FALSE; 207 } 208 } 209 210 public Object visit(ASTHandler node, Object data) { 211 ExpressionContext context = (ExpressionContext) data; 212 if (context.hasHandlerPointcut() && context.hasClassInfo()) { 213 return node.jjtGetChild(0).jjtAccept(this, context.getReflectionInfo()); 214 } else { 215 return Boolean.FALSE; 216 } 217 } 218 219 public Object visit(ASTStaticInitialization node, Object data) { 220 ExpressionContext context = (ExpressionContext) data; 221 222 if (context.hasStaticInitializationPointcut() && context.hasReflectionInfo()) { 223 ReflectionInfo reflectInfo = context.getReflectionInfo(); 224 225 if(reflectInfo instanceof StaticInitializationInfo) { 226 ClassInfo declaringClassInfo = ((StaticInitializationInfo) reflectInfo).getDeclaringType(); 227 228 Node patternNode = node.jjtGetChild(node.jjtGetNumChildren() - 1); 230 if (!(patternNode instanceof ASTAttribute)) { 231 Boolean matchPattern = (Boolean ) patternNode.jjtAccept(this, reflectInfo); 232 if (Boolean.FALSE.equals(matchPattern)) { 233 return Boolean.FALSE; 234 } 235 } 236 237 boolean matchedAnnotations = visitAttributes(node, declaringClassInfo); 239 if (!matchedAnnotations) { 240 return Boolean.FALSE; 241 } else { 242 return Boolean.TRUE; 243 } 244 } else { 245 return Boolean.FALSE; 246 } 247 } else { 248 return Boolean.FALSE; 249 } 250 } 251 252 public Object visit(ASTWithin node, Object data) { 253 ExpressionContext context = (ExpressionContext) data; 254 if (context.hasWithinReflectionInfo()) { 255 ReflectionInfo reflectInfo = context.getWithinReflectionInfo(); 256 ReflectionInfo withinInfo = null; 257 258 if(reflectInfo instanceof MemberInfo) { 259 withinInfo = ((MemberInfo) reflectInfo).getDeclaringType(); 260 } else if(reflectInfo instanceof ClassInfo) { 261 withinInfo = reflectInfo; 262 } else { 263 return Boolean.FALSE; 264 } 265 return visitAnnotatedNode( 266 node, 267 withinInfo); 268 } else { 269 return null; 270 } 271 } 272 273 public Object visit(ASTWithinCode node, Object data) { 274 ExpressionContext context = (ExpressionContext) data; 275 276 if(!context.hasWithinReflectionInfo()) { 277 return null; 278 } 279 280 ReflectionInfo reflectInfo = context.getWithinReflectionInfo(); 281 282 if(node.isStaticInitializer()) { 283 if(reflectInfo instanceof StaticInitializationInfo) { 284 SimpleNode staticClinitNode = (SimpleNode) node.jjtGetChild(0); 286 ClassInfo declaringClassInfo = ((StaticInitializationInfo) reflectInfo).getDeclaringType(); 287 288 boolean matchedAnnotations = visitAttributes(staticClinitNode, declaringClassInfo); 289 if(!matchedAnnotations) { 290 return Boolean.FALSE; 291 } 292 293 Node lastNode = staticClinitNode.jjtGetChild(staticClinitNode.jjtGetNumChildren() - 1); 295 if(lastNode instanceof ASTAttribute) { 296 return Boolean.TRUE; 297 } else { 298 return lastNode.jjtAccept(this, reflectInfo); 299 } 300 } else { 301 return Boolean.FALSE; 302 } 303 } else { 304 return visitAnnotatedNode( 305 node, 306 reflectInfo 307 ); 308 } 309 } 310 311 312 public Object visit(ASTHasMethod node, Object data) { 313 ExpressionContext context = (ExpressionContext) data; 314 315 ReflectionInfo info = context.getWithinReflectionInfo(); 318 ClassInfo classInfo = info instanceof MemberInfo 319 ? ((MemberInfo) info).getDeclaringType() 320 : (ClassInfo) info; 321 322 Node patternNode = node.jjtGetChild(node.jjtGetNumChildren() - 1); 323 boolean hasPatternNode = !(patternNode instanceof ASTAttribute); 324 325 MethodInfo[] methodInfos = classInfo.getMethods(); 326 for (int i = 0; i < methodInfos.length; i++) { 327 if (hasPatternNode) { 328 if(Boolean.FALSE.equals(patternNode.jjtAccept(this, methodInfos[i]))) { 329 continue; 330 } 331 } 332 333 boolean matchAnnotations = visitAttributes(node, methodInfos[i]); 334 if (matchAnnotations) { 335 return Boolean.TRUE; 336 } 337 } 338 339 ConstructorInfo[] constructorInfos = classInfo.getConstructors(); 340 for (int i = 0; i < constructorInfos.length; i++) { 341 if (hasPatternNode) { 342 if(Boolean.FALSE.equals(patternNode.jjtAccept(this, constructorInfos[i]))) { 343 continue; 344 } 345 } 346 347 boolean matchAnnotations = visitAttributes(node, constructorInfos[i]); 348 if (matchAnnotations) { 349 return Boolean.TRUE; 350 } 351 } 352 353 return Boolean.FALSE; 354 } 355 356 public Object visit(ASTHasField node, Object data) { 357 ExpressionContext context = (ExpressionContext) data; 358 359 ReflectionInfo info = context.getWithinReflectionInfo(); 362 ClassInfo classInfo = (info instanceof MemberInfo) ? 363 ((MemberInfo) info).getDeclaringType() : (ClassInfo) info; 364 365 Node patternNode = node.jjtGetChild(node.jjtGetNumChildren() - 1); 366 boolean hasPatternNode = !(patternNode instanceof ASTAttribute); 367 368 FieldInfo[] fieldInfos = classInfo.getFields(); 369 for (int i = 0; i < fieldInfos.length; i++) { 370 if (hasPatternNode) { 371 if (Boolean.FALSE.equals(patternNode.jjtAccept(this, fieldInfos[i]))) { 372 continue; 373 } 374 } 375 376 boolean matchAnnotations = visitAttributes(node, fieldInfos[i]); 377 if (matchAnnotations) { 378 return Boolean.TRUE; 379 } 380 } 381 382 return Boolean.FALSE; 383 } 384 385 public Object visit(ASTTarget node, Object data) { 386 ExpressionContext context = (ExpressionContext) data; 387 ReflectionInfo info = context.getReflectionInfo(); 388 389 ClassInfo declaringType = null; 395 if (info instanceof MemberInfo) { 396 if (Modifier.isStatic(((MemberInfo) info).getModifiers())) { 398 return Boolean.FALSE; 399 } 400 401 declaringType = ((MemberInfo) info).getDeclaringType(); 402 } else if (info instanceof ClassInfo) { 403 declaringType = (ClassInfo) info; 404 } else { 405 return Boolean.FALSE; 406 } 407 408 String boundedTypeName = node.getBoundedType(m_expressionInfo); 409 if (declaringType.isInterface()) { 412 if (ClassInfoHelper.instanceOf(declaringType, boundedTypeName)) { 414 return Boolean.TRUE; 415 } else { 416 return null; 419 } 420 } else { 421 return Util.booleanValueOf(ClassInfoHelper.instanceOf(declaringType, boundedTypeName)); 422 } 423 } 424 425 public Object visit(ASTThis node, Object data) { 426 ExpressionContext context = (ExpressionContext) data; 427 if (context.hasWithinReflectionInfo()) { 430 ReflectionInfo withinInfo = context.getWithinReflectionInfo(); 431 if (withinInfo instanceof MemberInfo) { 432 if (Modifier.isStatic(((MemberInfo) withinInfo).getModifiers())) { 434 return Boolean.FALSE; 435 } 436 return Util.booleanValueOf( 437 ClassInfoHelper.instanceOf( 438 ((MemberInfo) withinInfo).getDeclaringType(), 439 node.getBoundedType(m_expressionInfo) 440 ) 441 ); 442 } else if (withinInfo instanceof ClassInfo) { 443 return Util.booleanValueOf( 444 ClassInfoHelper.instanceOf((ClassInfo) withinInfo, node.getBoundedType(m_expressionInfo)) 445 ); 446 } 447 } 448 return Boolean.FALSE; 449 } 450 451 public Object visit(ASTCflow node, Object data) { 452 return null; 453 } 454 455 public Object visit(ASTCflowBelow node, Object data) { 456 return null; 457 } 458 459 public Object visit(ASTClassPattern node, Object data) { 461 if (data instanceof ClassInfo) { 462 ClassInfo classInfo = (ClassInfo) data; 463 TypePattern typePattern = node.getTypePattern(); 464 465 if (typePattern.matchType(classInfo) 466 && visitModifiers(node, classInfo)) { 467 return Boolean.TRUE; 468 } else { 469 return Boolean.FALSE; 470 } 471 } else if (data instanceof StaticInitializationInfo) { 472 ClassInfo classInfo = ((StaticInitializationInfo) data).getDeclaringType(); 473 474 if(node.getTypePattern().matchType(classInfo)) { 475 return Boolean.TRUE; 476 } else { 477 return Boolean.FALSE; 478 } 479 480 } 482 483 return Boolean.FALSE; 484 } 485 486 public Object visit(ASTMethodPattern node, Object data) { 487 if (data instanceof MethodInfo) { 488 MethodInfo methodInfo = (MethodInfo) data; 489 if (node.getMethodNamePattern().matches(methodInfo.getName()) 490 && node.getDeclaringTypePattern().matchType(methodInfo.getDeclaringType()) 491 && node.getReturnTypePattern().matchType(methodInfo.getReturnType()) 492 && visitModifiers(node, methodInfo) 493 && visitParameters(node, methodInfo.getParameterTypes())) { 494 return Boolean.TRUE; 495 } 496 } 497 498 return Boolean.FALSE; 499 } 500 501 public Object visit(ASTConstructorPattern node, Object data) { 502 if (data instanceof ConstructorInfo) { 503 ConstructorInfo constructorMetaData = (ConstructorInfo) data; 504 if (node.getDeclaringTypePattern().matchType(constructorMetaData.getDeclaringType()) 505 && visitModifiers(node, constructorMetaData) 506 && visitParameters(node, constructorMetaData.getParameterTypes())) { 507 return Boolean.TRUE; 508 } 509 } 510 return Boolean.FALSE; 511 } 512 513 public Object visit(ASTFieldPattern node, Object data) { 514 if (data instanceof FieldInfo) { 515 FieldInfo fieldInfo = (FieldInfo) data; 516 if (node.getFieldNamePattern().matches(fieldInfo.getName()) 517 && node.getDeclaringTypePattern().matchType(fieldInfo.getDeclaringType()) 518 && node.getFieldTypePattern().matchType(fieldInfo.getType()) 519 && visitModifiers(node, fieldInfo)) { 520 return Boolean.TRUE; 521 } 522 } 523 return Boolean.FALSE; 524 } 525 526 public Object visit(ASTParameter node, Object data) { 527 ClassInfo parameterType = (ClassInfo) data; 528 if (node.getDeclaringClassPattern().matchType(parameterType)) { 529 return Boolean.TRUE; 530 } else { 531 return Boolean.FALSE; 532 } 533 } 534 535 public Object visit(ASTArgs node, Object data) { 536 ExpressionContext ctx = (ExpressionContext) data; 537 if (node.jjtGetNumChildren() <= 0) { 538 return (getParametersCount(ctx) == 0) ? Boolean.TRUE : Boolean.FALSE; 540 } else { 541 int expressionParameterCount = node.jjtGetNumChildren(); boolean isFirstArgEager = ((ASTArgParameter) node.jjtGetChild(0)).getTypePattern().isEagerWildCard(); 544 boolean isLastArgEager = ((ASTArgParameter) node.jjtGetChild(node.jjtGetNumChildren() - 1)) 545 .getTypePattern().isEagerWildCard(); 546 if (isFirstArgEager && expressionParameterCount == 1) { 548 return Boolean.TRUE; 549 } 550 int contextParametersCount = getParametersCount(ctx); 551 if (isFirstArgEager && isLastArgEager) { 552 expressionParameterCount -= 2; 553 if (expressionParameterCount == 0) { 554 return Boolean.TRUE; 556 } 557 int matchCount = 0; 562 int ictx = 0; 563 for (int iexp = 0; iexp < expressionParameterCount; iexp++) { 564 if (ictx >= contextParametersCount) { 565 matchCount = -1; 567 break; 568 } 569 ctx.setCurrentTargetArgsIndex(ictx); 570 boolean isEager = ((ASTArgParameter) node.jjtGetChild(iexp + 1)).getTypePattern().isEagerWildCard(); 572 if (isEager) { 573 } 575 if (Boolean.TRUE.equals((Boolean ) node.jjtGetChild(iexp + 1).jjtAccept(this, ctx))) { 576 matchCount += 1; 577 ictx++; 578 } else { 579 matchCount = 0; 581 ictx++; 582 iexp = -1; 583 } 584 } 585 if (matchCount == expressionParameterCount) { 586 return Boolean.TRUE; 587 } else { 588 return Boolean.FALSE; 589 } 590 } else if (isFirstArgEager) { 591 expressionParameterCount--; 592 if (contextParametersCount >= expressionParameterCount) { 593 for (int i = 0; (i < contextParametersCount) && (expressionParameterCount - i >= 0); i++) { 595 ctx.setCurrentTargetArgsIndex(contextParametersCount - 1 - i); 596 if (Boolean.TRUE.equals( 597 (Boolean ) node.jjtGetChild(expressionParameterCount - i).jjtAccept( 598 this, 599 ctx 600 ) 601 )) { 602 ; } else { 604 return Boolean.FALSE; 605 } 606 } 607 return Boolean.TRUE; 608 } else { 609 return Boolean.FALSE; 611 } 612 } else if (isLastArgEager) { 613 expressionParameterCount--; 614 if (contextParametersCount >= expressionParameterCount) { 615 for (int i = 0; (i < contextParametersCount) && (i < expressionParameterCount); i++) { 617 ctx.setCurrentTargetArgsIndex(i); 618 if (Boolean.TRUE.equals((Boolean ) node.jjtGetChild(i).jjtAccept(this, ctx))) { 619 ; } else { 621 return Boolean.FALSE; 622 } 623 } 624 return Boolean.TRUE; 625 } else { 626 return Boolean.FALSE; 627 } 628 } else { 629 if (expressionParameterCount == contextParametersCount) { 632 for (int i = 0; i < node.jjtGetNumChildren(); i++) { 633 ctx.setCurrentTargetArgsIndex(i); 634 if (Boolean.TRUE.equals((Boolean ) node.jjtGetChild(i).jjtAccept(this, ctx))) { 635 ; } else { 637 return Boolean.FALSE; 638 } 639 } 640 return Boolean.TRUE; 641 } else { 642 return Boolean.FALSE; 643 &nb
|