001: /*
002: * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package javax.lang.model.util;
027:
028: import java.lang.Iterable;
029: import java.util.Collections;
030: import java.util.Iterator;
031: import java.util.List;
032: import java.util.Set;
033: import java.util.EnumSet;
034: import java.util.ArrayList;
035: import java.util.LinkedHashSet;
036: import java.util.NoSuchElementException;
037:
038: import javax.lang.model.element.*;
039: import javax.lang.model.type.*;
040:
041: /**
042: * Filters for selecting just the elements of interest from a
043: * collection of elements. The returned sets and lists are new
044: * collections and do use the argument as a backing store. The
045: * methods in this class do not make any attempts to guard against
046: * concurrent modifications of the arguments. The returned sets and
047: * lists are mutable but unsafe for concurrent access. A returned set
048: * has the same iteration order as the argument set to a method.
049: *
050: * <p>If iterables and sets containing {@code null} are passed as
051: * arguments to methods in this class, a {@code NullPointerException}
052: * will be thrown.
053: *
054: * <p>Note that a <i>static import</i> statement can make the text of
055: * calls to the methods in this class more concise; for example:
056: *
057: * <blockquote><pre>
058: * import static javax.lang.model.util.ElementFilter.*;
059: * ...
060: * {@code List<VariableElement>} fs = fieldsIn(someClass.getEnclosedElements());
061: * </pre></blockquote>
062: *
063: * @author Joseph D. Darcy
064: * @author Scott Seligman
065: * @author Peter von der Ahé
066: * @author Martin Buchholz
067: * @version 1.12 07/05/05
068: * @since 1.6
069: */
070: public class ElementFilter {
071: private ElementFilter() {
072: } // Do not instantiate.
073:
074: private static Set<ElementKind> CONSTRUCTOR_KIND = Collections
075: .unmodifiableSet(EnumSet.of(ElementKind.CONSTRUCTOR));
076:
077: private static Set<ElementKind> FIELD_KINDS = Collections
078: .unmodifiableSet(EnumSet.of(ElementKind.FIELD,
079: ElementKind.ENUM_CONSTANT));
080: private static Set<ElementKind> METHOD_KIND = Collections
081: .unmodifiableSet(EnumSet.of(ElementKind.METHOD));
082:
083: private static Set<ElementKind> PACKAGE_KIND = Collections
084: .unmodifiableSet(EnumSet.of(ElementKind.PACKAGE));
085:
086: private static Set<ElementKind> TYPE_KINDS = Collections
087: .unmodifiableSet(EnumSet.of(ElementKind.CLASS,
088: ElementKind.ENUM, ElementKind.INTERFACE,
089: ElementKind.ANNOTATION_TYPE));
090:
091: /**
092: * Returns a list of fields in {@code elements}.
093: * @return a list of fields in {@code elements}
094: * @param elements the elements to filter
095: */
096: public static List<VariableElement> fieldsIn(
097: Iterable<? extends Element> elements) {
098: return listFilter(elements, FIELD_KINDS, VariableElement.class);
099: }
100:
101: /**
102: * Returns a set of fields in {@code elements}.
103: * @return a set of fields in {@code elements}
104: * @param elements the elements to filter
105: */
106: public static Set<VariableElement> fieldsIn(
107: Set<? extends Element> elements) {
108: return setFilter(elements, FIELD_KINDS, VariableElement.class);
109: }
110:
111: /**
112: * Returns a list of constructors in {@code elements}.
113: * @return a list of constructors in {@code elements}
114: * @param elements the elements to filter
115: */
116: public static List<ExecutableElement> constructorsIn(
117: Iterable<? extends Element> elements) {
118: return listFilter(elements, CONSTRUCTOR_KIND,
119: ExecutableElement.class);
120: }
121:
122: /**
123: * Returns a set of constructors in {@code elements}.
124: * @return a set of constructors in {@code elements}
125: * @param elements the elements to filter
126: */
127: public static Set<ExecutableElement> constructorsIn(
128: Set<? extends Element> elements) {
129: return setFilter(elements, CONSTRUCTOR_KIND,
130: ExecutableElement.class);
131: }
132:
133: /**
134: * Returns a list of methods in {@code elements}.
135: * @return a list of methods in {@code elements}
136: * @param elements the elements to filter
137: */
138: public static List<ExecutableElement> methodsIn(
139: Iterable<? extends Element> elements) {
140: return listFilter(elements, METHOD_KIND,
141: ExecutableElement.class);
142: }
143:
144: /**
145: * Returns a set of methods in {@code elements}.
146: * @return a set of methods in {@code elements}
147: * @param elements the elements to filter
148: */
149: public static Set<ExecutableElement> methodsIn(
150: Set<? extends Element> elements) {
151: return setFilter(elements, METHOD_KIND, ExecutableElement.class);
152: }
153:
154: /**
155: * Returns a list of types in {@code elements}.
156: * @return a list of types in {@code elements}
157: * @param elements the elements to filter
158: */
159: public static List<TypeElement> typesIn(
160: Iterable<? extends Element> elements) {
161: return listFilter(elements, TYPE_KINDS, TypeElement.class);
162: }
163:
164: /**
165: * Returns a set of types in {@code elements}.
166: * @return a set of types in {@code elements}
167: * @param elements the elements to filter
168: */
169: public static Set<TypeElement> typesIn(
170: Set<? extends Element> elements) {
171: return setFilter(elements, TYPE_KINDS, TypeElement.class);
172: }
173:
174: /**
175: * Returns a list of packages in {@code elements}.
176: * @return a list of packages in {@code elements}
177: * @param elements the elements to filter
178: */
179: public static List<PackageElement> packagesIn(
180: Iterable<? extends Element> elements) {
181: return listFilter(elements, PACKAGE_KIND, PackageElement.class);
182: }
183:
184: /**
185: * Returns a set of packages in {@code elements}.
186: * @return a set of packages in {@code elements}
187: * @param elements the elements to filter
188: */
189: public static Set<PackageElement> packagesIn(
190: Set<? extends Element> elements) {
191: return setFilter(elements, PACKAGE_KIND, PackageElement.class);
192: }
193:
194: // Assumes targetKinds and E are sensible.
195: private static <E extends Element> List<E> listFilter(
196: Iterable<? extends Element> elements,
197: Set<ElementKind> targetKinds, Class<E> clazz) {
198: List<E> list = new ArrayList<E>();
199: for (Element e : elements) {
200: if (targetKinds.contains(e.getKind()))
201: list.add(clazz.cast(e));
202: }
203: return list;
204: }
205:
206: // Assumes targetKinds and E are sensible.
207: private static <E extends Element> Set<E> setFilter(
208: Set<? extends Element> elements,
209: Set<ElementKind> targetKinds, Class<E> clazz) {
210: // Return set preserving iteration order of input set.
211: Set<E> set = new LinkedHashSet<E>();
212: for (Element e : elements) {
213: if (targetKinds.contains(e.getKind()))
214: set.add(clazz.cast(e));
215: }
216: return set;
217: }
218: }
|