Home | History | Annotate | Download | only in visitor
      1 /*
      2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
      3  *             of Java bytecode.
      4  *
      5  * Copyright (c) 2002-2014 Eric Lafortune (eric (at) graphics.cornell.edu)
      6  *
      7  * This program is free software; you can redistribute it and/or modify it
      8  * under the terms of the GNU General Public License as published by the Free
      9  * Software Foundation; either version 2 of the License, or (at your option)
     10  * any later version.
     11  *
     12  * This program is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
     15  * more details.
     16  *
     17  * You should have received a copy of the GNU General Public License along
     18  * with this program; if not, write to the Free Software Foundation, Inc.,
     19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
     20  */
     21 package proguard.classfile.visitor;
     22 
     23 import proguard.classfile.*;
     24 
     25 
     26 /**
     27  * This <code>MemberVisitor</code> delegates its visits to another given
     28  * <code>MemberVisitor</code>, but only when the visited member has the proper
     29  * access flags.
     30  * <p>
     31  * If conflicting access flags (public/private/protected) are specified,
     32  * having one of them set will be considered sufficient.
     33  *
     34  * @see ClassConstants
     35  *
     36  * @author Eric Lafortune
     37  */
     38 public class MemberAccessFilter
     39 implements   MemberVisitor
     40 {
     41     // A mask of conflicting access flags. These are interpreted in a special
     42     // way if more of them are required at the same time. In that case, one
     43     // of them being set is sufficient.
     44     private static final int ACCESS_MASK =
     45         ClassConstants.ACC_PUBLIC  |
     46         ClassConstants.ACC_PRIVATE |
     47         ClassConstants.ACC_PROTECTED;
     48 
     49     private final int           requiredSetAccessFlags;
     50     private final int           requiredUnsetAccessFlags;
     51     private final int           requiredOneSetAccessFlags;
     52     private final MemberVisitor memberVisitor;
     53 
     54 
     55     /**
     56      * Creates a new MemberAccessFilter.
     57      * @param requiredSetAccessFlags   the class access flags that should be
     58      *                                 set.
     59      * @param requiredUnsetAccessFlags the class access flags that should be
     60      *                                 unset.
     61      * @param memberVisitor            the <code>MemberVisitor</code> to
     62      *                                 which visits will be delegated.
     63      */
     64     public MemberAccessFilter(int           requiredSetAccessFlags,
     65                               int           requiredUnsetAccessFlags,
     66                               MemberVisitor memberVisitor)
     67     {
     68         this.requiredSetAccessFlags    = requiredSetAccessFlags & ~ACCESS_MASK;
     69         this.requiredUnsetAccessFlags  = requiredUnsetAccessFlags;
     70         this.requiredOneSetAccessFlags = requiredSetAccessFlags &  ACCESS_MASK;
     71         this.memberVisitor             = memberVisitor;
     72     }
     73 
     74 
     75     // Implementations for MemberVisitor.
     76 
     77     public void visitProgramField(ProgramClass programClass, ProgramField programField)
     78     {
     79         if (accepted(programField.getAccessFlags()))
     80         {
     81             memberVisitor.visitProgramField(programClass, programField);
     82         }
     83     }
     84 
     85 
     86     public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
     87     {
     88         if (accepted(programMethod.getAccessFlags()))
     89         {
     90             memberVisitor.visitProgramMethod(programClass, programMethod);
     91         }
     92     }
     93 
     94 
     95     public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
     96     {
     97         if (accepted(libraryField.getAccessFlags()))
     98         {
     99             memberVisitor.visitLibraryField(libraryClass, libraryField);
    100         }
    101     }
    102 
    103 
    104     public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
    105     {
    106         if (accepted(libraryMethod.getAccessFlags()))
    107         {
    108             memberVisitor.visitLibraryMethod(libraryClass, libraryMethod);
    109         }
    110     }
    111 
    112 
    113     // Small utility methods.
    114 
    115     private boolean accepted(int accessFlags)
    116     {
    117         return (requiredSetAccessFlags    & ~accessFlags) == 0 &&
    118                (requiredUnsetAccessFlags  &  accessFlags) == 0 &&
    119                (requiredOneSetAccessFlags == 0                 ||
    120                (requiredOneSetAccessFlags &  accessFlags) != 0);
    121     }
    122 }
    123