KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > util > StringUtils


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.util;
18
19 import java.util.ArrayList JavaDoc;
20 import java.util.Arrays JavaDoc;
21 import java.util.Collection JavaDoc;
22 import java.util.Iterator JavaDoc;
23 import java.util.LinkedList JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Locale JavaDoc;
26 import java.util.Properties JavaDoc;
27 import java.util.Set JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29 import java.util.TreeSet JavaDoc;
30
31 /**
32  * Miscellaneous string utility methods. Mainly for internal use
33  * within the framework; consider Jakarta's Commons Lang for a more
34  * comprehensive suite of string utilities.
35  *
36  * <p>This class delivers some simple functionality that should really
37  * be provided by the core Java String and StringBuffer classes, such
38  * as the ability to replace all occurrences of a given substring in a
39  * target string. It also provides easy-to-use methods to convert between
40  * delimited strings, such as CSV strings, and collections and arrays.
41  *
42  * @author Rod Johnson
43  * @author Juergen Hoeller
44  * @author Keith Donald
45  * @author Rob Harrop
46  * @since 16 April 2001
47  * @see org.apache.commons.lang.StringUtils
48  */

49 public abstract class StringUtils {
50
51     private static final String JavaDoc FOLDER_SEPARATOR = "/";
52
53     private static final String JavaDoc WINDOWS_FOLDER_SEPARATOR = "\\";
54
55     private static final String JavaDoc TOP_PATH = "..";
56
57     private static final String JavaDoc CURRENT_PATH = ".";
58
59     private static final char EXTENSION_SEPARATOR = '.';
60
61
62     //---------------------------------------------------------------------
63
// General convenience methods for working with Strings
64
//---------------------------------------------------------------------
65

66     /**
67      * Check that the given String is neither <code>null</code> nor of length 0.
68      * Note: Will return <code>true</code> for a String that purely consists of whitespace.
69      * <p><pre>
70      * StringUtils.hasLength(null) = false
71      * StringUtils.hasLength("") = false
72      * StringUtils.hasLength(" ") = true
73      * StringUtils.hasLength("Hello") = true
74      * </pre>
75      * @param str the String to check (may be <code>null</code>)
76      * @return <code>true</code> if the String is not null and has length
77      * @see #hasText(String)
78      */

79     public static boolean hasLength(String JavaDoc str) {
80         return (str != null && str.length() > 0);
81     }
82
83     /**
84      * Check whether the given String has actual text.
85      * More specifically, returns <code>true</code> if the string not <code>null<code>,
86      * its length is greater than 0, and it contains at least one non-whitespace character.
87      * <p><pre>
88      * StringUtils.hasText(null) = false
89      * StringUtils.hasText("") = false
90      * StringUtils.hasText(" ") = false
91      * StringUtils.hasText("12345") = true
92      * StringUtils.hasText(" 12345 ") = true
93      * </pre>
94      * @param str the String to check (may be <code>null</code>)
95      * @return <code>true</code> if the String is not <code>null</code>, its length is
96      * greater than 0, and is does not contain whitespace only
97      * @see java.lang.Character#isWhitespace
98      */

99     public static boolean hasText(String JavaDoc str) {
100         if (!hasLength(str)) {
101             return false;
102         }
103         int strLen = str.length();
104         for (int i = 0; i < strLen; i++) {
105             if (!Character.isWhitespace(str.charAt(i))) {
106                 return true;
107             }
108         }
109         return false;
110     }
111
112     /**
113      * Check whether the given String contains any whitespace characters.
114      * @param str the String to check (may be <code>null</code>)
115      * @return <code>true</code> if the String is not empty and
116      * contains at least 1 whitespace character
117      * @see java.lang.Character#isWhitespace
118      */

119     public static boolean containsWhitespace(String JavaDoc str) {
120         if (!hasLength(str)) {
121             return false;
122         }
123         int strLen = str.length();
124         for (int i = 0; i < strLen; i++) {
125             if (Character.isWhitespace(str.charAt(i))) {
126                 return true;
127             }
128         }
129         return false;
130     }
131
132     /**
133      * Trim leading and trailing whitespace from the given String.
134      * @param str the String to check
135      * @return the trimmed String
136      * @see java.lang.Character#isWhitespace
137      */

138     public static String JavaDoc trimWhitespace(String JavaDoc str) {
139         if (!hasLength(str)) {
140             return str;
141         }
142         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(str);
143         while (buf.length() > 0 && Character.isWhitespace(buf.charAt(0))) {
144             buf.deleteCharAt(0);
145         }
146         while (buf.length() > 0 && Character.isWhitespace(buf.charAt(buf.length() - 1))) {
147             buf.deleteCharAt(buf.length() - 1);
148         }
149         return buf.toString();
150     }
151
152     /**
153      * Trim leading whitespace from the given String.
154      * @param str the String to check
155      * @return the trimmed String
156      * @see java.lang.Character#isWhitespace
157      */

158     public static String JavaDoc trimLeadingWhitespace(String JavaDoc str) {
159         if (!hasLength(str)) {
160             return str;
161         }
162         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(str);
163         while (buf.length() > 0 && Character.isWhitespace(buf.charAt(0))) {
164             buf.deleteCharAt(0);
165         }
166         return buf.toString();
167     }
168
169     /**
170      * Trim trailing whitespace from the given String.
171      * @param str the String to check
172      * @return the trimmed String
173      * @see java.lang.Character#isWhitespace
174      */

175     public static String JavaDoc trimTrailingWhitespace(String JavaDoc str) {
176         if (!hasLength(str)) {
177             return str;
178         }
179         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(str);
180         while (buf.length() > 0 && Character.isWhitespace(buf.charAt(buf.length() - 1))) {
181             buf.deleteCharAt(buf.length() - 1);
182         }
183         return buf.toString();
184     }
185
186     /**
187      * Trim <i>all</i> whitespace from the given String:
188      * leading, trailing, and inbetween characters.
189      * @param str the String to check
190      * @return the trimmed String
191      * @see java.lang.Character#isWhitespace
192      */

193     public static String JavaDoc trimAllWhitespace(String JavaDoc str) {
194         if (!hasLength(str)) {
195             return str;
196         }
197         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(str);
198         int index = 0;
199         while (buf.length() > index) {
200             if (Character.isWhitespace(buf.charAt(index))) {
201                 buf.deleteCharAt(index);
202             }
203             else {
204                 index++;
205             }
206         }
207         return buf.toString();
208     }
209
210
211     /**
212      * Test if the given String starts with the specified prefix,
213      * ignoring upper/lower case.
214      * @param str the String to check
215      * @param prefix the prefix to look for
216      * @see java.lang.String#startsWith
217      */

218     public static boolean startsWithIgnoreCase(String JavaDoc str, String JavaDoc prefix) {
219         if (str == null || prefix == null) {
220             return false;
221         }
222         if (str.startsWith(prefix)) {
223             return true;
224         }
225         if (str.length() < prefix.length()) {
226             return false;
227         }
228         String JavaDoc lcStr = str.substring(0, prefix.length()).toLowerCase();
229         String JavaDoc lcPrefix = prefix.toLowerCase();
230         return lcStr.equals(lcPrefix);
231     }
232
233     /**
234      * Test if the given String ends with the specified suffix,
235      * ignoring upper/lower case.
236      * @param str the String to check
237      * @param suffix the suffix to look for
238      * @see java.lang.String#endsWith
239      */

240     public static boolean endsWithIgnoreCase(String JavaDoc str, String JavaDoc suffix) {
241         if (str == null || suffix == null) {
242             return false;
243         }
244         if (str.endsWith(suffix)) {
245             return true;
246         }
247         if (str.length() < suffix.length()) {
248             return false;
249         }
250
251         String JavaDoc lcStr = str.substring(str.length() - suffix.length()).toLowerCase();
252         String JavaDoc lcSuffix = suffix.toLowerCase();
253         return lcStr.equals(lcSuffix);
254     }
255
256     /**
257      * Count the occurrences of the substring in string s.
258      * @param str string to search in. Return 0 if this is null.
259      * @param sub string to search for. Return 0 if this is null.
260      */

261     public static int countOccurrencesOf(String JavaDoc str, String JavaDoc sub) {
262         if (str == null || sub == null || str.length() == 0 || sub.length() == 0) {
263             return 0;
264         }
265         int count = 0, pos = 0, idx = 0;
266         while ((idx = str.indexOf(sub, pos)) != -1) {
267             ++count;
268             pos = idx + sub.length();
269         }
270         return count;
271     }
272
273     /**
274      * Replace all occurences of a substring within a string with
275      * another string.
276      * @param inString String to examine
277      * @param oldPattern String to replace
278      * @param newPattern String to insert
279      * @return a String with the replacements
280      */

281     public static String JavaDoc replace(String JavaDoc inString, String JavaDoc oldPattern, String JavaDoc newPattern) {
282         if (inString == null) {
283             return null;
284         }
285         if (oldPattern == null || newPattern == null) {
286             return inString;
287         }
288
289         StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
290         // output StringBuffer we'll build up
291
int pos = 0; // our position in the old string
292
int index = inString.indexOf(oldPattern);
293         // the index of an occurrence we've found, or -1
294
int patLen = oldPattern.length();
295         while (index >= 0) {
296             sbuf.append(inString.substring(pos, index));
297             sbuf.append(newPattern);
298             pos = index + patLen;
299             index = inString.indexOf(oldPattern, pos);
300         }
301         sbuf.append(inString.substring(pos));
302
303         // remember to append any characters to the right of a match
304
return sbuf.toString();
305     }
306
307     /**
308      * Delete all occurrences of the given substring.
309      * @param pattern the pattern to delete all occurrences of
310      */

311     public static String JavaDoc delete(String JavaDoc inString, String JavaDoc pattern) {
312         return replace(inString, pattern, "");
313     }
314
315     /**
316      * Delete any character in a given string.
317      * @param charsToDelete a set of characters to delete.
318      * E.g. "az\n" will delete 'a's, 'z's and new lines.
319      */

320     public static String JavaDoc deleteAny(String JavaDoc inString, String JavaDoc charsToDelete) {
321         if (inString == null || charsToDelete == null) {
322             return inString;
323         }
324         StringBuffer JavaDoc out = new StringBuffer JavaDoc();
325         for (int i = 0; i < inString.length(); i++) {
326             char c = inString.charAt(i);
327             if (charsToDelete.indexOf(c) == -1) {
328                 out.append(c);
329             }
330         }
331         return out.toString();
332     }
333
334
335     //---------------------------------------------------------------------
336
// Convenience methods for working with formatted Strings
337
//---------------------------------------------------------------------
338

339     /**
340      * Quote the given String with single quotes.
341      * @param str the input String (e.g. "myString")
342      * @return the quoted String (e.g. "'myString'"),
343      * or <code>null<code> if the input was <code>null</code>
344      */

345     public static String JavaDoc quote(String JavaDoc str) {
346         return (str != null ? "'" + str + "'" : null);
347     }
348
349     /**
350      * Turn the given Object into a String with single quotes
351      * if it is a String; keeping the Object as-is else.
352      * @param obj the input Object (e.g. "myString")
353      * @return the quoted String (e.g. "'myString'"),
354      * or the input object as-is if not a String
355      */

356     public static Object JavaDoc quoteIfString(Object JavaDoc obj) {
357         return (obj instanceof String JavaDoc ? quote((String JavaDoc) obj) : obj);
358     }
359
360     /**
361      * Unqualify a string qualified by a '.' dot character. For example,
362      * "this.name.is.qualified", returns "qualified".
363      * @param qualifiedName the qualified name
364      */

365     public static String JavaDoc unqualify(String JavaDoc qualifiedName) {
366         return unqualify(qualifiedName, '.');
367     }
368
369     /**
370      * Unqualify a string qualified by a separator character. For example,
371      * "this:name:is:qualified" returns "qualified" if using a ':' separator.
372      * @param qualifiedName the qualified name
373      * @param separator the separator
374      */

375     public static String JavaDoc unqualify(String JavaDoc qualifiedName, char separator) {
376         return qualifiedName.substring(qualifiedName.lastIndexOf(separator) + 1);
377     }
378
379     /**
380      * Capitalize a <code>String</code>, changing the first letter to
381      * upper case as per {@link Character#toUpperCase(char)}.
382      * No other letters are changed.
383      * @param str the String to capitalize, may be <code>null</code>
384      * @return the capitalized String, <code>null</code> if null
385      */

386     public static String JavaDoc capitalize(String JavaDoc str) {
387         return changeFirstCharacterCase(str, true);
388     }
389
390     /**
391      * Uncapitalize a <code>String</code>, changing the first letter to
392      * lower case as per {@link Character#toLowerCase(char)}.
393      * No other letters are changed.
394      * @param str the String to uncapitalize, may be <code>null</code>
395      * @return the uncapitalized String, <code>null</code> if null
396      */

397     public static String JavaDoc uncapitalize(String JavaDoc str) {
398         return changeFirstCharacterCase(str, false);
399     }
400
401     private static String JavaDoc changeFirstCharacterCase(String JavaDoc str, boolean capitalize) {
402         if (str == null || str.length() == 0) {
403             return str;
404         }
405         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(str.length());
406         if (capitalize) {
407             buf.append(Character.toUpperCase(str.charAt(0)));
408         }
409         else {
410             buf.append(Character.toLowerCase(str.charAt(0)));
411         }
412         buf.append(str.substring(1));
413         return buf.toString();
414     }
415
416     /**
417      * Extract the filename from the given path,
418      * e.g. "mypath/myfile.txt" -> "myfile.txt".
419      * @param path the file path (may be <code>null</code>)
420      * @return the extracted filename, or <code>null</code> if none
421      */

422     public static String JavaDoc getFilename(String JavaDoc path) {
423         if (path == null) {
424             return null;
425         }
426         int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR);
427         return (separatorIndex != -1 ? path.substring(separatorIndex + 1) : path);
428     }
429
430     /**
431      * Extract the filename extension from the given path,
432      * e.g. "mypath/myfile.txt" -> "txt".
433      * @param path the file path (may be <code>null</code>)
434      * @return the extracted filename extension, or <code>null</code> if none
435      */

