langtools/src/share/classes/com/sun/mirror/util/DeclarationFilter.java
changeset 11914 d1311b0c757f
parent 11913 be61e1597cc6
parent 11872 c51754cddc03
child 11915 33f703959597
child 11986 6f383069eb6d
equal deleted inserted replaced
11913:be61e1597cc6 11914:d1311b0c757f
     1 /*
       
     2  * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package com.sun.mirror.util;
       
    27 
       
    28 
       
    29 import java.util.ArrayList;
       
    30 import java.util.Collection;
       
    31 
       
    32 import com.sun.mirror.declaration.Declaration;
       
    33 import com.sun.mirror.declaration.Modifier;
       
    34 
       
    35 import static com.sun.mirror.declaration.Modifier.*;
       
    36 
       
    37 
       
    38 /**
       
    39  * A filter for selecting just the items of interest
       
    40  * from a collection of declarations.
       
    41  * The filter is said to <i>select</i> or to <i>match</i> those declarations.
       
    42  * Filters can be created in several ways:
       
    43  * by the static methods described below,
       
    44  * by negating or composing existing filters,
       
    45  * or by subclasses that implement arbitrary matching rules.
       
    46  *
       
    47  * <p> A subclass can create an arbitrary filter simply by implementing
       
    48  * the {@link #matches(Declaration)} method.
       
    49  *
       
    50  * <p> Examples.
       
    51  * <p> Selecting the <tt>public</tt> declarations from a collection:
       
    52  * <blockquote><pre>
       
    53  *     result = FILTER_PUBLIC.filter(decls);            </pre></blockquote>
       
    54  * Selecting class declarations (including enums):
       
    55  * <blockquote><pre>
       
    56  *     classFilter = DeclarationFilter.getFilter(ClassDeclaration.class);
       
    57  *     result = classFilter.filter(decls);              </pre></blockquote>
       
    58  * Selecting class declarations but excluding enums:
       
    59  * <blockquote><pre>
       
    60  *     enumFilter = DeclarationFilter.getFilter(EnumDeclaration.class);
       
    61  *     compoundFilter = classFilter.and(enumFilter.not());
       
    62  *     result = compoundFilter.filter(decls);           </pre></blockquote>
       
    63  * Selecting declarations named "Bob":
       
    64  * <blockquote><pre>
       
    65  *     nameFilter = new DeclarationFilter() {
       
    66  *                      public boolean matches(Declaration d) {
       
    67  *                          return d.getSimpleName().equals("Bob");
       
    68  *                      }
       
    69  *                  };
       
    70  *     result = nameFilter.filter(decls);               </pre></blockquote>
       
    71  *
       
    72  * @deprecated All components of this API have been superseded by the
       
    73  * standardized annotation processing API.  The replacement for the
       
    74  * functionality of this class is {@link
       
    75  * javax.lang.model.util.ElementFilter}.
       
    76  *
       
    77  * @author Joseph D. Darcy
       
    78  * @author Scott Seligman
       
    79  * @since 1.5
       
    80  */
       
    81 @Deprecated
       
    82 @SuppressWarnings("deprecation")
       
    83 public class DeclarationFilter {
       
    84 
       
    85     // Predefined filters for convenience.
       
    86 
       
    87     /**
       
    88      * A filter that selects only <tt>public</tt> declarations.
       
    89      */
       
    90     public static final DeclarationFilter FILTER_PUBLIC =
       
    91             new AccessFilter(PUBLIC);
       
    92 
       
    93     /**
       
    94      * A filter that selects only <tt>protected</tt> declarations.
       
    95      */
       
    96     public static final DeclarationFilter FILTER_PROTECTED =
       
    97             new AccessFilter(PROTECTED);
       
    98 
       
    99     /**
       
   100      * A filter that selects only <tt>public</tt> or <tt>protected</tt>
       
   101      * declarations.
       
   102      */
       
   103     public static final DeclarationFilter FILTER_PUBLIC_OR_PROTECTED =
       
   104             new AccessFilter(PUBLIC, PROTECTED);
       
   105 
       
   106     /**
       
   107      * A filter that selects only package-private (<i>default</i>)
       
   108      * declarations.
       
   109      */
       
   110     public static final DeclarationFilter FILTER_PACKAGE =
       
   111             new AccessFilter();
       
   112 
       
   113     /**
       
   114      * A filter that selects only <tt>private</tt> declarations.
       
   115      */
       
   116     public static final DeclarationFilter FILTER_PRIVATE =
       
   117             new AccessFilter(PRIVATE);
       
   118 
       
   119 
       
   120     /**
       
   121      * Constructs an identity filter:  one that selects all declarations.
       
   122      */
       
   123     public DeclarationFilter() {
       
   124     }
       
   125 
       
   126 
       
   127 
       
   128     // Methods to create a filter.
       
   129 
       
   130     /**
       
   131      * Returns a filter that selects declarations containing all of a
       
   132      * collection of modifiers.
       
   133      *
       
   134      * @param mods  the modifiers to match (non-null)
       
   135      * @return a filter that matches declarations containing <tt>mods</tt>
       
   136      */
       
   137     public static DeclarationFilter getFilter(
       
   138                                              final Collection<Modifier> mods) {
       
   139         return new DeclarationFilter() {
       
   140             public boolean matches(Declaration d) {
       
   141                 return d.getModifiers().containsAll(mods);
       
   142             }
       
   143         };
       
   144     }
       
   145 
       
   146     /**
       
   147      * Returns a filter that selects declarations of a particular kind.
       
   148      * For example, there may be a filter that selects only class
       
   149      * declarations, or only fields.
       
   150      * The filter will select declarations of the specified kind,
       
   151      * and also any subtypes of that kind; for example, a field filter
       
   152      * will also select enum constants.
       
   153      *
       
   154      * @param kind  the kind of declarations to select
       
   155      * @return a filter that selects declarations of a particular kind
       
   156      */
       
   157     public static DeclarationFilter getFilter(
       
   158                                      final Class<? extends Declaration> kind) {
       
   159         return new DeclarationFilter() {
       
   160             public boolean matches(Declaration d) {
       
   161                 return kind.isInstance(d);
       
   162             }
       
   163         };
       
   164     }
       
   165 
       
   166     /**
       
   167      * Returns a filter that selects those declarations selected
       
   168      * by both this filter and another.
       
   169      *
       
   170      * @param f  filter to be composed with this one
       
   171      * @return a filter that selects those declarations selected by
       
   172      *          both this filter and another
       
   173      */
       
   174     public DeclarationFilter and(DeclarationFilter f) {
       
   175         final DeclarationFilter f1 = this;
       
   176         final DeclarationFilter f2 = f;
       
   177         return new DeclarationFilter() {
       
   178             public boolean matches(Declaration d) {
       
   179                 return f1.matches(d) && f2.matches(d);
       
   180             }
       
   181         };
       
   182     }
       
   183 
       
   184     /**
       
   185      * Returns a filter that selects those declarations selected
       
   186      * by either this filter or another.
       
   187      *
       
   188      * @param f  filter to be composed with this one
       
   189      * @return a filter that selects those declarations selected by
       
   190      *          either this filter or another
       
   191      */
       
   192     public DeclarationFilter or(DeclarationFilter f) {
       
   193         final DeclarationFilter f1 = this;
       
   194         final DeclarationFilter f2 = f;
       
   195         return new DeclarationFilter() {
       
   196             public boolean matches(Declaration d) {
       
   197                 return f1.matches(d) || f2.matches(d);
       
   198             }
       
   199         };
       
   200     }
       
   201 
       
   202     /**
       
   203      * Returns a filter that selects those declarations not selected
       
   204      * by this filter.
       
   205      *
       
   206      * @return a filter that selects those declarations not selected
       
   207      * by this filter
       
   208      */
       
   209     public DeclarationFilter not() {
       
   210         return new DeclarationFilter() {
       
   211             public boolean matches(Declaration d) {
       
   212                 return !DeclarationFilter.this.matches(d);
       
   213             }
       
   214         };
       
   215     }
       
   216 
       
   217 
       
   218 
       
   219     // Methods to apply a filter.
       
   220 
       
   221     /**
       
   222      * Tests whether this filter matches a given declaration.
       
   223      * The default implementation always returns <tt>true</tt>;
       
   224      * subclasses should override this.
       
   225      *
       
   226      * @param decl  the declaration to match
       
   227      * @return <tt>true</tt> if this filter matches the given declaration
       
   228      */
       
   229     public boolean matches(Declaration decl) {
       
   230         return true;
       
   231     }
       
   232 
       
   233     /**
       
   234      * Returns the declarations matched by this filter.
       
   235      * The result is a collection of the same type as the argument;
       
   236      * the {@linkplain #filter(Collection, Class) two-parameter version}
       
   237      * of <tt>filter</tt> offers control over the result type.
       
   238      *
       
   239      * @param <D>    type of the declarations being filtered
       
   240      * @param decls  declarations being filtered
       
   241      * @return the declarations matched by this filter
       
   242      */
       
   243     public <D extends Declaration> Collection<D> filter(Collection<D> decls) {
       
   244         ArrayList<D> res = new ArrayList<D>(decls.size());
       
   245         for (D d : decls) {
       
   246             if (matches(d)) {
       
   247                 res.add(d);
       
   248             }
       
   249         }
       
   250         return res;
       
   251     }
       
   252 
       
   253     /**
       
   254      * Returns the declarations matched by this filter, with the result
       
   255      * being restricted to declarations of a given kind.
       
   256      * Similar to the simpler
       
   257      * {@linkplain #filter(Collection) single-parameter version}
       
   258      * of <tt>filter</tt>, but the result type is specified explicitly.
       
   259      *
       
   260      * @param <D>      type of the declarations being returned
       
   261      * @param decls    declarations being filtered
       
   262      * @param resType  type of the declarations being returned --
       
   263      *                  the reflective view of <tt>D</tt>
       
   264      * @return the declarations matched by this filter, restricted to those
       
   265      *                  of the specified type
       
   266      */
       
   267     public <D extends Declaration> Collection<D>
       
   268             filter(Collection<? extends Declaration> decls, Class<D> resType) {
       
   269         ArrayList<D> res = new ArrayList<D>(decls.size());
       
   270         for (Declaration d : decls) {
       
   271             if (resType.isInstance(d) && matches(d)) {
       
   272                 res.add(resType.cast(d));
       
   273             }
       
   274         }
       
   275         return res;
       
   276     }
       
   277 
       
   278 
       
   279 
       
   280     /*
       
   281      * A filter based on access modifiers.
       
   282      */
       
   283     private static class AccessFilter extends DeclarationFilter {
       
   284 
       
   285         // The first access modifier to filter on, or null if we're looking
       
   286         // for declarations with no access modifiers.
       
   287         private Modifier mod1 = null;
       
   288 
       
   289         // The second access modifier to filter on, or null if none.
       
   290         private Modifier mod2 = null;
       
   291 
       
   292         // Returns a filter that matches declarations with no access
       
   293         // modifiers.
       
   294         AccessFilter() {
       
   295         }
       
   296 
       
   297         // Returns a filter that matches m.
       
   298         AccessFilter(Modifier m) {
       
   299             mod1 = m;
       
   300         }
       
   301 
       
   302         // Returns a filter that matches either m1 or m2.
       
   303         AccessFilter(Modifier m1, Modifier m2) {
       
   304             mod1 = m1;
       
   305             mod2 = m2;
       
   306         }
       
   307 
       
   308         public boolean matches(Declaration d) {
       
   309             Collection<Modifier> mods = d.getModifiers();
       
   310             if (mod1 == null) { // looking for package private
       
   311                 return !(mods.contains(PUBLIC) ||
       
   312                          mods.contains(PROTECTED) ||
       
   313                          mods.contains(PRIVATE));
       
   314             }
       
   315             return mods.contains(mod1) &&
       
   316                    (mod2 == null || mods.contains(mod2));
       
   317         }
       
   318     }
       
   319 }