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