1b8cf1e5f607a5aaf09c904703a269ea7979781adcrazyboblee/**
2b8cf1e5f607a5aaf09c904703a269ea7979781adcrazyboblee * Copyright (C) 2006 Google Inc.
3b8cf1e5f607a5aaf09c904703a269ea7979781adcrazyboblee *
4b8cf1e5f607a5aaf09c904703a269ea7979781adcrazyboblee * Licensed under the Apache License, Version 2.0 (the "License");
5b8cf1e5f607a5aaf09c904703a269ea7979781adcrazyboblee * you may not use this file except in compliance with the License.
6b8cf1e5f607a5aaf09c904703a269ea7979781adcrazyboblee * You may obtain a copy of the License at
7b8cf1e5f607a5aaf09c904703a269ea7979781adcrazyboblee *
8b8cf1e5f607a5aaf09c904703a269ea7979781adcrazyboblee * http://www.apache.org/licenses/LICENSE-2.0
9b8cf1e5f607a5aaf09c904703a269ea7979781adcrazyboblee *
10b8cf1e5f607a5aaf09c904703a269ea7979781adcrazyboblee * Unless required by applicable law or agreed to in writing, software
11b8cf1e5f607a5aaf09c904703a269ea7979781adcrazyboblee * distributed under the License is distributed on an "AS IS" BASIS,
12b8cf1e5f607a5aaf09c904703a269ea7979781adcrazyboblee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b8cf1e5f607a5aaf09c904703a269ea7979781adcrazyboblee * See the License for the specific language governing permissions and
14b8cf1e5f607a5aaf09c904703a269ea7979781adcrazyboblee * limitations under the License.
15b8cf1e5f607a5aaf09c904703a269ea7979781adcrazyboblee */
162008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee
174f79e4007e8b08ccfb3a76ec0fb57ec413046304crazybobleepackage com.google.inject.matcher;
182008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee
19d9c913acca55023ef5d76a32c3d4a51ee6b420cbsberlinimport static com.google.common.base.Preconditions.checkArgument;
20d9c913acca55023ef5d76a32c3d4a51ee6b420cbsberlinimport static com.google.common.base.Preconditions.checkNotNull;
21b7a02b02d81c830d148355c90bc309bcd66fb592sberlin
22eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkitimport java.io.Serializable;
232008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazybobleeimport java.lang.annotation.Annotation;
24ade7be4cc85c534adce75692ae2988f056463d2bkevinbimport java.lang.annotation.Retention;
25ade7be4cc85c534adce75692ae2988f056463d2bkevinbimport java.lang.annotation.RetentionPolicy;
262008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazybobleeimport java.lang.reflect.AnnotatedElement;
2707bd1593837be3d851cbc55cdb0e12c00bdb129ecrazybobleeimport java.lang.reflect.Method;
282008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee
292008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee/**
3033ce069dc927d72483b25aa1c4265fdc9251fc32crazyboblee * Matcher implementations. Supports matching classes and methods.
312008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee *
322008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee * @author crazybob@google.com (Bob Lee)
332008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee */
3433ce069dc927d72483b25aa1c4265fdc9251fc32crazybobleepublic class Matchers {
3533ce069dc927d72483b25aa1c4265fdc9251fc32crazyboblee  private Matchers() {}
362008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee
37eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  /**
38eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit   * Returns a matcher which matches any input.
39eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit   */
40eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  public static Matcher<Object> any() {
41eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    return ANY;
42eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  }
43eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
44eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  private static final Matcher<Object> ANY = new Any();
45eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
46eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  private static class Any extends AbstractMatcher<Object> implements Serializable {
472008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee    public boolean matches(Object o) {
482008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee      return true;
492008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee    }
5007bd1593837be3d851cbc55cdb0e12c00bdb129ecrazyboblee
51eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public String toString() {
5207bd1593837be3d851cbc55cdb0e12c00bdb129ecrazyboblee      return "any()";
5307bd1593837be3d851cbc55cdb0e12c00bdb129ecrazyboblee    }
542008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee
55eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public Object readResolve() {
56eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return any();
57eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
58b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit
59b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit    private static final long serialVersionUID = 0;
602008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee  }
612008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee
622008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee  /**
6333ce069dc927d72483b25aa1c4265fdc9251fc32crazyboblee   * Inverts the given matcher.
642008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee   */
6533ce069dc927d72483b25aa1c4265fdc9251fc32crazyboblee  public static <T> Matcher<T> not(final Matcher<? super T> p) {
66eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    return new Not<T>(p);
67eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  }
68eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
69eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  private static class Not<T> extends AbstractMatcher<T> implements Serializable {
70eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    final Matcher<? super T> delegate;
7107bd1593837be3d851cbc55cdb0e12c00bdb129ecrazyboblee
72eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    private Not(Matcher<? super T> delegate) {
731601ae5cc3d7931d4ce4b78e0b493acdd6132ff1kevinb      this.delegate = checkNotNull(delegate, "delegate");
74eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
75eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
76eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public boolean matches(T t) {
77eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return !delegate.matches(t);
78eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
79eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
80eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public boolean equals(Object other) {
81eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return other instanceof Not
82eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit          && ((Not) other).delegate.equals(delegate);
83eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
84eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
85eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public int hashCode() {
86eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return -delegate.hashCode();
87eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
88eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
89eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public String toString() {
90eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return "not(" + delegate + ")";
91eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
92b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit
93b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit    private static final long serialVersionUID = 0;
942008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee  }
952008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee
96ade7be4cc85c534adce75692ae2988f056463d2bkevinb  private static void checkForRuntimeRetention(
97ade7be4cc85c534adce75692ae2988f056463d2bkevinb      Class<? extends Annotation> annotationType) {
98ade7be4cc85c534adce75692ae2988f056463d2bkevinb    Retention retention = annotationType.getAnnotation(Retention.class);
9932beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit    checkArgument(retention != null && retention.value() == RetentionPolicy.RUNTIME,
100c00df28be8bfa45b2bdc8b4d3c101c20a9cbdc12Sam Berlin        "Annotation %s is missing RUNTIME retention", annotationType.getSimpleName());
101ade7be4cc85c534adce75692ae2988f056463d2bkevinb  }
102ade7be4cc85c534adce75692ae2988f056463d2bkevinb
1032008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee  /**
10433ce069dc927d72483b25aa1c4265fdc9251fc32crazyboblee   * Returns a matcher which matches elements (methods, classes, etc.)
1052008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee   * with a given annotation.
1062008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee   */
10733ce069dc927d72483b25aa1c4265fdc9251fc32crazyboblee  public static Matcher<AnnotatedElement> annotatedWith(
1082008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee      final Class<? extends Annotation> annotationType) {
109eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    return new AnnotatedWithType(annotationType);
110eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  }
111eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
112eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  private static class AnnotatedWithType extends AbstractMatcher<AnnotatedElement>
113eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      implements Serializable {
114eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    private final Class<? extends Annotation> annotationType;
115eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
116eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public AnnotatedWithType(Class<? extends Annotation> annotationType) {
1171601ae5cc3d7931d4ce4b78e0b493acdd6132ff1kevinb      this.annotationType = checkNotNull(annotationType, "annotation type");
118eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      checkForRuntimeRetention(annotationType);
119eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
120eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
121eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public boolean matches(AnnotatedElement element) {
122c00df28be8bfa45b2bdc8b4d3c101c20a9cbdc12Sam Berlin      return element.isAnnotationPresent(annotationType);
123eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
124eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
125eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public boolean equals(Object other) {
126eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return other instanceof AnnotatedWithType
127eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit          && ((AnnotatedWithType) other).annotationType.equals(annotationType);
128eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
129eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
130eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public int hashCode() {
131eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return 37 * annotationType.hashCode();
132eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
13307bd1593837be3d851cbc55cdb0e12c00bdb129ecrazyboblee
134eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public String toString() {
135eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return "annotatedWith(" + annotationType.getSimpleName() + ".class)";
136eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
137b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit
138b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit    private static final long serialVersionUID = 0;
1392008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee  }
1402008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee
1412008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee  /**
142be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee   * Returns a matcher which matches elements (methods, classes, etc.)
143be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee   * with a given annotation.
144be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee   */
145be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee  public static Matcher<AnnotatedElement> annotatedWith(
146be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee      final Annotation annotation) {
147eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    return new AnnotatedWith(annotation);
148eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  }
149eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
150eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  private static class AnnotatedWith extends AbstractMatcher<AnnotatedElement>
151eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      implements Serializable {
152eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    private final Annotation annotation;
153be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee
154eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public AnnotatedWith(Annotation annotation) {
1551601ae5cc3d7931d4ce4b78e0b493acdd6132ff1kevinb      this.annotation = checkNotNull(annotation, "annotation");
156eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      checkForRuntimeRetention(annotation.annotationType());
157eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
158eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
159eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public boolean matches(AnnotatedElement element) {
160eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      Annotation fromElement = element.getAnnotation(annotation.annotationType());
161eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return fromElement != null && annotation.equals(fromElement);
162eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
163eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
164eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public boolean equals(Object other) {
165eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return other instanceof AnnotatedWith
166eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit          && ((AnnotatedWith) other).annotation.equals(annotation);
167eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
168eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
169eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public int hashCode() {
170eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return 37 * annotation.hashCode();
171eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
172eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
173eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public String toString() {
174eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return "annotatedWith(" + annotation + ")";
175eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
176b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit
177b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit    private static final long serialVersionUID = 0;
178be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee  }
179be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee
180be2a67fab538548f580477d8a6aca41297fe083ccrazyboblee  /**
18133ce069dc927d72483b25aa1c4265fdc9251fc32crazyboblee   * Returns a matcher which matches subclasses of the given type (as well as
18207bd1593837be3d851cbc55cdb0e12c00bdb129ecrazyboblee   * the given type).
1832008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee   */
18433ce069dc927d72483b25aa1c4265fdc9251fc32crazyboblee  public static Matcher<Class> subclassesOf(final Class<?> superclass) {
185eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    return new SubclassesOf(superclass);
186eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  }
187eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
188eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  private static class SubclassesOf extends AbstractMatcher<Class>
189eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      implements Serializable {
190eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    private final Class<?> superclass;
191eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
192eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public SubclassesOf(Class<?> superclass) {
1931601ae5cc3d7931d4ce4b78e0b493acdd6132ff1kevinb      this.superclass = checkNotNull(superclass, "superclass");
194eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
195eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
196eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public boolean matches(Class subclass) {
197eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return superclass.isAssignableFrom(subclass);
198eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
199eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
200eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public boolean equals(Object other) {
201eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return other instanceof SubclassesOf
202eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit          && ((SubclassesOf) other).superclass.equals(superclass);
203eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
20407bd1593837be3d851cbc55cdb0e12c00bdb129ecrazyboblee
205eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public int hashCode() {
206eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return 37 * superclass.hashCode();
207eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
208eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
209eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public String toString() {
210eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return "subclassesOf(" + superclass.getSimpleName() + ".class)";
211eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
212b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit
213b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit    private static final long serialVersionUID = 0;
2142008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee  }
2152008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee
2162008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee  /**
21733ce069dc927d72483b25aa1c4265fdc9251fc32crazyboblee   * Returns a matcher which matches objects equal to the given object.
2182008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee   */
219eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  public static Matcher<Object> only(Object value) {
220eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    return new Only(value);
221eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  }
222eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
223eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  private static class Only extends AbstractMatcher<Object>
224eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      implements Serializable {
225eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    private final Object value;
226eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
227eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public Only(Object value) {
2281601ae5cc3d7931d4ce4b78e0b493acdd6132ff1kevinb      this.value = checkNotNull(value, "value");
229eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
230eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
231eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public boolean matches(Object other) {
232eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return value.equals(other);
233eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
234eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
235eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public boolean equals(Object other) {
236eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return other instanceof Only
237eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit          && ((Only) other).value.equals(value);
238eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
23907bd1593837be3d851cbc55cdb0e12c00bdb129ecrazyboblee
240eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public int hashCode() {
241eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return 37 * value.hashCode();
242eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
243eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
244eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public String toString() {
245eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return "only(" + value + ")";
246eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
247b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit
248b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit    private static final long serialVersionUID = 0;
2492008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee  }
2502008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee
2512008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee  /**
25233ce069dc927d72483b25aa1c4265fdc9251fc32crazyboblee   * Returns a matcher which matches only the given object.
2532008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee   */
254eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  public static Matcher<Object> identicalTo(final Object value) {
255eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    return new IdenticalTo(value);
256eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  }
257eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
258eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  private static class IdenticalTo extends AbstractMatcher<Object>
259eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      implements Serializable {
260eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    private final Object value;
261eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
262eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public IdenticalTo(Object value) {
2631601ae5cc3d7931d4ce4b78e0b493acdd6132ff1kevinb      this.value = checkNotNull(value, "value");
264eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
265eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
266eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public boolean matches(Object other) {
267eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return value == other;
268eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
269eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
270eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public boolean equals(Object other) {
271eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return other instanceof IdenticalTo
272eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit          && ((IdenticalTo) other).value == value;
273eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
274eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
275eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public int hashCode() {
276eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return 37 * System.identityHashCode(value);
277eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
27807bd1593837be3d851cbc55cdb0e12c00bdb129ecrazyboblee
279eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public String toString() {
280eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return "identicalTo(" + value + ")";
281eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
282b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit
283b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit    private static final long serialVersionUID = 0;
2842008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee  }
2852008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee
2862008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee  /**
28732beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit   * Returns a matcher which matches classes in the given package. Packages are specific to their
28832beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit   * classloader, so classes with the same package name may not have the same package at runtime.
2892008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee   */
290eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  public static Matcher<Class> inPackage(final Package targetPackage) {
291eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    return new InPackage(targetPackage);
292eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  }
293eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
294eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  private static class InPackage extends AbstractMatcher<Class> implements Serializable {
295eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    private final transient Package targetPackage;
296eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    private final String packageName;
297eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
298eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public InPackage(Package targetPackage) {
2991601ae5cc3d7931d4ce4b78e0b493acdd6132ff1kevinb      this.targetPackage = checkNotNull(targetPackage, "package");
300eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      this.packageName = targetPackage.getName();
301eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
302eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
303eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public boolean matches(Class c) {
304eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return c.getPackage().equals(targetPackage);
305eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
30607bd1593837be3d851cbc55cdb0e12c00bdb129ecrazyboblee
307eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public boolean equals(Object other) {
308eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return other instanceof InPackage
309eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit          && ((InPackage) other).targetPackage.equals(targetPackage);
310eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
311eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
312eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public int hashCode() {
313eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return 37 * targetPackage.hashCode();
314eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
315eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
316eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public String toString() {
317f530b2542e7a93416b392f598c90b018d0f38991limpbizkit      return "inPackage(" + targetPackage.getName() + ")";
318eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
319eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
320eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public Object readResolve() {
321eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return inPackage(Package.getPackage(packageName));
322eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
323b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit
324b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit    private static final long serialVersionUID = 0;
3252008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee  }
3262008ec7e532ae11c1b52f62b02a98e9f6ee00ac8crazyboblee
32707bd1593837be3d851cbc55cdb0e12c00bdb129ecrazyboblee  /**
32832beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit   * Returns a matcher which matches classes in the given package and its subpackages. Unlike
32932beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit   * {@link #inPackage(Package) inPackage()}, this matches classes from any classloader.
330c489adf4671b41765698d167e13960d998190c5elimpbizkit   *
331c489adf4671b41765698d167e13960d998190c5elimpbizkit   * @since 2.0
33232beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit   */
33332beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit  public static Matcher<Class> inSubpackage(final String targetPackageName) {
33432beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit    return new InSubpackage(targetPackageName);
33532beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit  }
33632beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit
33732beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit  private static class InSubpackage extends AbstractMatcher<Class> implements Serializable {
33832beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit    private final String targetPackageName;
33932beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit
34032beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit    public InSubpackage(String targetPackageName) {
34132beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit      this.targetPackageName = targetPackageName;
34232beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit    }
34332beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit
34432beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit    public boolean matches(Class c) {
34532beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit      String classPackageName = c.getPackage().getName();
34632beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit      return classPackageName.equals(targetPackageName)
34732beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit          || classPackageName.startsWith(targetPackageName + ".");
34832beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit    }
34932beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit
35032beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit    @Override public boolean equals(Object other) {
35132beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit      return other instanceof InSubpackage
35232beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit          && ((InSubpackage) other).targetPackageName.equals(targetPackageName);
35332beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit    }
35432beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit
35532beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit    @Override public int hashCode() {
35632beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit      return 37 * targetPackageName.hashCode();
35732beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit    }
35832beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit
35932beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit    @Override public String toString() {
36032beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit      return "inSubpackage(" + targetPackageName + ")";
36132beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit    }
362b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit
363b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit    private static final long serialVersionUID = 0;
36432beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit  }
36532beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit
36632beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit  /**
36733ce069dc927d72483b25aa1c4265fdc9251fc32crazyboblee   * Returns a matcher which matches methods with matching return types.
36807bd1593837be3d851cbc55cdb0e12c00bdb129ecrazyboblee   */
36933ce069dc927d72483b25aa1c4265fdc9251fc32crazyboblee  public static Matcher<Method> returns(
37033ce069dc927d72483b25aa1c4265fdc9251fc32crazyboblee      final Matcher<? super Class<?>> returnType) {
371eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    return new Returns(returnType);
372eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  }
373eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
374eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  private static class Returns extends AbstractMatcher<Method> implements Serializable {
375eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    private final Matcher<? super Class<?>> returnType;
376eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
377eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public Returns(Matcher<? super Class<?>> returnType) {
3781601ae5cc3d7931d4ce4b78e0b493acdd6132ff1kevinb      this.returnType = checkNotNull(returnType, "return type matcher");
379eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
380eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
381eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    public boolean matches(Method m) {
382eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return returnType.matches(m.getReturnType());
383eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
384eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
385eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public boolean equals(Object other) {
386eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return other instanceof Returns
387eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit          && ((Returns) other).returnType.equals(returnType);
388eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
389eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
390eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public int hashCode() {
391eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return 37 * returnType.hashCode();
392eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
393eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit
394eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    @Override public String toString() {
395eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit      return "returns(" + returnType + ")";
396eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit    }
397b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit
398b3a8f0bda3259af41e639f1872c42377989704d9limpbizkit    private static final long serialVersionUID = 0;
399eab76471fbc2118a3c07d103d4b5548e153ed9e7limpbizkit  }
40032beee6de35ef77d1d2018e699cbca13a778ebf0limpbizkit}
401