1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.pluto.util;
21
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.Map;
25
26 /***
27 ** <CODE>StringUtils</CODE> hosts a couple of utility methods around
28 ** strings.
29 **/
30
31 public class StringUtils
32 {
33
34 static java.util.BitSet dontNeedEncoding;
35 static final int caseDiff = ('a' - 'A');
36
37
38
39
40 static {
41 dontNeedEncoding = new java.util.BitSet(256);
42 int i;
43 for (i = 'a'; i <= 'z'; i++)
44 {
45 dontNeedEncoding.set(i);
46 }
47 for (i = 'A'; i <= 'Z'; i++)
48 {
49 dontNeedEncoding.set(i);
50 }
51 for (i = '0'; i <= '9'; i++)
52 {
53 dontNeedEncoding.set(i);
54 }
55 dontNeedEncoding.set('-');
56 dontNeedEncoding.set('_');
57 dontNeedEncoding.set('.');
58 dontNeedEncoding.set('*');
59 }
60
61 /***
62 ** The operating system's line separator ('\n' on UNIX, '\r\n' on Windows)
63 **/
64
65 public static final String lineSeparator = System.getProperty("line.separator");
66
67 /***
68 ** Returns the name of the package of the specified class.
69 ** The package will not include the common (short) name of the
70 ** class or the file extension.
71 **
72 ** @param aClass
73 ** a class object
74 **
75 ** @return its package
76 **/
77
78 public static String packageOf (Class aClass)/package-summary.html">ong> static String packageOf (Class aClass)
79 {
80 if (aClass == null)
81 {
82 throw (new IllegalArgumentException ("StringUtils: Argument \"aClass\" cannot be null."));
83 }
84
85 String result = "";
86
87 int index = aClass.getName ().lastIndexOf (".");
88
89 if (index >= 0)
90 {
91 result = aClass.getName ().substring (0, index);
92 }
93
94 return(result);
95 }
96
97 /***
98 * Returns the short name of the specified class.
99 * The name will not include the package name or file extension.
100 *
101 * @param aClass
102 * a class object
103 *
104 * @return its name
105 */
106
107 public static String nameOf (Class aClass)
108 {
109 if (aClass == null)
110 {
111 throw new IllegalArgumentException ("StringUtils: Argument \"aClass\" cannot be null.");
112 }
113
114 String className = aClass.getName ();
115
116 int index = className.lastIndexOf (".");
117
118 if (index >= 0)
119 {
120 className = className.substring (index + 1);
121 }
122
123 return(className);
124 }
125
126 /***
127 * Returns a combination of two paths, inserting slashes as appropriate.
128 *
129 * @param aRoot
130 * a root path
131 * @param aPath
132 * a path
133 *
134 * @return the path
135 */
136
137 public static String pathOf (String aRoot, String aPath)
138 {
139 if (aPath == null)
140 {
141 throw new IllegalArgumentException ("StringUtils: Argument \"aPath\" cannot be null.");
142 }
143
144 String result = null;
145
146 if (aPath.startsWith ("/") ||
147 aPath.startsWith ("//") ||
148 (aPath.length () >= 2 && aPath.charAt (1) == ':'))
149 {
150 result = aPath;
151 }
152 else
153 {
154 if (aRoot == null)
155 {
156 throw new IllegalArgumentException ("StringUtils: Argument \"aRoot\" cannot be null.");
157 }
158
159 StringBuffer temp = new StringBuffer (aRoot);
160
161 if (! aRoot.endsWith ("/") &&
162 ! aRoot.endsWith ("//"))
163 {
164 temp.append ('/');
165 }
166
167 temp.append (aPath);
168
169 result = temp.toString ();
170 }
171
172 return result.toString();
173 }
174
175 /***
176 * Returns a <CODE>Boolean</CODE> object that corresponds the given value.
177 * A value of <CODE>true</CODE> or <CODE>yes</CODE> corresponds to
178 * <CODE>Boolean.TRUE</CODE> and a value of <CODE>false</CODE> or
179 * <CODE>no</CODE> corresponds to <CODE>Boolean.FALSE</CODE>.
180 * The comparions is case-insensitive, but for performance reasons,
181 * lower-case values of <CODE>true</CODE> and <CODE>false</CODE>
182 * should be used.
183 *
184 * @param aValue
185 * to value to convert
186 *
187 * @return the boolean value
188 */
189 public static Boolean booleanOf (String aValue)
190 {
191 Boolean result = null;
192
193 if (aValue != null)
194 {
195 if (aValue == "true" ||
196 aValue == "yes" ||
197 aValue.equalsIgnoreCase ("true") ||
198 aValue.equalsIgnoreCase ("yes"))
199 {
200 result = Boolean.TRUE;
201 }
202 else if (aValue == "false" ||
203 aValue == "no" ||
204 aValue.equalsIgnoreCase ("false") ||
205 aValue.equalsIgnoreCase ("no"))
206 {
207 result = Boolean.FALSE;
208 }
209 }
210
211 return(result);
212 }
213
214 /***
215 * Replace all occurrences of a pattern within a string by a replacement
216 *
217 * @param source The string that should be searched
218 * @param pattern The pattern that should be replaced
219 * @param replace The replacement that should be inserted instead of the pattern
220 *
221 * @return The updated source string
222 */
223 public static String replace(String source, String pattern, String replace)
224 {
225 if (source == null || source.length() == 0 ||
226 pattern == null || pattern.length() == 0)
227 {
228 return source;
229 }
230
231 int k = source.indexOf(pattern);
232
233 if (k == -1)
234 {
235 return source;
236 }
237
238 StringBuffer out = new StringBuffer();
239 int i=0, l=pattern.length();
240
241 while (k != -1)
242 {
243 out.append(source.substring(i,k));
244
245 if (replace != null) {
246 out.append(replace);
247 }
248
249 i = k+l;
250 k = source.indexOf(pattern, i);
251 }
252 out.append(source.substring(i));
253 return out.toString();
254 }
255
256 public static void newLine(StringBuffer buffer, int indent)
257 {
258 buffer.append(StringUtils.lineSeparator);
259 indent(buffer, indent);
260 }
261
262 public static void indent(StringBuffer buffer, int indent)
263 {
264 for (int i=0; i<indent; i++) buffer.append(' ');
265 }
266
267 public static String encode(String s)
268 {
269 int maxBytesPerChar = 10;
270 StringBuffer out = new StringBuffer(s.length());
271 java.io.ByteArrayOutputStream buf = new java.io.ByteArrayOutputStream(maxBytesPerChar);
272 java.io.OutputStreamWriter writer = new java.io.OutputStreamWriter(buf);
273
274 for (int i = 0; i < s.length(); i++)
275 {
276 int c = (int)s.charAt(i);
277 if (dontNeedEncoding.get(c))
278 {
279 out.append((char)c);
280 }
281 else
282 {
283
284 try
285 {
286 writer.write(c);
287 writer.flush();
288 }
289 catch (java.io.IOException e)
290 {
291 buf.reset();
292 continue;
293 }
294 byte[] ba = buf.toByteArray();
295 for (int j = 0; j < ba.length; j++)
296 {
297 out.append('x');
298 char ch = Character.forDigit((ba[j] >> 4) & 0xF, 16);
299
300
301 if (Character.isLetter(ch))
302 {
303 ch -= caseDiff;
304 }
305 out.append(ch);
306 ch = Character.forDigit(ba[j] & 0xF, 16);
307 if (Character.isLetter(ch))
308 {
309 ch -= caseDiff;
310 }
311 out.append(ch);
312 }
313 buf.reset();
314 }
315 }
316
317 return out.toString();
318 }
319
320 public static String decode(String s)
321 {
322 StringBuffer sb = new StringBuffer();
323 for (int i=0; i<s.length(); i++)
324 {
325 char c = s.charAt(i);
326 switch (c)
327 {
328 case '%':
329 if (((s.charAt(i+1)>='0') && (s.charAt(i+1)<='9')) &&
330 ((s.charAt(i+2)>='0') && (s.charAt(i+2)<='9')))
331 {
332 try
333 {
334 sb.append((char)Integer.parseInt(s.substring(i+1, i+3), 16));
335 }
336 catch (java.lang.NumberFormatException e)
337 {
338 throw new java.lang.IllegalArgumentException();
339 }
340 i += 2;
341 break;
342 }
343 default:
344 sb.append(c);
345 break;
346 }
347 }
348
349 String result = sb.toString();
350 try
351 {
352 byte[] inputBytes = result.getBytes("8859_1");
353 result = new String(inputBytes);
354 }
355 catch (java.io.UnsupportedEncodingException e)
356 {
357
358 }
359 return result;
360 }
361
362 public static String[] copy(String[] source)
363 {
364 if (source == null)
365 return null;
366 int length = source.length;
367 String[] result = new String[length];
368 System.arraycopy(source, 0, result, 0, length);
369 return result;
370 }
371
372 public static Map copyParameters(Map parameters)
373 {
374 Map result = new HashMap(parameters);
375 for (Iterator iter = result.entrySet().iterator(); iter.hasNext();) {
376 Map.Entry entry = (Map.Entry)iter.next();
377 if (!(entry.getKey() instanceof String)) {
378 throw new IllegalArgumentException("Parameter map keys must not be null and of type java.lang.String.");
379 }
380 try {
381 entry.setValue(copy((String[]) entry.getValue()));
382 } catch (ClassCastException ex) {
383 throw new IllegalArgumentException("Parameter map values must not be null and of type java.lang.String[].");
384 }
385 }
386 return result;
387 }
388
389 }