Coverage Report - com.puppycrawl.tools.checkstyle.api.Utils
 
Classes in this File Line Coverage Branch Coverage Complexity
Utils
65%
42/64
69%
18/26
2.538
 
 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.api;
 20  
 
 21  
 import com.google.common.collect.Lists;
 22  
 import com.google.common.collect.Maps;
 23  
 import java.io.Closeable;
 24  
 import java.io.File;
 25  
 import java.io.FileInputStream;
 26  
 import java.io.IOException;
 27  
 import java.io.InputStreamReader;
 28  
 import java.io.LineNumberReader;
 29  
 import java.io.UnsupportedEncodingException;
 30  
 import java.util.List;
 31  
 import java.util.Map;
 32  
 import java.util.regex.Pattern;
 33  
 import java.util.regex.PatternSyntaxException;
 34  
 import org.apache.commons.beanutils.ConversionException;
 35  
 import org.apache.commons.logging.Log;
 36  
 import org.apache.commons.logging.LogFactory;
 37  
 
 38  
 /**
 39  
  * Contains utility methods.
 40  
  *
 41  
  * @author Oliver Burn
 42  
  * @version 1.0
 43  
  */
 44  
 public final class Utils
 45  
 {
 46  
     /** Map of all created regular expressions **/
 47  1
     private static final Map<String, Pattern> CREATED_RES = Maps.newHashMap();
 48  
     /** Shared instance of logger for exception logging. */
 49  1
     private static final Log EXCEPTION_LOG =
 50  
         LogFactory.getLog("com.puppycrawl.tools.checkstyle.ExceptionLog");
 51  
 
 52  
     ///CLOVER:OFF
 53  
     /** stop instances being created **/
 54  
     private Utils()
 55  0
     {
 56  0
     }
 57  
     ///CLOVER:ON
 58  
 
 59  
     /**
 60  
      * Accessor for shared instance of logger which should be
 61  
      * used to log all exceptions occurred during <code>FileSetCheck</code>
 62  
      * work (<code>debug()</code> should be used).
 63  
      * @return shared exception logger.
 64  
      */
 65  
     public static Log getExceptionLogger()
 66  
     {
 67  2
         return EXCEPTION_LOG;
 68  
     }
 69  
 
 70  
     /**
 71  
      * Returns whether the specified string contains only whitespace up to the
 72  
      * specified index.
 73  
      *
 74  
      * @param aIndex index to check up to
 75  
      * @param aLine the line to check
 76  
      * @return whether there is only whitespace
 77  
      */
 78  
     public static boolean whitespaceBefore(int aIndex, String aLine)
 79  
     {
 80  2581
         for (int i = 0; i < aIndex; i++) {
 81  2445
             if (!Character.isWhitespace(aLine.charAt(i))) {
 82  170
                 return false;
 83  
             }
 84  
         }
 85  136
         return true;
 86  
     }
 87  
 
 88  
     /**
 89  
      * Returns the length of a string ignoring all trailing whitespace. It is a
 90  
      * pity that there is not a trim() like method that only removed the
 91  
      * trailing whitespace.
 92  
      * @param aLine the string to process
 93  
      * @return the length of the string ignoring all trailing whitespace
 94  
      **/
 95  
     public static int lengthMinusTrailingWhitespace(String aLine)
 96  
     {
 97  161
         int len = aLine.length();
 98  177
         for (int i = len - 1; i >= 0; i--) {
 99  169
             if (!Character.isWhitespace(aLine.charAt(i))) {
 100  153
                 break;
 101  
             }
 102  16
             len--;
 103  
         }
 104  161
         return len;
 105  
     }
 106  
 
 107  
     /**
 108  
      * Returns the length of a String prefix with tabs expanded.
 109  
      * Each tab is counted as the number of characters is takes to
 110  
      * jump to the next tab stop.
 111  
      * @param aString the input String
 112  
      * @param aToIdx index in aString (exclusive) where the calculation stops
 113  
      * @param aTabWidth the distance between tab stop position.
 114  
      * @return the length of aString.substring(0, aToIdx) with tabs expanded.
 115  
      */
 116  
     public static int lengthExpandedTabs(String aString,
 117  
                                          int aToIdx,
 118  
                                          int aTabWidth)
 119  
     {
 120  20026
         int len = 0;
 121  20026
         final char[] chars = aString.toCharArray();
 122  380920
         for (int idx = 0; idx < aToIdx; idx++) {
 123  360894
             if (chars[idx] == '\t') {
 124  283
                 len = (len / aTabWidth + 1) * aTabWidth;
 125  
             }
 126  
             else {
 127  360611
                 len++;
 128  
             }
 129  
         }
 130  20026
         return len;
 131  
     }
 132  
 
 133  
     /**
 134  
      * This is a factory method to return an Pattern object for the specified
 135  
      * regular expression. It calls {@link #getPattern(String, int)} with the
 136  
      * compile flags defaults to 0.
 137  
      * @return an Pattern object for the supplied pattern
 138  
      * @param aPattern the regular expression pattern
 139  
      * @throws PatternSyntaxException an invalid pattern was supplied
 140  
      **/
 141  
     public static Pattern getPattern(String aPattern)
 142  
         throws PatternSyntaxException
 143  
     {
 144  803
         return getPattern(aPattern, 0);
 145  
     }
 146  
 
 147  
     /**
 148  
      * This is a factory method to return an Pattern object for the specified
 149  
      * regular expression and compile flags.
 150  
      * <p>
 151  
      * This method is not MT safe, but neither are the returned Pattern objects.
 152  
      * @return an Pattern object for the supplied pattern
 153  
      * @param aPattern the regular expression pattern
 154  
      * @param aCompileFlags the compilation flags
 155  
      * @throws PatternSyntaxException an invalid pattern was supplied
 156  
      **/
 157  
     public static Pattern getPattern(String aPattern, int aCompileFlags)
 158  
         throws PatternSyntaxException
 159  
     {
 160  3492
         final String key = aPattern + ":flags-" + aCompileFlags;
 161  3492
         Pattern retVal = CREATED_RES.get(key);
 162  3492
         if (retVal == null) {
 163  153
             retVal = Pattern.compile(aPattern, aCompileFlags);
 164  150
             CREATED_RES.put(key, retVal);
 165  
         }
 166  3489
         return retVal;
 167  
     }
 168  
 
 169  
     /**
 170  
      * Loads the contents of a file in a String array.
 171  
      * @return the lines in the file
 172  
      * @param aFileName the name of the file to load
 173  
      * @throws IOException error occurred
 174  
      * @deprecated consider using {@link FileText} instead
 175  
      **/
 176  
     @Deprecated
 177  
     public static String[] getLines(String aFileName)
 178  
         throws IOException
 179  
     {
 180  0
         return getLines(
 181  
             aFileName,
 182  
             System.getProperty("file.encoding", "UTF-8"));
 183  
     }
 184  
 
 185  
     /**
 186  
      * Loads the contents of a file in a String array using
 187  
      * the named charset.
 188  
      * @return the lines in the file
 189  
      * @param aFileName the name of the file to load
 190  
      * @param aCharsetName the name of a supported charset
 191  
      * @throws IOException error occurred
 192  
      * @deprecated consider using {@link FileText} instead
 193  
      **/
 194  
     @Deprecated
 195  
     public static String[] getLines(String aFileName, String aCharsetName)
 196  
         throws IOException
 197  
     {
 198  0
         final List<String> lines = Lists.newArrayList();
 199  0
         final FileInputStream fr = new FileInputStream(aFileName);
 200  0
         LineNumberReader lnr = null;
 201  
         try {
 202  0
             lnr = new LineNumberReader(new InputStreamReader(fr, aCharsetName));
 203  
         }
 204  0
         catch (final UnsupportedEncodingException ex) {
 205  0
             final String message = "unsupported charset: " + ex.getMessage();
 206  0
             throw new UnsupportedEncodingException(message);
 207  0
         }
 208  
         try {
 209  
             while (true) {
 210  0
                 final String l = lnr.readLine();
 211  0
                 if (l == null) {
 212  0
                     break;
 213  
                 }
 214  0
                 lines.add(l);
 215  0
             }
 216  
         }
 217  
         finally {
 218  0
             Utils.closeQuietly(lnr);
 219  0
         }
 220  0
         return lines.toArray(new String[lines.size()]);
 221  
     }
 222  
 
 223  
     /**
 224  
      * Helper method to create a regular expression.
 225  
      * @param aPattern the pattern to match
 226  
      * @return a created regexp object
 227  
      * @throws ConversionException if unable to create Pattern object.
 228  
      **/
 229  
     public static Pattern createPattern(String aPattern)
 230  
         throws ConversionException
 231  
     {
 232  13
         Pattern retVal = null;
 233  
         try {
 234  13
             retVal = getPattern(aPattern);
 235  
         }
 236  1
         catch (final PatternSyntaxException e) {
 237  1
             throw new ConversionException(
 238  
                 "Failed to initialise regexp expression " + aPattern, e);
 239  12
         }
 240  12
         return retVal;
 241  
     }
 242  
 
 243  
     /**
 244  
      * @return the base class name from a fully qualified name
 245  
      * @param aType the fully qualified name. Cannot be null
 246  
      */
 247  
     public static String baseClassname(String aType)
 248  
     {
 249  94
         final int i = aType.lastIndexOf(".");
 250  94
         return (i == -1) ? aType : aType.substring(i + 1);
 251  
     }
 252  
 
 253  
     /**
 254  
      * Create a stripped down version of a filename.
 255  
      * @param aBasedir the prefix to strip off the original filename
 256  
      * @param aFileName the original filename
 257  
      * @return the filename where an initial prefix of basedir is stripped
 258  
      */
 259  
     public static String getStrippedFileName(
 260  
             final String aBasedir, final String aFileName)
 261  
     {
 262  
         final String stripped;
 263  1799
         if ((aBasedir == null) || !aFileName.startsWith(aBasedir)) {
 264  1799
             stripped = aFileName;
 265  
         }
 266  
         else {
 267  
             // making the assumption that there is text after basedir
 268  0
             final int skipSep = aBasedir.endsWith(File.separator) ? 0 : 1;
 269  0
             stripped = aFileName.substring(aBasedir.length() + skipSep);
 270  
         }
 271  1799
         return stripped;
 272  
     }
 273  
 
 274  
     /**
 275  
      * Closes the supplied {@link Closeable} object ignoring an
 276  
      * {@link IOException} if it is thrown. Honestly, what are you going to
 277  
      * do if you cannot close a file.
 278  
      * @param aShutting the object to be closed.
 279  
      */
 280  
     public static void closeQuietly(Closeable aShutting)
 281  
     {
 282  1409
         if (null != aShutting) {
 283  
             try {
 284  1408
                 aShutting.close();
 285  
             }
 286  0
             catch (IOException e) {
 287  
                 ; // ignore
 288  1408
             }
 289  
         }
 290  1409
     }
 291  
 }