1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   * 
13   */
14  
15  package com.liferay.portal.kernel.util;
16  
17  import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
18  import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
19  import com.liferay.portal.kernel.log.Log;
20  import com.liferay.portal.kernel.log.LogFactoryUtil;
21  
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.InputStreamReader;
25  
26  import java.net.URL;
27  
28  import java.util.ArrayList;
29  import java.util.Collection;
30  import java.util.Enumeration;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.StringTokenizer;
34  import java.util.regex.Matcher;
35  import java.util.regex.Pattern;
36  
37  /**
38   * <a href="StringUtil.java.html"><b><i>View Source</i></b></a>
39   *
40   * @author Brian Wing Shun Chan
41   * @author Sandeep Soni
42   * @author Ganesh Ram
43   */
44  public class StringUtil {
45  
46      public static String add(String s, String add) {
47          return add(s, add, StringPool.COMMA);
48      }
49  
50      public static String add(String s, String add, String delimiter) {
51          return add(s, add, delimiter, false);
52      }
53  
54      public static String add(
55          String s, String add, String delimiter, boolean allowDuplicates) {
56  
57          if ((add == null) || (delimiter == null)) {
58              return null;
59          }
60  
61          if (s == null) {
62              s = StringPool.BLANK;
63          }
64  
65          if (allowDuplicates || !contains(s, add, delimiter)) {
66              StringBundler sb = new StringBundler();
67  
68              sb.append(s);
69  
70              if (Validator.isNull(s) || s.endsWith(delimiter)) {
71                  sb.append(add);
72                  sb.append(delimiter);
73              }
74              else {
75                  sb.append(delimiter);
76                  sb.append(add);
77                  sb.append(delimiter);
78              }
79  
80              s = sb.toString();
81          }
82  
83          return s;
84      }
85  
86      public static String bytesToHexString(byte[] bytes) {
87          StringBuilder sb = new StringBuilder(bytes.length * 2);
88  
89          for (int i = 0; i < bytes.length; i++) {
90              String hex = Integer.toHexString(
91                  0x0100 + (bytes[i] & 0x00FF)).substring(1);
92  
93              if (hex.length() < 2) {
94                  sb.append("0");
95              }
96  
97              sb.append(hex);
98          }
99  
100         return sb.toString();
101     }
102 
103     public static boolean contains(String s, String text) {
104         return contains(s, text, StringPool.COMMA);
105     }
106 
107     public static boolean contains(String s, String text, String delimiter) {
108         if ((s == null) || (text == null) || (delimiter == null)) {
109             return false;
110         }
111 
112         if (!s.endsWith(delimiter)) {
113             s = s.concat(delimiter);
114         }
115 
116         String dtd = delimiter.concat(text).concat(delimiter);
117 
118         int pos = s.indexOf(dtd);
119 
120         if (pos == -1) {
121             String td = text.concat(delimiter);
122 
123             if (s.startsWith(td)) {
124                 return true;
125             }
126 
127             return false;
128         }
129 
130         return true;
131     }
132 
133     public static int count(String s, String text) {
134         if ((s == null) || (text == null)) {
135             return 0;
136         }
137 
138         int count = 0;
139 
140         int pos = s.indexOf(text);
141 
142         while (pos != -1) {
143             pos = s.indexOf(text, pos + text.length());
144 
145             count++;
146         }
147 
148         return count;
149     }
150 
151     public static boolean endsWith(String s, char end) {
152         return endsWith(s, (new Character(end)).toString());
153     }
154 
155     public static boolean endsWith(String s, String end) {
156         if ((s == null) || (end == null)) {
157             return false;
158         }
159 
160         if (end.length() > s.length()) {
161             return false;
162         }
163 
164         String temp = s.substring(s.length() - end.length(), s.length());
165 
166         if (temp.equalsIgnoreCase(end)) {
167             return true;
168         }
169         else {
170             return false;
171         }
172     }
173 
174     public static String extractChars(String s) {
175         if (s == null) {
176             return StringPool.BLANK;
177         }
178 
179         StringBuilder sb = new StringBuilder();
180 
181         char[] charArray = s.toCharArray();
182 
183         for (int i = 0; i < charArray.length; i++) {
184             if (Validator.isChar(charArray[i])) {
185                 sb.append(charArray[i]);
186             }
187         }
188 
189         return sb.toString();
190     }
191 
192     public static String extractDigits(String s) {
193         if (s == null) {
194             return StringPool.BLANK;
195         }
196 
197         StringBuilder sb = new StringBuilder();
198 
199         char[] charArray = s.toCharArray();
200 
201         for (int i = 0; i < charArray.length; i++) {
202             if (Validator.isDigit(charArray[i])) {
203                 sb.append(charArray[i]);
204             }
205         }
206 
207         return sb.toString();
208     }
209 
210     public static String extractFirst(String s, String delimiter) {
211         if (s == null) {
212             return null;
213         }
214         else {
215             String[] array = split(s, delimiter);
216 
217             if (array.length > 0) {
218                 return array[0];
219             }
220             else {
221                 return null;
222             }
223         }
224     }
225 
226     public static String extractLast(String s, String delimiter) {
227         if (s == null) {
228             return null;
229         }
230         else {
231             String[] array = split(s, delimiter);
232 
233             if (array.length > 0) {
234                 return array[array.length - 1];
235             }
236             else {
237                 return null;
238             }
239         }
240     }
241 
242     /**
243      * @deprecated
244      */
245     public static String highlight(String s, String keywords) {
246         return highlight(s, keywords, "<span class=\"highlight\">", "</span>");
247     }
248 
249     /**
250      * @deprecated
251      */
252     public static String highlight(
253         String s, String keywords, String highlight1, String highlight2) {
254 
255         if (s == null) {
256             return null;
257         }
258 
259         if (Validator.isNull(keywords)) {
260             return s;
261         }
262 
263         // The problem with using a regexp is that it searches the text in a
264         // case insenstive manner but doens't replace the text in a case
265         // insenstive manner. So the search results actually get messed up. The
266         // best way is to actually parse the results.
267 
268         //return s.replaceAll(
269         //  "(?i)" + keywords, highlight1 + keywords + highlight2);
270 
271         StringBuilder sb = new StringBuilder();
272 
273         StringTokenizer st = new StringTokenizer(s);
274 
275         Pattern pattern = Pattern.compile(
276             Pattern.quote(keywords), Pattern.CASE_INSENSITIVE);
277 
278         while (st.hasMoreTokens()) {
279             String token = st.nextToken();
280 
281             Matcher matcher = pattern.matcher(token);
282 
283             if (matcher.find()) {
284                 String highlightedToken = matcher.replaceAll(
285                     highlight1 + matcher.group() + highlight2);
286 
287                 sb.append(highlightedToken);
288             }
289             else {
290                 sb.append(token);
291             }
292 
293             if (st.hasMoreTokens()) {
294                 sb.append(StringPool.SPACE);
295             }
296         }
297 
298         return sb.toString();
299     }
300 
301     public static String insert(String s, String insert, int offset) {
302         if (s == null) {
303             return null;
304         }
305 
306         if (insert == null) {
307             return s;
308         }
309 
310         if (offset > s.length()) {
311             offset = s.length();
312         }
313 
314         StringBuilder sb = new StringBuilder(s);
315 
316         sb.insert(offset, insert);
317 
318         return sb.toString();
319     }
320 
321     public static String lowerCase(String s) {
322         if (s == null) {
323             return null;
324         }
325         else {
326             return s.toLowerCase();
327         }
328     }
329 
330     public static boolean matches(String s, String pattern) {
331         String[] array = pattern.split("\\*");
332 
333         for (int i = 0; i < array.length; i++) {
334             int pos = s.indexOf(array[i]);
335 
336             if (pos == -1) {
337                 return false;
338             }
339 
340             s = s.substring(pos + array[i].length());
341         }
342 
343         return true;
344     }
345 
346     public static String merge(boolean[] array) {
347         return merge(array, StringPool.COMMA);
348     }
349 
350     public static String merge(boolean[] array, String delimiter) {
351         if (array == null) {
352             return null;
353         }
354 
355         StringBundler sb = null;
356 
357         if (array.length == 0) {
358             sb = new StringBundler();
359         }
360         else {
361             sb = new StringBundler(2 * array.length - 1);
362         }
363 
364         for (int i = 0; i < array.length; i++) {
365             sb.append(String.valueOf(array[i]).trim());
366 
367             if ((i + 1) != array.length) {
368                 sb.append(delimiter);
369             }
370         }
371 
372         return sb.toString();
373     }
374 
375     public static String merge(Collection<?> col) {
376         return merge(col, StringPool.COMMA);
377     }
378 
379     public static String merge(Collection<?> col, String delimiter) {
380         if (col == null) {
381             return null;
382         }
383 
384         return merge(col.toArray(new Object[col.size()]), delimiter);
385     }
386 
387     public static String merge(double[] array) {
388         return merge(array, StringPool.COMMA);
389     }
390 
391     public static String merge(double[] array, String delimiter) {
392         if (array == null) {
393             return null;
394         }
395 
396         StringBundler sb = null;
397 
398         if (array.length == 0) {
399             sb = new StringBundler();
400         }
401         else {
402             sb = new StringBundler(2 * array.length - 1);
403         }
404 
405         for (int i = 0; i < array.length; i++) {
406             sb.append(String.valueOf(array[i]).trim());
407 
408             if ((i + 1) != array.length) {
409                 sb.append(delimiter);
410             }
411         }
412 
413         return sb.toString();
414     }
415 
416     public static String merge(float[] array) {
417         return merge(array, StringPool.COMMA);
418     }
419 
420     public static String merge(float[] array, String delimiter) {
421         if (array == null) {
422             return null;
423         }
424 
425         StringBundler sb = null;
426 
427         if (array.length == 0) {
428             sb = new StringBundler();
429         }
430         else {
431             sb = new StringBundler(2 * array.length - 1);
432         }
433 
434         for (int i = 0; i < array.length; i++) {
435             sb.append(String.valueOf(array[i]).trim());
436 
437             if ((i + 1) != array.length) {
438                 sb.append(delimiter);
439             }
440         }
441 
442         return sb.toString();
443     }
444 
445     public static String merge(int[] array) {
446         return merge(array, StringPool.COMMA);
447     }
448 
449     public static String merge(int[] array, String delimiter) {
450         if (array == null) {
451             return null;
452         }
453 
454         StringBundler sb = null;
455 
456         if (array.length == 0){
457             sb = new StringBundler();
458         }
459         else {
460             sb = new StringBundler(2 * array.length - 1);
461         }
462 
463         for (int i = 0; i < array.length; i++) {
464             sb.append(String.valueOf(array[i]).trim());
465 
466             if ((i + 1) != array.length) {
467                 sb.append(delimiter);
468             }
469         }
470 
471         return sb.toString();
472     }
473 
474     public static String merge(long[] array) {
475         return merge(array, StringPool.COMMA);
476     }
477 
478     public static String merge(long[] array, String delimiter) {
479         if (array == null) {
480             return null;
481         }
482 
483         StringBundler sb = null;
484 
485         if (array.length == 0) {
486             sb = new StringBundler();
487         }
488         else {
489             sb = new StringBundler(2 * array.length - 1);
490         }
491 
492         for (int i = 0; i < array.length; i++) {
493             sb.append(String.valueOf(array[i]).trim());
494 
495             if ((i + 1) != array.length) {
496                 sb.append(delimiter);
497             }
498         }
499 
500         return sb.toString();
501     }
502 
503     public static String merge(Object[] array) {
504         return merge(array, StringPool.COMMA);
505     }
506 
507     public static String merge(Object[] array, String delimiter) {
508         if (array == null) {
509             return null;
510         }
511 
512         StringBundler sb = null;
513 
514         if (array.length == 0) {
515             sb = new StringBundler();
516         }
517         else {
518             sb = new StringBundler(2 * array.length - 1);
519         }
520 
521         for (int i = 0; i < array.length; i++) {
522             sb.append(String.valueOf(array[i]).trim());
523 
524             if ((i + 1) != array.length) {
525                 sb.append(delimiter);
526             }
527         }
528 
529         return sb.toString();
530     }
531 
532     public static String merge(short[] array) {
533         return merge(array, StringPool.COMMA);
534     }
535 
536     public static String merge(short[] array, String delimiter) {
537         if (array == null) {
538             return null;
539         }
540 
541         StringBundler sb = null;
542 
543         if (array.length == 0) {
544             sb = new StringBundler();
545         }
546         else {
547             sb = new StringBundler(2 * array.length - 1);
548         }
549 
550         for (int i = 0; i < array.length; i++) {
551             sb.append(String.valueOf(array[i]).trim());
552 
553             if ((i + 1) != array.length) {
554                 sb.append(delimiter);
555             }
556         }
557 
558         return sb.toString();
559     }
560 
561     public static String randomize(String s) {
562         return Randomizer.getInstance().randomize(s);
563     }
564 
565     public static String read(ClassLoader classLoader, String name)
566         throws IOException {
567 
568         return read(classLoader, name, false);
569     }
570 
571     public static String read(ClassLoader classLoader, String name, boolean all)
572         throws IOException {
573 
574         if (all) {
575             StringBundler sb = new StringBundler();
576 
577             Enumeration<URL> enu = classLoader.getResources(name);
578 
579             while (enu.hasMoreElements()) {
580                 URL url = enu.nextElement();
581 
582                 InputStream is = url.openStream();
583 
584                 if (is == null) {
585                     throw new IOException(
586                         "Unable to open resource at " + url.toString());
587                 }
588 
589                 String s = read(is);
590 
591                 if (s != null) {
592                     sb.append(s);
593                     sb.append(StringPool.NEW_LINE);
594                 }
595 
596                 is.close();
597             }
598 
599             return sb.toString().trim();
600         }
601         else {
602             InputStream is = classLoader.getResourceAsStream(name);
603 
604             if (is == null) {
605                 throw new IOException(
606                     "Unable to open resource in class loader " + name);
607             }
608 
609             String s = read(is);
610 
611             is.close();
612 
613             return s;
614         }
615     }
616 
617     public static String read(InputStream is) throws IOException {
618         StringBundler sb = new StringBundler();
619 
620         UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
621             new InputStreamReader(is));
622 
623         String line = null;
624 
625         while ((line = unsyncBufferedReader.readLine()) != null) {
626             sb.append(line);
627             sb.append(CharPool.NEW_LINE);
628         }
629 
630         unsyncBufferedReader.close();
631 
632         return sb.toString().trim();
633     }
634 
635     public static String remove(String s, String remove) {
636         return remove(s, remove, StringPool.COMMA);
637     }
638 
639     public static String remove(String s, String remove, String delimiter) {
640         if ((s == null) || (remove == null) || (delimiter == null)) {
641             return null;
642         }
643 
644         if (Validator.isNotNull(s) && !s.endsWith(delimiter)) {
645             s += delimiter;
646         }
647 
648         String drd = delimiter.concat(remove).concat(delimiter);
649 
650         String rd = remove.concat(delimiter);
651 
652         while (contains(s, remove, delimiter)) {
653             int pos = s.indexOf(drd);
654 
655             if (pos == -1) {
656                 if (s.startsWith(rd)) {
657                     int x = remove.length() + delimiter.length();
658                     int y = s.length();
659 
660                     s = s.substring(x, y);
661                 }
662             }
663             else {
664                 int x = pos + remove.length() + delimiter.length();
665                 int y = s.length();
666 
667                 String temp = s.substring(0, pos);
668 
669                 s = temp.concat(s.substring(x, y));
670             }
671         }
672 
673         return s;
674     }
675 
676     public static String replace(String s, char oldSub, char newSub) {
677         if (s == null) {
678             return null;
679         }
680 
681         return s.replace(oldSub, newSub);
682     }
683 
684     public static String replace(String s, char oldSub, String newSub) {
685         if ((s == null) || (newSub == null)) {
686             return null;
687         }
688 
689         // The number 5 is arbitrary and is used as extra padding to reduce
690         // buffer expansion
691 
692         StringBuilder sb = new StringBuilder(s.length() + 5 * newSub.length());
693 
694         char[] charArray = s.toCharArray();
695 
696         for (char c : charArray) {
697             if (c == oldSub) {
698                 sb.append(newSub);
699             }
700             else {
701                 sb.append(c);
702             }
703         }
704 
705         return sb.toString();
706     }
707 
708     public static String replace(String s, String oldSub, String newSub) {
709         return replace(s, oldSub, newSub, 0);
710     }
711 
712     public static String replace(
713         String s, String oldSub, String newSub, int fromIndex) {
714 
715         if ((s == null) || (oldSub == null) || (newSub == null)) {
716             return null;
717         }
718 
719         int y = s.indexOf(oldSub, fromIndex);
720 
721         if (y >= 0) {
722 
723             // The number 5 is arbitrary and is used as extra padding to reduce
724             // buffer expansion
725 
726             StringBuilder sb = new StringBuilder(
727                 s.length() + 5 * newSub.length());
728 
729             int length = oldSub.length();
730             int x = 0;
731 
732             while (x <= y) {
733                 sb.append(s.substring(x, y));
734                 sb.append(newSub);
735 
736                 x = y + length;
737                 y = s.indexOf(oldSub, x);
738             }
739 
740             sb.append(s.substring(x));
741 
742             return sb.toString();
743         }
744         else {
745             return s;
746         }
747     }
748 
749     public static String replace(String s, String[] oldSubs, String[] newSubs) {
750         if ((s == null) || (oldSubs == null) || (newSubs == null)) {
751             return null;
752         }
753 
754         if (oldSubs.length != newSubs.length) {
755             return s;
756         }
757 
758         for (int i = 0; i < oldSubs.length; i++) {
759             s = replace(s, oldSubs[i], newSubs[i]);
760         }
761 
762         return s;
763     }
764 
765     public static String replace(
766         String s, String[] oldSubs, String[] newSubs, boolean exactMatch) {
767 
768         if ((s == null) || (oldSubs == null) || (newSubs == null)) {
769             return null;
770         }
771 
772         if (oldSubs.length != newSubs.length) {
773             return s;
774         }
775 
776         if (!exactMatch) {
777             replace(s, oldSubs, newSubs);
778         }
779         else {
780             for (int i = 0; i < oldSubs.length; i++) {
781                 s = s.replaceAll("\\b" + oldSubs[i] + "\\b" , newSubs[i]);
782             }
783         }
784 
785         return s;
786     }
787 
788     public static String replaceFirst(String s, char oldSub, char newSub) {
789         if (s == null) {
790             return null;
791         }
792 
793         return s.replaceFirst(String.valueOf(oldSub), String.valueOf(newSub));
794     }
795 
796     public static String replaceFirst(String s, char oldSub, String newSub) {
797         if ((s == null) || (newSub == null)) {
798             return null;
799         }
800 
801         return s.replaceFirst(String.valueOf(oldSub), newSub);
802     }
803 
804     public static String replaceFirst(String s, String oldSub, String newSub) {
805         if ((s == null) || (oldSub == null) || (newSub == null)) {
806             return null;
807         }
808 
809         return s.replaceFirst(oldSub, newSub);
810     }
811 
812     public static String replaceFirst(
813         String s, String[] oldSubs, String[] newSubs) {
814 
815         if ((s == null) || (oldSubs == null) || (newSubs == null)) {
816             return null;
817         }
818 
819         if (oldSubs.length != newSubs.length) {
820             return s;
821         }
822 
823         for (int i = 0; i < oldSubs.length; i++) {
824             s = replaceFirst(s, oldSubs[i], newSubs[i]);
825         }
826 
827         return s;
828     }
829 
830     public static String replaceLast(String s, char oldSub, char newSub) {
831         if (s == null) {
832             return null;
833         }
834 
835         return replaceLast(s, String.valueOf(oldSub), String.valueOf(newSub));
836     }
837 
838     public static String replaceLast(String s, char oldSub, String newSub) {
839         if ((s == null) || (newSub == null)) {
840             return null;
841         }
842 
843         return replaceLast(s, String.valueOf(oldSub), newSub);
844     }
845 
846     public static String replaceLast(String s, String oldSub, String newSub) {
847         if ((s == null) || (oldSub == null) || (newSub == null)) {
848             return null;
849         }
850 
851         int y = s.lastIndexOf(oldSub);
852 
853         if (y >= 0) {
854 
855             // The number 5 is arbitrary and is used as extra padding to reduce
856             // buffer expansion
857 
858             StringBuilder sb = new StringBuilder(
859                 s.length() + 5 * newSub.length());
860 
861             int length = oldSub.length();
862             int x = 0;
863 
864             while (x <= y) {
865                 sb.append(s.substring(x, y));
866                 sb.append(newSub);
867 
868                 x = y + length;
869                 y = s.indexOf(oldSub, x);
870             }
871 
872             sb.append(s.substring(x));
873 
874             return sb.toString();
875         }
876         else {
877             return s;
878         }
879     }
880 
881     public static String replaceLast(
882         String s, String[] oldSubs, String[] newSubs) {
883 
884         if ((s == null) || (oldSubs == null) || (newSubs == null)) {
885             return null;
886         }
887 
888         if (oldSubs.length != newSubs.length) {
889             return s;
890         }
891 
892         for (int i = 0; i < oldSubs.length; i++) {
893             s = replaceLast(s, oldSubs[i], newSubs[i]);
894         }
895 
896         return s;
897     }
898 
899     /**
900      * Returns a string with replaced values. This method will replace all text
901      * in the given string, between the beginning and ending delimiter, with new
902      * values found in the given map. For example, if the string contained the
903      * text <code>[$HELLO$]</code>, and the beginning delimiter was
904      * <code>[$]</code>, and the ending delimiter was <code>$]</code>, and the
905      * values map had a key of <code>HELLO</code> that mapped to
906      * <code>WORLD</code>, then the replaced string will contain the text
907      * <code>[$WORLD$]</code>.
908      *
909      * @return a string with replaced values
910      */
911     public static String replaceValues(
912         String s, String begin, String end, Map<String, String> values) {
913 
914         if ((s == null) || (begin == null) || (end == null) ||
915             (values == null) || (values.size() == 0)) {
916 
917             return s;
918         }
919 
920         StringBuilder sb = new StringBuilder(s.length());
921 
922         int pos = 0;
923 
924         while (true) {
925             int x = s.indexOf(begin, pos);
926             int y = s.indexOf(end, x + begin.length());
927 
928             if ((x == -1) || (y == -1)) {
929                 sb.append(s.substring(pos, s.length()));
930 
931                 break;
932             }
933             else {
934                 sb.append(s.substring(pos, x + begin.length()));
935 
936                 String oldValue = s.substring(x + begin.length(), y);
937 
938                 String newValue = values.get(oldValue);
939 
940                 if (newValue == null) {
941                     newValue = oldValue;
942                 }
943 
944                 sb.append(newValue);
945 
946                 pos = y;
947             }
948         }
949 
950         return sb.toString();
951     }
952 
953     public static String reverse(String s) {
954         if (s == null) {
955             return null;
956         }
957 
958         char[] charArray = s.toCharArray();
959         char[] reverse = new char[charArray.length];
960 
961         for (int i = 0; i < charArray.length; i++) {
962             reverse[i] = charArray[charArray.length - i - 1];
963         }
964 
965         return new String(reverse);
966     }
967 
968     public static String safePath(String path) {
969         return replace(path, StringPool.DOUBLE_SLASH, StringPool.SLASH);
970     }
971 
972     public static String shorten(String s) {
973         return shorten(s, 20);
974     }
975 
976     public static String shorten(String s, int length) {
977         return shorten(s, length, "...");
978     }
979 
980     public static String shorten(String s, int length, String suffix) {
981         if ((s == null) || (suffix == null)) {
982             return null;
983         }
984 
985         if (s.length() > length) {
986             for (int j = length; j >= 0; j--) {
987                 if (Character.isWhitespace(s.charAt(j))) {
988                     length = j;
989 
990                     break;
991                 }
992             }
993 
994             String temp = s.substring(0, length);
995 
996             s = temp.concat(suffix);
997         }
998 
999         return s;
1000    }
1001
1002    public static String shorten(String s, String suffix) {
1003        return shorten(s, 20, suffix);
1004    }
1005
1006    public static String[] split(String s) {
1007        return split(s, StringPool.COMMA);
1008    }
1009
1010    public static boolean[] split(String s, boolean x) {
1011        return split(s, StringPool.COMMA, x);
1012    }
1013
1014    public static double[] split(String s, double x) {
1015        return split(s, StringPool.COMMA, x);
1016    }
1017
1018    public static float[] split(String s, float x) {
1019        return split(s, StringPool.COMMA, x);
1020    }
1021
1022    public static int[] split(String s, int x) {
1023        return split(s, StringPool.COMMA, x);
1024    }
1025
1026    public static long[] split(String s, long x) {
1027        return split(s, StringPool.COMMA, x);
1028    }
1029
1030    public static short[] split(String s, short x) {
1031        return split(s, StringPool.COMMA, x);
1032    }
1033
1034    public static String[] split(String s, String delimiter) {
1035        if ((Validator.isNull(s)) || (delimiter == null) ||
1036            (delimiter.equals(StringPool.BLANK))) {
1037
1038            return new String[0];
1039        }
1040
1041        s = s.trim();
1042
1043        if (s.equals(delimiter)) {
1044            return new String[0];
1045        }
1046
1047        List<String> nodeValues = new ArrayList<String>();
1048
1049        if (delimiter.equals(StringPool.NEW_LINE) ||
1050            delimiter.equals(StringPool.RETURN)) {
1051
1052            try {
1053                UnsyncBufferedReader unsyncBufferedReader =
1054                    new UnsyncBufferedReader(new UnsyncStringReader(s));
1055
1056                String line = null;
1057
1058                while ((line = unsyncBufferedReader.readLine()) != null) {
1059                    nodeValues.add(line);
1060                }
1061
1062                unsyncBufferedReader.close();
1063            }
1064            catch (IOException ioe) {
1065                _log.error(ioe.getMessage());
1066            }
1067        }
1068        else {
1069            int offset = 0;
1070            int pos = s.indexOf(delimiter, offset);
1071
1072            while (pos != -1) {
1073                nodeValues.add(s.substring(offset, pos));
1074
1075                offset = pos + delimiter.length();
1076                pos = s.indexOf(delimiter, offset);
1077            }
1078
1079            if (offset < s.length()) {
1080                nodeValues.add(s.substring(offset));
1081            }
1082        }
1083
1084        return nodeValues.toArray(new String[nodeValues.size()]);
1085    }
1086
1087    public static boolean[] split(String s, String delimiter, boolean x) {
1088        String[] array = split(s, delimiter);
1089        boolean[] newArray = new boolean[array.length];
1090
1091        for (int i = 0; i < array.length; i++) {
1092            boolean value = x;
1093
1094            try {
1095                value = Boolean.valueOf(array[i]).booleanValue();
1096            }
1097            catch (Exception e) {
1098            }
1099
1100            newArray[i] = value;
1101        }
1102
1103        return newArray;
1104    }
1105
1106    public static double[] split(String s, String delimiter, double x) {
1107        String[] array = split(s, delimiter);
1108        double[] newArray = new double[array.length];
1109
1110        for (int i = 0; i < array.length; i++) {
1111            double value = x;
1112
1113            try {
1114                value = Double.parseDouble(array[i]);
1115            }
1116            catch (Exception e) {
1117            }
1118
1119            newArray[i] = value;
1120        }
1121
1122        return newArray;
1123    }
1124
1125    public static float[] split(String s, String delimiter, float x) {
1126        String[] array = split(s, delimiter);
1127        float[] newArray = new float[array.length];
1128
1129        for (int i = 0; i < array.length; i++) {
1130            float value = x;
1131
1132            try {
1133                value = Float.parseFloat(array[i]);
1134            }
1135            catch (Exception e) {
1136            }
1137
1138            newArray[i] = value;
1139        }
1140
1141        return newArray;
1142    }
1143
1144    public static int[] split(String s, String delimiter, int x) {
1145        String[] array = split(s, delimiter);
1146        int[] newArray = new int[array.length];
1147
1148        for (int i = 0; i < array.length; i++) {
1149            int value = x;
1150
1151            try {
1152                value = Integer.parseInt(array[i]);
1153            }
1154            catch (Exception e) {
1155            }
1156
1157            newArray[i] = value;
1158        }
1159
1160        return newArray;
1161    }
1162
1163    public static long[] split(String s, String delimiter, long x) {
1164        String[] array = split(s, delimiter);
1165        long[] newArray = new long[array.length];
1166
1167        for (int i = 0; i < array.length; i++) {
1168            long value = x;
1169
1170            try {
1171                value = Long.parseLong(array[i]);
1172            }
1173            catch (Exception e) {
1174            }
1175
1176            newArray[i] = value;
1177        }
1178
1179        return newArray;
1180    }
1181
1182    public static short[] split(String s, String delimiter, short x) {
1183        String[] array = split(s, delimiter);
1184        short[] newArray = new short[array.length];
1185
1186        for (int i = 0; i < array.length; i++) {
1187            short value = x;
1188
1189            try {
1190                value = Short.parseShort(array[i]);
1191            }
1192            catch (Exception e) {
1193            }
1194
1195            newArray[i] = value;
1196        }
1197
1198        return newArray;
1199    }
1200
1201    public static boolean startsWith(String s, char begin) {
1202        return startsWith(s, (new Character(begin)).toString());
1203    }
1204
1205    public static boolean startsWith(String s, String start) {
1206        if ((s == null) || (start == null)) {
1207            return false;
1208        }
1209
1210        if (start.length() > s.length()) {
1211            return false;
1212        }
1213
1214        String temp = s.substring(0, start.length());
1215
1216        if (temp.equalsIgnoreCase(start)) {
1217            return true;
1218        }
1219        else {
1220            return false;
1221        }
1222    }
1223
1224    /**
1225     * Return the number of starting letters that s1 and s2 have in common
1226     * before they deviate.
1227     *
1228     * @return the number of starting letters that s1 and s2 have in common
1229     *         before they deviate
1230     */
1231    public static int startsWithWeight(String s1, String s2) {
1232        if ((s1 == null) || (s2 == null)) {
1233            return 0;
1234        }
1235
1236        char[] charArray1 = s1.toCharArray();
1237        char[] charArray2 = s2.toCharArray();
1238
1239        int i = 0;
1240
1241        for (; (i < charArray1.length) && (i < charArray2.length); i++) {
1242            if (charArray1[i] != charArray2[i]) {
1243                break;
1244            }
1245        }
1246
1247        return i;
1248    }
1249
1250    public static String stripBetween(String s, String begin, String end) {
1251        if ((s == null) || (begin == null) || (end == null)) {
1252            return s;
1253        }
1254
1255        StringBuilder sb = new StringBuilder(s.length());
1256
1257        int pos = 0;
1258
1259        while (true) {
1260            int x = s.indexOf(begin, pos);
1261            int y = s.indexOf(end, x + begin.length());
1262
1263            if ((x == -1) || (y == -1)) {
1264                sb.append(s.substring(pos, s.length()));
1265
1266                break;
1267            }
1268            else {
1269                sb.append(s.substring(pos, x));
1270
1271                pos = y + end.length();
1272            }
1273        }
1274
1275        return sb.toString();
1276    }
1277
1278    public static String trim(String s) {
1279        return trim(s, null);
1280    }
1281
1282    public static String trim(String s, char c) {
1283        return trim(s, new char[] {c});
1284    }
1285
1286    public static String trim(String s, char[] exceptions) {
1287        if (s == null) {
1288            return null;
1289        }
1290
1291        char[] charArray = s.toCharArray();
1292
1293        int len = charArray.length;
1294
1295        int x = 0;
1296        int y = charArray.length;
1297
1298        for (int i = 0; i < len; i++) {
1299            char c = charArray[i];
1300
1301            if (_isTrimable(c, exceptions)) {
1302                x = i + 1;
1303            }
1304            else {
1305                break;
1306            }
1307        }
1308
1309        for (int i = len - 1; i >= 0; i--) {
1310            char c = charArray[i];
1311
1312            if (_isTrimable(c, exceptions)) {
1313                y = i;
1314            }
1315            else {
1316                break;
1317            }
1318        }
1319
1320        if ((x != 0) || (y != len)) {
1321            return s.substring(x, y);
1322        }
1323        else {
1324            return s;
1325        }
1326    }
1327
1328    public static String trimLeading(String s) {
1329        return trimLeading(s, null);
1330    }
1331
1332    public static String trimLeading(String s, char c) {
1333        return trimLeading(s, new char[] {c});
1334    }
1335
1336    public static String trimLeading(String s, char[] exceptions) {
1337        if (s == null) {
1338            return null;
1339        }
1340
1341        char[] charArray = s.toCharArray();
1342
1343        int len = charArray.length;
1344
1345        int x = 0;
1346        int y = charArray.length;
1347
1348        for (int i = 0; i < len; i++) {
1349            char c = charArray[i];
1350
1351            if (_isTrimable(c, exceptions)) {
1352                x = i + 1;
1353            }
1354            else {
1355                break;
1356            }
1357        }
1358
1359        if ((x != 0) || (y != len)) {
1360            return s.substring(x, y);
1361        }
1362        else {
1363            return s;
1364        }
1365    }
1366
1367    public static String trimTrailing(String s) {
1368        return trimTrailing(s, null);
1369    }
1370
1371    public static String trimTrailing(String s, char c) {
1372        return trimTrailing(s, new char[] {c});
1373    }
1374
1375    public static String trimTrailing(String s, char[] exceptions) {
1376        if (s == null) {
1377            return null;
1378        }
1379
1380        char[] charArray = s.toCharArray();
1381
1382        int len = charArray.length;
1383
1384        int x = 0;
1385        int y = charArray.length;
1386
1387        for (int i = len - 1; i >= 0; i--) {
1388            char c = charArray[i];
1389
1390            if (_isTrimable(c, exceptions)) {
1391                y = i;
1392            }
1393            else {
1394                break;
1395            }
1396        }
1397
1398        if ((x != 0) || (y != len)) {
1399            return s.substring(x, y);
1400        }
1401        else {
1402            return s;
1403        }
1404    }
1405
1406    public static String upperCase(String s) {
1407        if (s == null) {
1408            return null;
1409        }
1410        else {
1411            return s.toUpperCase();
1412        }
1413    }
1414
1415    public static String upperCaseFirstLetter(String s) {
1416        char[] charArray = s.toCharArray();
1417
1418        if ((charArray[0] >= 97) && (charArray[0] <= 122)) {
1419            charArray[0] = (char)(charArray[0] - 32);
1420        }
1421
1422        return new String(charArray);
1423    }
1424
1425    public static String valueOf(Object obj) {
1426        return String.valueOf(obj);
1427    }
1428
1429    public static String wrap(String text) {
1430        return wrap(text, 80, StringPool.NEW_LINE);
1431    }
1432
1433    public static String wrap(String text, int width, String lineSeparator) {
1434        try {
1435            return _wrap(text, width, lineSeparator);
1436        }
1437        catch (IOException ioe) {
1438            _log.error(ioe.getMessage());
1439
1440            return text;
1441        }
1442    }
1443
1444    private static boolean _isTrimable(char c, char[] exceptions) {
1445        if ((exceptions != null) && (exceptions.length > 0)) {
1446            for (int i = 0; i < exceptions.length; i++) {
1447                if (c == exceptions[i]) {
1448                    return false;
1449                }
1450            }
1451        }
1452
1453        return Character.isWhitespace(c);
1454    }
1455
1456    private static String _wrap(String text, int width, String lineSeparator)
1457        throws IOException {
1458
1459        if (text == null) {
1460            return null;
1461        }
1462
1463        StringBundler sb = new StringBundler();
1464
1465        UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
1466            new UnsyncStringReader(text));
1467
1468        String s = StringPool.BLANK;
1469
1470        while ((s = unsyncBufferedReader.readLine()) != null) {
1471            if (s.length() == 0) {
1472                sb.append(lineSeparator);
1473
1474                continue;
1475            }
1476
1477            int lineLength = 0;
1478
1479            String[] tokens = s.split(StringPool.SPACE);
1480
1481            for (String token : tokens) {
1482                if ((lineLength + token.length() + 1) > width) {
1483                    if (lineLength > 0) {
1484                        sb.append(lineSeparator);
1485                    }
1486
1487                    if (token.length() > width) {
1488                        int pos = token.indexOf(StringPool.OPEN_PARENTHESIS);
1489
1490                        if (pos != -1) {
1491                            sb.append(token.substring(0, pos + 1));
1492                            sb.append(lineSeparator);
1493
1494                            token = token.substring(pos + 1);
1495
1496                            sb.append(token);
1497
1498                            lineLength = token.length();
1499                        }
1500                        else {
1501                            sb.append(token);
1502
1503                            lineLength = token.length();
1504                        }
1505                    }
1506                    else {
1507                        sb.append(token);
1508
1509                        lineLength = token.length();
1510                    }
1511                }
1512                else {
1513                    if (lineLength > 0) {
1514                        sb.append(StringPool.SPACE);
1515
1516                        lineLength++;
1517                    }
1518
1519                    sb.append(token);
1520
1521                    lineLength += token.length();
1522                }
1523            }
1524
1525            sb.append(lineSeparator);
1526        }
1527
1528        return sb.toString();
1529    }
1530
1531    private static Log _log = LogFactoryUtil.getLog(StringUtil.class);
1532
1533}