Clover Coverage Report
Coverage timestamp: Sa Aug 2 2008 13:56:27 CEST
../../../../img/srcFileCovDistChart4.png 82% of files have more coverage
110   381   51   7,33
62   195   0,46   15
15     3,4  
1    
 
  StringUtility       Line # 38 110 51 39,6% 0.3957219
 
  (19)
 
1    /* $Id: StringUtility.java,v 1.1 2008/07/26 07:55:42 m31 Exp $
2    *
3    * This file is part of the project "Hilbert II" - http://www.qedeq.org
4    *
5    * Copyright 2000-2008, Michael Meyling <mime@qedeq.org>.
6    *
7    * "Hilbert II" is free software; you can redistribute
8    * it and/or modify it under the terms of the GNU General Public
9    * License as published by the Free Software Foundation; either
10    * version 2 of the License, or (at your option) any later version.
11    *
12    * This program is distributed in the hope that it will be useful,
13    * but WITHOUT ANY WARRANTY; without even the implied warranty of
14    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15    * GNU General Public License for more details.
16    */
17   
18    package org.qedeq.base.utility;
19   
20    import java.io.BufferedReader;
21    import java.io.ByteArrayOutputStream;
22    import java.io.IOException;
23    import java.io.StringReader;
24    import java.io.UnsupportedEncodingException;
25    import java.util.Properties;
26   
27    import org.apache.commons.lang.SystemUtils;
28   
29   
30    /**
31    * A collection of useful static methods for strings.
32    *
33    * LATER mime 20070101: use StringBuilder instead of StringBuffer if working under JDK 1.5
34    *
35    * @version $Revision: 1.1 $
36    * @author Michael Meyling
37    */
 
