Coverage Report - com.puppycrawl.tools.checkstyle.checks.imports.AvoidStarImportCheck
 
Classes in this File Line Coverage Branch Coverage Complexity
AvoidStarImportCheck
91%
22/24
90%
18/20
2.286
 
 1  
 ////////////////////////////////////////////////////////////////////////////////
 2  
 // checkstyle: Checks Java source code for adherence to a set of rules.
 3  
 // Copyright (C) 2001-2014  Oliver Burn
 4  
 //
 5  
 // This library is free software; you can redistribute it and/or
 6  
 // modify it under the terms of the GNU Lesser General Public
 7  
 // License as published by the Free Software Foundation; either
 8  
 // version 2.1 of the License, or (at your option) any later version.
 9  
 //
 10  
 // This library is distributed in the hope that it will be useful,
 11  
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  
 // Lesser General Public License for more details.
 14  
 //
 15  
 // You should have received a copy of the GNU Lesser General Public
 16  
 // License along with this library; if not, write to the Free Software
 17  
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 18  
 ////////////////////////////////////////////////////////////////////////////////
 19  
 package com.puppycrawl.tools.checkstyle.checks.imports;
 20  
 
 21  
 import java.util.List;
 22  
 import com.google.common.collect.Lists;
 23  
 import com.puppycrawl.tools.checkstyle.api.Check;
 24  
 import com.puppycrawl.tools.checkstyle.api.DetailAST;
 25  
 import com.puppycrawl.tools.checkstyle.api.FullIdent;
 26  
 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
 27  
 
 28  
 /**
 29  
  * <p>
 30  
  * Check that finds import statements that use the * notation.
 31  
  * </p>
 32  
  * <p>
 33  
  * Rationale: Importing all classes from a package or static
 34  
  * members from a class leads to tight coupling between packages
 35  
  * or classes and might lead to problems when a new version of a
 36  
  * library introduces name clashes.
 37  
  * </p>
 38  
  * <p>
 39  
  * An example of how to configure the check is:
 40  
  * </p>
 41  
  * <pre>
 42  
  * &lt;module name="AvoidStarImport"&gt;
 43  
  *   &lt;property name="excludes" value="java.io,java.net,java.lang.Math"/&gt;
 44  
  *   &lt;property name="allowClassImports" value="false"/&gt;
 45  
  *   &lt;property name="allowStaticMemberImports" value="false"/&gt;
 46  
  * &lt;/module&gt;
 47  
  * </pre>
 48  
  *
 49  
  * The optional "excludes" property allows for certain packages like
 50  
  * java.io or java.net to be exempted from the rule. It also is used to
 51  
  * allow certain classes like java.lang.Math or java.io.File to be
 52  
  * excluded in order to support static member imports.
 53  
  *
 54  
  * The optional "allowClassImports" when set to true, will allow starred
 55  
  * class imports but will not affect static member imports.
 56  
  *
 57  
  * The optional "allowStaticMemberImports" when set to true will allow
 58  
  * starred static member imports but will not affect class imports.
 59  
  *
 60  
  * @author Oliver Burn
 61  
  * @author <a href="bschneider@vecna.com">Bill Schneider</a>
 62  
  * @author Travis Schneeberger
 63  
  * @version 2.0
 64  
  */
 65  3
 public class AvoidStarImportCheck
 66  
     extends Check
 67  
 {
 68  
     /** the packages/classes to exempt from this check. */
 69  3
     private final List<String> mExcludes = Lists.newArrayList();
 70  
 
 71  
     /** whether to allow all class imports */
 72  
     private boolean mAllowClassImports;
 73  
 
 74  
     /** whether to allow all static member imports */
 75  
     private boolean mAllowStaticMemberImports;
 76  
 
 77  
     @Override
 78  
     public int[] getDefaultTokens()
 79  
     {
 80  3
         return new int[] {TokenTypes.IMPORT, TokenTypes.STATIC_IMPORT};
 81  
     }
 82  
 
 83  
     /**
 84  
      * Sets the list of packages or classes to be exempt from the check.
 85  
      * The excludes can contain a .* or not.
 86  
      * @param aExcludes a list of package names/fully-qualifies class names
 87  
      * where star imports are ok
 88  
      */
 89  
     public void setExcludes(String[] aExcludes)
 90  
     {
 91  1
         mExcludes.clear();
 92  5
         for (final String exclude : aExcludes) {
 93  4
             mExcludes.add(exclude.endsWith(".*") ? exclude : exclude + ".*");
 94  
         }
 95  1
     }
 96  
 
 97  
     /**
 98  
      * Sets whether or not to allow all non-static class imports.
 99  
      * @param aAllow true to allow false to disallow
 100  
      */
 101  
     public void setAllowClassImports(boolean aAllow)
 102  
     {
 103  1
         mAllowClassImports = aAllow;
 104  1
     }
 105  
 
 106  
     /**
 107  
      * Sets whether or not to allow all static member imports.
 108  
      * @param aAllow true to allow false to disallow
 109  
      */
 110  
     public void setAllowStaticMemberImports(boolean aAllow)
 111  
     {
 112  0
         mAllowStaticMemberImports = aAllow;
 113  0
     }
 114  
 
 115  
     @Override
 116  
     public void visitToken(final DetailAST aAST)
 117  
     {
 118  84
         if (!mAllowClassImports && (TokenTypes.IMPORT == aAST.getType())) {
 119  46
             final DetailAST startingDot = aAST.getFirstChild();
 120  46
             logsStarredImportViolation(startingDot);
 121  46
         }
 122  38
         else if (!mAllowStaticMemberImports
 123  
             && (TokenTypes.STATIC_IMPORT == aAST.getType()))
 124  
         {
 125  
             // must navigate past the static keyword
 126  15
             final DetailAST startingDot = aAST.getFirstChild().getNextSibling();
 127  15
             logsStarredImportViolation(startingDot);
 128  
         }
 129  84
     }
 130  
 
 131  
     /**
 132  
      * Gets the full import identifier.  If the import is a starred import and
 133  
      * it's not excluded then a violation is logged.
 134  
      * @param aStartingDot the starting dot for the import statement
 135  
      */
 136  
     private void logsStarredImportViolation(DetailAST aStartingDot)
 137  
     {
 138  61
         final FullIdent name = FullIdent.createFullIdent(aStartingDot);
 139  61
         if (isStaredImport(name) && !mExcludes.contains(name.getText())) {
 140  11
             log(aStartingDot.getLineNo(), "import.avoidStar", name.getText());
 141  
         }
 142  61
     }
 143  
 
 144  
     /**
 145  
      * Checks is an import is a stared import.
 146  
      * @param aImportIdent the full import identifier
 147  
      * @return true if a start import false if not
 148  
      */
 149  
     private boolean isStaredImport(FullIdent aImportIdent)
 150  
     {
 151  61
         return (null != aImportIdent) && aImportIdent.getText().endsWith(".*");
 152  
     }
 153  
 }