001
014
015 package com.liferay.portal.kernel.util;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
018 import com.liferay.portal.kernel.io.unsync.UnsyncStringReader;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021
022 import java.io.IOException;
023 import java.io.InputStream;
024 import java.io.InputStreamReader;
025
026 import java.net.URL;
027
028 import java.util.ArrayList;
029 import java.util.Collection;
030 import java.util.Enumeration;
031 import java.util.List;
032 import java.util.Map;
033 import java.util.StringTokenizer;
034 import java.util.regex.Matcher;
035 import java.util.regex.Pattern;
036
037
043 public class StringUtil {
044
045 public static String add(String s, String add) {
046 return add(s, add, StringPool.COMMA);
047 }
048
049 public static String add(String s, String add, String delimiter) {
050 return add(s, add, delimiter, false);
051 }
052
053 public static String add(
054 String s, String add, String delimiter, boolean allowDuplicates) {
055
056 if ((add == null) || (delimiter == null)) {
057 return null;
058 }
059
060 if (s == null) {
061 s = StringPool.BLANK;
062 }
063
064 if (allowDuplicates || !contains(s, add, delimiter)) {
065 StringBundler sb = new StringBundler();
066
067 sb.append(s);
068
069 if (Validator.isNull(s) || s.endsWith(delimiter)) {
070 sb.append(add);
071 sb.append(delimiter);
072 }
073 else {
074 sb.append(delimiter);
075 sb.append(add);
076 sb.append(delimiter);
077 }
078
079 s = sb.toString();
080 }
081
082 return s;
083 }
084
085 public static String bytesToHexString(byte[] bytes) {
086 StringBuilder sb = new StringBuilder(bytes.length * 2);
087
088 for (byte b : bytes) {
089 String hex = Integer.toHexString(
090 0x0100 + (b & 0x00FF)).substring(1);
091
092 if (hex.length() < 2) {
093 sb.append("0");
094 }
095
096 sb.append(hex);
097 }
098
099 return sb.toString();
100 }
101
102 public static boolean contains(String s, String text) {
103 return contains(s, text, StringPool.COMMA);
104 }
105
106 public static boolean contains(String s, String text, String delimiter) {
107 if ((s == null) || (text == null) || (delimiter == null)) {
108 return false;
109 }
110
111 if (!s.endsWith(delimiter)) {
112 s = s.concat(delimiter);
113 }
114
115 String dtd = delimiter.concat(text).concat(delimiter);
116
117 int pos = s.indexOf(dtd);
118
119 if (pos == -1) {
120 String td = text.concat(delimiter);
121
122 if (s.startsWith(td)) {
123 return true;
124 }
125
126 return false;
127 }
128
129 return true;
130 }
131
132 public static int count(String s, String text) {
133 if ((s == null) || (text == null)) {
134 return 0;
135 }
136
137 int count = 0;
138
139 int pos = s.indexOf(text);
140
141 while (pos != -1) {
142 pos = s.indexOf(text, pos + text.length());
143
144 count++;
145 }
146
147 return count;
148 }
149
150 public static boolean endsWith(String s, char end) {
151 return endsWith(s, (new Character(end)).toString());
152 }
153
154 public static boolean endsWith(String s, String end) {
155 if ((s == null) || (end == null)) {
156 return false;
157 }
158
159 if (end.length() > s.length()) {
160 return false;
161 }
162
163 String temp = s.substring(s.length() - end.length(), s.length());
164
165 if (temp.equalsIgnoreCase(end)) {
166 return true;
167 }
168 else {
169 return false;
170 }
171 }
172
173 public static String extractChars(String s) {
174 if (s == null) {
175 return StringPool.BLANK;
176 }
177
178 StringBuilder sb = new StringBuilder();
179
180 char[] chars = s.toCharArray();
181
182 for (char c : chars) {
183 if (Validator.isChar(c)) {
184 sb.append(c);
185 }
186 }
187
188 return sb.toString();
189 }
190
191 public static String extractDigits(String s) {
192 if (s == null) {
193 return StringPool.BLANK;
194 }
195
196 StringBuilder sb = new StringBuilder();
197
198 char[] chars = s.toCharArray();
199
200 for (char c : chars) {
201 if (Validator.isDigit(c)) {
202 sb.append(c);
203 }
204 }
205
206 return sb.toString();
207 }
208
209 public static String extractFirst(String s, char delimiter) {
210 if (s == null) {
211 return null;
212 }
213 else {
214 int index = s.indexOf(delimiter);
215
216 if (index < 0) {
217 return null;
218 }
219 else {
220 return s.substring(0, index);
221 }
222 }
223 }
224
225 public static String extractFirst(String s, String delimiter) {
226 if (s == null) {
227 return null;
228 }
229 else {
230 int index = s.indexOf(delimiter);
231
232 if (index < 0) {
233 return null;
234 }
235 else {
236 return s.substring(0, index);
237 }
238 }
239 }
240
241 public static String extractLast(String s, char delimiter) {
242 if (s == null) {
243 return null;
244 }
245 else {
246 int index = s.lastIndexOf(delimiter);
247
248 if (index < 0) {
249 return null;
250 }
251 else {
252 return s.substring(index + 1);
253 }
254 }
255 }
256
257 public static String extractLast(String s, String delimiter) {
258 if (s == null) {
259 return null;
260 }
261 else {
262 int index = s.lastIndexOf(delimiter);
263
264 if (index < 0) {
265 return null;
266 }
267 else {
268 return s.substring(index + delimiter.length());
269 }
270 }
271 }
272
273
276 public static String highlight(String s, String keywords) {
277 return highlight(s, keywords, "<span class=\"highlight\">", "</span>");
278 }
279
280
283 public static String highlight(
284 String s, String keywords, String highlight1, String highlight2) {
285
286 if (Validator.isNull(s) || Validator.isNull(keywords)) {
287 return s;
288 }
289
290 Pattern pattern = Pattern.compile(
291 Pattern.quote(keywords), Pattern.CASE_INSENSITIVE);
292
293 return _highlight(s, pattern, highlight1, highlight2);
294 }
295
296 public static String highlight(String s, String[] queryTerms) {
297 return highlight(
298 s, queryTerms, "<span class=\"highlight\">", "</span>");
299 }
300
301 public static String highlight(
302 String s, String[] queryTerms, String highlight1, String highlight2) {
303
304 if (Validator.isNull(s) || Validator.isNull(queryTerms)) {
305 return s;
306 }
307
308 if (queryTerms.length == 0) {
309 return StringPool.BLANK;
310 }
311
312 StringBundler sb = new StringBundler(2 * queryTerms.length - 1);
313
314 for (int i = 0; i < queryTerms.length; i++) {
315 sb.append(Pattern.quote(queryTerms[i].trim()));
316
317 if ((i + 1) < queryTerms.length) {
318 sb.append(StringPool.PIPE);
319 }
320 }
321
322 int flags =
323 Pattern.CANON_EQ | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
324
325 Pattern pattern = Pattern.compile(sb.toString(), flags);
326
327 return _highlight(s, pattern, highlight1, highlight2);
328 }
329
330 public static String insert(String s, String insert, int offset) {
331 if (s == null) {
332 return null;
333 }
334
335 if (insert == null) {
336 return s;
337 }
338
339 if (offset > s.length()) {
340 return s.concat(insert);
341 }
342 else {
343 String prefix = s.substring(0, offset);
344 String postfix = s.substring(offset);
345
346 return prefix.concat(insert).concat(postfix);
347 }
348 }
349
350 public static String lowerCase(String s) {
351 if (s == null) {
352 return null;
353 }
354 else {
355 return s.toLowerCase();
356 }
357 }
358
359 public static boolean matches(String s, String pattern) {
360 String[] array = pattern.split("\\*");
361
362 for (String element : array) {
363 int pos = s.indexOf(element);
364
365 if (pos == -1) {
366 return false;
367 }
368
369 s = s.substring(pos + element.length());
370 }
371
372 return true;
373 }
374
375 public static boolean matchesIgnoreCase(String s, String pattern) {
376 return matches(lowerCase(s), lowerCase(pattern));
377 }
378
379 public static String merge(boolean[] array) {
380 return merge(array, StringPool.COMMA);
381 }
382
383 public static String merge(boolean[] array, String delimiter) {
384 if (array == null) {
385 return null;
386 }
387
388 if (array.length == 0) {
389 return StringPool.BLANK;
390 }
391
392 StringBundler sb = new StringBundler(2 * array.length - 1);
393
394 for (int i = 0; i < array.length; i++) {
395 sb.append(String.valueOf(array[i]).trim());
396
397 if ((i + 1) != array.length) {
398 sb.append(delimiter);
399 }
400 }
401
402 return sb.toString();
403 }
404
405 public static String merge(Collection<?> col) {
406 return merge(col, StringPool.COMMA);
407 }
408
409 public static String merge(Collection<?> col, String delimiter) {
410 if (col == null) {
411 return null;
412 }
413
414 return merge(col.toArray(new Object[col.size()]), delimiter);
415 }
416
417 public static String merge(char[] array) {
418 return merge(array, StringPool.COMMA);
419 }
420
421 public static String merge(char[] array, String delimiter) {
422 if (array == null) {
423 return null;
424 }
425
426 if (array.length == 0) {
427 return StringPool.BLANK;
428 }
429
430 StringBundler sb = new StringBundler(2 * array.length - 1);
431
432 for (int i = 0; i < array.length; i++) {
433 sb.append(String.valueOf(array[i]).trim());
434
435 if ((i + 1) != array.length) {
436 sb.append(delimiter);
437 }
438 }
439
440 return sb.toString();
441 }
442
443 public static String merge(double[] array) {
444 return merge(array, StringPool.COMMA);
445 }
446
447 public static String merge(double[] array, String delimiter) {
448 if (array == null) {
449 return null;
450 }
451
452 if (array.length == 0) {
453 return StringPool.BLANK;
454 }
455
456 StringBundler sb = new StringBundler(2 * array.length - 1);
457
458 for (int i = 0; i < array.length; i++) {
459 sb.append(String.valueOf(array[i]).trim());
460
461 if ((i + 1) != array.length) {
462 sb.append(delimiter);
463 }
464 }
465
466 return sb.toString();
467 }
468
469 public static String merge(float[] array) {
470 return merge(array, StringPool.COMMA);
471 }
472
473 public static String merge(float[] array, String delimiter) {
474 if (array == null) {
475 return null;
476 }
477
478 if (array.length == 0) {
479 return StringPool.BLANK;
480 }
481
482 StringBundler sb = new StringBundler(2 * array.length - 1);
483
484 for (int i = 0; i < array.length; i++) {
485 sb.append(String.valueOf(array[i]).trim());
486
487 if ((i + 1) != array.length) {
488 sb.append(delimiter);
489 }
490 }
491
492 return sb.toString();
493 }
494
495 public static String merge(int[] array) {
496 return merge(array, StringPool.COMMA);
497 }
498
499 public static String merge(int[] array, String delimiter) {
500 if (array == null) {
501 return null;
502 }
503
504 if (array.length == 0) {
505 return StringPool.BLANK;
506 }
507
508 StringBundler sb = new StringBundler(2 * array.length - 1);
509
510 for (int i = 0; i < array.length; i++) {
511 sb.append(String.valueOf(array[i]).trim());
512
513 if ((i + 1) != array.length) {
514 sb.append(delimiter);
515 }
516 }
517
518 return sb.toString();
519 }
520
521 public static String merge(long[] array) {
522 return merge(array, StringPool.COMMA);
523 }
524
525 public static String merge(long[] array, String delimiter) {
526 if (array == null) {
527 return null;
528 }
529
530 if (array.length == 0) {
531 return StringPool.BLANK;
532 }
533
534 StringBundler sb = new StringBundler(2 * array.length - 1);
535
536 for (int i = 0; i < array.length; i++) {
537 sb.append(String.valueOf(array[i]).trim());
538
539 if ((i + 1) != array.length) {
540 sb.append(delimiter);
541 }
542 }
543
544 return sb.toString();
545 }
546
547 public static String merge(Object[] array) {
548 return merge(array, StringPool.COMMA);
549 }
550
551 public static String merge(Object[] array, String delimiter) {
552 if (array == null) {
553 return null;
554 }
555
556 if (array.length == 0) {
557 return StringPool.BLANK;
558 }
559
560 StringBundler sb = new StringBundler(2 * array.length - 1);
561
562 for (int i = 0; i < array.length; i++) {
563 sb.append(String.valueOf(array[i]).trim());
564
565 if ((i + 1) != array.length) {
566 sb.append(delimiter);
567 }
568 }
569
570 return sb.toString();
571 }
572
573 public static String merge(short[] array) {
574 return merge(array, StringPool.COMMA);
575 }
576
577 public static String merge(short[] array, String delimiter) {
578 if (array == null) {
579 return null;
580 }
581
582 if (array.length == 0) {
583 return StringPool.BLANK;
584 }
585
586 StringBundler sb = new StringBundler(2 * array.length - 1);
587
588 for (int i = 0; i < array.length; i++) {
589 sb.append(String.valueOf(array[i]).trim());
590
591 if ((i + 1) != array.length) {
592 sb.append(delimiter);
593 }
594 }
595
596 return sb.toString();
597 }
598
599 public static String quote(String s) {
600 return quote(s, CharPool.APOSTROPHE);
601 }
602
603 public static String quote(String s, char quote) {
604 if (s == null) {
605 return null;
606 }
607
608 return quote(s, String.valueOf(quote));
609 }
610
611 public static String quote(String s, String quote) {
612 if (s == null) {
613 return null;
614 }
615
616 return quote.concat(s).concat(quote);
617 }
618
619 public static String randomize(String s) {
620 return Randomizer.getInstance().randomize(s);
621 }
622
623 public static String read(ClassLoader classLoader, String name)
624 throws IOException {
625
626 return read(classLoader, name, false);
627 }
628
629 public static String read(ClassLoader classLoader, String name, boolean all)
630 throws IOException {
631
632 if (all) {
633 StringBundler sb = new StringBundler();
634
635 Enumeration<URL> enu = classLoader.getResources(name);
636
637 while (enu.hasMoreElements()) {
638 URL url = enu.nextElement();
639
640 InputStream is = url.openStream();
641
642 if (is == null) {
643 throw new IOException(
644 "Unable to open resource at " + url.toString());
645 }
646
647 String s = read(is);
648
649 if (s != null) {
650 sb.append(s);
651 sb.append(StringPool.NEW_LINE);
652 }
653
654 is.close();
655 }
656
657 return sb.toString().trim();
658 }
659 else {
660 InputStream is = classLoader.getResourceAsStream(name);
661
662 if (is == null) {
663 throw new IOException(
664 "Unable to open resource in class loader " + name);
665 }
666
667 String s = read(is);
668
669 is.close();
670
671 return s;
672 }
673 }
674
675 public static String read(InputStream is) throws IOException {
676 StringBundler sb = new StringBundler();
677
678 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
679 new InputStreamReader(is));
680
681 String line = null;
682
683 while ((line = unsyncBufferedReader.readLine()) != null) {
684 sb.append(line);
685 sb.append(CharPool.NEW_LINE);
686 }
687
688 unsyncBufferedReader.close();
689
690 return sb.toString().trim();
691 }
692
693 public static void readLines(InputStream is, Collection<String> lines)
694 throws IOException {
695
696 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
697 new InputStreamReader(is));
698
699 String line = null;
700
701 while ((line = unsyncBufferedReader.readLine()) != null) {
702 lines.add(line);
703 }
704
705 unsyncBufferedReader.close();
706 }
707
708 public static String remove(String s, String remove) {
709 return remove(s, remove, StringPool.COMMA);
710 }
711
712 public static String remove(String s, String remove, String delimiter) {
713 if ((s == null) || (remove == null) || (delimiter == null)) {
714 return null;
715 }
716
717 if (Validator.isNotNull(s) && !s.endsWith(delimiter)) {
718 s += delimiter;
719 }
720
721 String drd = delimiter.concat(remove).concat(delimiter);
722
723 String rd = remove.concat(delimiter);
724
725 while (contains(s, remove, delimiter)) {
726 int pos = s.indexOf(drd);
727
728 if (pos == -1) {
729 if (s.startsWith(rd)) {
730 int x = remove.length() + delimiter.length();
731 int y = s.length();
732
733 s = s.substring(x, y);
734 }
735 }
736 else {
737 int x = pos + remove.length() + delimiter.length();
738 int y = s.length();
739
740 String temp = s.substring(0, pos);
741
742 s = temp.concat(s.substring(x, y));
743 }
744 }
745
746 return s;
747 }
748
749 public static String replace(String s, char oldSub, char newSub) {
750 if (s == null) {
751 return null;
752 }
753
754 return s.replace(oldSub, newSub);
755 }
756
757 public static String replace(String s, char oldSub, String newSub) {
758 if ((s == null) || (newSub == null)) {
759 return null;
760 }
761
762
763
764
765 StringBuilder sb = new StringBuilder(s.length() + 5 * newSub.length());
766
767 char[] chars = s.toCharArray();
768
769 for (char c : chars) {
770 if (c == oldSub) {
771 sb.append(newSub);
772 }
773 else {
774 sb.append(c);
775 }
776 }
777
778 return sb.toString();
779 }
780
781 public static String replace(String s, String oldSub, String newSub) {
782 return replace(s, oldSub, newSub, 0);
783 }
784
785 public static String replace(
786 String s, String oldSub, String newSub, int fromIndex) {
787
788 if (s == null) {
789 return null;
790 }
791
792 if ((oldSub == null) || oldSub.equals(StringPool.BLANK)) {
793 return s;
794 }
795
796 if (newSub == null) {
797 newSub = StringPool.BLANK;
798 }
799
800 int y = s.indexOf(oldSub, fromIndex);
801
802 if (y >= 0) {
803 StringBundler sb = new StringBundler();
804
805 int length = oldSub.length();
806 int x = 0;
807
808 while (x <= y) {
809 sb.append(s.substring(x, y));
810 sb.append(newSub);
811
812 x = y + length;
813 y = s.indexOf(oldSub, x);
814 }
815
816 sb.append(s.substring(x));
817
818 return sb.toString();
819 }
820 else {
821 return s;
822 }
823 }
824
825 public static String replace(
826 String s, String begin, String end, Map<String, String> values) {
827
828 StringBundler sb = replaceToStringBundler(s, begin, end, values);
829
830 return sb.toString();
831 }
832
833 public static String replace(String s, String[] oldSubs, String[] newSubs) {
834 if ((s == null) || (oldSubs == null) || (newSubs == null)) {
835 return null;
836 }
837
838 if (oldSubs.length != newSubs.length) {
839 return s;
840 }
841
842 for (int i = 0; i < oldSubs.length; i++) {
843 s = replace(s, oldSubs[i], newSubs[i]);
844 }
845
846 return s;
847 }
848
849 public static String replace(
850 String s, String[] oldSubs, String[] newSubs, boolean exactMatch) {
851
852 if ((s == null) || (oldSubs == null) || (newSubs == null)) {
853 return null;
854 }
855
856 if (oldSubs.length != newSubs.length) {
857 return s;
858 }
859
860 if (!exactMatch) {
861 replace(s, oldSubs, newSubs);
862 }
863 else {
864 for (int i = 0; i < oldSubs.length; i++) {
865 s = s.replaceAll("\\b" + oldSubs[i] + "\\b" , newSubs[i]);
866 }
867 }
868
869 return s;
870 }
871
872 public static String replaceFirst(String s, char oldSub, char newSub) {
873 if (s == null) {
874 return null;
875 }
876
877 return replaceFirst(s, String.valueOf(oldSub), String.valueOf(newSub));
878 }
879
880 public static String replaceFirst(String s, char oldSub, String newSub) {
881 if ((s == null) || (newSub == null)) {
882 return null;
883 }
884
885 return replaceFirst(s, String.valueOf(oldSub), newSub);
886 }
887
888 public static String replaceFirst(String s, String oldSub, String newSub) {
889 if ((s == null) || (oldSub == null) || (newSub == null)) {
890 return null;
891 }
892
893 if (oldSub.equals(newSub)) {
894 return s;
895 }
896
897 int y = s.indexOf(oldSub);
898
899 if (y >= 0) {
900 return s.substring(0, y).concat(newSub).concat(
901 s.substring(y + oldSub.length()));
902 }
903 else {
904 return s;
905 }
906 }
907
908 public static String replaceFirst(
909 String s, String[] oldSubs, String[] newSubs) {
910
911 if ((s == null) || (oldSubs == null) || (newSubs == null)) {
912 return null;
913 }
914
915 if (oldSubs.length != newSubs.length) {
916 return s;
917 }
918
919 for (int i = 0; i < oldSubs.length; i++) {
920 s = replaceFirst(s, oldSubs[i], newSubs[i]);
921 }
922
923 return s;
924 }
925
926 public static String replaceLast(String s, char oldSub, char newSub) {
927 if (s == null) {
928 return null;
929 }
930
931 return replaceLast(s, String.valueOf(oldSub), String.valueOf(newSub));
932 }
933
934 public static String replaceLast(String s, char oldSub, String newSub) {
935 if ((s == null) || (newSub == null)) {
936 return null;
937 }
938
939 return replaceLast(s, String.valueOf(oldSub), newSub);
940 }
941
942 public static String replaceLast(String s, String oldSub, String newSub) {
943 if ((s == null) || (oldSub == null) || (newSub == null)) {
944 return null;
945 }
946
947 if (oldSub.equals(newSub)) {
948 return s;
949 }
950
951 int y = s.lastIndexOf(oldSub);
952
953 if (y >= 0) {
954 return s.substring(0, y).concat(newSub).concat(
955 s.substring(y + oldSub.length()));
956 }
957 else {
958 return s;
959 }
960 }
961
962 public static String replaceLast(
963 String s, String[] oldSubs, String[] newSubs) {
964
965 if ((s == null) || (oldSubs == null) || (newSubs == null)) {
966 return null;
967 }
968
969 if (oldSubs.length != newSubs.length) {
970 return s;
971 }
972
973 for (int i = 0; i < oldSubs.length; i++) {
974 s = replaceLast(s, oldSubs[i], newSubs[i]);
975 }
976
977 return s;
978 }
979
980 public static StringBundler replaceToStringBundler(
981 String s, String begin, String end, Map<String, String> values) {
982
983 if ((s == null) || (begin == null) || (end == null) ||
984 (values == null) || (values.size() == 0)) {
985
986 return new StringBundler(s);
987 }
988
989 StringBundler sb = new StringBundler(values.size() * 2 + 1);
990
991 int pos = 0;
992
993 while (true) {
994 int x = s.indexOf(begin, pos);
995 int y = s.indexOf(end, x + begin.length());
996
997 if ((x == -1) || (y == -1)) {
998 sb.append(s.substring(pos, s.length()));
999
1000 break;
1001 }
1002 else {
1003 sb.append(s.substring(pos, x));
1004
1005 String oldValue = s.substring(x + begin.length(), y);
1006
1007 String newValue = values.get(oldValue);
1008
1009 if (newValue == null) {
1010 newValue = oldValue;
1011 }
1012
1013 sb.append(newValue);
1014
1015 pos = y + end.length();
1016 }
1017 }
1018
1019 return sb;
1020 }
1021
1022 public static StringBundler replaceWithStringBundler(
1023 String s, String begin, String end, Map<String, StringBundler> values) {
1024
1025 if ((s == null) || (begin == null) || (end == null) ||
1026 (values == null) || (values.size() == 0)) {
1027
1028 return new StringBundler(s);
1029 }
1030
1031 int size = values.size() + 1;
1032
1033 for (StringBundler valueSB : values.values()) {
1034 size += valueSB.index();
1035 }
1036
1037 StringBundler sb = new StringBundler(size);
1038
1039 int pos = 0;
1040
1041 while (true) {
1042 int x = s.indexOf(begin, pos);
1043 int y = s.indexOf(end, x + begin.length());
1044
1045 if ((x == -1) || (y == -1)) {
1046 sb.append(s.substring(pos, s.length()));
1047
1048 break;
1049 }
1050 else {
1051 sb.append(s.substring(pos, x));
1052
1053 String oldValue = s.substring(x + begin.length(), y);
1054
1055 StringBundler newValue = values.get(oldValue);
1056
1057 if (newValue == null) {
1058 sb.append(oldValue);
1059 }
1060 else {
1061 sb.append(newValue);
1062 }
1063
1064 pos = y + end.length();
1065 }
1066 }
1067
1068 return sb;
1069 }
1070
1071 public static String reverse(String s) {
1072 if (s == null) {
1073 return null;
1074 }
1075
1076 char[] chars = s.toCharArray();
1077 char[] reverse = new char[chars.length];
1078
1079 for (int i = 0; i < chars.length; i++) {
1080 reverse[i] = chars[chars.length - i - 1];
1081 }
1082
1083 return new String(reverse);
1084 }
1085
1086 public static String safePath(String path) {
1087 return replace(path, StringPool.DOUBLE_SLASH, StringPool.SLASH);
1088 }
1089
1090 public static String shorten(String s) {
1091 return shorten(s, 20);
1092 }
1093
1094 public static String shorten(String s, int length) {
1095 return shorten(s, length, "...");
1096 }
1097
1098 public static String shorten(String s, int length, String suffix) {
1099 if ((s == null) || (suffix == null)) {
1100 return null;
1101 }
1102
1103 if (s.length() > length) {
1104 for (int j = length; j >= 0; j--) {
1105 if (Character.isWhitespace(s.charAt(j))) {
1106 length = j;
1107
1108 break;
1109 }
1110 }
1111
1112 String temp = s.substring(0, length);
1113
1114 s = temp.concat(suffix);
1115 }
1116
1117 return s;
1118 }
1119
1120 public static String shorten(String s, String suffix) {
1121 return shorten(s, 20, suffix);
1122 }
1123
1124 public static String[] split(String s) {
1125 return split(s, CharPool.COMMA);
1126 }
1127
1128 public static boolean[] split(String s, boolean x) {
1129 return split(s, StringPool.COMMA, x);
1130 }
1131
1132 public static double[] split(String s, double x) {
1133 return split(s, StringPool.COMMA, x);
1134 }
1135
1136 public static float[] split(String s, float x) {
1137 return split(s, StringPool.COMMA, x);
1138 }
1139
1140 public static int[] split(String s, int x) {
1141 return split(s, StringPool.COMMA, x);
1142 }
1143
1144 public static long[] split(String s, long x) {
1145 return split(s, StringPool.COMMA, x);
1146 }
1147
1148 public static short[] split(String s, short x) {
1149 return split(s, StringPool.COMMA, x);
1150 }
1151
1152 public static String[] split(String s, char delimiter) {
1153 if (Validator.isNull(s)) {
1154 return _emptyStringArray;
1155 }
1156
1157 s = s.trim();
1158
1159 if (s.length() == 0) {
1160 return _emptyStringArray;
1161 }
1162
1163 if ((delimiter == CharPool.RETURN) ||
1164 (delimiter == CharPool.NEW_LINE)) {
1165
1166 return splitLines(s);
1167 }
1168
1169 List<String> nodeValues = new ArrayList<String>();
1170
1171 int offset = 0;
1172 int pos = s.indexOf(delimiter, offset);
1173
1174 while (pos != -1) {
1175 nodeValues.add(s.substring(offset, pos));
1176
1177 offset = pos + 1;
1178 pos = s.indexOf(delimiter, offset);
1179 }
1180
1181 if (offset < s.length()) {
1182 nodeValues.add(s.substring(offset));
1183 }
1184
1185 return nodeValues.toArray(new String[nodeValues.size()]);
1186 }
1187
1188 public static String[] split(String s, String delimiter) {
1189 if ((Validator.isNull(s)) || (delimiter == null) ||
1190 (delimiter.equals(StringPool.BLANK))) {
1191
1192 return _emptyStringArray;
1193 }
1194
1195 s = s.trim();
1196
1197 if (s.equals(delimiter)) {
1198 return _emptyStringArray;
1199 }
1200
1201 if (delimiter.length() == 1) {
1202 return split(s, delimiter.charAt(0));
1203 }
1204
1205 List<String> nodeValues = new ArrayList<String>();
1206
1207 int offset = 0;
1208 int pos = s.indexOf(delimiter, offset);
1209
1210 while (pos != -1) {
1211 nodeValues.add(s.substring(offset, pos));
1212
1213 offset = pos + delimiter.length();
1214 pos = s.indexOf(delimiter, offset);
1215 }
1216
1217 if (offset < s.length()) {
1218 nodeValues.add(s.substring(offset));
1219 }
1220
1221 return nodeValues.toArray(new String[nodeValues.size()]);
1222 }
1223
1224 public static boolean[] split(String s, String delimiter, boolean x) {
1225 String[] array = split(s, delimiter);
1226 boolean[] newArray = new boolean[array.length];
1227
1228 for (int i = 0; i < array.length; i++) {
1229 boolean value = x;
1230
1231 try {
1232 value = Boolean.valueOf(array[i]).booleanValue();
1233 }
1234 catch (Exception e) {
1235 }
1236
1237 newArray[i] = value;
1238 }
1239
1240 return newArray;
1241 }
1242
1243 public static double[] split(String s, String delimiter, double x) {
1244 String[] array = split(s, delimiter);
1245 double[] newArray = new double[array.length];
1246
1247 for (int i = 0; i < array.length; i++) {
1248 double value = x;
1249
1250 try {
1251 value = Double.parseDouble(array[i]);
1252 }
1253 catch (Exception e) {
1254 }
1255
1256 newArray[i] = value;
1257 }
1258
1259 return newArray;
1260 }
1261
1262 public static float[] split(String s, String delimiter, float x) {
1263 String[] array = split(s, delimiter);
1264 float[] newArray = new float[array.length];
1265
1266 for (int i = 0; i < array.length; i++) {
1267 float value = x;
1268
1269 try {
1270 value = Float.parseFloat(array[i]);
1271 }
1272 catch (Exception e) {
1273 }
1274
1275 newArray[i] = value;
1276 }
1277
1278 return newArray;
1279 }
1280
1281 public static int[] split(String s, String delimiter, int x) {
1282 String[] array = split(s, delimiter);
1283 int[] newArray = new int[array.length];
1284
1285 for (int i = 0; i < array.length; i++) {
1286 int value = x;
1287
1288 try {
1289 value = Integer.parseInt(array[i]);
1290 }
1291 catch (Exception e) {
1292 }
1293
1294 newArray[i] = value;
1295 }
1296
1297 return newArray;
1298 }
1299
1300 public static long[] split(String s, String delimiter, long x) {
1301 String[] array = split(s, delimiter);
1302 long[] newArray = new long[array.length];
1303
1304 for (int i = 0; i < array.length; i++) {
1305 long value = x;
1306
1307 try {
1308 value = Long.parseLong(array[i]);
1309 }
1310 catch (Exception e) {
1311 }
1312
1313 newArray[i] = value;
1314 }
1315
1316 return newArray;
1317 }
1318
1319 public static short[] split(String s, String delimiter, short x) {
1320 String[] array = split(s, delimiter);
1321 short[] newArray = new short[array.length];
1322
1323 for (int i = 0; i < array.length; i++) {
1324 short value = x;
1325
1326 try {
1327 value = Short.parseShort(array[i]);
1328 }
1329 catch (Exception e) {
1330 }
1331
1332 newArray[i] = value;
1333 }
1334
1335 return newArray;
1336 }
1337
1338 public static String[] splitLines(String s) {
1339 if (Validator.isNull(s)) {
1340 return _emptyStringArray;
1341 }
1342
1343 s = s.trim();
1344
1345 List<String> lines = new ArrayList<String>();
1346
1347 int lastIndex = 0;
1348
1349 while (true) {
1350 int returnIndex = s.indexOf(CharPool.RETURN, lastIndex);
1351 int newLineIndex = s.indexOf(CharPool.NEW_LINE, lastIndex);
1352
1353 if ((returnIndex == -1) && (newLineIndex == -1)) {
1354 break;
1355 }
1356
1357 if (returnIndex == -1) {
1358 lines.add(s.substring(lastIndex, newLineIndex));
1359
1360 lastIndex = newLineIndex + 1;
1361 }
1362 else if (newLineIndex == -1) {
1363 lines.add(s.substring(lastIndex, returnIndex));
1364
1365 lastIndex = returnIndex + 1;
1366 }
1367 else if (newLineIndex < returnIndex) {
1368 lines.add(s.substring(lastIndex, newLineIndex));
1369
1370 lastIndex = newLineIndex + 1;
1371 }
1372 else {
1373 lines.add(s.substring(lastIndex, returnIndex));
1374
1375 lastIndex = returnIndex + 1;
1376
1377 if (lastIndex == newLineIndex) {
1378 lastIndex++;
1379 }
1380 }
1381 }
1382
1383 if (lastIndex < s.length()) {
1384 lines.add(s.substring(lastIndex));
1385 }
1386
1387 return lines.toArray(new String[lines.size()]);
1388 }
1389
1390 public static boolean startsWith(String s, char begin) {
1391 return startsWith(s, (new Character(begin)).toString());
1392 }
1393
1394 public static boolean startsWith(String s, String start) {
1395 if ((s == null) || (start == null)) {
1396 return false;
1397 }
1398
1399 if (start.length() > s.length()) {
1400 return false;
1401 }
1402
1403 String temp = s.substring(0, start.length());
1404
1405 if (temp.equalsIgnoreCase(start)) {
1406 return true;
1407 }
1408 else {
1409 return false;
1410 }
1411 }
1412
1413
1420 public static int startsWithWeight(String s1, String s2) {
1421 if ((s1 == null) || (s2 == null)) {
1422 return 0;
1423 }
1424
1425 char[] chars1 = s1.toCharArray();
1426 char[] chars2 = s2.toCharArray();
1427
1428 int i = 0;
1429
1430 for (; (i < chars1.length) && (i < chars2.length); i++) {
1431 if (chars1[i] != chars2[i]) {
1432 break;
1433 }
1434 }
1435
1436 return i;
1437 }
1438
1439 public static String strip(String s, char remove) {
1440 if (s == null) {
1441 return null;
1442 }
1443
1444 int x = s.indexOf(remove);
1445
1446 if (x < 0) {
1447 return s;
1448 }
1449
1450 int y = 0;
1451
1452 StringBuilder sb = new StringBuilder(s.length());
1453
1454 while (x >= 0) {
1455 sb.append(s.subSequence(y, x));
1456
1457 y = x + 1;
1458
1459 x = s.indexOf(remove, y);
1460 }
1461
1462 sb.append(s.substring(y));
1463
1464 return sb.toString();
1465 }
1466
1467 public static String stripBetween(String s, String begin, String end) {
1468 if ((s == null) || (begin == null) || (end == null)) {
1469 return s;
1470 }
1471
1472 StringBuilder sb = new StringBuilder(s.length());
1473
1474 int pos = 0;
1475
1476 while (true) {
1477 int x = s.indexOf(begin, pos);
1478 int y = s.indexOf(end, x + begin.length());
1479
1480 if ((x == -1) || (y == -1)) {
1481 sb.append(s.substring(pos, s.length()));
1482
1483 break;
1484 }
1485 else {
1486 sb.append(s.substring(pos, x));
1487
1488 pos = y + end.length();
1489 }
1490 }
1491
1492 return sb.toString();
1493 }
1494
1495 public static String toCharCode(String s) {
1496 StringBundler sb = new StringBundler(s.length());
1497
1498 for (int i = 0; i < s.length(); i++) {
1499 sb.append(s.codePointAt(i));
1500 }
1501
1502 return sb.toString();
1503 }
1504
1505 public static String toHexString(int i) {
1506 char[] buffer = new char[8];
1507
1508 int index = 8;
1509
1510 do {
1511 buffer[--index] = _HEX_DIGITS[i & 15];
1512
1513 i >>>= 4;
1514 }
1515 while (i != 0);
1516
1517 return new String(buffer, index, 8 - index);
1518 }
1519
1520 public static String toHexString(long l) {
1521 char[] buffer = new char[16];
1522
1523 int index = 16;
1524
1525 do {
1526 buffer[--index] = _HEX_DIGITS[(int) (l & 15)];
1527
1528 l >>>= 4;
1529 }
1530 while (l != 0);
1531
1532 return new String(buffer, index, 16 - index);
1533 }
1534
1535 public static String toHexString(Object obj) {
1536 if (obj instanceof Integer) {
1537 return toHexString(((Integer)obj).intValue());
1538 }
1539 else if (obj instanceof Long) {
1540 return toHexString(((Long)obj).longValue());
1541 }
1542 else {
1543 return String.valueOf(obj);
1544 }
1545 }
1546
1547 public static String trim(String s) {
1548 return trim(s, null);
1549 }
1550
1551 public static String trim(String s, char c) {
1552 return trim(s, new char[] {c});
1553 }
1554
1555 public static String trim(String s, char[] exceptions) {
1556 if (s == null) {
1557 return null;
1558 }
1559
1560 char[] chars = s.toCharArray();
1561
1562 int len = chars.length;
1563
1564 int x = 0;
1565 int y = chars.length;
1566
1567 for (int i = 0; i < len; i++) {
1568 char c = chars[i];
1569
1570 if (_isTrimable(c, exceptions)) {
1571 x = i + 1;
1572 }
1573 else {
1574 break;
1575 }
1576 }
1577
1578 for (int i = len - 1; i >= 0; i--) {
1579 char c = chars[i];
1580
1581 if (_isTrimable(c, exceptions)) {
1582 y = i;
1583 }
1584 else {
1585 break;
1586 }
1587 }
1588
1589 if ((x != 0) || (y != len)) {
1590 return s.substring(x, y);
1591 }
1592 else {
1593 return s;
1594 }
1595 }
1596
1597 public static String trimLeading(String s) {
1598 return trimLeading(s, null);
1599 }
1600
1601 public static String trimLeading(String s, char c) {
1602 return trimLeading(s, new char[] {c});
1603 }
1604
1605 public static String trimLeading(String s, char[] exceptions) {
1606 if (s == null) {
1607 return null;
1608 }
1609
1610 char[] chars = s.toCharArray();
1611
1612 int len = chars.length;
1613
1614 int x = 0;
1615 int y = chars.length;
1616
1617 for (int i = 0; i < len; i++) {
1618 char c = chars[i];
1619
1620 if (_isTrimable(c, exceptions)) {
1621 x = i + 1;
1622 }
1623 else {
1624 break;
1625 }
1626 }
1627
1628 if ((x != 0) || (y != len)) {
1629 return s.substring(x, y);
1630 }
1631 else {
1632 return s;
1633 }
1634 }
1635
1636 public static String trimTrailing(String s) {
1637 return trimTrailing(s, null);
1638 }
1639
1640 public static String trimTrailing(String s, char c) {
1641 return trimTrailing(s, new char[] {c});
1642 }
1643
1644 public static String trimTrailing(String s, char[] exceptions) {
1645 if (s == null) {
1646 return null;
1647 }
1648
1649 char[] chars = s.toCharArray();
1650
1651 int len = chars.length;
1652
1653 int x = 0;
1654 int y = chars.length;
1655
1656 for (int i = len - 1; i >= 0; i--) {
1657 char c = chars[i];
1658
1659 if (_isTrimable(c, exceptions)) {
1660 y = i;
1661 }
1662 else {
1663 break;
1664 }
1665 }
1666
1667 if ((x != 0) || (y != len)) {
1668 return s.substring(x, y);
1669 }
1670 else {
1671 return s;
1672 }
1673 }
1674
1675 public static String unquote(String s) {
1676 if (Validator.isNull(s)) {
1677 return s;
1678 }
1679
1680 if ((s.charAt(0) == CharPool.APOSTROPHE) &&
1681 (s.charAt(s.length() - 1) == CharPool.APOSTROPHE)) {
1682
1683 return s.substring(1, s.length() - 1);
1684 }
1685 else if ((s.charAt(0) == CharPool.QUOTE) &&
1686 (s.charAt(s.length() - 1) == CharPool.QUOTE)) {
1687
1688 return s.substring(1, s.length() - 1);
1689 }
1690
1691 return s;
1692 }
1693
1694 public static String upperCase(String s) {
1695 if (s == null) {
1696 return null;
1697 }
1698 else {
1699 return s.toUpperCase();
1700 }
1701 }
1702
1703 public static String upperCaseFirstLetter(String s) {
1704 char[] chars = s.toCharArray();
1705
1706 if ((chars[0] >= 97) && (chars[0] <= 122)) {
1707 chars[0] = (char)(chars[0] - 32);
1708 }
1709
1710 return new String(chars);
1711 }
1712
1713 public static String valueOf(Object obj) {
1714 return String.valueOf(obj);
1715 }
1716
1717 public static String wrap(String text) {
1718 return wrap(text, 80, StringPool.NEW_LINE);
1719 }
1720
1721 public static String wrap(String text, int width, String lineSeparator) {
1722 try {
1723 return _wrap(text, width, lineSeparator);
1724 }
1725 catch (IOException ioe) {
1726 _log.error(ioe.getMessage());
1727
1728 return text;
1729 }
1730 }
1731
1732 private static String _highlight(
1733 String s, Pattern pattern, String highlight1, String highlight2) {
1734
1735 StringTokenizer st = new StringTokenizer(s);
1736
1737 if (st.countTokens() == 0) {
1738 return StringPool.BLANK;
1739 }
1740
1741 StringBundler sb = new StringBundler(2 * st.countTokens() - 1);
1742
1743 while (st.hasMoreTokens()) {
1744 String token = st.nextToken();
1745
1746 Matcher matcher = pattern.matcher(token);
1747
1748 if (matcher.find()) {
1749 StringBuffer hightlighted = new StringBuffer();
1750
1751 do {
1752 matcher.appendReplacement(
1753 hightlighted, highlight1 + matcher.group() +
1754 highlight2);
1755 }
1756 while (matcher.find());
1757
1758 matcher.appendTail(hightlighted);
1759
1760 sb.append(hightlighted);
1761 }
1762 else {
1763 sb.append(token);
1764 }
1765
1766 if (st.hasMoreTokens()) {
1767 sb.append(StringPool.SPACE);
1768 }
1769 }
1770
1771 return sb.toString();
1772 }
1773
1774 private static boolean _isTrimable(char c, char[] exceptions) {
1775 if ((exceptions != null) && (exceptions.length > 0)) {
1776 for (char exception : exceptions) {
1777 if (c == exception) {
1778 return false;
1779 }
1780 }
1781 }
1782
1783 return Character.isWhitespace(c);
1784 }
1785
1786 private static String _wrap(String text, int width, String lineSeparator)
1787 throws IOException {
1788
1789 if (text == null) {
1790 return null;
1791 }
1792
1793 StringBundler sb = new StringBundler();
1794
1795 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader(
1796 new UnsyncStringReader(text));
1797
1798 String s = StringPool.BLANK;
1799
1800 while ((s = unsyncBufferedReader.readLine()) != null) {
1801 if (s.length() == 0) {
1802 sb.append(lineSeparator);
1803
1804 continue;
1805 }
1806
1807 int lineLength = 0;
1808
1809 String[] tokens = s.split(StringPool.SPACE);
1810
1811 for (String token : tokens) {
1812 if ((lineLength + token.length() + 1) > width) {
1813 if (lineLength > 0) {
1814 sb.append(lineSeparator);
1815 }
1816
1817 if (token.length() > width) {
1818 int pos = token.indexOf(CharPool.OPEN_PARENTHESIS);
1819
1820 if (pos != -1) {
1821 sb.append(token.substring(0, pos + 1));
1822 sb.append(lineSeparator);
1823
1824 token = token.substring(pos + 1);
1825
1826 sb.append(token);
1827
1828 lineLength = token.length();
1829 }
1830 else {
1831 sb.append(token);
1832
1833 lineLength = token.length();
1834 }
1835 }
1836 else {
1837 sb.append(token);
1838
1839 lineLength = token.length();
1840 }
1841 }
1842 else {
1843 if (lineLength > 0) {
1844 sb.append(StringPool.SPACE);
1845
1846 lineLength++;
1847 }
1848
1849 sb.append(token);
1850
1851 lineLength += token.length();
1852 }
1853 }
1854
1855 sb.append(lineSeparator);
1856 }
1857
1858 return sb.toString();
1859 }
1860
1861 private static final char[] _HEX_DIGITS = {
1862 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
1863 'e', 'f'
1864 };
1865
1866 private static String[] _emptyStringArray = new String[0];
1867
1868 private static Log _log = LogFactoryUtil.getLog(StringUtil.class);
1869
1870 }