1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
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 (Validator.isNull(s) || Validator.isNull(keywords)) {
256             return s;
257         }
258 
259         Pattern pattern = Pattern.compile(
260             Pattern.quote(keywords), Pattern.CASE_INSENSITIVE);
261 
262         return _highlight(s, pattern, highlight1, highlight2);
263     }
264 
265     public static String highlight(String s, String[] queryTerms) {
266         return highlight(
267             s, queryTerms, "<span class=\"highlight\">", "</span>");
268     }
269 
270     public static String highlight(
271         String s, String[] queryTerms, String highlight1, String highlight2) {
272 
273         if (Validator.isNull(s) || Validator.isNull(queryTerms)) {
274             return s;
275         }
276 
277         StringBundler sb = null;
278 
279         if (queryTerms.length == 0) {
280             sb = new StringBundler();
281         }
282         else {
283             sb = new StringBundler(2 * queryTerms.length - 1);
284         }
285 
286         for (int i = 0; i < queryTerms.length; i++) {
287             sb.append(Pattern.quote(queryTerms[i].trim()));
288 
289             if ((i + 1) < queryTerms.length) {
290                 sb.append(StringPool.PIPE);
291             }
292         }
293 
294         int flags =
295             Pattern.CANON_EQ | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
296 
297         Pattern pattern = Pattern.compile(sb.toString(), flags);
298 
299         return _highlight(s, pattern, highlight1, highlight2);
300     }
301 
302     public static String insert(String s, String insert, int offset) {
303         if (s == null) {
304             return null;
305         }
306 
307         if (insert == null) {
308             return s;
309         }
310 
311         if (offset > s.length()) {
312             offset = s.length();
313         }
314 
315         StringBuilder sb = new StringBuilder(s);
316 
317         sb.insert(offset, insert);
318 
319         return sb.toString();
320     }
321 
322     public static String lowerCase(String s) {
323         if (s == null) {
324             return null;
325         }
326         else {
327             return s.toLowerCase();
328         }
329     }
330 
331     public static boolean matches(String s, String pattern) {
332         String[] array = pattern.split("\\*");
333 
334         for (int i = 0; i < array.length; i++) {
335             int pos = s.indexOf(array[i]);
336 
337             if (pos == -1) {
338                 return false;
339             }
340 
341             s = s.substring(pos + array[i].length());
342         }
343 
344         return true;
345     }
346 
347     public static String merge(boolean[] array) {
348         return merge(array, StringPool.COMMA);
349     }
350 
351     public static String merge(boolean[] array, String delimiter) {
352         if (array == null) {
353             return null;
354         }
355 
356         StringBundler sb = null;
357 
358         if (array.length == 0) {
359             sb = new StringBundler();
360         }
361         else {
362             sb = new StringBundler(2 * array.length - 1);
363         }
364 
365         for (int i = 0; i < array.length; i++) {
366             sb.append(String.valueOf(array[i]).trim());
367 
368             if ((i + 1) != array.length) {
369                 sb.append(delimiter);
370             }
371         }
372 
373         return sb.toString();
374     }
375 
376     public static String merge(Collection<?> col) {
377         return merge(col, StringPool.COMMA);
378     }
379 
380     public static String merge(Collection<?> col, String delimiter) {
381         if (col == null) {
382             return null;
383         }
384 
385         return merge(col.toArray(new Object[col.size()]), delimiter);
386     }
387 
388     public static String merge(double[] array) {
389         return merge(array, StringPool.COMMA);
390     }
391 
392     public static String merge(double[] array, String delimiter) {
393         if (array == null) {
394             return null;
395         }
396 
397         StringBundler sb = null;
398 
399         if (array.length == 0) {
400             sb = new StringBundler();
401         }
402         else {
403             sb = new StringBundler(2 * array.length - 1);
404         }
405 
406         for (int i = 0; i < array.length; i++) {
407             sb.append(String.valueOf(array[i]).trim());
408 
409             if ((i + 1) != array.length) {
410                 sb.append(delimiter);
411             }
412         }
413 
414         return sb.toString();
415     }
416 
417     public static String merge(float[] array) {
418         return merge(array, StringPool.COMMA);
419     }
420 
421     public static String merge(float[] array, String delimiter) {
422         if (array == null) {
423             return null;
424         }
425 
426         StringBundler sb = null;
427 
428         if (array.length == 0) {
429             sb = new StringBundler();
430         }
431         else {
432             sb = new StringBundler(2 * array.length - 1);
433         }
434 
435         for (int i = 0; i < array.length; i++) {
436             sb.append(String.valueOf(array[i]).trim());
437 
438             if ((i + 1) != array.length) {
439                 sb.append(delimiter);
440             }
441         }
442 
443         return sb.toString();
444     }
445 
446     public static String merge(int[] array) {
447         return merge(array, StringPool.COMMA);
448     }
449 
450     public static String merge(int[] array, String delimiter) {
451         if (array == null) {
452             return null;
453         }
454 
455         StringBundler sb = null;
456 
457         if (array.length == 0){
458             sb = new StringBundler();
459         }
460         else {
461             sb = new StringBundler(2 * array.length - 1);
462         }
463 
464         for (int i = 0; i < array.length; i++) {
465             sb.append(String.valueOf(array[i]).trim());
466 
467             if ((i + 1) != array.length) {
468                 sb.append(delimiter);
469             }
470         }
471 
472         return sb.toString();
473     }
474 
475     public static String merge(long[] array) {
476         return merge(array, StringPool.COMMA);
477     }
478 
479     public static String merge(long[] array, String delimiter) {
480         if (array == null) {
481             return null;
482         }
483 
484         StringBundler sb = null;
485 
486         if (array.length == 0) {
487             sb = new StringBundler();
488         }
489         else {
490             sb = new StringBundler(2 * array.length - 1);
491         }
492 
493         for (int i = 0; i < array.length; i++) {
494             sb.append(String.valueOf(array[i]).trim());
495 
496             if ((i + 1) != array.length) {
497                 sb.append(delimiter);
498             }
499         }
500 
501         return sb.toString();
502     }
503 
504     public static String merge(Object[] array) {
505         return merge(array, StringPool.COMMA);
506     }
507 
508     public static String merge(Object[] array, String delimiter) {
509         if (array == null) {
510             return null;
511         }
512 
513         StringBundler sb = null;
514 
515         if (array.length == 0) {
516             sb = new StringBundler();
517         }
518         else {
519             sb = new StringBundler(2 * array.length - 1);
520         }
521 
522         for (int i = 0; i < array.length; i++) {
523             sb.append(String.valueOf(array[i]).trim());
524 
525             if ((i + 1) != array.length) {
526                 sb.append(delimiter);
527             }
528         }
529 
530         return sb.toString();
531     }
532 
533     public static String merge(short[] array) {
534         return merge(array, StringPool.COMMA);
535     }
536 
537     public static String merge(short[] array, String delimiter) {
538         if (array == null) {
539             return null;
540         }
541 
542         StringBundler sb = null;
543 
544         if (array.length == 0) {
545             sb = new StringBundler();
546         }
547         else {
548             sb = new StringBundler(2 * array.length - 1);
549         }
550 
551         for (int i = 0; i < array.length; i++) {
552             sb.append(String.valueOf(array[i]).trim());
553 
554             if ((i + 1) != array.length) {
555                 sb.append(delimiter);
556             }
557         }
558 
559         return sb.toString();
560     }
561 
562     public static String randomize(String s) {
563         return Randomizer.getInstance().randomize(s);
564     }
565 
566     public static String read(ClassLoader classLoader, String name)
567         throws IOException {
568 
569         return read(classLoader, name, false);
570     }
571 
572     public static String read(ClassLoader classLoader, String name, boolean all)
573         throws IOException {
574 
575         if (all) {
576             StringBundler sb = new StringBundler();
577 
578             Enumeration<URL> enu = classLoader.getResources(name);
579 
580             while (enu.hasMoreElements()) {
581                 URL url = enu.nextElement();
582 
583                 InputStream is = url.openStream();
584 
585                 if (is == null) {
586                     throw new IOException(
587                         "Unable to open resource at " + url.toString());
588                 }
589 
590                 String s = read(is);
591 
592                 if (s != null) {
593                     sb.append(s);
594                     sb.append(StringPool.NEW_LINE);
595                 }
596 
597                 is.close();
598             }
599 
600             return sb.toString().trim();
601         }
602         else {
603             InputStream is = classLoader.getResourceAsStream(name);
604 
605             if (is == null) {
606                 throw new IOException(
607                     "Unable to open resource in class loader " + name);
608             }
609 
610             String s = read(is);
611 
612             is.close();
613 
614             return s;
615         }
616     }
617 
618     public static String read(InputStream is) throws IOException {
619         StringBundler sb = new StringBundler();
620 
621         UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
622             new InputStreamReader(is));
623 
624         String line = null;
625 
626         while ((line = unsyncBufferedReader.readLine()) != null) {
627             sb.append(line);
628             sb.append(CharPool.NEW_LINE);
629         }
630 
631         unsyncBufferedReader.close();
632 
633         return sb.toString().trim();
634     }
635 
636     public static String remove(String s, String remove) {
637         return remove(s, remove, StringPool.COMMA);
638     }
639 
640     public static String remove(String s, String remove, String delimiter) {
641         if ((s == null) || (remove == null) || (delimiter == null)) {
642             return null;
643         }
644 
645         if (Validator.isNotNull(s) && !s.endsWith(delimiter)) {
646             s += delimiter;
647         }
648 
649         String drd = delimiter.concat(remove).concat(delimiter);
650 
651         String rd = remove.concat(delimiter);
652 
653         while (contains(s, remove, delimiter)) {
654             int pos = s.indexOf(drd);
655 
656             if (pos == -1) {
657                 if (s.startsWith(rd)) {
658                     int x = remove.length() + delimiter.length();
659                     int y = s.length();
660 
661                     s = s.substring(x, y);
662                 }
663             }
664             else {
665                 int x = pos + remove.length() + delimiter.length();
666                 int y = s.length();
667 
668                 String temp = s.substring(0, pos);
669 
670                 s = temp.concat(s.substring(x, y));
671             }
672         }
673 
674         return s;
675     }
676 
677     public static String replace(String s, char oldSub, char newSub) {
678         if (s == null) {
679             return null;
680         }
681 
682         return s.replace(oldSub, newSub);
683     }
684 
685     public static String replace(String s, char oldSub, String newSub) {
686         if ((s == null) || (newSub == null)) {
687             return null;
688         }
689 
690         // The number 5 is arbitrary and is used as extra padding to reduce
691         // buffer expansion
692 
693         StringBuilder sb = new StringBuilder(s.length() + 5 * newSub.length());
694 
695         char[] charArray = s.toCharArray();
696 
697         for (char c : charArray) {
698             if (c == oldSub) {
699                 sb.append(newSub);
700             }
701             else {
702                 sb.append(c);
703             }
704         }
705 
706         return sb.toString();
707     }
708 
709     public static String replace(String s, String oldSub, String newSub) {
710         return replace(s, oldSub, newSub, 0);
711     }
712 
713     public static String replace(
714         String s, String oldSub, String newSub, int fromIndex) {
715 
716         if ((s == null) || (oldSub == null) || (newSub == null)) {
717             return null;
718         }
719 
720         int y = s.indexOf(oldSub, fromIndex);
721 
722         if (y >= 0) {
723             StringBundler sb = new StringBundler();
724 
725             int length = oldSub.length();
726             int x = 0;
727 
728             while (x <= y) {
729                 sb.append(s.substring(x, y));
730                 sb.append(newSub);
731 
732                 x = y + length;
733                 y = s.indexOf(oldSub, x);
734             }
735 
736             sb.append(s.substring(x));
737 
738             return sb.toString();
739         }
740         else {
741             return s;
742         }
743     }
744 
745     public static String replace(
746         String s, String begin, String end, Map<String, String> values) {
747 
748         if ((s == null) || (begin == null) || (end == null) ||
749             (values == null) || (values.size() == 0)) {
750 
751             return s;
752         }
753 
754         StringBundler sb = new StringBundler(values.size() * 2 + 1);
755 
756         int pos = 0;
757 
758         while (true) {
759             int x = s.indexOf(begin, pos);
760             int y = s.indexOf(end, x + begin.length());
761 
762             if ((x == -1) || (y == -1)) {
763                 sb.append(s.substring(pos, s.length()));
764 
765                 break;
766             }
767             else {
768                 sb.append(s.substring(pos, x));
769 
770                 String oldValue = s.substring(x + begin.length(), y);
771 
772                 String newValue = values.get(oldValue);
773 
774                 if (newValue == null) {
775                     newValue = oldValue;
776                 }
777 
778                 sb.append(newValue);
779 
780                 pos = y + end.length();
781             }
782         }
783 
784         return sb.toString();
785     }
786 
787     public static String replace(String s, String[] oldSubs, String[] newSubs) {
788         if ((s == null) || (oldSubs == null) || (newSubs == null)) {
789             return null;
790         }
791 
792         if (oldSubs.length != newSubs.length) {
793             return s;
794         }
795 
796         for (int i = 0; i < oldSubs.length; i++) {
797             s = replace(s, oldSubs[i], newSubs[i]);
798         }
799 
800         return s;
801     }
802 
803     public static String replace(
804         String s, String[] oldSubs, String[] newSubs, boolean exactMatch) {
805 
806         if ((s == null) || (oldSubs == null) || (newSubs == null)) {
807             return null;
808         }
809 
810         if (oldSubs.length != newSubs.length) {
811             return s;
812         }
813 
814         if (!exactMatch) {
815             replace(s, oldSubs, newSubs);
816         }
817         else {
818             for (int i = 0; i < oldSubs.length; i++) {
819                 s = s.replaceAll("\\b" + oldSubs[i] + "\\b" , newSubs[i]);
820             }
821         }
822 
823         return s;
824     }
825 
826     public static String replaceFirst(String s, char oldSub, char newSub) {
827         if (s == null) {
828             return null;
829         }
830 
831         return s.replaceFirst(String.valueOf(oldSub), String.valueOf(newSub));
832     }
833 
834     public static String replaceFirst(String s, char oldSub, String newSub) {
835         if ((s == null) || (newSub == null)) {
836             return null;
837         }
838 
839         return s.replaceFirst(String.valueOf(oldSub), newSub);
840     }
841 
842     public static String replaceFirst(String s, String oldSub, String newSub) {
843         if ((s == null) || (oldSub == null) || (newSub == null)) {
844             return null;
845         }
846 
847         return s.replaceFirst(oldSub, newSub);
848     }
849 
850     public static String replaceFirst(
851         String s, String[] oldSubs, String[] newSubs) {
852 
853         if ((s == null) || (oldSubs == null) || (newSubs == null)) {
854             return null;
855         }
856 
857         if (oldSubs.length != newSubs.length) {
858             return s;
859         }
860 
861         for (int i = 0; i < oldSubs.length; i++) {
862             s = replaceFirst(s, oldSubs[i], newSubs[i]);
863         }
864 
865         return s;
866     }
867 
868     public static String replaceLast(String s, char oldSub, char newSub) {
869         if (s == null) {
870             return null;
871         }
872 
873         return replaceLast(s, String.valueOf(oldSub), String.valueOf(newSub));
874     }
875 
876     public static String replaceLast(String s, char oldSub, String newSub) {
877         if ((s == null) || (newSub == null)) {
878             return null;
879         }
880 
881         return replaceLast(s, String.valueOf(oldSub), newSub);
882     }
883 
884     public static String replaceLast(String s, String oldSub, String newSub) {
885         if ((s == null) || (oldSub == null) || (newSub == null)) {
886             return null;
887         }
888 
889         int y = s.lastIndexOf(oldSub);
890 
891         if (y >= 0) {
892             StringBundler sb = new StringBundler();
893 
894             int length = oldSub.length();
895             int x = 0;
896 
897             while (x <= y) {
898                 sb.append(s.substring(x, y));
899                 sb.append(newSub);
900 
901                 x = y + length;
902                 y = s.indexOf(oldSub, x);
903             }
904 
905             sb.append(s.substring(x));
906 
907             return sb.toString();
908         }
909         else {
910             return s;
911         }
912     }
913 
914     public static String replaceLast(
915         String s, String[] oldSubs, String[] newSubs) {
916 
917         if ((s == null) || (oldSubs == null) || (newSubs == null)) {
918             return null;
919         }
920 
921         if (oldSubs.length != newSubs.length) {
922             return s;
923         }
924 
925         for (int i = 0; i < oldSubs.length; i++) {
926             s = replaceLast(s, oldSubs[i], newSubs[i]);
927         }
928 
929         return s;
930     }
931 
932     public static String reverse(String s) {
933         if (s == null) {
934             return null;
935         }
936 
937         char[] charArray = s.toCharArray();
938         char[] reverse = new char[charArray.length];
939 
940         for (int i = 0; i < charArray.length; i++) {
941             reverse[i] = charArray[charArray.length - i - 1];
942         }
943 
944         return new String(reverse);
945     }
946 
947     public static String safePath(String path) {
948         return replace(path, StringPool.DOUBLE_SLASH, StringPool.SLASH);
949     }
950 
951     public static String shorten(String s) {
952         return shorten(s, 20);
953     }
954 
955     public static String shorten(String s, int length) {
956         return shorten(s, length, "...");
957     }
958 
959     public static String shorten(String s, int length, String suffix) {
960         if ((s == null) || (suffix == null)) {
961             return null;
962         }
963 
964         if (s.length() > length) {
965             for (int j = length; j >= 0; j--) {
966                 if (Character.isWhitespace(s.charAt(j))) {
967                     length = j;
968 
969                     break;
970                 }
971             }
972 
973             String temp = s.substring(0, length);
974 
975             s = temp.concat(suffix);
976         }
977 
978         return s;
979     }
980 
981     public static String shorten(String s, String suffix) {
982         return shorten(s, 20, suffix);
983     }
984 
985     public static String[] split(String s) {
986         return split(s, StringPool.COMMA);
987     }
988 
989     public static boolean[] split(String s, boolean x) {
990         return split(s, StringPool.COMMA, x);
991     }
992 
993     public static double[] split(String s, double x) {
994         return split(s, StringPool.COMMA, x);
995     }
996 
997     public static float[] split(String s, float x) {
998         return split(s, StringPool.COMMA, x);
999     }
1000
1001    public static int[] split(String s, int x) {
1002        return split(s, StringPool.COMMA, x);
1003    }
1004
1005    public static long[] split(String s, long x) {
1006        return split(s, StringPool.COMMA, x);
1007    }
1008
1009    public static short[] split(String s, short x) {
1010        return split(s, StringPool.COMMA, x);
1011    }
1012
1013    public static String[] split(String s, String delimiter) {
1014        if ((Validator.isNull(s)) || (delimiter == null) ||
1015            (delimiter.equals(StringPool.BLANK))) {
1016
1017            return new String[0];
1018        }
1019
1020        s = s.trim();
1021
1022        if (s.equals(delimiter)) {
1023            return new String[0];
1024        }
1025
1026        List<String> nodeValues = new ArrayList<String>();
1027
1028        if (delimiter.equals(StringPool.NEW_LINE) ||
1029            delimiter.equals(StringPool.RETURN)) {
1030
1031            try {
1032                UnsyncBufferedReader unsyncBufferedReader =
1033                    new UnsyncBufferedReader(new UnsyncStringReader(s));
1034
1035                String line = null;
1036
1037                while ((line = unsyncBufferedReader.readLine()) != null) {
1038                    nodeValues.add(line);
1039                }
1040
1041                unsyncBufferedReader.close();
1042            }
1043            catch (IOException ioe) {
1044                _log.error(ioe.getMessage());
1045            }
1046        }
1047        else {
1048            int offset = 0;
1049            int pos = s.indexOf(delimiter, offset);
1050
1051            while (pos != -1) {
1052                nodeValues.add(s.substring(offset, pos));
1053
1054                offset = pos + delimiter.length();
1055                pos = s.indexOf(delimiter, offset);
1056            }
1057
1058            if (offset < s.length()) {
1059                nodeValues.add(s.substring(offset));
1060            }
1061        }
1062
1063        return nodeValues.toArray(new String[nodeValues.size()]);
1064    }
1065
1066    public static boolean[] split(String s, String delimiter, boolean x) {
1067        String[] array = split(s, delimiter);
1068        boolean[] newArray = new boolean[array.length];
1069
1070        for (int i = 0; i < array.length; i++) {
1071            boolean value = x;
1072
1073            try {
1074                value = Boolean.valueOf(array[i]).booleanValue();
1075            }
1076            catch (Exception e) {
1077            }
1078
1079            newArray[i] = value;
1080        }
1081
1082        return newArray;
1083    }
1084
1085    public static double[] split(String s, String delimiter, double x) {
1086        String[] array = split(s, delimiter);
1087        double[] newArray = new double[array.length];
1088
1089        for (int i = 0; i < array.length; i++) {
1090            double value = x;
1091
1092            try {
1093                value = Double.parseDouble(array[i]);
1094            }
1095            catch (Exception e) {
1096            }
1097
1098            newArray[i] = value;
1099        }
1100
1101        return newArray;
1102    }
1103
1104    public static float[] split(String s, String delimiter, float x) {
1105        String[] array = split(s, delimiter);
1106        float[] newArray = new float[array.length];
1107
1108        for (int i = 0; i < array.length; i++) {
1109            float value = x;
1110
1111            try {
1112                value = Float.parseFloat(array[i]);
1113            }
1114            catch (Exception e) {
1115            }
1116
1117            newArray[i] = value;
1118        }
1119
1120        return newArray;
1121    }
1122
1123    public static int[] split(String s, String delimiter, int x) {
1124        String[] array = split(s, delimiter);
1125        int[] newArray = new int[array.length];
1126
1127        for (int i = 0; i < array.length; i++) {
1128            int value = x;
1129
1130            try {
1131                value = Integer.parseInt(array[i]);
1132            }
1133            catch (Exception e) {
1134            }
1135
1136            newArray[i] = value;
1137        }
1138
1139        return newArray;
1140    }
1141
1142    public static long[] split(String s, String delimiter, long x) {
1143        String[] array = split(s, delimiter);
1144        long[] newArray = new long[array.length];
1145
1146        for (int i = 0; i < array.length; i++) {
1147            long value = x;
1148
1149            try {
1150                value = Long.parseLong(array[i]);
1151            }
1152            catch (Exception e) {
1153            }
1154
1155            newArray[i] = value;
1156        }
1157
1158        return newArray;
1159    }
1160
1161    public static short[] split(String s, String delimiter, short x) {
1162        String[] array = split(s, delimiter);
1163        short[] newArray = new short[array.length];
1164
1165        for (int i = 0; i < array.length; i++) {
1166            short value = x;
1167
1168            try {
1169                value = Short.parseShort(array[i]);
1170            }
1171            catch (Exception e) {
1172            }
1173
1174            newArray[i] = value;
1175        }
1176
1177        return newArray;
1178    }
1179
1180    public static boolean startsWith(String s, char begin) {
1181        return startsWith(s, (new Character(begin)).toString());
1182    }
1183
1184    public static boolean startsWith(String s, String start) {
1185        if ((s == null) || (start == null)) {
1186            return false;
1187        }
1188
1189        if (start.length() > s.length()) {
1190            return false;
1191        }
1192
1193        String temp = s.substring(0, start.length());
1194
1195        if (temp.equalsIgnoreCase(start)) {
1196            return true;
1197        }
1198        else {
1199            return false;
1200        }
1201    }
1202
1203    /**
1204     * Return the number of starting letters that s1 and s2 have in common
1205     * before they deviate.
1206     *
1207     * @return the number of starting letters that s1 and s2 have in common
1208     *         before they deviate
1209     */
1210    public static int startsWithWeight(String s1, String s2) {
1211        if ((s1 == null) || (s2 == null)) {
1212            return 0;
1213        }
1214
1215        char[] charArray1 = s1.toCharArray();
1216        char[] charArray2 = s2.toCharArray();
1217
1218        int i = 0;
1219
1220        for (; (i < charArray1.length) && (i < charArray2.length); i++) {
1221            if (charArray1[i] != charArray2[i]) {
1222                break;
1223            }
1224        }
1225
1226        return i;
1227    }
1228
1229    public static String stripBetween(String s, String begin, String end) {
1230        if ((s == null) || (begin == null) || (end == null)) {
1231            return s;
1232        }
1233
1234        StringBuilder sb = new StringBuilder(s.length());
1235
1236        int pos = 0;
1237
1238        while (true) {
1239            int x = s.indexOf(begin, pos);
1240            int y = s.indexOf(end, x + begin.length());
1241
1242            if ((x == -1) || (y == -1)) {
1243                sb.append(s.substring(pos, s.length()));
1244
1245                break;
1246            }
1247            else {
1248                sb.append(s.substring(pos, x));
1249
1250                pos = y + end.length();
1251            }
1252        }
1253
1254        return sb.toString();
1255    }
1256
1257    public static String trim(String s) {
1258        return trim(s, null);
1259    }
1260
1261    public static String trim(String s, char c) {
1262        return trim(s, new char[] {c});
1263    }
1264
1265    public static String trim(String s, char[] exceptions) {
1266        if (s == null) {
1267            return null;
1268        }
1269
1270        char[] charArray = s.toCharArray();
1271
1272        int len = charArray.length;
1273
1274        int x = 0;
1275        int y = charArray.length;
1276
1277        for (int i = 0; i < len; i++) {
1278            char c = charArray[i];
1279
1280            if (_isTrimable(c, exceptions)) {
1281                x = i + 1;
1282            }
1283            else {
1284                break;
1285            }
1286        }
1287
1288        for (int i = len - 1; i >= 0; i--) {
1289            char c = charArray[i];
1290
1291            if (_isTrimable(c, exceptions)) {
1292                y = i;
1293            }
1294            else {
1295                break;
1296            }
1297        }
1298
1299        if ((x != 0) || (y != len)) {
1300            return s.substring(x, y);
1301        }
1302        else {
1303            return s;
1304        }
1305    }
1306
1307    public static String trimLeading(String s) {
1308        return trimLeading(s, null);
1309    }
1310
1311    public static String trimLeading(String s, char c) {
1312        return trimLeading(s, new char[] {c});
1313    }
1314
1315    public static String trimLeading(String s, char[] exceptions) {
1316        if (s == null) {
1317            return null;
1318        }
1319
1320        char[] charArray = s.toCharArray();
1321
1322        int len = charArray.length;
1323
1324        int x = 0;
1325        int y = charArray.length;
1326
1327        for (int i = 0; i < len; i++) {
1328            char c = charArray[i];
1329
1330            if (_isTrimable(c, exceptions)) {
1331                x = i + 1;
1332            }
1333            else {
1334                break;
1335            }
1336        }
1337
1338        if ((x != 0) || (y != len)) {
1339            return s.substring(x, y);
1340        }
1341        else {
1342            return s;
1343        }
1344    }
1345
1346    public static String trimTrailing(String s) {
1347        return trimTrailing(s, null);
1348    }
1349
1350    public static String trimTrailing(String s, char c) {
1351        return trimTrailing(s, new char[] {c});
1352    }
1353
1354    public static String trimTrailing(String s, char[] exceptions) {
1355        if (s == null) {
1356            return null;
1357        }
1358
1359        char[] charArray = s.toCharArray();
1360
1361        int len = charArray.length;
1362
1363        int x = 0;
1364        int y = charArray.length;
1365
1366        for (int i = len - 1; i >= 0; i--) {
1367            char c = charArray[i];
1368
1369            if (_isTrimable(c, exceptions)) {
1370                y = i;
1371            }
1372            else {
1373                break;
1374            }
1375        }
1376
1377        if ((x != 0) || (y != len)) {
1378            return s.substring(x, y);
1379        }
1380        else {
1381            return s;
1382        }
1383    }
1384
1385    public static String upperCase(String s) {
1386        if (s == null) {
1387            return null;
1388        }
1389        else {
1390            return s.toUpperCase();
1391        }
1392    }
1393
1394    public static String upperCaseFirstLetter(String s) {
1395        char[] charArray = s.toCharArray();
1396
1397        if ((charArray[0] >= 97) && (charArray[0] <= 122)) {
1398            charArray[0] = (char)(charArray[0] - 32);
1399        }
1400
1401        return new String(charArray);
1402    }
1403
1404    public static String valueOf(Object obj) {
1405        return String.valueOf(obj);
1406    }
1407
1408    public static String wrap(String text) {
1409        return wrap(text, 80, StringPool.NEW_LINE);
1410    }
1411
1412    public static String wrap(String text, int width, String lineSeparator) {
1413        try {
1414            return _wrap(text, width, lineSeparator);
1415        }
1416        catch (IOException ioe) {
1417            _log.error(ioe.getMessage());
1418
1419            return text;
1420        }
1421    }
1422
1423    private static String _highlight(
1424        String s, Pattern pattern, String highlight1, String highlight2) {
1425
1426        StringTokenizer st = new StringTokenizer(s);
1427
1428        StringBundler sb = null;
1429
1430        if (st.countTokens() == 0) {
1431            sb = new StringBundler();
1432        }
1433        else {
1434            sb = new StringBundler(2 * st.countTokens() - 1);
1435        }
1436
1437        while (st.hasMoreTokens()) {
1438            String token = st.nextToken();
1439
1440            Matcher matcher = pattern.matcher(token);
1441
1442            if (matcher.find()) {
1443                String highlightedToken = matcher.replaceAll(
1444                    highlight1 + matcher.group() + highlight2);
1445
1446                sb.append(highlightedToken);
1447            }
1448            else {
1449                sb.append(token);
1450            }
1451
1452            if (st.hasMoreTokens()) {
1453                sb.append(StringPool.SPACE);
1454            }
1455        }
1456
1457        return sb.toString();
1458    }
1459
1460    private static boolean _isTrimable(char c, char[] exceptions) {
1461        if ((exceptions != null) && (exceptions.length > 0)) {
1462            for (int i = 0; i < exceptions.length; i++) {
1463                if (c == exceptions[i]) {
1464                    return false;
1465                }
1466            }
1467        }
1468
1469        return Character.isWhitespace(c);
1470    }
1471
1472    private static String _wrap(String text, int width, String lineSeparator)
1473        throws IOException {
1474
1475        if (text == null) {
1476            return null;
1477        }
1478
1479        StringBundler sb = new StringBundler();
1480
1481        UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
1482            new UnsyncStringReader(text));
1483
1484        String s = StringPool.BLANK;
1485
1486        while ((s = unsyncBufferedReader.readLine()) != null) {
1487            if (s.length() == 0) {
1488                sb.append(lineSeparator);
1489
1490                continue;
1491            }
1492
1493            int lineLength = 0;
1494
1495            String[] tokens = s.split(StringPool.SPACE);
1496
1497            for (String token : tokens) {
1498                if ((lineLength + token.length() + 1) > width) {
1499                    if (lineLength > 0) {
1500                        sb.append(lineSeparator);
1501                    }
1502
1503                    if (token.length() > width) {
1504                        int pos = token.indexOf(StringPool.OPEN_PARENTHESIS);
1505
1506                        if (pos != -1) {
1507                            sb.append(token.substring(0, pos + 1));
1508                            sb.append(lineSeparator);
1509
1510                            token = token.substring(pos + 1);
1511
1512                            sb.append(token);
1513
1514                            lineLength = token.length();
1515                        }
1516                        else {
1517                            sb.append(token);
1518
1519                            lineLength = token.length();
1520                        }
1521                    }
1522                    else {
1523                        sb.append(token);
1524
1525                        lineLength = token.length();
1526                    }
1527                }
1528                else {
1529                    if (lineLength > 0) {
1530                        sb.append(StringPool.SPACE);
1531
1532                        lineLength++;
1533                    }
1534
1535                    sb.append(token);
1536
1537                    lineLength += token.length();
1538                }
1539            }
1540
1541            sb.append(lineSeparator);
1542        }
1543
1544        return sb.toString();
1545    }
1546
1547    private static Log _log = LogFactoryUtil.getLog(StringUtil.class);
1548
1549}