Coverage Report - com.puppycrawl.tools.checkstyle.checks.header.AbstractHeaderCheck
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractHeaderCheck
100%
59/59
100%
16/16
2.6
 
 1  
 ////////////////////////////////////////////////////////////////////////////////
 2  
 // checkstyle: Checks Java source code for adherence to a set of rules.
 3  
 // Copyright (C) 2001-2017 the original author or authors.
 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  
 
 20  
 package com.puppycrawl.tools.checkstyle.checks.header;
 21  
 
 22  
 import java.io.BufferedInputStream;
 23  
 import java.io.IOException;
 24  
 import java.io.InputStreamReader;
 25  
 import java.io.LineNumberReader;
 26  
 import java.io.Reader;
 27  
 import java.io.StringReader;
 28  
 import java.io.UnsupportedEncodingException;
 29  
 import java.net.URI;
 30  
 import java.nio.charset.Charset;
 31  
 import java.nio.charset.StandardCharsets;
 32  
 import java.util.ArrayList;
 33  
 import java.util.Collections;
 34  
 import java.util.List;
 35  
 import java.util.Set;
 36  
 import java.util.regex.Pattern;
 37  
 
 38  
 import com.google.common.io.Closeables;
 39  
 import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
 40  
 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
 41  
 import com.puppycrawl.tools.checkstyle.api.ExternalResourceHolder;
 42  
 import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
 43  
 
 44  
 /**
 45  
  * Abstract super class for header checks.
 46  
  * Provides support for header and headerFile properties.
 47  
  * @author o_sukhosolsky
 48  
  */
 49  59
 public abstract class AbstractHeaderCheck extends AbstractFileSetCheck
 50  
     implements ExternalResourceHolder {
 51  
     /** Pattern to detect occurrences of '\n' in text. */
 52  3
     private static final Pattern ESCAPED_LINE_FEED_PATTERN = Pattern.compile("\\\\n");
 53  
 
 54  
     /** The lines of the header file. */
 55  59
     private final List<String> readerLines = new ArrayList<>();
 56  
 
 57  
     /** The file that contains the header to check against. */
 58  
     private URI headerFile;
 59  
 
 60  
     /** Name of a charset to use for loading the header from a file. */
 61  59
     private String charset = System.getProperty("file.encoding", StandardCharsets.UTF_8.name());
 62  
 
 63  
     /**
 64  
      * Hook method for post processing header lines.
 65  
      * This implementation does nothing.
 66  
      */
 67  
     protected abstract void postProcessHeaderLines();
 68  
 
 69  
     /**
 70  
      * Return the header lines to check against.
 71  
      * @return the header lines to check against.
 72  
      */
 73  
     protected List<String> getHeaderLines() {
 74  142
         final List<String> copy = new ArrayList<>(readerLines);
 75  142
         return Collections.unmodifiableList(copy);
 76  
     }
 77  
 
 78  
     /**
 79  
      * Set the charset to use for loading the header from a file.
 80  
      * @param charset the charset to use for loading the header from a file
 81  
      * @throws UnsupportedEncodingException if charset is unsupported
 82  
      */
 83  
     public void setCharset(String charset) throws UnsupportedEncodingException {
 84  50
         if (!Charset.isSupported(charset)) {
 85  1
             final String message = "unsupported charset: '" + charset + "'";
 86  1
             throw new UnsupportedEncodingException(message);
 87  
         }
 88  49
         this.charset = charset;
 89  49
     }
 90  
 
 91  
     /**
 92  
      * Set the header file to check against.
 93  
      * @param uri the uri of the header to load.
 94  
      * @throws CheckstyleException if fileName is empty.
 95  
      */
 96  
     public void setHeaderFile(URI uri) throws CheckstyleException {
 97  32
         if (uri == null) {
 98  3
             throw new CheckstyleException(
 99  
                 "property 'headerFile' is missing or invalid in module "
 100  3
                     + getConfiguration().getName());
 101  
         }
 102  
 
 103  29
         headerFile = uri;
 104  29
     }
 105  
 
 106  
     /**
 107  
      * Load the header from a file.
 108  
      * @throws CheckstyleException if the file cannot be loaded
 109  
      */
 110  
     private void loadHeaderFile() throws CheckstyleException {
 111  29
         checkHeaderNotInitialized();
 112  28
         Reader headerReader = null;
 113  
         try {
 114  28
             headerReader = new InputStreamReader(new BufferedInputStream(
 115  28
                     headerFile.toURL().openStream()), charset);
 116  28
             loadHeader(headerReader);
 117  
         }
 118  1
         catch (final IOException ex) {
 119  1
             throw new CheckstyleException(
 120  
                     "unable to load header file " + headerFile, ex);
 121  
         }
 122  
         finally {
 123  28
             Closeables.closeQuietly(headerReader);
 124  26
         }
 125  26
     }
 126  
 
 127  
     /**
 128  
      * Called before initializing the header.
 129  
      * @throws IllegalArgumentException if header has already been set
 130  
      */
 131  
     private void checkHeaderNotInitialized() {
 132  41
         if (!readerLines.isEmpty()) {
 133  2
             throw new IllegalArgumentException(
 134  
                     "header has already been set - "
 135  
                     + "set either header or headerFile, not both");
 136  
         }
 137  39
     }
 138  
 
 139  
     /**
 140  
      * Set the header to check against. Individual lines in the header
 141  
      * must be separated by '\n' characters.
 142  
      * @param header header content to check against.
 143  
      * @throws IllegalArgumentException if the header cannot be interpreted
 144  
      */
 145  
     public void setHeader(String header) {
 146  14
         if (!CommonUtils.isBlank(header)) {
 147  12
             checkHeaderNotInitialized();
 148  
 
 149  11
             final String headerExpandedNewLines = ESCAPED_LINE_FEED_PATTERN
 150  11
                     .matcher(header).replaceAll("\n");
 151  
 
 152  11
             final Reader headerReader = new StringReader(headerExpandedNewLines);
 153  
             try {
 154  11
                 loadHeader(headerReader);
 155  
             }
 156  1
             catch (final IOException ex) {
 157  1
                 throw new IllegalArgumentException("unable to load header", ex);
 158  
             }
 159  
             finally {
 160  11
                 Closeables.closeQuietly(headerReader);
 161  9
             }
 162  
         }
 163  11
     }
 164  
 
 165  
     /**
 166  
      * Load header to check against from a Reader into readerLines.
 167  
      * @param headerReader delivers the header to check against
 168  
      * @throws IOException if
 169  
      */
 170  
     private void loadHeader(final Reader headerReader) throws IOException {
 171  37
         final LineNumberReader lnr = new LineNumberReader(headerReader);
 172  
         try {
 173  
             while (true) {
 174  326
                 String line = lnr.readLine();
 175  326
                 if (line == null) {
 176  37
                     break;
 177  
                 }
 178  289
                 if (line.isEmpty()) {
 179  3
                     line = "^$";
 180  
                 }
 181  289
                 readerLines.add(line);
 182  289
             }
 183  37
             postProcessHeaderLines();
 184  
         }
 185  
         finally {
 186  37
             Closeables.closeQuietly(lnr);
 187  35
         }
 188  
 
 189  35
     }
 190  
 
 191  
     @Override
 192  
     protected final void finishLocalSetup() throws CheckstyleException {
 193  43
         if (headerFile != null) {
 194  27
             loadHeaderFile();
 195  
         }
 196  42
     }
 197  
 
 198  
     @Override
 199  
     public Set<String> getExternalResourceLocations() {
 200  
         final Set<String> result;
 201  
 
 202  3
         if (headerFile == null) {
 203  1
             result = Collections.emptySet();
 204  
         }
 205  
         else {
 206  2
             result = Collections.singleton(headerFile.toString());
 207  
         }
 208  
 
 209  3
         return result;
 210  
     }
 211  
 }