Coverage Report - com.puppycrawl.tools.checkstyle.checks.header.AbstractHeaderCheck
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractHeaderCheck
85%
61/71
79%
19/24
3.7
 
 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.header;
 20  
 
 21  
 import java.io.BufferedInputStream;
 22  
 import java.io.File;
 23  
 import java.io.FileNotFoundException;
 24  
 import java.io.IOException;
 25  
 import java.io.InputStreamReader;
 26  
 import java.io.LineNumberReader;
 27  
 import java.io.Reader;
 28  
 import java.io.StringReader;
 29  
 import java.io.UnsupportedEncodingException;
 30  
 import java.net.MalformedURLException;
 31  
 import java.net.URI;
 32  
 import java.net.URISyntaxException;
 33  
 import java.net.URL;
 34  
 import java.nio.charset.Charset;
 35  
 import java.util.List;
 36  
 
 37  
 import org.apache.commons.beanutils.ConversionException;
 38  
 
 39  
 import com.google.common.collect.ImmutableList;
 40  
 import com.google.common.collect.Lists;
 41  
 import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
 42  
 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
 43  
 import com.puppycrawl.tools.checkstyle.api.Utils;
 44  
 
 45  
 /**
 46  
  * Abstract super class for header checks.
 47  
  * Provides support for header and headerFile properties.
 48  
  * @author o_sukhosolsky
 49  
  */
 50  16
 public abstract class AbstractHeaderCheck extends AbstractFileSetCheck
 51  
 {
 52  
     /** The file that contains the header to check against. */
 53  
     private String mFilename;
 54  
 
 55  
     /** Name of a charset to use for loading the header from a file. */
 56  16
     private String mCharset = System.getProperty("file.encoding", "UTF-8");
 57  
 
 58  
     /** the lines of the header file. */
 59  16
     private final List<String> mHeaderLines = Lists.newArrayList();
 60  
 
 61  
 
 62  
     /**
 63  
      * Return the header lines to check against.
 64  
      * @return the header lines to check against.
 65  
      */
 66  
     protected ImmutableList<String> getHeaderLines()
 67  
     {
 68  25
         return ImmutableList.copyOf(mHeaderLines);
 69  
     }
 70  
 
 71  
     /**
 72  
      * Set the charset to use for loading the header from a file.
 73  
      * @param aCharset the charset to use for loading the header from a file
 74  
      * @throws UnsupportedEncodingException if aCharset is unsupported
 75  
      */
 76  
     public void setCharset(String aCharset) throws UnsupportedEncodingException
 77  
     {
 78  17
         if (!Charset.isSupported(aCharset)) {
 79  1
             final String message = "unsupported charset: '" + aCharset + "'";
 80  1
             throw new UnsupportedEncodingException(message);
 81  
         }
 82  16
         mCharset = aCharset;
 83  16
     }
 84  
 
 85  
     /**
 86  
      * Set the header file to check against.
 87  
      * @param aFileName the file that contains the header to check against.
 88  
      */
 89  
     public void setHeaderFile(String aFileName)
 90  
     {
 91  
         // Handle empty param
 92  12
         if ((aFileName == null) || (aFileName.trim().length() == 0)) {
 93  1
             return;
 94  
         }
 95  
 
 96  11
         mFilename = aFileName;
 97  11
     }
 98  
 
 99  
     /**
 100  
      * Load the header from a file.
 101  
      * @throws CheckstyleException if the file cannot be loaded
 102  
      */
 103  
     private void loadHeaderFile() throws CheckstyleException
 104  
     {
 105  11
         checkHeaderNotInitialized();
 106  11
         Reader headerReader = null;
 107  
         try {
 108  11
             final URI uri = resolveHeaderFile();
 109  10
             headerReader = new InputStreamReader(new BufferedInputStream(
 110  
                     uri.toURL().openStream()), mCharset);
 111  10
             loadHeader(headerReader);
 112  
         }
 113  1
         catch (final IOException ex) {
 114  1
             throw new CheckstyleException(
 115  
                     "unable to load header file " + mFilename, ex);
 116  
         }
 117  
         finally {
 118  11
             Utils.closeQuietly(headerReader);
 119  10
         }
 120  10
     }
 121  
 
 122  
     /**
 123  
      * Resolve the specified filename param to a URI.
 124  
      * @return resolved header file URI
 125  
      * @throws IOException on failure
 126  
      */
 127  
     private URI resolveHeaderFile() throws IOException
 128  
     {
 129  
         // figure out if this is a File or a URL
 130  
         URI uri;
 131  
         try {
 132  11
             final URL url = new URL(mFilename);
 133  1
             uri = url.toURI();
 134  
         }
 135  10
         catch (final MalformedURLException ex) {
 136  10
             uri = null;
 137  
         }
 138  0
         catch (final URISyntaxException ex) {
 139  
             // URL violating RFC 2396
 140  0
             uri = null;
 141  11
         }
 142  11
         if (uri == null) {
 143  10
             final File file = new File(mFilename);
 144  10
             if (file.exists()) {
 145  9
                 uri = file.toURI();
 146  
             }
 147  
             else {
 148  
                 // check to see if the file is in the classpath
 149  
                 try {
 150  1
                     final URL configUrl = AbstractHeaderCheck.class
 151  
                             .getResource(mFilename);
 152  1
                     if (configUrl == null) {
 153  1
                         throw new FileNotFoundException(mFilename);
 154  
                     }
 155  0
                     uri = configUrl.toURI();
 156  
                 }
 157  0
                 catch (final URISyntaxException e) {
 158  0
                     throw new FileNotFoundException(mFilename);
 159  0
                 }
 160  
             }
 161  
         }
 162  10
         return uri;
 163  
     }
 164  
 
 165  
     /**
 166  
      * Called before initializing the header.
 167  
      * @throws ConversionException if header has already been set
 168  
      */
 169  
     private void checkHeaderNotInitialized()
 170  
     {
 171  13
         if (!mHeaderLines.isEmpty()) {
 172  0
             throw new ConversionException(
 173  
                     "header has already been set - "
 174  
                     + "set either header or headerFile, not both");
 175  
         }
 176  13
     }
 177  
 
 178  
     /**
 179  
      * Set the header to check against. Individual lines in the header
 180  
      * must be separated by '\n' characters.
 181  
      * @param aHeader header content to check against.
 182  
      * @throws ConversionException if the header cannot be interpreted
 183  
      */
 184  
     public void setHeader(String aHeader)
 185  
     {
 186  2
         if ((aHeader == null) || (aHeader.trim().length() == 0)) {
 187  0
             return;
 188  
         }
 189  
 
 190  2
         checkHeaderNotInitialized();
 191  
 
 192  2
         final String headerExpandedNewLines = aHeader.replaceAll("\\\\n", "\n");
 193  
 
 194  2
         final Reader headerReader = new StringReader(headerExpandedNewLines);
 195  
         try {
 196  2
             loadHeader(headerReader);
 197  
         }
 198  0
         catch (final IOException ex) {
 199  0
             throw new ConversionException("unable to load header", ex);
 200  
         }
 201  
         finally {
 202  2
             Utils.closeQuietly(headerReader);
 203  1
         }
 204  1
     }
 205  
 
 206  
     /**
 207  
      * Load header to check against from a Reader into mHeaderLines.
 208  
      * @param aHeaderReader delivers the header to check against
 209  
      * @throws IOException if
 210  
      */
 211  
     private void loadHeader(final Reader aHeaderReader) throws IOException
 212  
     {
 213  12
         final LineNumberReader lnr = new LineNumberReader(aHeaderReader);
 214  12
         mHeaderLines.clear();
 215  
         while (true) {
 216  80
             final String l = lnr.readLine();
 217  80
             if (l == null) {
 218  12
                 break;
 219  
             }
 220  68
             mHeaderLines.add(l);
 221  68
         }
 222  12
         postprocessHeaderLines();
 223  11
     }
 224  
 
 225  
     /**
 226  
      * Hook method for post processing header lines.
 227  
      * This implementation does nothing.
 228  
      */
 229  
     protected void postprocessHeaderLines()
 230  
     {
 231  1
     }
 232  
 
 233  
     @Override
 234  
     protected final void finishLocalSetup() throws CheckstyleException
 235  
     {
 236  14
         if (mFilename != null) {
 237  11
             loadHeaderFile();
 238  
         }
 239  13
         if (mHeaderLines.isEmpty()) {
 240  2
             throw new CheckstyleException(
 241  
                     "property 'headerFile' is missing or invalid in module "
 242  
                     + getConfiguration().getName());
 243  
         }
 244  11
     }
 245  
 }