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