436     public static String JavaDoc getFilenameExtension(String JavaDoc path) {
437         if (path == null) {
438             return null;
439         }
440         int sepIndex = path.lastIndexOf(EXTENSION_SEPARATOR);
441         return (sepIndex != -1 ? path.substring(sepIndex + 1) : null);
442     }
443
444     /**
445      * Strip the filename extension from the given path,
446      * e.g. "mypath/myfile.txt" -> "mypath/myfile".
447      * @param path the file path (may be <code>null</code>)
448      * @return the path with stripped filename extension,
449      * or <code>null</code> if none
450      */

451     public static String JavaDoc stripFilenameExtension(String JavaDoc path) {
452         if (path == null) {
453             return null;
454         }
455         int sepIndex = path.lastIndexOf(EXTENSION_SEPARATOR);
456         return (sepIndex != -1 ? path.substring(0, sepIndex) : path);
457     }
458
459     /**
460      * Apply the given relative path to the given path,
461      * assuming standard Java folder separation (i.e. "/" separators);
462      * @param path the path to start from (usually a full file path)
463      * @param relativePath the relative path to apply
464      * (relative to the full file path above)
465      * @return the full file path that results from applying the relative path
466      */

467     public static String JavaDoc applyRelativePath(String JavaDoc path, String JavaDoc relativePath) {
468         int separatorIndex = path.lastIndexOf(FOLDER_SEPARATOR);
469         if (separatorIndex != -1) {
470             String JavaDoc newPath = path.substring(0, separatorIndex);
471             if (!relativePath.startsWith(FOLDER_SEPARATOR)) {
472                 newPath += FOLDER_SEPARATOR;
473             }
474             return newPath + relativePath;
475         }
476         else {
477             return relativePath;
478         }
479     }
480
481     /**
482      * Normalize the path by suppressing sequences like "path/.." and
483      * inner simple dots.
484      * <p>The result is convenient for path comparison. For other uses,
485      * notice that Windows separators ("\") are replaced by simple slashes.
486      * @param path the original path
487      * @return the normalized path
488      */

