Source code: com/puppycrawl/tools/checkstyle/api/Utils.java
1 ////////////////////////////////////////////////////////////////////////////////
2 // checkstyle: Checks Java source code for adherence to a set of rules.
3 // Copyright (C) 2001-2003 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
20 package com.puppycrawl.tools.checkstyle.api;
21
22 import java.io.FileReader;
23 import java.io.IOException;
24 import java.io.LineNumberReader;
25 import java.io.File;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.Map;
29
30 import org.apache.commons.beanutils.ConversionException;
31 import org.apache.regexp.RE;
32 import org.apache.regexp.RESyntaxException;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36
37 /**
38 * Contains utility methods.
39 *
40 * @author Oliver Burn
41 * @version 1.0
42 */
43 public final class Utils
44 {
45 /** Map of all created regular expressions **/
46 private static final Map CREATED_RES = new HashMap();
47 /** Shared instance of logger for exception logging. */
48 private static final Log EXCEPTION_LOG =
49 LogFactory.getLog("com.puppycrawl.tools.checkstyle.ExceptionLog");
50
51 ///CLOVER:OFF
52 /** stop instances being created **/
53 private Utils()
54 {
55 }
56 ///CLOVER:ON
57
58 /**
59 * Accessor for shared instance of logger which should be
60 * used to log all exceptions occured during <code>FileSetCheck</code>
61 * work (<code>debug()</code> should be used).
62 * @return shared exception logger.
63 */
64 public static Log getExceptionLogger()
65 {
66 return EXCEPTION_LOG;
67 }
68
69 /**
70 * Returns whether the specified string contains only whitespace up to the
71 * specified index.
72 *
73 * @param aIndex index to check up to
74 * @param aLine the line to check
75 * @return whether there is only whitespace
76 */
77 public static boolean whitespaceBefore(int aIndex, String aLine)
78 {
79 for (int i = 0; i < aIndex; i++) {
80 if (!Character.isWhitespace(aLine.charAt(i))) {
81 return false;
82 }
83 }
84 return true;
85 }
86
87 /**
88 * Returns the length of a string ignoring all trailing whitespace. It is a
89 * pity that there is not a trim() like method that only removed the
90 * trailing whitespace.
91 * @param aLine the string to process
92 * @return the length of the string ignoring all trailing whitespace
93 **/
94 public static int lengthMinusTrailingWhitespace(String aLine)
95 {
96 int len = aLine.length();
97 for (int i = len - 1; i >= 0; i--) {
98 if (!Character.isWhitespace(aLine.charAt(i))) {
99 break;
100 }
101 len--;
102 }
103 return len;
104 }
105
106 /**
107 * Returns the length of a String prefix with tabs expanded.
108 * Each tab is counted as the number of characters is takes to
109 * jump to the next tab stop.
110 * @param aString the input String
111 * @param aToIdx index in aString (exclusive) where the calculation stops
112 * @param aTabWidth the distance betweeen tab stop position.
113 * @return the length of aString.substring(0, aToIdx) with tabs expanded.
114 */
115 public static int lengthExpandedTabs(String aString,
116 int aToIdx,
117 int aTabWidth)
118 {
119 int len = 0;
120 final char[] chars = aString.toCharArray();
121 for (int idx = 0; idx < aToIdx; idx++) {
122 if (chars[idx] == '\t') {
123 len = (len / aTabWidth + 1) * aTabWidth;
124 }
125 else {
126 len++;
127 }
128 }
129 return len;
130 }
131
132 /**
133 * This is a factory method to return an RE object for the specified
134 * regular expression. This method is not MT safe, but neither are the
135 * returned RE objects.
136 * @return an RE object for the supplied pattern
137 * @param aPattern the regular expression pattern
138 * @throws RESyntaxException an invalid pattern was supplied
139 **/
140 public static RE getRE(String aPattern)
141 throws RESyntaxException
142 {
143 RE retVal = (RE) CREATED_RES.get(aPattern);
144 if (retVal == null) {
145 retVal = new RE(aPattern);
146 CREATED_RES.put(aPattern, retVal);
147 }
148 return retVal;
149 }
150
151 /**
152 * Loads the contents of a file in a String array.
153 * @return the lines in the file
154 * @param aFileName the name of the file to load
155 * @throws IOException error occurred
156 **/
157 public static String[] getLines(String aFileName)
158 throws IOException
159 {
160 final ArrayList lines = new ArrayList();
161 final LineNumberReader lnr =
162 new LineNumberReader(new FileReader(aFileName));
163 try {
164 while (true) {
165 final String l = lnr.readLine();
166 if (l == null) {
167 break;
168 }
169 lines.add(l);
170 }
171 }
172 finally {
173 try {
174 lnr.close();
175 }
176 catch (IOException e) {
177 ; // silently ignore
178 }
179 }
180
181 return (String[]) lines.toArray(new String[0]);
182 }
183
184 /**
185 * Helper method to create a regular expression.
186 * @param aPattern the pattern to match
187 * @return a created regexp object
188 * @throws ConversionException if unable to create RE object.
189 **/
190 public static RE createRE(String aPattern)
191 throws ConversionException
192 {
193 RE retVal = null;
194 try {
195 retVal = getRE(aPattern);
196 }
197 catch (RESyntaxException e) {
198 throw new ConversionException(
199 "Failed to initialise regexp expression " + aPattern, e);
200 }
201 return retVal;
202 }
203
204 /**
205 * @return the base class name from a fully qualified name
206 * @param aType the fully qualified name. Cannot be null
207 */
208 public static String baseClassname(String aType)
209 {
210 final int i = aType.lastIndexOf(".");
211 return (i == -1) ? aType : aType.substring(i + 1);
212 }
213
214 /**
215 * Create a stripped down version of a filename.
216 * @param aBasedir the prefix to strip off the original filename
217 * @param aFileName the original filename
218 * @return the filename where an initial prefix of basedir is stripped
219 */
220 public static String getStrippedFileName(
221 final String aBasedir, final String aFileName)
222 {
223 final String stripped;
224 if ((aBasedir == null) || !aFileName.startsWith(aBasedir)) {
225 stripped = aFileName;
226 }
227 else {
228 // making the assumption that there is text after basedir
229 final int skipSep = aBasedir.endsWith(File.separator) ? 0 : 1;
230 stripped = aFileName.substring(aBasedir.length() + skipSep);
231 }
232 return stripped;
233 }
234
235 }