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 }
|