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