Coverage Report - com.puppycrawl.tools.checkstyle.filters.SuppressionsLoader
 
Classes in this File Line Coverage Branch Coverage Complexity
SuppressionsLoader
80%
54/67
72%
16/22
6.667
 
 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.filters;
 20  
 
 21  
 import java.io.File;
 22  
 import java.io.FileNotFoundException;
 23  
 import java.io.IOException;
 24  
 import java.net.MalformedURLException;
 25  
 import java.net.URI;
 26  
 import java.net.URISyntaxException;
 27  
 import java.net.URL;
 28  
 import java.util.Map;
 29  
 import java.util.regex.PatternSyntaxException;
 30  
 
 31  
 import javax.xml.parsers.ParserConfigurationException;
 32  
 
 33  
 import org.xml.sax.Attributes;
 34  
 import org.xml.sax.InputSource;
 35  
 import org.xml.sax.SAXException;
 36  
 
 37  
 import com.google.common.collect.Maps;
 38  
 import com.puppycrawl.tools.checkstyle.api.AbstractLoader;
 39  
 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
 40  
 import com.puppycrawl.tools.checkstyle.api.FilterSet;
 41  
 
 42  
 /**
 43  
  * Loads a filter chain of suppressions.
 44  
  * @author Rick Giles
 45  
  */
 46  
 public final class SuppressionsLoader
 47  
     extends AbstractLoader
 48  
 {
 49  
     /** the public ID for the configuration dtd */
 50  
     private static final String DTD_PUBLIC_ID_1_0 =
 51  
         "-//Puppy Crawl//DTD Suppressions 1.0//EN";
 52  
     /** the resource for the configuration dtd */
 53  
     private static final String DTD_RESOURCE_NAME_1_0 =
 54  
         "com/puppycrawl/tools/checkstyle/suppressions_1_0.dtd";
 55  
     /** the public ID for the configuration dtd */
 56  
     private static final String DTD_PUBLIC_ID_1_1 =
 57  
         "-//Puppy Crawl//DTD Suppressions 1.1//EN";
 58  
     /** the resource for the configuration dtd */
 59  
     private static final String DTD_RESOURCE_NAME_1_1 =
 60  
         "com/puppycrawl/tools/checkstyle/suppressions_1_1.dtd";
 61  
 
 62  
     /**
 63  
      * the filter chain to return in getAFilterChain(),
 64  
      * configured during parsing
 65  
      */
 66  7
     private final FilterSet mFilterChain = new FilterSet();
 67  
 
 68  
     /**
 69  
      * Creates a new <code>SuppressionsLoader</code> instance.
 70  
      * @throws ParserConfigurationException if an error occurs
 71  
      * @throws SAXException if an error occurs
 72  
      */
 73  
     private SuppressionsLoader()
 74  
         throws ParserConfigurationException, SAXException
 75  
     {
 76  7
         super(createIdToResourceNameMap());
 77  7
     }
 78  
 
 79  
     /**
 80  
      * Returns the loaded filter chain.
 81  
      * @return the loaded filter chain.
 82  
      */
 83  
     public FilterSet getFilterChain()
 84  
     {
 85  4
         return mFilterChain;
 86  
     }
 87  
 
 88  
     @Override
 89  
     public void startElement(String aNamespaceURI,
 90  
                              String aLocalName,
 91  
                              String aQName,
 92  
                              Attributes aAtts)
 93  
         throws SAXException
 94  
     {
 95  12
         if ("suppress".equals(aQName)) {
 96  
             //add SuppressElement filter to the filter chain
 97  5
             final String files = aAtts.getValue("files");
 98  5
             if (files == null) {
 99  0
                 throw new SAXException("missing files attribute");
 100  
             }
 101  5
             final String checks = aAtts.getValue("checks");
 102  5
             final String modId = aAtts.getValue("id");
 103  5
             if ((checks == null) && (modId == null)) {
 104  0
                 throw new SAXException("missing checks and id attribute");
 105  
             }
 106  
             final SuppressElement suppress;
 107  
             try {
 108  5
                 suppress = new SuppressElement(files);
 109  5
                 if (modId != null) {
 110  0
                     suppress.setModuleId(modId);
 111  
                 }
 112  5
                 if (checks != null) {
 113  5
                     suppress.setChecks(checks);
 114  
                 }
 115  
             }
 116  0
             catch (final PatternSyntaxException e) {
 117  0
                 throw new SAXException("invalid files or checks format");
 118  5
             }
 119  5
             final String lines = aAtts.getValue("lines");
 120  5
             if (lines != null) {
 121  3
                 suppress.setLines(lines);
 122  
             }
 123  4
             final String columns = aAtts.getValue("columns");
 124  4
             if (columns != null) {
 125  2
                 suppress.setColumns(columns);
 126  
             }
 127  4
             mFilterChain.addFilter(suppress);
 128  
         }
 129  11
     }
 130  
 
 131  
     /**
 132  
      * Returns the suppression filters in a specified file.
 133  
      * @param aFilename name of the suppresssions file.
 134  
      * @return the filter chain of suppression elements specified in the file.
 135  
      * @throws CheckstyleException if an error occurs.
 136  
      */
 137  
     public static FilterSet loadSuppressions(String aFilename)
 138  
         throws CheckstyleException
 139  
     {
 140  
         try {
 141  
             // figure out if this is a File or a URL
 142  
             URI uri;
 143  
             try {
 144  9
                 final URL url = new URL(aFilename);
 145  2
                 uri = url.toURI();
 146  
             }
 147  7
             catch (final MalformedURLException ex) {
 148  7
                 uri = null;
 149  
             }
 150  1
             catch (final URISyntaxException ex) {
 151  
                 // URL violating RFC 2396
 152  1
                 uri = null;
 153  8
             }
 154  9
             if (uri == null) {
 155  8
                 final File file = new File(aFilename);
 156  8
                 if (file.exists()) {
 157  5
                     uri = file.toURI();
 158  
                 }
 159  
                 else {
 160  
                     // check to see if the file is in the classpath
 161  
                     try {
 162  3
                         final URL configUrl = SuppressionsLoader.class
 163  
                                 .getResource(aFilename);
 164  3
                         if (configUrl == null) {
 165  2
                             throw new FileNotFoundException(aFilename);
 166  
                         }
 167  1
                         uri = configUrl.toURI();
 168  
                     }
 169  0
                     catch (final URISyntaxException e) {
 170  0
                         throw new FileNotFoundException(aFilename);
 171  1
                     }
 172  
                 }
 173  
             }
 174  7
             final InputSource source = new InputSource(uri.toString());
 175  7
             return loadSuppressions(source, aFilename);
 176  
         }
 177  2
         catch (final FileNotFoundException e) {
 178  2
             throw new CheckstyleException("unable to find " + aFilename, e);
 179  
         }
 180  
     }
 181  
 
 182  
     /**
 183  
      * Returns the suppression filters in a specified source.
 184  
      * @param aSource the source for the suppressions.
 185  
      * @param aSourceName the name of the source.
 186  
      * @return the filter chain of suppression elements in aSource.
 187  
      * @throws CheckstyleException if an error occurs.
 188  
      */
 189  
     private static FilterSet loadSuppressions(
 190  
             InputSource aSource, String aSourceName)
 191  
         throws CheckstyleException
 192  
     {
 193  
         try {
 194  7
             final SuppressionsLoader suppressionsLoader =
 195  
                 new SuppressionsLoader();
 196  7
             suppressionsLoader.parseInputSource(aSource);
 197  4
             return suppressionsLoader.getFilterChain();
 198  
         }
 199  0
         catch (final FileNotFoundException e) {
 200  0
             throw new CheckstyleException("unable to find " + aSourceName, e);
 201  
         }
 202  0
         catch (final ParserConfigurationException e) {
 203  0
             throw new CheckstyleException("unable to parse " + aSourceName, e);
 204  
         }
 205  2
         catch (final SAXException e) {
 206  2
             throw new CheckstyleException("unable to parse "
 207  
                     + aSourceName + " - " + e.getMessage(), e);
 208  
         }
 209  0
         catch (final IOException e) {
 210  0
             throw new CheckstyleException("unable to read " + aSourceName, e);
 211  
         }
 212  1
         catch (final NumberFormatException e) {
 213  1
             throw new CheckstyleException("number format exception "
 214  
                 + aSourceName + " - " + e.getMessage(), e);
 215  
         }
 216  
     }
 217  
 
 218  
     /**
 219  
      * Creates mapping between local resources and dtd ids.
 220  
      * @return map between local resources and dtd ids.
 221  
      */
 222  
     private static Map<String, String> createIdToResourceNameMap()
 223  
     {
 224  7
         final Map<String, String> map = Maps.newHashMap();
 225  7
         map.put(DTD_PUBLIC_ID_1_0, DTD_RESOURCE_NAME_1_0);
 226  7
         map.put(DTD_PUBLIC_ID_1_1, DTD_RESOURCE_NAME_1_1);
 227  7
         return map;
 228  
     }
 229  
 }