38    public final class StringUtility {
39   
40    /** Trimed with zeros. */
41    static final String FORMATED_ZERO = "0000000000000000000000000";
42   
43    /**
44    * Constructor, should never be called.
45    */
 
46  0 toggle private StringUtility() {
47    // don't call me
48    }
49   
50    /**
51    * Replaces all occurrences of <code>search</code> in <code>text</code>
52    * by <code>replace</code> and returns the result.
53    *
54    * @param text text to work on
55    * @param search replace this text by <code>replace</code>
56    * @param replace replacement for <code>search</code>
57    * @return resulting string
58    */
 
59  28509 toggle public static String replace(final String text,
60    final String search, final String replace) {
61   
62  28509 final int len = search.length();
63  28509 if (len == 0) {
64  0 return text;
65    }
66  28509 final StringBuffer result = new StringBuffer();
67  28509 int pos1 = 0;
68  28509 int pos2;
69  ? while (0 <= (pos2 = text.indexOf(search, pos1))) {
70  8706 result.append(text.substring(pos1, pos2));
71  8706 result.append(replace);
72  8706 pos1 = pos2 + len;
73    }
74  28509 if (pos1 < text.length()) {
75  27405 result.append(text.substring(pos1));
76    }
77  28509 return result.toString();
78    }
79   
80   
81    /**
82    * Replaces all occurrences of <code>search</code> in <code>text</code>
83    * by <code>replace</code> and returns the result.
84    *
85    * @param text text to work on
86    * @param search replace this text by <code>replace</code>
87    * @param replace replacement for <code>search</code>
88    */
 
89  28505 toggle public static void replace(final StringBuffer text,
90    final String search, final String replace) {
91   
92  28505 final String result = replace(text.toString(), search, replace);
93  28505 text.setLength(0);
94  28505 text.append(result);
95    // LATER mime 20050205: check if the above could be replaced with:
96    /*
97    final StringBuffer result = new StringBuffer();
98    int pos1 = 0;
99    int pos2;
100    final int len = search.length();
101    while (0 <= (pos2 = text.indexOf(search, pos1))) {
102    result.append(text.substring(pos1, pos2));
103    result.append(replace);
104    pos1 = pos2 + len;
105    }
106    if (pos1 < text.length()) {
107    result.append(text.substring(pos1));
108    }
109    text.setLength(0);
110    text.append(result);
111    */
112    }
113   
114    /**
115    * Quotes a <code>String</code>. A a quote character &quot; is appended at the
116    * beginning and the end of the <code>String</code>. If a quote character occurs
117    * within the string it is replaced by two quotes.
118    *
119    * @param unquoted the unquoted <code>String</code>
120    * @return quoted <code>String</code>
121    * @throws NullPointerException if <code>unquoted == null</code>
122    */
 
123  0 toggle public static String quote(final String unquoted) {
124  0 String result = "\"";
125   
126  0 for (int i = 0; i < unquoted.length(); i++) {
127  0 if (unquoted.charAt(i) == '\"') {
128  0 result += "\"\"";
129    } else {
130  0 result += unquoted.charAt(i);
131    }
132    }
133  0 result += '\"';
134  0 return result;
135    }
136   
137    /**
138    * Tests if given <code>String</code> begins with a letter and contains
139    * only letters and digits.
140    *
141    * @param text test this
142    * @return is <code>text</code> only made of letters and digits and has
143    * a leading letter?
144    * @throws NullPointerException if <code>text == null</code>
145    */
 
146  0 toggle public static boolean isLetterDigitString(final String text) {
147  0 if (text.length() <= 0) {
148  0 return false;
149    }
150  0 if (!Character.isLetter(text.charAt(0))) {
151  0 return false;
152    }
153  0 for (int i = 1; i < text.length(); i++) {
154  0 if (!Character.isLetterOrDigit(text.charAt(i))) {
155  0 return false;
156    }
157    }
158  0 return true;
159    }
160   
161    /**
162    * Get amount of spaces.
163    *
164    * @param length number of spaces
165    * @return String contains exactly <code>number</code> spaces
166    */
 
167  4 toggle public static StringBuffer getSpaces(final int length) {
168  4 final StringBuffer buffer = new StringBuffer(length >= 0 ? length : 0);
169  76 for (int i = 0; i < length; i++) {
170  72 buffer.append(' ');
171    }
172  4 return buffer;
173    }
174   
175    /**
176    * Get non qualified class name.
177    *
178    * @param clazz Class.
179    * @return Non qualified class name.
180    */
 
181  30222 toggle public static String getClassName(final Class clazz) {
182  30222 return clazz.getName().substring(clazz.getName().lastIndexOf('.') + 1);
183    }
184   
185    /**
186    * Search for first line followed by whitespace and delete this string within the whole
187    * text.
188    * <p>
189    * For example the following text
190    *<pre>
191    * Do you know the muffin man,
192    * The muffin man, the muffin man,
193    * Do you know the muffin man,
194    * Who lives on Drury Lane?
195    *</pre>
196    * will be converted into:
197    *<pre>
198    *Do you know the muffin man,
199    *The muffin man, the muffin man,
200    *Do you know the muffin man,
201    *Who lives on Drury Lane?
202    *</pre>
203    *
204    * @param buffer Work on this text.
205    */
 
206  1846 toggle public static void deleteLineLeadingWhitespace(final StringBuffer buffer) {
207  1846 int start = -1;
208  ? while (0 <= (start = buffer.indexOf("\n", start + 1))) {
209  438 if (start + 1 < buffer.length() && '\n' != buffer.charAt(start + 1)) {
210  392 break;
211    }
212    }
213  1846 if (start >= 0) {
214  392 int next = start + 1;
215  5982 while (next < buffer.length() && Character.isWhitespace(buffer.charAt(next))
216    && '\n' != buffer.charAt(next)) {
217  5590 next++;
218    }
219  392 final String empty = buffer.substring(start, next);
220  392 if (empty.length() > 0) {
221  392 replace(buffer, empty, "\n");
222    }
223    }
224    }
225   
226    /**
227    * Return a String like it appears in an property file. Thus certain characters are escaped.
228    *
229    * @param value Escape this value.
230    * @return Escaped form.
231    */
 
232  0 toggle public static String escapeProperty(final String value) {
233  0 Properties newprops = new Properties();
234  0 newprops.put("key", value);
235  0 ByteArrayOutputStream out = new ByteArrayOutputStream();
236  0 try {
237  0 newprops.store(out, null);
238    } catch (IOException e) {
239  0 throw new RuntimeException(e);
240    }
241  0 try {
242  0 final String file = out.toString("ISO-8859-1");
243  0 return file.substring(file.indexOf('\n') + 1 + "key=".length());
244    } catch (UnsupportedEncodingException e) {
245  0 throw new RuntimeException(e);
246    }
247    }
248   
249    /**
250    * Return a String without XML specific encoding.
251    *
252    * @param value Data containing markup like &gt;.
253    * @return Escaped form.
254    */
 
255  3745 toggle public static String decodeXmlMarkup(final StringBuffer value) {
256    // TODO mime 20080309: replace numerical entities starting with "&"
257    // see http://www.w3.org/TR/2000/WD-xml-2e-20000814#dt-charref
258  3745 replace(value, "&lt;", "<");
259  3745 replace(value, "&gt;", ">");
260  3745 replace(value, "&amp;", "&");
261  3745 return value.toString();
262    }
263   
264    /**
265    * Trim an integer with zeros to a given maximum length.
266    *
267    * @param number Format this long. Must not be less than 0.
268    * @param length Maximum length. Must not be bigger than 20.
269    * @return String with minimum <code>length</code>, trimed with leading zeros.
270    */
 
271  0 toggle public static final String format(final long number, final int length) {
272  0 if (length > FORMATED_ZERO.length()) {
273  0 throw new IllegalArgumentException("maximum length " + FORMATED_ZERO + " exceeded: "
274    + length);
275    }
276  0 if (number < 0) {
277  0 throw new IllegalArgumentException("number must be bigger than 0: " + number);
278    }
279  0 final String temp = FORMATED_ZERO + number;
280  0 return temp.substring(temp.length() - length);
281    }
282   
283    /**
284    * Get a hex string representation for an byte array.
285    *
286    * @param data <code>byte</code> array to work on
287    * @return hex string of <code>data</code>
288    */
 
289  0 toggle public static String string2Hex(final String data) {
290   
291  0 StringBuffer buffer = new StringBuffer();
292  0 for (int i = 0; i < data.length(); i++) {
293  0 String b = Integer.toHexString(255 & data.charAt(i));
294  0 if (i != 0) {
295  0 if (0 != i % 16) {
296  0 buffer.append(" ");
297    } else {
298  0 buffer.append("\n");
299    }
300    }
301  0 if (b.length() < 2) {
302  0 buffer.append("0");
303    }
304  0 buffer.append(b.toUpperCase());
305    }
306  0 return buffer.toString();
307    }
308   
309    /**
310    * Get a String out of a hex string representation.
311    *
312    * @param hex hex string representation of data
313    * @return String
314    */
 
315  0 toggle public static String hex2String(final String hex) {
316   
317  0 StringBuffer buffer = new StringBuffer(hex.length());
318  0 char c;
319  0 for (int i = 0; i < hex.length(); i++) {
320  0 c = hex.charAt(i);
321  0 if (!Character.isWhitespace(c)) {
322  0 if (!Character.isLetterOrDigit(c)) {
323  0 throw new IllegalArgumentException("Illegal hex char");
324    }
325  0 buffer.append(c);
326    }
327    }
328  0 if (buffer.length() % 2 != 0) {
329  0 throw new IllegalArgumentException("Bad padding");
330    }
331  0 StringBuffer result = new StringBuffer(buffer.length() / 2);
332  0 for (int i = 0; i < buffer.length() / 2; i++) {
333  0 try {
334  0 result.append((char) Integer.parseInt(buffer.substring(2 * i, 2 * i + 2), 16));
335    } catch (Exception e) {
336  0 throw new IllegalArgumentException("Illegal hex char");
337    }
338    }
339  0 return result.toString();
340    }
341   
342    /**
343    * Get platform dependent line separator. (<code>&quot;\n&quot;</code> on UNIX).
344    *
345    * @return Platform dependent line separator.
346    */
 
347  573 toggle public static String getSystemLineSeparator() {
348  573 return (SystemUtils.LINE_SEPARATOR != null ? SystemUtils.LINE_SEPARATOR
349    : "\n");
350    }
351   
352    /**
353    * Creates String with platform dependent line ends.
354    *
355    * @param text Text with CR or CR LF as line end markers. Might be <code>null</code>.
356    * @return Text with platform dependent line ends.
357    */
 
358  573 toggle public static String useSystemLineSeparator(final String text) {
359  573 if (text == null) {
360  0 return null;
361    }
362  573 final StringBuffer buffer = new StringBuffer(text.length());
363  573 final BufferedReader reader = new BufferedReader(new StringReader(text));
364  573 final String separator = getSystemLineSeparator();
365  573 String line;
366  573 boolean notFirst = false;
367  573 try {
368  ? while (null != (line = reader.readLine())) {
369  1175 if (notFirst) {
370  602 buffer.append(separator);
371    }
372  1175 buffer.append(line);
373  1175 notFirst = true;
374    }
375    } catch (IOException e) {
376  0 throw new RuntimeException(e);
377    }
378  573 return buffer.toString();
379    }
380   
381    }