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