489     public static String JavaDoc cleanPath(String JavaDoc path) {
490         String JavaDoc pathToUse = replace(path, WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR);
491
492         // Strip prefix from path to analyze, to not treat it as part of the
493
// first path element. This is necessary to correctly parse paths like
494
// "file:core/../core/io/Resource.class", where the ".." should just
495
// strip the first "core" directory while keeping the "file:" prefix.
496
int prefixIndex = pathToUse.indexOf(":");
497         String JavaDoc prefix = "";
498         if (prefixIndex != -1) {
499             prefix = pathToUse.substring(0, prefixIndex + 1);
500             pathToUse = pathToUse.substring(prefixIndex + 1);
501         }
502
503         String JavaDoc[] pathArray = delimitedListToStringArray(pathToUse, FOLDER_SEPARATOR);
504         List JavaDoc pathElements = new LinkedList JavaDoc();
505         int tops = 0;
506
507         for (int i = pathArray.length - 1; i >= 0; i--) {
508             if (CURRENT_PATH.equals(pathArray[i])) {
509                 // Points to current directory - drop it.
510
}
511             else if (TOP_PATH.equals(pathArray[i])) {
512                 // Registering top path found.
513
tops++;
514             }
515             else {
516                 if (tops > 0) {
517                     // Merging path element with corresponding to top path.
518
tops--;
519                 }
520                 else {
521                     // Normal path element found.
522
pathElements.add(0, pathArray[i]);
523                 }
524             }
525         }
526
527         // Remaining top paths need to be retained.
528
for (int i = 0; i < tops; i++) {
529             pathElements.add(0, TOP_PATH);
530         }
531
532         return prefix + collectionToDelimitedString(pathElements, FOLDER_SEPARATOR);
533     }
534
535     /**
536      * Compare two paths after normalization of them.
537      * @param path1 First path for comparizon
538      * @param path2 Second path for comparizon
539      * @return whether the two paths are equivalent after normalization
540      */

