Clover coverage report - PMD - 3.9
Coverage timestamp: Tue Dec 19 2006 09:38:44 EST
file stats: LOC: 259   Methods: 11
NCLOC: 157   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
StringUtil.java 42.6% 50.4% 54.5% 47.9%
coverage coverage
 1    /**
 2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
 3    */
 4    package net.sourceforge.pmd.util;
 5   
 6    import java.util.ArrayList;
 7    import java.util.Iterator;
 8    import java.util.List;
 9   
 10    public class StringUtil {
 11   
 12    public static final String[] EMPTY_STRINGS = new String[0];
 13    private static final boolean supportsUTF8 = System.getProperty("net.sourceforge.pmd.supportUTF8", "no").equals("yes");
 14    private static final String[] ENTITIES;
 15   
 16    static {
 17  17 ENTITIES = new String[256 - 126];
 18  17 for (int i = 126; i <= 255; i++) {
 19  2210 ENTITIES[i - 126] = "&#" + i + ';';
 20    }
 21    }
 22   
 23  24 public static String replaceString(String original, char oldChar, String newString) {
 24   
 25  24 String fixedNew = newString == null ? "" : newString;
 26   
 27  24 StringBuffer desc = new StringBuffer();
 28  24 int index = original.indexOf(oldChar);
 29  24 int last = 0;
 30  24 while (index != -1) {
 31  6 desc.append(original.substring(last, index));
 32  6 desc.append(fixedNew);
 33  6 last = index + 1;
 34  6 index = original.indexOf(oldChar, last);
 35    }
 36  24 desc.append(original.substring(last));
 37  24 return desc.toString();
 38    }
 39   
 40  5 public static String replaceString(String original, String oldString, String newString) {
 41   
 42  5 String fixedNew = newString == null ? "" : newString;
 43   
 44  5 StringBuffer desc = new StringBuffer();
 45  5 int index = original.indexOf(oldString);
 46  5 int last = 0;
 47  5 while (index != -1) {
 48  1 desc.append(original.substring(last, index));
 49  1 desc.append(fixedNew);
 50  1 last = index + oldString.length();
 51  1 index = original.indexOf(oldString, last);
 52    }
 53  5 desc.append(original.substring(last));
 54  5 return desc.toString();
 55    }
 56   
 57    /**
 58    * Appends to a StringBuffer the String src where non-ASCII and
 59    * XML special chars are escaped.
 60    *
 61    * @param buf The destination XML stream
 62    * @param src The String to append to the stream
 63    */
 64  41 public static void appendXmlEscaped(StringBuffer buf, String src) {
 65  41 appendXmlEscaped(buf, src, supportsUTF8);
 66    }
 67   
 68  6 public static String htmlEncode(String string) {
 69  6 String encoded = StringUtil.replaceString(string, '&', "&amp;");
 70  6 encoded = StringUtil.replaceString(encoded, '<', "&lt;");
 71  6 return StringUtil.replaceString(encoded, '>', "&gt;");
 72    }
 73   
 74    // TODO - unify the method above with the one below
 75   
 76  41 private static void appendXmlEscaped(StringBuffer buf, String src, boolean supportUTF8) {
 77  41 char c;
 78  41 for (int i = 0; i < src.length(); i++) {
 79  205 c = src.charAt(i);
 80  205 if (c > '~') {// 126
 81  0 if (!supportUTF8) {
 82  0 if (c <= 255) {
 83  0 buf.append(ENTITIES[c - 126]);
 84    } else {
 85  0 buf.append("&u").append(Integer.toHexString(c)).append(';');
 86    }
 87    } else {
 88  0 buf.append(c);
 89    }
 90  205 } else if (c == '&')
 91  0 buf.append("&amp;");
 92  205 else if (c == '"')
 93  0 buf.append("&quot;");
 94  205 else if (c == '<')
 95  0 buf.append("&lt;");
 96  205 else if (c == '>')
 97  0 buf.append("&gt;");
 98    else
 99  205 buf.append(c);
 100    }
 101    }
 102   
 103    /**
 104    * Parses the input source using the delimiter specified. This method is much
 105    * faster than using the StringTokenizer or String.split(char) approach and
 106    * serves as a replacement for String.split() for JDK1.3 that doesn't have it.
 107    *
 108    * @param source String
 109    * @param delimiter char
 110    * @return String[]
 111    */
 112  13 public static String[] substringsOf(String source, char delimiter) {
 113   
 114  13 if (source == null || source.length() == 0) {
 115  0 return EMPTY_STRINGS;
 116    }
 117   
 118  13 int delimiterCount = 0;
 119  13 int length = source.length();
 120  13 char[] chars = source.toCharArray();
 121   
 122  13 for (int i=0; i<length; i++) {
 123  75 if (chars[i] == delimiter) delimiterCount++;
 124    }
 125   
 126  2 if (delimiterCount == 0) return new String[] { source };
 127   
 128  11 String results[] = new String[delimiterCount+1];
 129   
 130  11 int i = 0;
 131  11 int offset = 0;
 132   
 133  11 while (offset <= length) {
 134  86 int pos = source.indexOf(delimiter, offset);
 135  11 if (pos < 0) pos = length;
 136  86 results[i++] = pos == offset ? "" : source.substring(offset, pos);
 137  86 offset = pos + 1;
 138    }
 139   
 140  11 return results;
 141    }
 142   
 143    /**
 144    * Much more efficient than StringTokenizer.
 145    *
 146    * @param str String
 147    * @param separator char
 148    * @return String[]
 149    */
 150  0 public static String[] substringsOf(String str, String separator) {
 151   
 152  0 if (str == null || str.length() == 0) {
 153  0 return EMPTY_STRINGS;
 154    }
 155   
 156  0 int index = str.indexOf(separator);
 157  0 if (index == -1) {
 158  0 return new String[]{str};
 159    }
 160   
 161  0 List list = new ArrayList();
 162  0 int currPos = 0;
 163  0 int len = separator.length();
 164  0 while (index != -1) {
 165  0 list.add(str.substring(currPos, index));
 166  0 currPos = index + len;
 167  0 index = str.indexOf(separator, currPos);
 168    }
 169  0 list.add(str.substring(currPos));
 170  0 return (String[]) list.toArray(new String[list.size()]);
 171    }
 172   
 173   
 174    /**
 175    * Copies the elements returned by the iterator onto the string buffer
 176    * each delimited by the separator.
 177    *
 178    * @param sb StringBuffer
 179    * @param iter Iterator
 180    * @param separator String
 181    */
 182  0 public static void asStringOn(StringBuffer sb, Iterator iter, String separator) {
 183   
 184  0 if (!iter.hasNext()) return;
 185   
 186  0 sb.append(iter.next());
 187   
 188  0 while (iter.hasNext()) {
 189  0 sb.append(separator);
 190  0 sb.append(iter.next());
 191    }
 192    }
 193    /**
 194    * Return the length of the shortest string in the array.
 195    * If any one of them is null then it returns 0.
 196    *
 197    * @param strings String[]
 198    * @return int
 199    */
 200  0 public static int lengthOfShortestIn(String[] strings) {
 201   
 202  0 int minLength = Integer.MAX_VALUE;
 203   
 204  0 for (int i=0; i<strings.length; i++) {
 205  0 if (strings[i] == null) return 0;
 206  0 minLength = Math.min(minLength, strings[i].length());
 207    }
 208   
 209  0 return minLength;
 210    }
 211   
 212    /**
 213    * Determine the maximum number of common leading whitespace characters
 214    * the strings share in the same sequence. Useful for determining how
 215    * many leading characters can be removed to shift all the text in the
 216    * strings to the left without misaligning them.
 217    *
 218    * @param strings String[]
 219    * @return int
 220    */
 221  0 public static int maxCommonLeadingWhitespaceForAll(String[] strings) {
 222   
 223  0 int shortest = lengthOfShortestIn(strings);
 224  0 if (shortest == 0) return 0;
 225   
 226  0 char[] matches = new char[shortest];
 227   
 228  0 String str;
 229  0 for (int m=0; m<matches.length; m++) {
 230  0 matches[m] = strings[0].charAt(m);
 231  0 if (!Character.isWhitespace(matches[m])) return m;
 232  0 for (int i=0; i<strings.length; i++) {
 233  0 str = strings[i];
 234  0 if (str.charAt(m) != matches[m]) return m;
 235    }
 236    }
 237   
 238  0 return shortest;
 239    }
 240   
 241    /**
 242    * Trims off the leading characters off the strings up to the trimDepth
 243    * specified. Returns the same strings if trimDepth = 0
 244    *
 245    * @param strings
 246    * @param trimDepth
 247    * @return String[]
 248    */
 249  0 public static String[] trimStartOn(String[] strings, int trimDepth) {
 250   
 251  0 if (trimDepth == 0) return strings;
 252   
 253  0 String[] results = new String[strings.length];
 254  0 for (int i=0; i<strings.length; i++) {
 255  0 results[i] = strings[i].substring(trimDepth);
 256    }
 257  0 return results;
 258    }
 259    }