Clover coverage report - PMD - 3.9 Coverage timestamp: Tue Dec 19 2006 09:38:44 EST FRAMES NO FRAMES |
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% |

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 |  | }