541     public static boolean pathEquals(String JavaDoc path1, String JavaDoc path2) {
542         return cleanPath(path1).equals(cleanPath(path2));
543     }
544
545     /**
546      * Parse the given locale string into a <code>java.util.Locale</code>.
547      * This is the inverse operation of Locale's <code>toString</code>.
548      * @param localeString the locale string, following
549      * <code>java.util.Locale</code>'s toString format ("en", "en_UK", etc).
550      * Also accepts spaces as separators, as alternative to underscores.
551      * @return a corresponding Locale instance
552      */

553     public static Locale JavaDoc parseLocaleString(String JavaDoc localeString) {
554         String JavaDoc[] parts = tokenizeToStringArray(localeString, "_ ", false, false);
555         String JavaDoc language = (parts.length > 0 ? parts[0] : "");
556         String JavaDoc country = (parts.length > 1 ? parts[1] : "");
557         String JavaDoc variant = (parts.length > 2 ? parts[2] : "");
558         return (language.length() > 0 ? new Locale JavaDoc(language, country, variant) : null);
559     }
560
561
562     //---------------------------------------------------------------------
563
// Convenience methods for working with String arrays
564
//---------------------------------------------------------------------
565

566     /**
567      * Append the given String to the given String array, returning a new array
568      * consisting of the input array contents plus the given String.
569      * @param array the array to append to (can be <code>null</code>)
570      * @param str the String to append
571      * @return the new array (never <code>null</code>)
572      */

