Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

PointcutEvaluationExpenseComparator.java 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /* *******************************************************************
  2. * Copyright (c) 2004 IBM Corporation.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Common Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * ******************************************************************/
  10. package org.aspectj.weaver.patterns;
  11. import java.util.Comparator;
  12. import org.aspectj.weaver.Shadow;
  13. public class PointcutEvaluationExpenseComparator implements Comparator {
  14. private static final int MATCHES_NOTHING = -1;
  15. private static final int WITHIN = 1;
  16. private static final int ATWITHIN = 2;
  17. private static final int STATICINIT = 3;
  18. private static final int ADVICEEXECUTION = 4;
  19. private static final int HANDLER = 5;
  20. private static final int GET_OR_SET = 6;
  21. private static final int WITHINCODE = 7;
  22. private static final int ATWITHINCODE = 8;
  23. private static final int EXE_INIT_PREINIT = 9;
  24. private static final int CALL = 10;
  25. private static final int ANNOTATION = 11;
  26. private static final int THIS_OR_TARGET = 12;
  27. private static final int AT_THIS_OR_TARGET = 13;
  28. private static final int ARGS = 14;
  29. private static final int AT_ARGS = 15;
  30. private static final int CFLOW = 16;
  31. private static final int IF = 17;
  32. private static final int OTHER = 20;
  33. /**
  34. * Compare 2 pointcuts based on an estimate of how expensive they may be
  35. * to evaluate.
  36. *
  37. * within
  38. * @within
  39. * staticinitialization [make sure this has a fast match method]
  40. * adviceexecution
  41. * handler
  42. * get, set
  43. * withincode
  44. * @withincode
  45. * execution, initialization, preinitialization
  46. * call
  47. * @annotation
  48. * this, target
  49. * @this, @target
  50. * args
  51. * @args
  52. * cflow, cflowbelow
  53. * if
  54. */
  55. public int compare(Object o1, Object o2) {
  56. Pointcut p1 = (Pointcut) o1;
  57. Pointcut p2 = (Pointcut) o2;
  58. // important property for a well-defined comparator
  59. if (p1.equals(p2)) return 0;
  60. int result = getScore(p1) - getScore(p2);
  61. if (result == 0) {
  62. // they have the same evaluation expense, but are not 'equal'
  63. // sort by hashCode
  64. result = p1.hashCode() - p2.hashCode();
  65. if (result == 0) /*not allowed if ne*/ return -1;
  66. }
  67. return result;
  68. }
  69. // a higher score means a more expensive evaluation
  70. private int getScore(Pointcut p) {
  71. if (p.couldMatchKinds().isEmpty()) return MATCHES_NOTHING;
  72. if (p instanceof WithinPointcut) return WITHIN;
  73. if (p instanceof WithinAnnotationPointcut) return ATWITHIN;
  74. if (p instanceof KindedPointcut) {
  75. KindedPointcut kp = (KindedPointcut) p;
  76. Shadow.Kind kind = kp.getKind();
  77. if (kind == Shadow.AdviceExecution) {
  78. return ADVICEEXECUTION;
  79. } else if ((kind == Shadow.ConstructorCall) || (kind == Shadow.MethodCall)) {
  80. return CALL;
  81. } else if ((kind == Shadow.ConstructorExecution) || (kind == Shadow.MethodExecution) ||
  82. (kind == Shadow.Initialization) || (kind == Shadow.PreInitialization)) {
  83. return EXE_INIT_PREINIT;
  84. } else if (kind == Shadow.ExceptionHandler) {
  85. return HANDLER;
  86. } else if ((kind == Shadow.FieldGet) || (kind == Shadow.FieldSet)) {
  87. return GET_OR_SET;
  88. } else if (kind == Shadow.StaticInitialization) {
  89. return STATICINIT;
  90. } else return OTHER;
  91. }
  92. if (p instanceof AnnotationPointcut) return ANNOTATION;
  93. if (p instanceof ArgsPointcut) return ARGS;
  94. if (p instanceof ArgsAnnotationPointcut) return AT_ARGS;
  95. if (p instanceof CflowPointcut) return CFLOW;
  96. if (p instanceof HandlerPointcut) return HANDLER;
  97. if (p instanceof IfPointcut) return IF;
  98. if (p instanceof ThisOrTargetPointcut) return THIS_OR_TARGET;
  99. if (p instanceof ThisOrTargetAnnotationPointcut) return AT_THIS_OR_TARGET;
  100. if (p instanceof WithincodePointcut) return WITHINCODE;
  101. if (p instanceof WithinCodeAnnotationPointcut) return ATWITHINCODE;
  102. if (p instanceof NotPointcut) return getScore(((NotPointcut)p).getNegatedPointcut());
  103. if (p instanceof AndPointcut) return getScore(((AndPointcut)p).getLeft());
  104. if (p instanceof OrPointcut) return getScore(((OrPointcut)p).getLeft());
  105. return OTHER;
  106. }
  107. }