You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

NamePattern.java 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v 2.0
  6. * which accompanies this distribution and is available at
  7. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver.patterns;
  13. import java.io.IOException;
  14. import org.aspectj.weaver.CompressingDataOutputStream;
  15. import org.aspectj.weaver.VersionedDataInputStream;
  16. public class NamePattern extends PatternNode {
  17. char[] pattern;
  18. int starCount = 0;
  19. private int hashcode = -1;
  20. public static final NamePattern ELLIPSIS = new NamePattern("");
  21. public static final NamePattern ANY = new NamePattern("*");
  22. public NamePattern(String name) {
  23. this(name.toCharArray());
  24. }
  25. public NamePattern(char[] pattern) {
  26. this.pattern = pattern;
  27. for (char c : pattern) {
  28. if (c == '*') {
  29. starCount++;
  30. }
  31. }
  32. hashcode = new String(pattern).hashCode();
  33. }
  34. public boolean matches(char[] a2) {
  35. char[] a1 = pattern;
  36. int len1 = a1.length;
  37. int len2 = a2.length;
  38. if (starCount == 0) {
  39. if (len1 != len2) {
  40. return false;
  41. }
  42. for (int i = 0; i < len1; i++) {
  43. if (a1[i] != a2[i]) {
  44. return false;
  45. }
  46. }
  47. return true;
  48. } else if (starCount == 1) {
  49. // just '*' matches anything
  50. if (len1 == 1) {
  51. return true;
  52. }
  53. if (len1 > len2 + 1) {
  54. return false;
  55. }
  56. int i2 = 0;
  57. for (int i1 = 0; i1 < len1; i1++) {
  58. char c1 = a1[i1];
  59. if (c1 == '*') {
  60. i2 = len2 - (len1 - (i1 + 1));
  61. } else if (c1 != a2[i2++]) {
  62. return false;
  63. }
  64. }
  65. return true;
  66. } else {
  67. // System.err.print("match(\"" + pattern + "\", \"" + target + "\") -> ");
  68. boolean b = outOfStar(a1, a2, 0, 0, len1 - starCount, len2, starCount);
  69. // System.err.println(b);
  70. return b;
  71. }
  72. }
  73. private static boolean outOfStar(final char[] pattern, final char[] target, int pi, int ti, int pLeft, int tLeft,
  74. final int starsLeft) {
  75. if (pLeft > tLeft) {
  76. return false;
  77. }
  78. while (true) {
  79. // invariant: if (tLeft > 0) then (ti < target.length && pi < pattern.length)
  80. if (tLeft == 0) {
  81. return true;
  82. }
  83. if (pLeft == 0) {
  84. return (starsLeft > 0);
  85. }
  86. if (pattern[pi] == '*') {
  87. return inStar(pattern, target, pi + 1, ti, pLeft, tLeft, starsLeft - 1);
  88. }
  89. if (target[ti] != pattern[pi]) {
  90. return false;
  91. }
  92. pi++;
  93. ti++;
  94. pLeft--;
  95. tLeft--;
  96. }
  97. }
  98. private static boolean inStar(final char[] pattern, final char[] target, int pi, int ti, final int pLeft, int tLeft,
  99. int starsLeft) {
  100. // invariant: pLeft > 0, so we know we'll run out of stars and find a real char in pattern
  101. char patternChar = pattern[pi];
  102. while (patternChar == '*') {
  103. starsLeft--;
  104. patternChar = pattern[++pi];
  105. }
  106. while (true) {
  107. // invariant: if (tLeft > 0) then (ti < target.length)
  108. if (pLeft > tLeft) {
  109. return false;
  110. }
  111. if (target[ti] == patternChar) {
  112. if (outOfStar(pattern, target, pi + 1, ti + 1, pLeft - 1, tLeft - 1, starsLeft)) {
  113. return true;
  114. }
  115. }
  116. ti++;
  117. tLeft--;
  118. }
  119. }
  120. public boolean matches(String other) {
  121. if (starCount == 1 && pattern.length == 1) {
  122. // optimize for wildcard
  123. return true;
  124. }
  125. return matches(other.toCharArray());
  126. }
  127. @Override
  128. public String toString() {
  129. return new String(pattern);
  130. }
  131. @Override
  132. public boolean equals(Object other) {
  133. if (other instanceof NamePattern) {
  134. NamePattern otherPat = (NamePattern) other;
  135. if (otherPat.starCount != this.starCount) {
  136. return false;
  137. }
  138. if (otherPat.pattern.length != this.pattern.length) {
  139. return false;
  140. }
  141. for (int i = 0; i < this.pattern.length; i++) {
  142. if (this.pattern[i] != otherPat.pattern[i]) {
  143. return false;
  144. }
  145. }
  146. return true;
  147. }
  148. return false;
  149. }
  150. @Override
  151. public int hashCode() {
  152. return hashcode;
  153. }
  154. @Override
  155. public void write(CompressingDataOutputStream out) throws IOException {
  156. out.writeUTF(new String(pattern));
  157. }
  158. public static NamePattern read(VersionedDataInputStream in) throws IOException {
  159. String s = in.readUTF();
  160. if (s.length() == 0) {
  161. return ELLIPSIS;
  162. }
  163. return new NamePattern(s);
  164. }
  165. /**
  166. * Method maybeGetSimpleName.
  167. *
  168. * @return String
  169. */
  170. public String maybeGetSimpleName() {
  171. if (starCount == 0 && pattern.length > 0) {
  172. return new String(pattern);
  173. }
  174. return null;
  175. }
  176. /**
  177. * Method isAny.
  178. *
  179. * @return boolean
  180. */
  181. public boolean isAny() {
  182. return starCount == 1 && pattern.length == 1;
  183. }
  184. @Override
  185. public Object accept(PatternNodeVisitor visitor, Object data) {
  186. return visitor.visit(this, data);
  187. }
  188. }