573     public static String JavaDoc[] addStringToArray(String JavaDoc[] array, String JavaDoc str) {
574         if (ObjectUtils.isEmpty(array)) {
575             return new String JavaDoc[] {str};
576         }
577         String JavaDoc[] newArr = new String JavaDoc[array.length + 1];
578         System.arraycopy(array, 0, newArr, 0, array.length);
579         newArr[array.length] = str;
580         return newArr;
581     }
582
583     /**
584      * Concatenate the given String arrays into one,
585      * with overlapping array elements included twice.
586      * <p>The order of elements in the original arrays is preserved.
587      * @param array1 the first array (can be <code>null</code>)
588      * @param array2 the second array (can be <code>null</code>)
589      * @return the new array (<code>null</code> if both given arrays were <code>null</code>)
590      */

591     public static String JavaDoc[] concatenateStringArrays(String JavaDoc[] array1, String JavaDoc[] array2) {
592         if (ObjectUtils.isEmpty(array1)) {
593             return array2;
594         }
595         if (ObjectUtils.isEmpty(array2)) {
596             return array1;
597         }
598         String JavaDoc[] newArr = new String JavaDoc[array1.length + array2.length];
599         System.arraycopy(array1, 0, newArr, 0, array1.length);
600         System.arraycopy(array2, 0, newArr, array1.length, array2.length);
601         return newArr;
602     }
603
604     /**
605      * Merge the given String arrays into one, with overlapping
606      * array elements only included once.
607      * <p>The order of elements in the original arrays is preserved
608      * (with the exception of overlapping elements, which are only
609      * included on their first occurence).
610      * @param array1 the first array (can be <code>null</code>)
611      * @param array2 the second array (can be <code>null</code>)
612      * @return the new array (<code>null</code> if both given arrays were <code>null</code>)
613      */

