Coverage Report - com.puppycrawl.tools.checkstyle.checks.imports.ImportControlCheck
 
Classes in this File Line Coverage Branch Coverage Complexity
ImportControlCheck
72%
29/40
75%
15/20
4.6
 
 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.io.File;
 22  
 import java.net.URI;
 23  
 
 24  
 import com.puppycrawl.tools.checkstyle.api.Check;
 25  
 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
 26  
 import com.puppycrawl.tools.checkstyle.api.DetailAST;
 27  
 import com.puppycrawl.tools.checkstyle.api.FullIdent;
 28  
 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
 29  
 import org.apache.commons.beanutils.ConversionException;
 30  
 
 31  
 /**
 32  
  * Check that controls what packages can be imported in each package. Useful
 33  
  * for ensuring that application layering is not violated. Ideas on how the
 34  
  * check can be improved include support for:
 35  
  * <ul>
 36  
  * <li>Change the default policy that if a package being checked does not
 37  
  *     match any guards, then it is allowed. Currently defaults to disallowed.
 38  
  *
 39  
  * </ul>
 40  
  * @author Oliver Burn
 41  
  */
 42  9
 public class ImportControlCheck extends Check
 43  
 {
 44  
     /** The root package controller. */
 45  
     private PkgControl mRoot;
 46  
     /** The package doing the import. */
 47  
     private String mInPkg;
 48  
 
 49  
     /**
 50  
      * The package controller for the current file. Used for performance
 51  
      * optimisation.
 52  
      */
 53  
     private PkgControl mCurrentLeaf;
 54  
 
 55  
     @Override
 56  
     public int[] getDefaultTokens()
 57  
     {
 58  7
         return new int[] {TokenTypes.PACKAGE_DEF, TokenTypes.IMPORT,
 59  
                           TokenTypes.STATIC_IMPORT, };
 60  
     }
 61  
 
 62  
     @Override
 63  
     public void beginTree(final DetailAST aRootAST)
 64  
     {
 65  7
         mCurrentLeaf = null;
 66  7
     }
 67  
 
 68  
     @Override
 69  
     public void visitToken(final DetailAST aAST)
 70  
     {
 71  35
         if (aAST.getType() == TokenTypes.PACKAGE_DEF) {
 72  7
             final DetailAST nameAST = aAST.getLastChild().getPreviousSibling();
 73  7
             final FullIdent full = FullIdent.createFullIdent(nameAST);
 74  7
             if (mRoot == null) {
 75  2
                 log(nameAST, "import.control.missing.file");
 76  
             }
 77  
             else {
 78  5
                 mInPkg = full.getText();
 79  5
                 mCurrentLeaf = mRoot.locateFinest(mInPkg);
 80  5
                 if (mCurrentLeaf == null) {
 81  1
                     log(nameAST, "import.control.unknown.pkg");
 82  
                 }
 83  
             }
 84  7
         }
 85  28
         else if (mCurrentLeaf != null) {
 86  
             final FullIdent imp;
 87  16
             if (aAST.getType() == TokenTypes.IMPORT) {
 88  12
                 imp = FullIdent.createFullIdentBelow(aAST);
 89  
             }
 90  
             else {
 91  
                 // know it is a static import
 92  4
                 imp = FullIdent.createFullIdent(aAST
 93  
                         .getFirstChild().getNextSibling());
 94  
             }
 95  16
             final AccessResult access = mCurrentLeaf.checkAccess(imp.getText(),
 96  
                     mInPkg);
 97  16
             if (!AccessResult.ALLOWED.equals(access)) {
 98  8
                 log(aAST, "import.control.disallowed", imp.getText());
 99  
             }
 100  
         }
 101  35
     }
 102  
 
 103  
     /**
 104  
      * Set the parameter for the url containing the import control
 105  
      * configuration. It will cause the url to be loaded.
 106  
      * @param aUrl the url of the file to load.
 107  
      * @throws ConversionException on error loading the file.
 108  
      */
 109  
     public void setUrl(final String aUrl)
 110  
     {
 111  
         // Handle empty param
 112  0
         if ((aUrl == null) || (aUrl.trim().length() == 0)) {
 113  0
             return;
 114  
         }
 115  
         final URI uri;
 116  
         try {
 117  0
             uri = URI.create(aUrl);
 118  
         }
 119  0
         catch (final IllegalArgumentException ex) {
 120  0
             throw new ConversionException("syntax error in url " + aUrl, ex);
 121  0
         }
 122  
         try {
 123  0
             mRoot = ImportControlLoader.load(uri);
 124  
         }
 125  0
         catch (final CheckstyleException ex) {
 126  0
             throw new ConversionException("Unable to load " + aUrl, ex);
 127  0
         }
 128  0
     }
 129  
 
 130  
     /**
 131  
      * Set the parameter for the file containing the import control
 132  
      * configuration. It will cause the file to be loaded.
 133  
      * @param aName the name of the file to load.
 134  
      * @throws ConversionException on error loading the file.
 135  
      */
 136  
     public void setFile(final String aName)
 137  
     {
 138  
         // Handle empty param
 139  8
         if ((aName == null) || (aName.trim().length() == 0)) {
 140  1
             return;
 141  
         }
 142  
 
 143  
         try {
 144  7
             mRoot = ImportControlLoader.load(new File(aName).toURI());
 145  
         }
 146  2
         catch (final CheckstyleException ex) {
 147  2
             throw new ConversionException("Unable to load " + aName, ex);
 148  5
         }
 149  5
     }
 150  
 }