123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- /* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License v 2.0
- * which accompanies this distribution and is available at
- * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
- *
- * Contributors:
- * PARC initial implementation
- * ******************************************************************/
-
- package org.aspectj.weaver.patterns;
-
- import java.io.IOException;
-
- import org.aspectj.weaver.CompressingDataOutputStream;
- import org.aspectj.weaver.VersionedDataInputStream;
-
- public class NamePattern extends PatternNode {
- char[] pattern;
- int starCount = 0;
- private int hashcode = -1;
-
- public static final NamePattern ELLIPSIS = new NamePattern("");
- public static final NamePattern ANY = new NamePattern("*");
-
- public NamePattern(String name) {
- this(name.toCharArray());
- }
-
- public NamePattern(char[] pattern) {
- this.pattern = pattern;
-
- for (char c : pattern) {
- if (c == '*') {
- starCount++;
- }
- }
- hashcode = new String(pattern).hashCode();
- }
-
- public boolean matches(char[] a2) {
- char[] a1 = pattern;
- int len1 = a1.length;
- int len2 = a2.length;
- if (starCount == 0) {
- if (len1 != len2) {
- return false;
- }
- for (int i = 0; i < len1; i++) {
- if (a1[i] != a2[i]) {
- return false;
- }
- }
- return true;
- } else if (starCount == 1) {
- // just '*' matches anything
- if (len1 == 1) {
- return true;
- }
- if (len1 > len2 + 1) {
- return false;
- }
- int i2 = 0;
- for (int i1 = 0; i1 < len1; i1++) {
- char c1 = a1[i1];
- if (c1 == '*') {
- i2 = len2 - (len1 - (i1 + 1));
- } else if (c1 != a2[i2++]) {
- return false;
- }
- }
- return true;
- } else {
- // System.err.print("match(\"" + pattern + "\", \"" + target + "\") -> ");
- boolean b = outOfStar(a1, a2, 0, 0, len1 - starCount, len2, starCount);
- // System.err.println(b);
- return b;
- }
- }
-
- private static boolean outOfStar(final char[] pattern, final char[] target, int pi, int ti, int pLeft, int tLeft,
- final int starsLeft) {
- if (pLeft > tLeft) {
- return false;
- }
- while (true) {
- // invariant: if (tLeft > 0) then (ti < target.length && pi < pattern.length)
- if (tLeft == 0) {
- return true;
- }
- if (pLeft == 0) {
- return (starsLeft > 0);
- }
- if (pattern[pi] == '*') {
- return inStar(pattern, target, pi + 1, ti, pLeft, tLeft, starsLeft - 1);
- }
- if (target[ti] != pattern[pi]) {
- return false;
- }
- pi++;
- ti++;
- pLeft--;
- tLeft--;
- }
- }
-
- private static boolean inStar(final char[] pattern, final char[] target, int pi, int ti, final int pLeft, int tLeft,
- int starsLeft) {
- // invariant: pLeft > 0, so we know we'll run out of stars and find a real char in pattern
- char patternChar = pattern[pi];
- while (patternChar == '*') {
- starsLeft--;
- patternChar = pattern[++pi];
- }
- while (true) {
- // invariant: if (tLeft > 0) then (ti < target.length)
- if (pLeft > tLeft) {
- return false;
- }
- if (target[ti] == patternChar) {
- if (outOfStar(pattern, target, pi + 1, ti + 1, pLeft - 1, tLeft - 1, starsLeft)) {
- return true;
- }
- }
- ti++;
- tLeft--;
- }
- }
-
- public boolean matches(String other) {
- if (starCount == 1 && pattern.length == 1) {
- // optimize for wildcard
- return true;
- }
- return matches(other.toCharArray());
- }
-
- @Override
- public String toString() {
- return new String(pattern);
- }
-
- @Override
- public boolean equals(Object other) {
- if (other instanceof NamePattern) {
- NamePattern otherPat = (NamePattern) other;
- if (otherPat.starCount != this.starCount) {
- return false;
- }
- if (otherPat.pattern.length != this.pattern.length) {
- return false;
- }
- for (int i = 0; i < this.pattern.length; i++) {
- if (this.pattern[i] != otherPat.pattern[i]) {
- return false;
- }
- }
- return true;
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return hashcode;
- }
-
- @Override
- public void write(CompressingDataOutputStream out) throws IOException {
- out.writeUTF(new String(pattern));
- }
-
- public static NamePattern read(VersionedDataInputStream in) throws IOException {
- String s = in.readUTF();
- if (s.length() == 0) {
- return ELLIPSIS;
- }
- return new NamePattern(s);
- }
-
- /**
- * Method maybeGetSimpleName.
- *
- * @return String
- */
- public String maybeGetSimpleName() {
- if (starCount == 0 && pattern.length > 0) {
- return new String(pattern);
- }
- return null;
- }
-
- /**
- * Method isAny.
- *
- * @return boolean
- */
- public boolean isAny() {
- return starCount == 1 && pattern.length == 1;
- }
-
- @Override
- public Object accept(PatternNodeVisitor visitor, Object data) {
- return visitor.visit(this, data);
- }
- }
|