614     public static String JavaDoc[] mergeStringArrays(String JavaDoc[] array1, String JavaDoc[] array2) {
615         if (ObjectUtils.isEmpty(array1)) {
616             return array2;
617         }
618         if (ObjectUtils.isEmpty(array2)) {
619             return array1;
620         }
621         List JavaDoc result = new ArrayList JavaDoc();
622         result.addAll(Arrays.asList(array1));
623         for (int i = 0; i < array2.length; i++) {
624             String JavaDoc str = array2[i];
625             if (!result.contains(str)) {
626                 result.add(str);
627             }
628         }
629         return toStringArray(result);
630     }
631
632     /**
633      * Turn given source String array into sorted array.
634      * @param array the source array
635      * @return the sorted array (never <code>null</code>)
636      */

637     public static String JavaDoc[] sortStringArray(String JavaDoc[] array) {
638         if (ObjectUtils.isEmpty(array)) {
639             return new String JavaDoc[0];
640         }
641         Arrays.sort(array);
642         return array;
643     }
644
645     /**
646      * Copy the given Collection into a String array.
647      * The Collection must contain String elements only.
648      * @param collection the Collection to copy
649      * @return the String array (<code>null</code> if the passed-in
650      * Collection was <code>null</code>)
651      */

652     public static String JavaDoc[] toStringArray(Collection JavaDoc collection) {
653         if (collection == null) {
654             return null;
655         }
656         return (String JavaDoc[]) collection.toArray(new String JavaDoc[collection.size()]);
657     }
658
659     /**
660      * Remove duplicate Strings from the given array.
661      * Also sorts the array, as it uses a TreeSet.
662      * @param array the String array
663      * @return an array without duplicates, in natural sort order
664      */

665     public static String JavaDoc[] removeDuplicateStrings(String JavaDoc[] array) {
666         if (ObjectUtils.isEmpty(array)) {
667             return array;
668         }
669         Set JavaDoc set = new TreeSet JavaDoc();
670         for (int i = 0; i < array.length; i++) {
671             set.add(array[i]);
672         }
673         return toStringArray(set);
674     }
675
676     /**
677      * Split a String at the first occurrence of the delimiter.
678      * Does not include the delimiter in the result.
679      * @param toSplit the string to split
680      * @param delimiter to split the string up with
681      * @return a two element array with index 0 being before the delimiter, and
682      * index 1 being after the delimiter (neither element includes the delimiter);
683      * or <code>null</code> if the delimiter wasn't found in the given input String
684      */

685     public static String JavaDoc[] split(String JavaDoc toSplit, String JavaDoc delimiter) {
686         if (!hasLength(toSplit) || !hasLength(delimiter)) {
687             return null;
688         }
689         int offset = toSplit.indexOf(delimiter);
690         if (offset < 0) {
691             return null;
692         }
693         String JavaDoc beforeDelimiter = toSplit.substring(0, offset);
694         String JavaDoc afterDelimiter = toSplit.substring(offset + delimiter.length());
695         return new String JavaDoc[] {beforeDelimiter, afterDelimiter};
696     }
697
698     /**
699      * Take an array Strings and split each element based on the given delimiter.
700      * A <code>Properties</code> instance is then generated, with the left of the
701      * delimiter providing the key, and the right of the delimiter providing the value.
702      * <p>Will trim both the key and value before adding them to the
703      * <code>Properties</code> instance.
704      * @param array the array to process
705      * @param delimiter to split each element using (typically the equals symbol)
706      * @return a <code>Properties</code> instance representing the array contents,
707      * or <code>null</code> if the array to process was null or empty
708      */

709     public static Properties JavaDoc splitArrayElementsIntoProperties(String JavaDoc[] array, String JavaDoc delimiter) {
710         return splitArrayElementsIntoProperties(array, delimiter, null);
711     }
712
713     /**
714      * Take an array Strings and split each element based on the given delimiter.
715      * A <code>Properties</code> instance is then generated, with the left of the
716      * delimiter providing the key, and the right of the delimiter providing the value.
717      * <p>Will trim both the key and value before adding them to the
718      * <code>Properties</code> instance.
719      * @param array the array to process
720      * @param delimiter to split each element using (typically the equals symbol)
721      * @param charsToDelete one or more characters to remove from each element
722      * prior to attempting the split operation (typically the quotation mark
723      * symbol), or <code>null</code> if no removal should occur
724      * @return a <code>Properties</code> instance representing the array contents,
725      * or <code>null</code> if the array to process was <code>null</code> or empty
726      */

