1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.fulcrum.yaafi.framework.util;
21
22 import java.util.Map;
23
24
25 /**
26 * A subset of the utilities available in commons-lang-2.1 StringUtils.
27 *
28 * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
29 */
30 public class StringUtils
31 {
32
33
34 /**
35 * <p>Replaces a String with another String inside a larger String, once.</p>
36 *
37 * <p>A <code>null</code> reference passed to this method is a no-op.</p>
38 *
39 * <pre>
40 * StringUtils.replaceOnce(null, *, *) = null
41 * StringUtils.replaceOnce("", *, *) = ""
42 * StringUtils.replaceOnce("aba", null, null) = "aba"
43 * StringUtils.replaceOnce("aba", null, null) = "aba"
44 * StringUtils.replaceOnce("aba", "a", null) = "aba"
45 * StringUtils.replaceOnce("aba", "a", "") = "aba"
46 * StringUtils.replaceOnce("aba", "a", "z") = "zba"
47 * </pre>
48 *
49 * @see #replace(String text, String repl, String with, int max)
50 * @param text text to search and replace in, may be null
51 * @param repl the String to search for, may be null
52 * @param with the String to replace with, may be null
53 * @return the text with any replacements processed,
54 * <code>null</code> if null String input
55 */
56 public static String replaceOnce(String text, String repl, String with) {
57 return replace(text, repl, with, 1);
58 }
59
60 /**
61 * <p>Replaces all occurrences of a String within another String.</p>
62 *
63 * <p>A <code>null</code> reference passed to this method is a no-op.</p>
64 *
65 * <pre>
66 * StringUtils.replace(null, *, *) = null
67 * StringUtils.replace("", *, *) = ""
68 * StringUtils.replace("aba", null, null) = "aba"
69 * StringUtils.replace("aba", null, null) = "aba"
70 * StringUtils.replace("aba", "a", null) = "aba"
71 * StringUtils.replace("aba", "a", "") = "aba"
72 * StringUtils.replace("aba", "a", "z") = "zbz"
73 * </pre>
74 *
75 * @see #replace(String text, String repl, String with, int max)
76 * @param text text to search and replace in, may be null
77 * @param repl the String to search for, may be null
78 * @param with the String to replace with, may be null
79 * @return the text with any replacements processed,
80 * <code>null</code> if null String input
81 */
82 public static String replace(String text, String repl, String with) {
83 return replace(text, repl, with, -1);
84 }
85
86 /**
87 * <p>Replaces a String with another String inside a larger String,
88 * for the first <code>max</code> values of the search String.</p>
89 *
90 * <p>A <code>null</code> reference passed to this method is a no-op.</p>
91 *
92 * <pre>
93 * StringUtils.replace(null, *, *, *) = null
94 * StringUtils.replace("", *, *, *) = ""
95 * StringUtils.replace("abaa", null, null, 1) = "abaa"
96 * StringUtils.replace("abaa", null, null, 1) = "abaa"
97 * StringUtils.replace("abaa", "a", null, 1) = "abaa"
98 * StringUtils.replace("abaa", "a", "", 1) = "abaa"
99 * StringUtils.replace("abaa", "a", "z", 0) = "abaa"
100 * StringUtils.replace("abaa", "a", "z", 1) = "zbaa"
101 * StringUtils.replace("abaa", "a", "z", 2) = "zbza"
102 * StringUtils.replace("abaa", "a", "z", -1) = "zbzz"
103 * </pre>
104 *
105 * @param text text to search and replace in, may be null
106 * @param repl the String to search for, may be null
107 * @param with the String to replace with, may be null
108 * @param max maximum number of values to replace, or <code>-1</code> if no maximum
109 * @return the text with any replacements processed,
110 * <code>null</code> if null String input
111 */
112 public static String replace(String text, String repl, String with, int max) {
113 if (text == null || repl == null || with == null || repl.length() == 0 || max == 0) {
114 return text;
115 }
116
117 StringBuffer buf = new StringBuffer(text.length());
118 int start = 0, end = 0;
119 while ((end = text.indexOf(repl, start)) != -1) {
120 buf.append(text.substring(start, end)).append(with);
121 start = end + repl.length();
122
123 if (--max == 0) {
124 break;
125 }
126 }
127 buf.append(text.substring(start));
128 return buf.toString();
129 }
130
131
132
133 /**
134 * <p>Replaces all occurrences of a character in a String with another.
135 * This is a null-safe version of {@link String#replace(char, char)}.</p>
136 *
137 * <p>A <code>null</code> string input returns <code>null</code>.
138 * An empty ("") string input returns an empty string.</p>
139 *
140 * <pre>
141 * StringUtils.replaceChars(null, *, *) = null
142 * StringUtils.replaceChars("", *, *) = ""
143 * StringUtils.replaceChars("abcba", 'b', 'y') = "aycya"
144 * StringUtils.replaceChars("abcba", 'z', 'y') = "abcba"
145 * </pre>
146 *
147 * @param str String to replace characters in, may be null
148 * @param searchChar the character to search for, may be null
149 * @param replaceChar the character to replace, may be null
150 * @return modified String, <code>null</code> if null string input
151 * @since 2.0
152 */
153 public static String replaceChars(String str, char searchChar,
154 char replaceChar)
155 {
156 if (str == null)
157 {
158 return null;
159 }
160 return str.replace( searchChar, replaceChar );
161 }
162
163 /**
164 * <p>Replaces multiple characters in a String in one go.
165 * This method can also be used to delete characters.</p>
166 *
167 * <p>For example:<br />
168 * <code>replaceChars("hello", "ho", "jy") = jelly</code>.</p>
169 *
170 * <p>A <code>null</code> string input returns <code>null</code>.
171 * An empty ("") string input returns an empty string.
172 * A null or empty set of search characters returns the input string.</p>
173 *
174 * <p>The length of the search characters should normally equal the length
175 * of the replace characters.
176 * If the search characters is longer, then the extra search characters
177 * are deleted.
178 * If the search characters is shorter, then the extra replace characters
179 * are ignored.</p>
180 *
181 * <pre>
182 * StringUtils.replaceChars(null, *, *) = null
183 * StringUtils.replaceChars("", *, *) = ""
184 * StringUtils.replaceChars("abc", null, *) = "abc"
185 * StringUtils.replaceChars("abc", "", *) = "abc"
186 * StringUtils.replaceChars("abc", "b", null) = "ac"
187 * StringUtils.replaceChars("abc", "b", "") = "ac"
188 * StringUtils.replaceChars("abcba", "bc", "yz") = "ayzya"
189 * StringUtils.replaceChars("abcba", "bc", "y") = "ayya"
190 * StringUtils.replaceChars("abcba", "bc", "yzx") = "ayzya"
191 * </pre>
192 *
193 * @param str String to replace characters in, may be null
194 * @param searchChars a set of characters to search for, may be null
195 * @param replaceChars a set of characters to replace, may be null
196 * @return modified String, <code>null</code> if null string input
197 * @since 2.0
198 */
199 public static String replaceChars(String str, String searchChars,
200 String replaceChars)
201 {
202 if (isEmpty( str ) || isEmpty( searchChars ))
203 {
204 return str;
205 }
206 if (replaceChars == null)
207 {
208 replaceChars = "";
209 }
210 boolean modified = false;
211 StringBuffer buf = new StringBuffer( str.length() );
212 for (int i = 0; i < str.length(); i++)
213 {
214 char ch = str.charAt( i );
215 int index = searchChars.indexOf( ch );
216 if (index >= 0)
217 {
218 modified = true;
219 if (index < replaceChars.length())
220 {
221 buf.append( replaceChars.charAt( index ) );
222 }
223 }
224 else
225 {
226 buf.append( ch );
227 }
228 }
229 if (modified)
230 {
231 return buf.toString();
232 }
233 else
234 {
235 return str;
236 }
237 }
238
239 /**
240 * <p>Checks if a String is empty ("") or null.</p>
241 *
242 * <pre>
243 * StringUtils.isEmpty(null) = true
244 * StringUtils.isEmpty("") = true
245 * StringUtils.isEmpty(" ") = false
246 * StringUtils.isEmpty("bob") = false
247 * StringUtils.isEmpty(" bob ") = false
248 * </pre>
249 *
250 * <p>NOTE: This method changed in Lang version 2.0.
251 * It no longer trims the String.
252 * That functionality is available in isBlank().</p>
253 *
254 * @param str the String to check, may be null
255 * @return <code>true</code> if the String is empty or null
256 */
257 public static boolean isEmpty(String str)
258 {
259 return str == null || str.length() == 0;
260 }
261
262 /**
263 * Perform a series of substitutions. The substitions
264 * are performed by replacing ${variable} in the target
265 * string with the value of provided by the key "variable"
266 * in the provided hashtable.
267 *
268 * @param argStr target string
269 * @param vars name/value pairs used for substitution
270 * @param isLenient ignore failures
271 * @return String target string with replacements.
272 */
273 public static StringBuffer stringSubstitution(String argStr, Map vars, boolean isLenient)
274 {
275 StringBuffer argBuf = new StringBuffer();
276 int argStrLength = argStr.length();
277
278 for (int cIdx = 0 ; cIdx < argStrLength;)
279 {
280 char ch = argStr.charAt(cIdx);
281 char del = ' ';
282
283 switch (ch)
284 {
285 case '$':
286 StringBuffer nameBuf = new StringBuffer();
287 del = argStr.charAt(cIdx+1);
288 if( del == '{')
289 {
290 cIdx++;
291
292 for (++cIdx ; cIdx < argStr.length(); ++cIdx)
293 {
294 ch = argStr.charAt(cIdx);
295 if (ch != '}')
296 nameBuf.append(ch);
297 else
298 break;
299 }
300
301 if (nameBuf.length() > 0)
302 {
303 Object value = vars.get(nameBuf.toString());
304
305 if (value != null)
306 {
307 argBuf.append(value.toString());
308 }
309 else
310 {
311 if (!isLenient)
312 {
313 throw new RuntimeException("No value found for : " + nameBuf );
314 }
315 }
316
317 del = argStr.charAt(cIdx);
318
319 if( del != '}')
320 {
321 throw new RuntimeException("Delimineter not found for : " + nameBuf );
322 }
323 }
324
325 cIdx++;
326 }
327 else
328 {
329 argBuf.append(ch);
330 ++cIdx;
331 }
332
333 break;
334
335 default:
336 argBuf.append(ch);
337 ++cIdx;
338 break;
339 }
340 }
341
342 return argBuf;
343 }
344 }