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