727     public static Properties JavaDoc splitArrayElementsIntoProperties(
728             String JavaDoc[] array, String JavaDoc delimiter, String JavaDoc charsToDelete) {
729
730         if (ObjectUtils.isEmpty(array)) {
731             return null;
732         }
733         Properties JavaDoc result = new Properties JavaDoc();
734         for (int i = 0; i < array.length; i++) {
735             String JavaDoc element = array[i];
736             if (charsToDelete != null) {
737                 element = deleteAny(array[i], charsToDelete);
738             }
739             String JavaDoc[] splittedElement = split(element, delimiter);
740             if (splittedElement == null) {
741                 continue;
742             }
743             result.setProperty(splittedElement[0].trim(), splittedElement[1].trim());
744         }
745         return result;
746     }
747
748     /**
749      * Tokenize the given String into a String array via a StringTokenizer.
750      * Trims tokens and omits empty tokens.
751      * <p>The given delimiters string is supposed to consist of any number of
752      * delimiter characters. Each of those characters can be used to separate
753      * tokens. A delimiter is always a single character; for multi-character
754      * delimiters, consider using <code>delimitedListToStringArray</code>
755      * @param str the String to tokenize
756      * @param delimiters the delimiter characters, assembled as String
757      * (each of those characters is individually considered as delimiter).
758      * @return an array of the tokens
759      * @see java.util.StringTokenizer
760      * @see java.lang.String#trim()
761      * @see #delimitedListToStringArray
762      */

763     public static String JavaDoc[] tokenizeToStringArray(String JavaDoc str, String JavaDoc delimiters) {
764         return tokenizeToStringArray(str, delimiters, true, true);
765     }
766
767     /**
768      * Tokenize the given String into a String array via a StringTokenizer.
769      * <p>The given delimiters string is supposed to consist of any number of
770      * delimiter characters. Each of those characters can be used to separate
771      * tokens. A delimiter is always a single character; for multi-character
772      * delimiters, consider using <code>delimitedListToStringArray</code>
773      * @param str the String to tokenize
774      * @param delimiters the delimiter characters, assembled as String
775      * (each of those characters is individually considered as delimiter)
776      * @param trimTokens trim the tokens via String's <code>trim</code>
777      * @param ignoreEmptyTokens omit empty tokens from the result array
778      * (only applies to tokens that are empty after trimming; StringTokenizer
779      * will not consider subsequent delimiters as token in the first place).
780      * @return an array of the tokens (<code>null</code> if the input String
781      * was <code>null</code>)
782      * @see java.util.StringTokenizer
783      * @see java.lang.String#trim()
784      * @see #delimitedListToStringArray
785      */

786     public static String JavaDoc[] tokenizeToStringArray(
787             String JavaDoc str, String JavaDoc delimiters, boolean trimTokens, boolean ignoreEmptyTokens) {
788
789         if (str == null) {
790             return null;
791         }
792         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(str, delimiters);
793         List JavaDoc tokens = new ArrayList JavaDoc();
794         while (st.hasMoreTokens()) {
795             String JavaDoc token = st.nextToken();
796             if (trimTokens) {
797                 token = token.trim();
798             }
799             if (!ignoreEmptyTokens || token.length() > 0) {
800                 tokens.add(token);
801             }
802         }
803         return toStringArray(tokens);
804     }
805
806     /**
807      * Take a String which is a delimited list and convert it to a String array.
808      * <p>A single delimiter can consists of more than one character: It will still
809      * be considered as single delimiter string, rather than as bunch of potential
810      * delimiter characters - in contrast to <code>tokenizeToStringArray</code>.
811      * @param str the input String
812      * @param delimiter the delimiter between elements (this is a single delimiter,
813      * rather than a bunch individual delimiter characters)
814      * @return an array of the tokens in the list
815      * @see #tokenizeToStringArray
816      */

