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                 if (is == null) {
542                     throw new IOException(
543                         "Unable to open resource at " + url.toString());
544                 }
545 
546                 String s = read(is);
547 
548                 if (s != null) {
549                     sb.append(s);
550                     sb.append(StringPool.NEW_LINE);
551                 }
552 
553                 is.close();
554             }
555 
556             return sb.toString().trim();
557         }
558         else {
559             InputStream is = classLoader.getResourceAsStream(name);
560 
561             if (is == null) {
562                 throw new IOException(
563                     "Unable to open resource in class loader " + name);
564             }
565 
566             String s = read(is);
567 
568             is.close();
569 
570             return s;
571         }
572     }
573 
574     public static String read(InputStream is) throws IOException {
575         StringBuilder sb = new StringBuilder();
576 
577         BufferedReader br = new BufferedReader(new InputStreamReader(is));
578 
579         String line = null;
580 
581         while ((line = br.readLine()) != null) {
582             sb.append(line).append('\n');
583         }
584 
585         br.close();
586 
587         return sb.toString().trim();
588     }
589 
590     public static String remove(String s, String remove) {
591         return remove(s, remove, StringPool.COMMA);
592     }
593 
594     public static String remove(String s, String remove, String delimiter) {
595         if ((s == null) || (remove == null) || (delimiter == null)) {
596             return null;
597         }
598 
599         if (Validator.isNotNull(s) && !s.endsWith(delimiter)) {
600             s += delimiter;
601         }
602 
603         StringBuilder sb = new StringBuilder();
604 
605         sb.append(delimiter);
606         sb.append(remove);
607         sb.append(delimiter);
608 
609         String drd = sb.toString();
610 
611         sb = new StringBuilder();
612 
613         sb.append(remove);
614         sb.append(delimiter);
615 
616         String rd = sb.toString();
617 
618         while (contains(s, remove, delimiter)) {
619             int pos = s.indexOf(drd);
620 
621             if (pos == -1) {
622                 if (s.startsWith(rd)) {
623                     int x = remove.length() + delimiter.length();
624                     int y = s.length();
625 
626                     s = s.substring(x, y);
627                 }
628             }
629             else {
630                 int x = pos + remove.length() + delimiter.length();
631                 int y = s.length();
632 
633                 sb = new StringBuilder();
634 
635                 sb.append(s.substring(0, pos));
636                 sb.append(s.substring(x, y));
637 
638                 s = sb.toString();
639             }
640         }
641 
642         return s;
643     }
644 
645     public static String replace(String s, char oldSub, char newSub) {
646         if (s == null) {
647             return null;
648         }
649 
650         return s.replace(oldSub, newSub);
651     }
652 
653     public static String replace(String s, char oldSub, String newSub) {
654         if ((s == null) || (newSub == null)) {
655             return null;
656         }
657 
658         // The number 5 is arbitrary and is used as extra padding to reduce
659         // buffer expansion
660 
661         StringBuilder sb = new StringBuilder(s.length() + 5 * newSub.length());
662 
663         char[] charArray = s.toCharArray();
664 
665         for (char c : charArray) {
666             if (c == oldSub) {
667                 sb.append(newSub);
668             }
669             else {
670                 sb.append(c);
671             }
672         }
673 
674         return sb.toString();
675     }
676 
677     public static String replace(String s, String oldSub, String newSub) {
678         if ((s == null) || (oldSub == null) || (newSub == null)) {
679             return null;
680         }
681 
682         int y = s.indexOf(oldSub);
683 
684         if (y >= 0) {
685 
686             // The number 5 is arbitrary and is used as extra padding to reduce
687             // buffer expansion
688 
689             StringBuilder sb = new StringBuilder(
690                 s.length() + 5 * newSub.length());
691 
692             int length = oldSub.length();
693             int x = 0;
694 
695             while (x <= y) {
696                 sb.append(s.substring(x, y));
697                 sb.append(newSub);
698 
699                 x = y + length;
700                 y = s.indexOf(oldSub, x);
701             }
702 
703             sb.append(s.substring(x));
704 
705             return sb.toString();
706         }
707         else {
708             return s;
709         }
710     }
711 
712     public static String replace(String s, String[] oldSubs, String[] newSubs) {
713         if ((s == null) || (oldSubs == null) || (newSubs == null)) {
714             return null;
715         }
716 
717         if (oldSubs.length != newSubs.length) {
718             return s;
719         }
720 
721         for (int i = 0; i < oldSubs.length; i++) {
722             s = replace(s, oldSubs[i], newSubs[i]);
723         }
724 
725         return s;
726     }
727 
728     public static String replace(
729         String s, String[] oldSubs, String[] newSubs, boolean exactMatch) {
730 
731         if ((s == null) || (oldSubs == null) || (newSubs == null)) {
732             return null;
733         }
734 
735         if (oldSubs.length != newSubs.length) {
736             return s;
737         }
738 
739         if (!exactMatch) {
740             replace(s, oldSubs, newSubs);
741         }
742         else {
743             for (int i = 0; i < oldSubs.length; i++) {
744                 s = s.replaceAll("\\b" + oldSubs[i] + "\\b" , newSubs[i]);
745             }
746         }
747 
748         return s;
749     }
750 
751     public static String replaceFirst(String s, char oldSub, char newSub) {
752         if (s == null) {
753             return null;
754         }
755 
756         return s.replaceFirst(String.valueOf(oldSub), String.valueOf(newSub));
757     }
758 
759     public static String replaceFirst(String s, char oldSub, String newSub) {
760         if ((s == null) || (newSub == null)) {
761             return null;
762         }
763 
764         return s.replaceFirst(String.valueOf(oldSub), newSub);
765     }
766 
767     public static String replaceFirst(String s, String oldSub, String newSub) {
768         if ((s == null) || (oldSub == null) || (newSub == null)) {
769             return null;
770         }
771 
772         return s.replaceFirst(oldSub, newSub);
773     }
774 
775     public static String replaceFirst(
776         String s, String[] oldSubs, String[] newSubs) {
777 
778         if ((s == null) || (oldSubs == null) || (newSubs == null)) {
779             return null;
780         }
781 
782         if (oldSubs.length != newSubs.length) {
783             return s;
784         }
785 
786         for (int i = 0; i < oldSubs.length; i++) {
787             s = replaceFirst(s, oldSubs[i], newSubs[i]);
788         }
789 
790         return s;
791     }
792 
793     /**
794      * Returns a string with replaced values. This method will replace all text
795      * in the given string, between the beginning and ending delimiter, with new
796      * values found in the given map. For example, if the string contained the
797      * text <code>[$HELLO$]</code>, and the beginning delimiter was
798      * <code>[$]</code>, and the ending delimiter was <code>$]</code>, and the
799      * values map had a key of <code>HELLO</code> that mapped to
800      * <code>WORLD</code>, then the replaced string will contain the text
801      * <code>[$WORLD$]</code>.
802      *
803      * @param       s the original string
804      * @param       begin the beginning delimiter
805      * @param       end the ending delimiter
806      * @param       values a map of old and new values
807      * @return      a string with replaced values
808      */
809     public static String replaceValues(
810         String s, String begin, String end, Map<String, String> values) {
811 
812         if ((s == null) || (begin == null) || (end == null) ||
813             (values == null) || (values.size() == 0)) {
814 
815             return s;
816         }
817 
818         StringBuilder sb = new StringBuilder(s.length());
819 
820         int pos = 0;
821 
822         while (true) {
823             int x = s.indexOf(begin, pos);
824             int y = s.indexOf(end, x + begin.length());
825 
826             if ((x == -1) || (y == -1)) {
827                 sb.append(s.substring(pos, s.length()));
828 
829                 break;
830             }
831             else {
832                 sb.append(s.substring(pos, x + begin.length()));
833 
834                 String oldValue = s.substring(x + begin.length(), y);
835 
836                 String newValue = values.get(oldValue);
837 
838                 if (newValue == null) {
839                     newValue = oldValue;
840                 }
841 
842                 sb.append(newValue);
843 
844                 pos = y;
845             }
846         }
847 
848         return sb.toString();
849     }
850 
851     public static String reverse(String s) {
852         if (s == null) {
853             return null;
854         }
855 
856         char[] c = s.toCharArray();
857         char[] reverse = new char[c.length];
858 
859         for (int i = 0; i < c.length; i++) {
860             reverse[i] = c[c.length - i - 1];
861         }
862 
863         return new String(reverse);
864     }
865 
866     public static String safePath(String path) {
867         return replace(path, StringPool.DOUBLE_SLASH, StringPool.SLASH);
868     }
869 
870     public static String shorten(String s) {
871         return shorten(s, 20);
872     }
873 
874     public static String shorten(String s, int length) {
875         return shorten(s, length, "...");
876     }
877 
878     public static String shorten(String s, String suffix) {
879         return shorten(s, 20, suffix);
880     }
881 
882     public static String shorten(String s, int length, String suffix) {
883         if ((s == null) || (suffix == null)) {
884             return null;
885         }
886 
887         if (s.length() > length) {
888             for (int j = length; j >= 0; j--) {
889                 if (Character.isWhitespace(s.charAt(j))) {
890                     length = j;
891 
892                     break;
893                 }
894             }
895 
896             StringBuilder sb = new StringBuilder();
897 
898             sb.append(s.substring(0, length));
899             sb.append(suffix);
900 
901             s =  sb.toString();
902         }
903 
904         return s;
905     }
906 
907     public static String[] split(String s) {
908         return split(s, StringPool.COMMA);
909     }
910 
911     public static String[] split(String s, String delimiter) {
912         if ((Validator.isNull(s)) || (delimiter == null) ||
913             (delimiter.equals(StringPool.BLANK))) {
914 
915             return new String[0];
916         }
917 
918         s = s.trim();
919 
920         if (!s.endsWith(delimiter)) {
921             StringBuilder sb = new StringBuilder();
922 
923             sb.append(s);
924             sb.append(delimiter);
925 
926             s = sb.toString();
927         }
928 
929         if (s.equals(delimiter)) {
930             return new String[0];
931         }
932 
933         List<String> nodeValues = new ArrayList<String>();
934 
935         if (delimiter.equals(StringPool.NEW_LINE) ||
936             delimiter.equals(StringPool.RETURN)) {
937 
938             try {
939                 BufferedReader br = new BufferedReader(new StringReader(s));
940 
941                 String line = null;
942 
943                 while ((line = br.readLine()) != null) {
944                     nodeValues.add(line);
945                 }
946 
947                 br.close();
948             }
949             catch (IOException ioe) {
950                 _log.error(ioe.getMessage());
951             }
952         }
953         else {
954             int offset = 0;
955             int pos = s.indexOf(delimiter, offset);
956 
957             while (pos != -1) {
958                 nodeValues.add(new String(s.substring(offset, pos)));
959 
960                 offset = pos + delimiter.length();
961                 pos = s.indexOf(delimiter, offset);
962             }
963         }
964 
965         return nodeValues.toArray(new String[nodeValues.size()]);
966     }
967 
968     public static boolean[] split(String s, boolean x) {
969         return split(s, StringPool.COMMA, x);
970     }
971 
972     public static boolean[] split(String s, String delimiter, boolean x) {
973         String[] array = split(s, delimiter);
974         boolean[] newArray = new boolean[array.length];
975 
976         for (int i = 0; i < array.length; i++) {
977             boolean value = x;
978 
979             try {
980                 value = Boolean.valueOf(array[i]).booleanValue();
981             }
982             catch (Exception e) {
983             }
984 
985             newArray[i] = value;
986         }
987 
988         return newArray;
989     }
990 
991     public static double[] split(String s, double x) {
992         return split(s, StringPool.COMMA, x);
993     }
994 
995     public static double[] split(String s, String delimiter, double x) {
996         String[] array = split(s, delimiter);
997         double[] newArray = new double[array.length];
998 
999         for (int i = 0; i < array.length; i++) {
1000            double value = x;
1001
1002            try {
1003                value = Double.parseDouble(array[i]);
1004            }
1005            catch (Exception e) {
1006            }
1007
1008            newArray[i] = value;
1009        }
1010
1011        return newArray;
1012    }
1013
1014    public static float[] split(String s, float x) {
1015        return split(s, StringPool.COMMA, x);
1016    }
1017
1018    public static float[] split(String s, String delimiter, float x) {
1019        String[] array = split(s, delimiter);
1020        float[] newArray = new float[array.length];
1021
1022        for (int i = 0; i < array.length; i++) {
1023            float value = x;
1024
1025            try {
1026                value = Float.parseFloat(array[i]);
1027            }
1028            catch (Exception e) {
1029            }
1030
1031            newArray[i] = value;
1032        }
1033
1034        return newArray;
1035    }
1036
1037    public static int[] split(String s, int x) {
1038        return split(s, StringPool.COMMA, x);
1039    }
1040
1041    public static int[] split(String s, String delimiter, int x) {
1042        String[] array = split(s, delimiter);
1043        int[] newArray = new int[array.length];
1044
1045        for (int i = 0; i < array.length; i++) {
1046            int value = x;
1047
1048            try {
1049                value = Integer.parseInt(array[i]);
1050            }
1051            catch (Exception e) {
1052            }
1053
1054            newArray[i] = value;
1055        }
1056
1057        return newArray;
1058    }
1059
1060    public static long[] split(String s, long x) {
1061        return split(s, StringPool.COMMA, x);
1062    }
1063
1064    public static long[] split(String s, String delimiter, long x) {
1065        String[] array = split(s, delimiter);
1066        long[] newArray = new long[array.length];
1067
1068        for (int i = 0; i < array.length; i++) {
1069            long value = x;
1070
1071            try {
1072                value = Long.parseLong(array[i]);
1073            }
1074            catch (Exception e) {
1075            }
1076
1077            newArray[i] = value;
1078        }
1079
1080        return newArray;
1081    }
1082
1083    public static short[] split(String s, short x) {
1084        return split(s, StringPool.COMMA, x);
1085    }
1086
1087    public static short[] split(String s, String delimiter, short x) {
1088        String[] array = split(s, delimiter);
1089        short[] newArray = new short[array.length];
1090
1091        for (int i = 0; i < array.length; i++) {
1092            short value = x;
1093
1094            try {
1095                value = Short.parseShort(array[i]);
1096            }
1097            catch (Exception e) {
1098            }
1099
1100            newArray[i] = value;
1101        }
1102
1103        return newArray;
1104    }
1105
1106    public static boolean startsWith(String s, char begin) {
1107        return startsWith(s, (new Character(begin)).toString());
1108    }
1109
1110    public static boolean startsWith(String s, String start) {
1111        if ((s == null) || (start == null)) {
1112            return false;
1113        }
1114
1115        if (start.length() > s.length()) {
1116            return false;
1117        }
1118
1119        String temp = s.substring(0, start.length());
1120
1121        if (temp.equalsIgnoreCase(start)) {
1122            return true;
1123        }
1124        else {
1125            return false;
1126        }
1127    }
1128
1129    /**
1130     * Return the number of starting letters that s1 and s2 have in common
1131     * before they deviate.
1132     *
1133     * @param       s1 the first string
1134     * @param       s2 the second string
1135     *
1136     * @return      the number of starting letters that s1 and s2 have in common
1137     *              before they deviate
1138     */
1139    public static int startsWithWeight(String s1, String s2) {
1140        if ((s1 == null) || (s2 == null)) {
1141            return 0;
1142        }
1143
1144        char[] charArray1 = s1.toCharArray();
1145        char[] charArray2 = s2.toCharArray();
1146
1147        int i = 0;
1148
1149        for (; (i < charArray1.length) && (i < charArray2.length); i++) {
1150            if (charArray1[i] != charArray2[i]) {
1151                break;
1152            }
1153        }
1154
1155        return i;
1156    }
1157
1158    public static String stripBetween(String s, String begin, String end) {
1159        if ((s == null) || (begin == null) || (end == null)) {
1160            return s;
1161        }
1162
1163        StringBuilder sb = new StringBuilder(s.length());
1164
1165        int pos = 0;
1166
1167        while (true) {
1168            int x = s.indexOf(begin, pos);
1169            int y = s.indexOf(end, x + begin.length());
1170
1171            if ((x == -1) || (y == -1)) {
1172                sb.append(s.substring(pos, s.length()));
1173
1174                break;
1175            }
1176            else {
1177                sb.append(s.substring(pos, x));
1178
1179                pos = y + end.length();
1180            }
1181        }
1182
1183        return sb.toString();
1184    }
1185
1186    public static String trim(String s) {
1187        return trim(s, null);
1188    }
1189
1190    public static String trim(String s, char c) {
1191        return trim(s, new char[] {c});
1192    }
1193
1194    public static String trim(String s, char[] exceptions) {
1195        if (s == null) {
1196            return null;
1197        }
1198
1199        char[] charArray = s.toCharArray();
1200
1201        int len = charArray.length;
1202
1203        int x = 0;
1204        int y = charArray.length;
1205
1206        for (int i = 0; i < len; i++) {
1207            char c = charArray[i];
1208
1209            if (_isTrimable(c, exceptions)) {
1210                x = i + 1;
1211            }
1212            else {
1213                break;
1214            }
1215        }
1216
1217        for (int i = len - 1; i >= 0; i--) {
1218            char c = charArray[i];
1219
1220            if (_isTrimable(c, exceptions)) {
1221                y = i;
1222            }
1223            else {
1224                break;
1225            }
1226        }
1227
1228        if ((x != 0) || (y != len)) {
1229            return s.substring(x, y);
1230        }
1231        else {
1232            return s;
1233        }
1234    }
1235
1236    public static String trimLeading(String s) {
1237        return trimLeading(s, null);
1238    }
1239
1240    public static String trimLeading(String s, char c) {
1241        return trimLeading(s, new char[] {c});
1242    }
1243
1244    public static String trimLeading(String s, char[] exceptions) {
1245        if (s == null) {
1246            return null;
1247        }
1248
1249        char[] charArray = s.toCharArray();
1250
1251        int len = charArray.length;
1252
1253        int x = 0;
1254        int y = charArray.length;
1255
1256        for (int i = 0; i < len; i++) {
1257            char c = charArray[i];
1258
1259            if (_isTrimable(c, exceptions)) {
1260                x = i + 1;
1261            }
1262            else {
1263                break;
1264            }
1265        }
1266
1267        if ((x != 0) || (y != len)) {
1268            return s.substring(x, y);
1269        }
1270        else {
1271            return s;
1272        }
1273    }
1274
1275    public static String trimTrailing(String s) {
1276        return trimTrailing(s, null);
1277    }
1278
1279    public static String trimTrailing(String s, char c) {
1280        return trimTrailing(s, new char[] {c});
1281    }
1282
1283    public static String trimTrailing(String s, char[] exceptions) {
1284        if (s == null) {
1285            return null;
1286        }
1287
1288        char[] charArray = s.toCharArray();
1289
1290        int len = charArray.length;
1291
1292        int x = 0;
1293        int y = charArray.length;
1294
1295        for (int i = len - 1; i >= 0; i--) {
1296            char c = charArray[i];
1297
1298            if (_isTrimable(c, exceptions)) {
1299                y = i;
1300            }
1301            else {
1302                break;
1303            }
1304        }
1305
1306        if ((x != 0) || (y != len)) {
1307            return s.substring(x, y);
1308        }
1309        else {
1310            return s;
1311        }
1312    }
1313
1314    public static String upperCase(String s) {
1315        if (s == null) {
1316            return null;
1317        }
1318        else {
1319            return s.toUpperCase();
1320        }
1321    }
1322
1323    public static String upperCaseFirstLetter(String s) {
1324        char[] chars = s.toCharArray();
1325
1326        if ((chars[0] >= 97) && (chars[0] <= 122)) {
1327            chars[0] = (char)(chars[0] - 32);
1328        }
1329
1330        return new String(chars);
1331    }
1332
1333    public static String valueOf(Object obj) {
1334        return String.valueOf(obj);
1335    }
1336
1337    public static String wrap(String text) {
1338        return wrap(text, 80, StringPool.NEW_LINE);
1339    }
1340
1341    public static String wrap(String text, int width, String lineSeparator) {
1342        if (text == null) {
1343            return null;
1344        }
1345
1346        StringBuilder sb = new StringBuilder();
1347
1348        try {
1349            BufferedReader br = new BufferedReader(new StringReader(text));
1350
1351            String s = StringPool.BLANK;
1352
1353            while ((s = br.readLine()) != null) {
1354                if (s.length() == 0) {
1355                    sb.append(lineSeparator);
1356                }
1357                else {
1358                    String[] tokens = s.split(StringPool.SPACE);
1359                    boolean firstWord = true;
1360                    int curLineLength = 0;
1361
1362                    for (int i = 0; i < tokens.length; i++) {
1363                        if (!firstWord) {
1364                            sb.append(StringPool.SPACE);
1365                            curLineLength++;
1366                        }
1367
1368                        if (firstWord) {
1369                            sb.append(lineSeparator);
1370                        }
1371
1372                        sb.append(tokens[i]);
1373
1374                        curLineLength += tokens[i].length();
1375
1376                        if (curLineLength >= width) {
1377                            firstWord = true;
1378                            curLineLength = 0;
1379                        }
1380                        else {
1381                            firstWord = false;
1382                        }
1383                    }
1384                }
1385            }
1386        }
1387        catch (IOException ioe) {
1388            _log.error(ioe.getMessage());
1389        }
1390
1391        return sb.toString();
1392    }
1393
1394    private static boolean _isTrimable(char c, char[] exceptions) {
1395        if ((exceptions != null) && (exceptions.length > 0)) {
1396            for (int i = 0; i < exceptions.length; i++) {
1397                if (c == exceptions[i]) {
1398                    return false;
1399                }
1400            }
1401        }
1402
1403        return Character.isWhitespace(c);
1404    }
1405
1406    private static Log _log = LogFactoryUtil.getLog(StringUtil.class);
1407
1408}