817     public static String JavaDoc[] delimitedListToStringArray(String JavaDoc str, String JavaDoc delimiter) {
818         if (str == null) {
819             return new String JavaDoc[0];
820         }
821         if (delimiter == null) {
822             return new String JavaDoc[] {str};
823         }
824         List JavaDoc result = new ArrayList JavaDoc();
825         if ("".equals(delimiter)) {
826             for (int i = 0; i < str.length(); i++) {
827                 result.add(str.substring(i, i + 1));
828             }
829         }
830         else {
831             int pos = 0;
832             int delPos = 0;
833             while ((delPos = str.indexOf(delimiter, pos)) != -1) {
834                 result.add(str.substring(pos, delPos));
835                 pos = delPos + delimiter.length();
836             }
837             if (str.length() > 0 && pos <= str.length()) {
838                 // Add rest of String, but not in case of empty input.
839
result.add(str.substring(pos));
840             }
841         }
842         return toStringArray(result);
843     }
844
845     /**
846      * Convert a CSV list into an array of Strings.
847      * @param str the input String
848      * @return an array of Strings, or the empty array in case of empty input
849      */

850     public static String JavaDoc[] commaDelimitedListToStringArray(String JavaDoc str) {
851         return delimitedListToStringArray(str, ",");
852     }
853
854     /**
855      * Convenience method to convert a CSV string list to a set.
856      * Note that this will suppress duplicates.
857      * @param str the input String
858      * @return a Set of String entries in the list
859      */

860     public static Set JavaDoc commaDelimitedListToSet(String JavaDoc str) {
861         Set JavaDoc set = new TreeSet JavaDoc();
862         String JavaDoc[] tokens = commaDelimitedListToStringArray(str);
863         for (int i = 0; i < tokens.length; i++) {
864             set.add(tokens[i]);
865         }
866         return set;
867     }
868
869     /**
870      * Convenience method to return a Collection as a delimited (e.g. CSV)
871      * String. E.g. useful for <code>toString()</code> implementations.
872      * @param coll the Collection to display
873      * @param delim the delimiter to use (probably a ",")
874      * @param prefix the String to start each element with
875      * @param suffix the String to end each element with
876      */

877     public static String JavaDoc collectionToDelimitedString(Collection JavaDoc coll, String JavaDoc delim, String JavaDoc prefix, String JavaDoc suffix) {
878         if (CollectionUtils.isEmpty(coll)) {
879             return "";
880         }
881         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
882         Iterator JavaDoc it = coll.iterator();
883         while (it.hasNext()) {
884             sb.append(prefix).append(it.next()).append(suffix);
885             if (it.hasNext()) {
886                 sb.append(delim);
887             }
888         }
889         return sb.toString();
890     }
891
892     /**
893      * Convenience method to return a Collection as a delimited (e.g. CSV)
894      * String. E.g. useful for <code>toString()</code> implementations.
895      * @param coll the Collection to display
896      * @param delim the delimiter to use (probably a ",")
897      */

898     public static String JavaDoc collectionToDelimitedString(Collection JavaDoc coll, String JavaDoc delim) {
899         return collectionToDelimitedString(coll, delim, "", "");
900     }
901
902     /**
903      * Convenience method to return a Collection as a CSV String.
904      * E.g. useful for <code>toString()</code> implementations.
905      * @param coll the Collection to display
906      */

907     public static String JavaDoc collectionToCommaDelimitedString(Collection JavaDoc coll) {
908         return collectionToDelimitedString(coll, ",");
909     }
910
911     /**
912      * Convenience method to return a String array as a delimited (e.g. CSV)
913      * String. E.g. useful for <code>toString()</code> implementations.
914      * @param arr the array to display
915      * @param delim the delimiter to use (probably a ",")
916      */

917     public static String JavaDoc arrayToDelimitedString(Object JavaDoc[] arr, String JavaDoc delim) {
918         if (ObjectUtils.isEmpty(arr)) {
919             return "";
920         }
921         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
922         for (int i = 0; i < arr.length; i++) {
923             if (i > 0) {
924                 sb.append(delim);
925             }
926             sb.append(arr[i]);
927         }
928         return sb.toString();
929     }
930
931     /**
932      * Convenience method to return a String array as a CSV String.
933      * E.g. useful for <code>toString()</code> implementations.
934      * @param arr the array to display
935      */

936     public static String JavaDoc arrayToCommaDelimitedString(Object JavaDoc[] arr) {
937         return arrayToDelimitedString(arr, ",");
938     }
939
940 }
941
Popular Tags