001 /** 002 * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved. 003 * 004 * This library is free software; you can redistribute it and/or modify it under 005 * the terms of the GNU Lesser General Public License as published by the Free 006 * Software Foundation; either version 2.1 of the License, or (at your option) 007 * any later version. 008 * 009 * This library is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 011 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 012 * details. 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 * The String utility class. 039 * 040 * @author Brian Wing Shun Chan 041 * @author Sandeep Soni 042 * @author Ganesh Ram 043 * @author Shuyang Zhou 044 */ 045 public class StringUtil { 046 047 /** 048 * Adds string <code>add</code> to string <code>s</code> resulting in a 049 * comma delimited list of strings, disallowing duplicate strings in the 050 * list. 051 * 052 * <p> 053 * The resulting string ends with a comma even if the original string does 054 * not. 055 * </p> 056 * 057 * @param s the original string, representing a comma delimited list of 058 * strings 059 * @param add the string to add to the original, representing the string to 060 * add to the list 061 * @return a string that represents the original string and the added string 062 * separated by a comma, or <code>null</code> if the string to add 063 * is <code>null</code> 064 */ 065 public static String add(String s, String add) { 066 return add(s, add, StringPool.COMMA); 067 } 068 069 /** 070 * Adds string <code>add</code> to string <code>s</code> that represents a 071 * delimited list of strings, using a specified delimiter and disallowing 072 * duplicate words. 073 * 074 * <p> 075 * The returned string ends with the delimiter even if the original string 076 * does not. 077 * </p> 078 * 079 * @param s the original string, representing a delimited list of strings 080 * @param add the string to add to the original, representing the string to 081 * add to the list 082 * @param delimiter the delimiter used to separate strings in the list 083 * @return a string that represents the original string and the added string 084 * separated by the delimiter, or <code>null</code> if the string to 085 * add or the delimiter string is <code>null</code> 086 */ 087 public static String add(String s, String add, String delimiter) { 088 return add(s, add, delimiter, false); 089 } 090 091 /** 092 * Adds string <code>add</code> to string <code>s</code> that represents a 093 * delimited list of strings, using a specified delimiter and optionally 094 * allowing duplicate words. 095 * 096 * <p> 097 * The returned string ends with the delimiter even if the original string 098 * does not. 099 * </p> 100 * 101 * @param s the original string, representing a delimited list of strings 102 * @param add the string to add to the original, representing the string to 103 * add to the list 104 * @param delimiter the delimiter used to separate strings in the list 105 * @param allowDuplicates whether to allow duplicate strings 106 * @return a string that represents the original string and the added string 107 * separated by the delimiter, or <code>null</code> if the string to 108 * add or the delimiter string is <code>null</code> 109 */ 110 public static String add( 111 String s, String add, String delimiter, boolean allowDuplicates) { 112 113 if ((add == null) || (delimiter == null)) { 114 return null; 115 } 116 117 if (s == null) { 118 s = StringPool.BLANK; 119 } 120 121 if (allowDuplicates || !contains(s, add, delimiter)) { 122 StringBundler sb = new StringBundler(); 123 124 sb.append(s); 125 126 if (Validator.isNull(s) || s.endsWith(delimiter)) { 127 sb.append(add); 128 sb.append(delimiter); 129 } 130 else { 131 sb.append(delimiter); 132 sb.append(add); 133 sb.append(delimiter); 134 } 135 136 s = sb.toString(); 137 } 138 139 return s; 140 } 141 142 /** 143 * Returns the original string with an appended space followed by the string 144 * value of the suffix surrounded by parentheses. 145 * 146 * <p> 147 * If the original string ends with a numerical parenthetical suffix having 148 * an integer value equal to <code>suffix - 1</code>, then the existing 149 * parenthetical suffix is replaced by the new one. 150 * </p> 151 * 152 * <p> 153 * Examples: 154 * </p> 155 * 156 * <p> 157 * <pre> 158 * <code> 159 * appendParentheticalSuffix("file", 0) returns "file (0)" 160 * appendParentheticalSuffix("file (0)", 0) returns "file (0) (0)" 161 * appendParentheticalSuffix("file (0)", 1) returns "file (1)" 162 * appendParentheticalSuffix("file (0)", 2) returns "file (0) (2)" 163 * </code> 164 * </pre> 165 * </p> 166 * 167 * @param s the original string 168 * @param suffix the suffix to be appended 169 * @return the resultant string whose characters equal those of the original 170 * string, followed by a space, followed by the specified suffix 171 * enclosed in parentheses, or, if the difference between the 172 * provided suffix and the existing suffix is 1, the existing suffix 173 * is incremented by 1 174 */ 175 public static String appendParentheticalSuffix(String s, int suffix) { 176 if (Pattern.matches(".* \\(" + String.valueOf(suffix - 1) + "\\)", s)) { 177 int pos = s.lastIndexOf(" ("); 178 179 s = s.substring(0, pos); 180 } 181 182 return appendParentheticalSuffix(s, String.valueOf(suffix)); 183 } 184 185 /** 186 * Returns the original string with an appended space followed by the suffix 187 * surrounded by parentheses. 188 * 189 * <p> 190 * Example: 191 * </p> 192 * 193 * <p> 194 * <pre> 195 * <code> 196 * appendParentheticalSuffix("Java", "EE") returns "Java (EE)" 197 * </code> 198 * </pre> 199 * </p> 200 * 201 * @param s the original string 202 * @param suffix the suffix to be appended 203 * @return a string that represents the original string, followed by a 204 * space, followed by the suffix enclosed in parentheses 205 */ 206 public static String appendParentheticalSuffix(String s, String suffix) { 207 StringBundler sb = new StringBundler(5); 208 209 sb.append(s); 210 sb.append(StringPool.SPACE); 211 sb.append(StringPool.OPEN_PARENTHESIS); 212 sb.append(suffix); 213 sb.append(StringPool.CLOSE_PARENTHESIS); 214 215 return sb.toString(); 216 } 217 218 /** 219 * Converts an array of bytes to a string representing the bytes in 220 * hexadecimal form. 221 * 222 * @param bytes the array of bytes to be converted 223 * @return the string representing the bytes in hexadecimal form 224 */ 225 public static String bytesToHexString(byte[] bytes) { 226 StringBundler sb = new StringBundler(bytes.length * 2); 227 228 for (byte b : bytes) { 229 String hex = Integer.toHexString( 230 0x0100 + (b & 0x00FF)).substring(1); 231 232 if (hex.length() < 2) { 233 sb.append("0"); 234 } 235 236 sb.append(hex); 237 } 238 239 return sb.toString(); 240 } 241 242 /** 243 * Returns <code>true</code> if the string contains the text as a comma 244 * delimited list entry. 245 * 246 * <p> 247 * Example: 248 * </p> 249 * 250 * <p> 251 * <pre> 252 * <code> 253 * contains("one,two,three", "two") returns true 254 * contains("one,two,three", "thr") returns false 255 * </code> 256 * </pre> 257 * </p> 258 * 259 * @param s the string in which to search 260 * @param text the text to search for in the string 261 * @return <code>true</code> if the string contains the text as a comma 262 * delimited list entry; <code>false</code> otherwise 263 */ 264 public static boolean contains(String s, String text) { 265 return contains(s, text, StringPool.COMMA); 266 } 267 268 /** 269 * Returns <code>true</code> if the string contains the text as a delimited 270 * list entry. 271 * 272 * <p> 273 * Examples: 274 * </p> 275 * 276 * <p> 277 * <pre> 278 * <code> 279 * contains("three...two...one", "two", "...") returns true 280 * contains("three...two...one", "thr", "...") returns false 281 * </code> 282 * </pre> 283 * </p> 284 * 285 * @param s the string in which to search 286 * @param text the text to search for in the string 287 * @param delimiter the delimiter 288 * @return <code>true</code> if the string contains the text as a delimited 289 * list entry; <code>false</code> otherwise 290 */ 291 public static boolean contains(String s, String text, String delimiter) { 292 if ((s == null) || (text == null) || (delimiter == null)) { 293 return false; 294 } 295 296 if (!s.endsWith(delimiter)) { 297 s = s.concat(delimiter); 298 } 299 300 String dtd = delimiter.concat(text).concat(delimiter); 301 302 int pos = s.indexOf(dtd); 303 304 if (pos == -1) { 305 String td = text.concat(delimiter); 306 307 if (s.startsWith(td)) { 308 return true; 309 } 310 311 return false; 312 } 313 314 return true; 315 } 316 317 /** 318 * Returns the number of times the text appears in the string. 319 * 320 * @param s the string in which to search 321 * @param text the text to search for in the string 322 * @return the number of times the text appears in the string 323 */ 324 public static int count(String s, String text) { 325 if ((s == null) || (s.length() == 0) || (text == null) || 326 (text.length() == 0)) { 327 328 return 0; 329 } 330 331 int count = 0; 332 333 int pos = s.indexOf(text); 334 335 while (pos != -1) { 336 pos = s.indexOf(text, pos + text.length()); 337 338 count++; 339 } 340 341 return count; 342 } 343 344 /** 345 * Returns <code>true</code> if the string ends with the specified 346 * character. 347 * 348 * @param s the string in which to search 349 * @param end the character to search for at the end of the string 350 * @return <code>true</code> if the string ends with the specified 351 * character; <code>false</code> otherwise 352 */ 353 public static boolean endsWith(String s, char end) { 354 return endsWith(s, (new Character(end)).toString()); 355 } 356 357 /** 358 * Returns <code>true</code> if the string ends with the string 359 * <code>end</code>. 360 * 361 * @param s the string in which to search 362 * @param end the string to check for at the end of the string 363 * @return <code>true</code> if the string ends with the string 364 * <code>end</code>; <code>false</code> otherwise 365 */ 366 public static boolean endsWith(String s, String end) { 367 if ((s == null) || (end == null)) { 368 return false; 369 } 370 371 if (end.length() > s.length()) { 372 return false; 373 } 374 375 String temp = s.substring(s.length() - end.length()); 376 377 if (temp.equalsIgnoreCase(end)) { 378 return true; 379 } 380 else { 381 return false; 382 } 383 } 384 385 /** 386 * Returns the substring of each character instance in string <code>s</code> 387 * that is found in the character array <code>chars</code>. The substring of 388 * characters returned maintain their original order. 389 * 390 * @param s the string from which to extract characters 391 * @param chars the characters to extract from the string 392 * @return the substring of each character instance in string <code>s</code> 393 * that is found in the character array <code>chars</code>, or an 394 * empty string if the given string is <code>null</code> 395 */ 396 public static String extract(String s, char[] chars) { 397 if (s == null) { 398 return StringPool.BLANK; 399 } 400 401 StringBundler sb = new StringBundler(); 402 403 for (char c1 : s.toCharArray()) { 404 for (char c2 : chars) { 405 if (c1 == c2) { 406 sb.append(c1); 407 408 break; 409 } 410 } 411 } 412 413 return sb.toString(); 414 } 415 416 /** 417 * Returns the substring of English characters from the string. 418 * 419 * @param s the string from which to extract characters 420 * @return the substring of English characters from the string, or an empty 421 * string if the given string is <code>null</code> 422 */ 423 public static String extractChars(String s) { 424 if (s == null) { 425 return StringPool.BLANK; 426 } 427 428 StringBundler sb = new StringBundler(); 429 430 char[] chars = s.toCharArray(); 431 432 for (char c : chars) { 433 if (Validator.isChar(c)) { 434 sb.append(c); 435 } 436 } 437 438 return sb.toString(); 439 } 440 441 /** 442 * Returns a string consisting of all of the digits extracted from the 443 * string. 444 * 445 * @param s the string from which to extract digits 446 * @return a string consisting of all of the digits extracted from the 447 * string 448 */ 449 public static String extractDigits(String s) { 450 if (s == null) { 451 return StringPool.BLANK; 452 } 453 454 StringBundler sb = new StringBundler(); 455 456 char[] chars = s.toCharArray(); 457 458 for (char c : chars) { 459 if (Validator.isDigit(c)) { 460 sb.append(c); 461 } 462 } 463 464 return sb.toString(); 465 } 466 467 /** 468 * Returns the substring of <code>s</code> up to but not including the first 469 * occurrence of the delimiter. 470 * 471 * @param s the string from which to extract a substring 472 * @param delimiter the character whose index in the string marks where to 473 * end the substring 474 * @return the substring of <code>s</code> up to but not including the first 475 * occurrence of the delimiter, <code>null</code> if the string is 476 * <code>null</code> or the delimiter does not occur in the string 477 */ 478 public static String extractFirst(String s, char delimiter) { 479 if (s == null) { 480 return null; 481 } 482 else { 483 int index = s.indexOf(delimiter); 484 485 if (index < 0) { 486 return null; 487 } 488 else { 489 return s.substring(0, index); 490 } 491 } 492 } 493 494 /** 495 * Returns the substring of <code>s</code> up to but not including the first 496 * occurrence of the delimiter. 497 * 498 * @param s the string from which to extract a substring 499 * @param delimiter the smaller string whose index in the larger string 500 * marks where to end the substring 501 * @return the substring of <code>s</code> up to but not including the first 502 * occurrence of the delimiter, <code>null</code> if the string is 503 * <code>null</code> or the delimiter does not occur in the string 504 */ 505 public static String extractFirst(String s, String delimiter) { 506 if (s == null) { 507 return null; 508 } 509 else { 510 int index = s.indexOf(delimiter); 511 512 if (index < 0) { 513 return null; 514 } 515 else { 516 return s.substring(0, index); 517 } 518 } 519 } 520 521 /** 522 * Returns the substring of <code>s</code> after but not including the last 523 * occurrence of the delimiter. 524 * 525 * @param s the string from which to extract the substring 526 * @param delimiter the character whose last index in the string marks 527 * where to begin the substring 528 * @return the substring of <code>s</code> after but not including the last 529 * occurrence of the delimiter, <code>null</code> if the string is 530 * <code>null</code> or the delimiter does not occur in the string 531 */ 532 public static String extractLast(String s, char delimiter) { 533 if (s == null) { 534 return null; 535 } 536 else { 537 int index = s.lastIndexOf(delimiter); 538 539 if (index < 0) { 540 return null; 541 } 542 else { 543 return s.substring(index + 1); 544 } 545 } 546 } 547 548 /** 549 * Returns the substring of <code>s</code> after but not including the last 550 * occurrence of the delimiter. 551 * 552 * @param s the string from which to extract the substring 553 * @param delimiter the string whose last index in the string marks where 554 * to begin the substring 555 * @return the substring of <code>s</code> after but not including the last 556 * occurrence of the delimiter, <code>null</code> if the string is 557 * <code>null</code> or the delimiter does not occur in the string 558 */ 559 public static String extractLast(String s, String delimiter) { 560 if (s == null) { 561 return null; 562 } 563 else { 564 int index = s.lastIndexOf(delimiter); 565 566 if (index < 0) { 567 return null; 568 } 569 else { 570 return s.substring(index + delimiter.length()); 571 } 572 } 573 } 574 575 public static String extractLeadingDigits(String s) { 576 if (s == null) { 577 return StringPool.BLANK; 578 } 579 580 StringBundler sb = new StringBundler(); 581 582 char[] chars = s.toCharArray(); 583 584 for (char c : chars) { 585 if (Validator.isDigit(c)) { 586 sb.append(c); 587 } 588 else { 589 return sb.toString(); 590 } 591 } 592 593 return sb.toString(); 594 } 595 596 /** 597 * @deprecated 598 */ 599 public static String highlight(String s, String keywords) { 600 return highlight(s, keywords, "<span class=\"highlight\">", "</span>"); 601 } 602 603 /** 604 * @deprecated 605 */ 606 public static String highlight( 607 String s, String keywords, String highlight1, String highlight2) { 608 609 if (Validator.isNull(s) || Validator.isNull(keywords)) { 610 return s; 611 } 612 613 Pattern pattern = Pattern.compile( 614 Pattern.quote(keywords), Pattern.CASE_INSENSITIVE); 615 616 return _highlight(s, pattern, highlight1, highlight2); 617 } 618 619 public static String highlight(String s, String[] queryTerms) { 620 return highlight( 621 s, queryTerms, "<span class=\"highlight\">", "</span>"); 622 } 623 624 public static String highlight( 625 String s, String[] queryTerms, String highlight1, String highlight2) { 626 627 if (Validator.isNull(s) || Validator.isNull(queryTerms)) { 628 return s; 629 } 630 631 if (queryTerms.length == 0) { 632 return StringPool.BLANK; 633 } 634 635 StringBundler sb = new StringBundler(2 * queryTerms.length - 1); 636 637 for (int i = 0; i < queryTerms.length; i++) { 638 sb.append(Pattern.quote(queryTerms[i].trim())); 639 640 if ((i + 1) < queryTerms.length) { 641 sb.append(StringPool.PIPE); 642 } 643 } 644 645 int flags = Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE; 646 647 Pattern pattern = Pattern.compile(sb.toString(), flags); 648 649 return _highlight(s, pattern, highlight1, highlight2); 650 } 651 652 /** 653 * Inserts one string into the other at the specified offset index. 654 * 655 * @param s the original string 656 * @param insert the string to be inserted into the original string 657 * @param offset the index of the original string where the insertion 658 * should take place 659 * @return a string representing the original string with the other string 660 * inserted at the specified offset index, or <code>null</code> if 661 * the original string is <code>null</code> 662 */ 663 public static String insert(String s, String insert, int offset) { 664 if (s == null) { 665 return null; 666 } 667 668 if (insert == null) { 669 return s; 670 } 671 672 if (offset > s.length()) { 673 return s.concat(insert); 674 } 675 else { 676 String prefix = s.substring(0, offset); 677 String postfix = s.substring(offset); 678 679 return prefix.concat(insert).concat(postfix); 680 } 681 } 682 683 /** 684 * Converts all of the characters in the string to lower case. 685 * 686 * @param s the string to convert 687 * @return the string, converted to lowercase, or <code>null</code> if the 688 * string is <code>null</code> 689 * @see {@link String#toLowerCase()} 690 */ 691 public static String lowerCase(String s) { 692 if (s == null) { 693 return null; 694 } 695 else { 696 return s.toLowerCase(); 697 } 698 } 699 700 public static void lowerCase(String... array) { 701 if (array != null) { 702 for (int i = 0; i < array.length; i++) { 703 array[i] = array[i].toLowerCase(); 704 } 705 } 706 } 707 708 /** 709 * Returns <code>true</code> if the specified pattern occurs at any position 710 * in the string. 711 * 712 * @param s the string 713 * @param pattern the pattern to search for in the string 714 * @return <code>true</code> if the specified pattern occurs at any position 715 * in the string 716 */ 717 public static boolean matches(String s, String pattern) { 718 String[] array = pattern.split("\\*"); 719 720 for (String element : array) { 721 int pos = s.indexOf(element); 722 723 if (pos == -1) { 724 return false; 725 } 726 727 s = s.substring(pos + element.length()); 728 } 729 730 return true; 731 } 732 733 /** 734 * Returns <code>true</code> if the specified pattern occurs at any position 735 * in the string, ignoring case. 736 * 737 * @param s the string 738 * @param pattern the pattern to search for in the string 739 * @return <code>true</code> if the specified pattern occurs at any position 740 * in the string 741 */ 742 public static boolean matchesIgnoreCase(String s, String pattern) { 743 return matches(lowerCase(s), lowerCase(pattern)); 744 } 745 746 /** 747 * Merges the elements of the boolean array into a string representing a 748 * comma delimited list of its values. 749 * 750 * @param array the boolean values to merge 751 * @return a string representing a comma delimited list of the values of the 752 * boolean array, an empty string if the array is empty, or 753 * <code>null</code> if the array is <code>null</code> 754 */ 755 public static String merge(boolean[] array) { 756 return merge(array, StringPool.COMMA); 757 } 758 759 /** 760 * Merges the elements of the boolean array into a string representing a 761 * delimited list of its values. 762 * 763 * @param array the boolean values to merge 764 * @param delimiter the delimiter 765 * @return a string representing a comma delimited list of the values of the 766 * boolean array, an empty string if the array is empty, or 767 * <code>null</code> if the array is <code>null</code> 768 */ 769 public static String merge(boolean[] array, String delimiter) { 770 if (array == null) { 771 return null; 772 } 773 774 if (array.length == 0) { 775 return StringPool.BLANK; 776 } 777 778 StringBundler sb = new StringBundler(2 * array.length - 1); 779 780 for (int i = 0; i < array.length; i++) { 781 sb.append(String.valueOf(array[i]).trim()); 782 783 if ((i + 1) != array.length) { 784 sb.append(delimiter); 785 } 786 } 787 788 return sb.toString(); 789 } 790 791 /** 792 * Merges the elements of the character array into a string representing a 793 * comma delimited list of its values. 794 * 795 * @param array the characters to merge 796 * @return a string representing a comma delimited list of the values of the 797 * character array, an empty string if the array is empty, or 798 * <code>null</code> if the array is <code>null</code> 799 */ 800 public static String merge(char[] array) { 801 return merge(array, StringPool.COMMA); 802 } 803 804 /** 805 * Merges the elements of the character array into a string representing a 806 * delimited list of its values. 807 * 808 * @param array the characters to merge 809 * @param delimiter the delimiter 810 * @return a string representing a delimited list of the values of the 811 * character array, an empty string if the array is empty, or 812 * <code>null</code> if the array is <code>null</code> 813 */ 814 public static String merge(char[] array, String delimiter) { 815 if (array == null) { 816 return null; 817 } 818 819 if (array.length == 0) { 820 return StringPool.BLANK; 821 } 822 823 StringBundler sb = new StringBundler(2 * array.length - 1); 824 825 for (int i = 0; i < array.length; i++) { 826 sb.append(String.valueOf(array[i]).trim()); 827 828 if ((i + 1) != array.length) { 829 sb.append(delimiter); 830 } 831 } 832 833 return sb.toString(); 834 } 835 836 public static String merge(Collection<?> col) { 837 return merge(col, StringPool.COMMA); 838 } 839 840 public static String merge(Collection<?> col, String delimiter) { 841 if (col == null) { 842 return null; 843 } 844 845 return merge(col.toArray(new Object[col.size()]), delimiter); 846 } 847 848 /** 849 * Merges the elements of an array of double-precision decimal numbers by 850 * returning a string representing a comma delimited list of its values. 851 * 852 * @param array the doubles to merge 853 * @return a string representing a comma delimited list of the values of the 854 * array of double-precision decimal numbers, an empty string if the 855 * array is empty, or <code>null</code> if the array is 856 * <code>null</code> 857 */ 858 public static String merge(double[] array) { 859 return merge(array, StringPool.COMMA); 860 } 861 862 /** 863 * Merges the elements of an array of double-precision decimal numbers by 864 * returning a string representing a delimited list of its values. 865 * 866 * @param array the doubles to merge 867 * @param delimiter the delimiter 868 * @return a string representing a delimited list of the values of the array 869 * of double-precision decimal numbers, an empty string if the array 870 * is empty, or <code>null</code> if the array is <code>null</code> 871 */ 872 public static String merge(double[] array, String delimiter) { 873 if (array == null) { 874 return null; 875 } 876 877 if (array.length == 0) { 878 return StringPool.BLANK; 879 } 880 881 StringBundler sb = new StringBundler(2 * array.length - 1); 882 883 for (int i = 0; i < array.length; i++) { 884 sb.append(String.valueOf(array[i]).trim()); 885 886 if ((i + 1) != array.length) { 887 sb.append(delimiter); 888 } 889 } 890 891 return sb.toString(); 892 } 893 894 /** 895 * Merges the elements of an array of decimal numbers into a string 896 * representing a comma delimited list of its values. 897 * 898 * @param array the floats to merge 899 * @return a string representing a comma delimited list of the values of the 900 * array of decimal numbers, an empty string if the array is empty, 901 * or <code>null</code> if the array is <code>null</code> 902 */ 903 public static String merge(float[] array) { 904 return merge(array, StringPool.COMMA); 905 } 906 907 /** 908 * Merges the elements of an array of decimal numbers into a string 909 * representing a delimited list of its values. 910 * 911 * @param array the floats to merge 912 * @param delimiter the delimiter 913 * @return a string representing a delimited list of the values of the array 914 * of decimal numbers, an empty string if the array is empty, or 915 * <code>null</code> if the array is <code>null</code> 916 */ 917 public static String merge(float[] array, String delimiter) { 918 if (array == null) { 919 return null; 920 } 921 922 if (array.length == 0) { 923 return StringPool.BLANK; 924 } 925 926 StringBundler sb = new StringBundler(2 * array.length - 1); 927 928 for (int i = 0; i < array.length; i++) { 929 sb.append(String.valueOf(array[i]).trim()); 930 931 if ((i + 1) != array.length) { 932 sb.append(delimiter); 933 } 934 } 935 936 return sb.toString(); 937 } 938 939 /** 940 * Merges the elements of an array of integers into a string representing a 941 * comma delimited list of its values. 942 * 943 * @param array the integers to merge 944 * @return a string representing a comma delimited list of the values of the 945 * array of integers, an empty string if the array is empty, or 946 * <code>null</code> if the array is <code>null</code> 947 */ 948 public static String merge(int[] array) { 949 return merge(array, StringPool.COMMA); 950 } 951 952 /** 953 * Merges the elements of an array of integers into a string representing a 954 * delimited list of its values. 955 * 956 * @param array the integers to merge 957 * @param delimiter the delimiter 958 * @return a string representing a delimited list of the values of the array 959 * of integers, an empty string if the array is empty, or 960 * <code>null</code> if the array is <code>null</code> 961 */ 962 public static String merge(int[] array, String delimiter) { 963 if (array == null) { 964 return null; 965 } 966 967 if (array.length == 0) { 968 return StringPool.BLANK; 969 } 970 971 StringBundler sb = new StringBundler(2 * array.length - 1); 972 973 for (int i = 0; i < array.length; i++) { 974 sb.append(String.valueOf(array[i]).trim()); 975 976 if ((i + 1) != array.length) { 977 sb.append(delimiter); 978 } 979 } 980 981 return sb.toString(); 982 } 983 984 /** 985 * Merges the elements of an array of long integers by returning a string 986 * representing a comma delimited list of its values. 987 * 988 * @param array the long integers to merge 989 * @return a string representing a comma delimited list of the values of the 990 * array of long integers, an empty string if the array is empty, or 991 * <code>null</code> if the array is <code>null</code> 992 */ 993 public static String merge(long[] array) { 994 return merge(array, StringPool.COMMA); 995 } 996 997 /** 998 * Merges the elements of an array of long integers by returning a string 999 * representing a delimited list of its values. 1000 * 1001 * @param array the long integers to merge 1002 * @param delimiter the delimiter 1003 * @return a string representing a delimited list of the values of the array 1004 * of long integers, an empty string if the array is empty, or 1005 * <code>null</code> if the array is <code>null</code> 1006 */ 1007 public static String merge(long[] array, String delimiter) { 1008 if (array == null) { 1009 return null; 1010 } 1011 1012 if (array.length == 0) { 1013 return StringPool.BLANK; 1014 } 1015 1016 StringBundler sb = new StringBundler(2 * array.length - 1); 1017 1018 for (int i = 0; i < array.length; i++) { 1019 sb.append(String.valueOf(array[i]).trim()); 1020 1021 if ((i + 1) != array.length) { 1022 sb.append(delimiter); 1023 } 1024 } 1025 1026 return sb.toString(); 1027 } 1028 1029 /** 1030 * Merges the elements of an array of objects into a string representing a 1031 * comma delimited list of the objects. 1032 * 1033 * @param array the objects to merge 1034 * @return a string representing a comma delimited list of the objects, an 1035 * empty string if the array is empty, or <code>null</code> if the 1036 * array is <code>null</code> 1037 */ 1038 public static String merge(Object[] array) { 1039 return merge(array, StringPool.COMMA); 1040 } 1041 1042 /** 1043 * Merges the elements of an array of objects into a string representing a 1044 * delimited list of the objects. 1045 * 1046 * @param array the objects to merge 1047 * @param delimiter the delimiter 1048 * @return a string representing a delimited list of the objects, an empty 1049 * string if the array is empty, or <code>null</code> if the array 1050 * is <code>null</code> 1051 */ 1052 public static String merge(Object[] array, String delimiter) { 1053 if (array == null) { 1054 return null; 1055 } 1056 1057 if (array.length == 0) { 1058 return StringPool.BLANK; 1059 } 1060 1061 StringBundler sb = new StringBundler(2 * array.length - 1); 1062 1063 for (int i = 0; i < array.length; i++) { 1064 sb.append(String.valueOf(array[i]).trim()); 1065 1066 if ((i + 1) != array.length) { 1067 sb.append(delimiter); 1068 } 1069 } 1070 1071 return sb.toString(); 1072 } 1073 1074 /** 1075 * Merges the elements of an array of short integers by returning a string 1076 * representing a comma delimited list of its values. 1077 * 1078 * @param array the short integers to merge 1079 * @return a string representing a comma delimited list of the values of the 1080 * array of short integers, an empty string if the array is empty, 1081 * or <code>null</code> if the array is <code>null</code> 1082 */ 1083 public static String merge(short[] array) { 1084 return merge(array, StringPool.COMMA); 1085 } 1086 1087 /** 1088 * Merges the elements of an array of short integers by returning a string 1089 * representing a delimited list of its values. 1090 * 1091 * @param array the short integers to merge 1092 * @param delimiter the delimiter 1093 * @return a string representing a delimited list of the values of the array 1094 * of short integers, an empty string if the array is empty, or 1095 * <code>null</code> if the array is <code>null</code> 1096 */ 1097 public static String merge(short[] array, String delimiter) { 1098 if (array == null) { 1099 return null; 1100 } 1101 1102 if (array.length == 0) { 1103 return StringPool.BLANK; 1104 } 1105 1106 StringBundler sb = new StringBundler(2 * array.length - 1); 1107 1108 for (int i = 0; i < array.length; i++) { 1109 sb.append(String.valueOf(array[i]).trim()); 1110 1111 if ((i + 1) != array.length) { 1112 sb.append(delimiter); 1113 } 1114 } 1115 1116 return sb.toString(); 1117 } 1118 1119 /** 1120 * Returns the string enclosed by apostrophes. 1121 * 1122 * <p> 1123 * Example: 1124 * </p> 1125 * 1126 * <p> 1127 * <pre> 1128 * <code> 1129 * quote("Hello, World!") returns "'Hello, World!'" 1130 * </code> 1131 * </pre> 1132 * </p> 1133 * 1134 * @param s the string to enclose in apostrophes 1135 * @return the string enclosed by apostrophes, or <code>null</code> if the 1136 * string is <code>null</code> 1137 */ 1138 public static String quote(String s) { 1139 return quote(s, CharPool.APOSTROPHE); 1140 } 1141 1142 /** 1143 * Returns the string enclosed by the quote character. 1144 * 1145 * <p> 1146 * Example: 1147 * </p> 1148 * 1149 * <p> 1150 * <pre> 1151 * <code> 1152 * quote("PATH", '%') returns "%PATH%" 1153 * </code> 1154 * </pre> 1155 * </p> 1156 * 1157 * @param s the string to enclose in quotes 1158 * @param quote the character to insert to insert to the beginning of and 1159 * append to the end of the string 1160 * @return the string enclosed in the quote characters, or <code>null</code> 1161 * if the string is <code>null</code> 1162 */ 1163 public static String quote(String s, char quote) { 1164 if (s == null) { 1165 return null; 1166 } 1167 1168 return quote(s, String.valueOf(quote)); 1169 } 1170 1171 /** 1172 * Returns the string enclosed by the quote strings. 1173 * 1174 * <p> 1175 * Example: 1176 * </p> 1177 * 1178 * <p> 1179 * <pre> 1180 * <code> 1181 * quote("WARNING", "!!!") returns "!!!WARNING!!!" 1182 * </code> 1183 * </pre> 1184 * </p> 1185 * 1186 * @param s the string to enclose in quotes 1187 * @param quote the quote string to insert to insert to the beginning of 1188 * and append to the end of the string 1189 * @return the string enclosed in the quote strings, or <code>null</code> if 1190 * the string is <code>null</code> 1191 */ 1192 public static String quote(String s, String quote) { 1193 if (s == null) { 1194 return null; 1195 } 1196 1197 return quote.concat(s).concat(quote); 1198 } 1199 1200 /** 1201 * Pseudorandomly permutes the characters of the string. 1202 * 1203 * @param s the string whose characters are to be randomized 1204 * @return a string of the same length as the string whose characters 1205 * represent a pseudorandom permutation of the characters of the 1206 * string 1207 */ 1208 public static String randomize(String s) { 1209 return Randomizer.getInstance().randomize(s); 1210 } 1211 1212 public static String read(ClassLoader classLoader, String name) 1213 throws IOException { 1214 1215 return read(classLoader, name, false); 1216 } 1217 1218 public static String read(ClassLoader classLoader, String name, boolean all) 1219 throws IOException { 1220 1221 if (all) { 1222 StringBundler sb = new StringBundler(); 1223 1224 Enumeration<URL> enu = classLoader.getResources(name); 1225 1226 while (enu.hasMoreElements()) { 1227 URL url = enu.nextElement(); 1228 1229 InputStream is = url.openStream(); 1230 1231 if (is == null) { 1232 throw new IOException( 1233 "Unable to open resource at " + url.toString()); 1234 } 1235 1236 String s = read(is); 1237 1238 if (s != null) { 1239 sb.append(s); 1240 sb.append(StringPool.NEW_LINE); 1241 } 1242 1243 is.close(); 1244 } 1245 1246 return sb.toString().trim(); 1247 } 1248 else { 1249 InputStream is = classLoader.getResourceAsStream(name); 1250 1251 if (is == null) { 1252 throw new IOException( 1253 "Unable to open resource in class loader " + name); 1254 } 1255 1256 String s = read(is); 1257 1258 is.close(); 1259 1260 return s; 1261 } 1262 } 1263 1264 public static String read(InputStream is) throws IOException { 1265 StringBundler sb = new StringBundler(); 1266 1267 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader( 1268 new InputStreamReader(is)); 1269 1270 String line = null; 1271 1272 while ((line = unsyncBufferedReader.readLine()) != null) { 1273 sb.append(line); 1274 sb.append(CharPool.NEW_LINE); 1275 } 1276 1277 unsyncBufferedReader.close(); 1278 1279 return sb.toString().trim(); 1280 } 1281 1282 public static void readLines(InputStream is, Collection<String> lines) 1283 throws IOException { 1284 1285 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader( 1286 new InputStreamReader(is)); 1287 1288 String line = null; 1289 1290 while ((line = unsyncBufferedReader.readLine()) != null) { 1291 lines.add(line); 1292 } 1293 1294 unsyncBufferedReader.close(); 1295 } 1296 1297 /** 1298 * Removes the <code>remove</code> string from string <code>s</code> that 1299 * represents a list of comma delimited strings. 1300 * 1301 * <p> 1302 * The resulting string ends with a comma even if the original string does 1303 * not. 1304 * </p> 1305 * 1306 * <p> 1307 * Examples: 1308 * </p> 1309 * 1310 * <p> 1311 * <pre> 1312 * <code> 1313 * remove("red,blue,green,yellow", "blue") returns "red,green,yellow," 1314 * remove("blue", "blue") returns "" 1315 * remove("blue,", "blue") returns "" 1316 * </code> 1317 * </pre> 1318 * </p> 1319 * 1320 * @param s the string representing the list of comma delimited strings 1321 * @param remove the string to remove 1322 * @return a string representing the list of comma delimited strings with 1323 * the <code>remove</code> string removed, or <code>null</code> if 1324 * the original string, the string to remove, or the delimiter is 1325 * <code>null</code> 1326 */ 1327 public static String remove(String s, String remove) { 1328 return remove(s, remove, StringPool.COMMA); 1329 } 1330 1331 /** 1332 * Removes the <code>remove</code> string from string <code>s</code> that 1333 * represents a list of delimited strings. 1334 * 1335 * <p> 1336 * The resulting string ends with the delimiter even if the original string 1337 * does not. 1338 * </p> 1339 * 1340 * <p> 1341 * Examples: 1342 * </p> 1343 * 1344 * <p> 1345 * <pre> 1346 * <code> 1347 * remove("red;blue;green;yellow", "blue", ";") returns "red;green;yellow;" 1348 * remove("blue", "blue", ";") returns "" 1349 * remove("blue;", "blue", ";") returns "" 1350 * </code> 1351 * </pre> 1352 * </p> 1353 * 1354 * @param s the string representing the list of delimited strings 1355 * @param remove the string to remove 1356 * @param delimiter the delimiter 1357 * @return a string representing the list of delimited strings with the 1358 * <code>remove</code> string removed, or <code>null</code> if the 1359 * original string, the string to remove, or the delimiter is 1360 * <code>null</code> 1361 */ 1362 public static String remove(String s, String remove, String delimiter) { 1363 if ((s == null) || (remove == null) || (delimiter == null)) { 1364 return null; 1365 } 1366 1367 if (Validator.isNotNull(s) && !s.endsWith(delimiter)) { 1368 s += delimiter; 1369 } 1370 1371 String drd = delimiter.concat(remove).concat(delimiter); 1372 1373 String rd = remove.concat(delimiter); 1374 1375 while (contains(s, remove, delimiter)) { 1376 int pos = s.indexOf(drd); 1377 1378 if (pos == -1) { 1379 if (s.startsWith(rd)) { 1380 int x = remove.length() + delimiter.length(); 1381 int y = s.length(); 1382 1383 s = s.substring(x, y); 1384 } 1385 } 1386 else { 1387 int x = pos + remove.length() + delimiter.length(); 1388 int y = s.length(); 1389 1390 String temp = s.substring(0, pos); 1391 1392 s = temp.concat(s.substring(x, y)); 1393 } 1394 } 1395 1396 return s; 1397 } 1398 1399 /** 1400 * Replaces all occurrences of the character with the new character. 1401 * 1402 * @param s the original string 1403 * @param oldSub the character to be searched for and replaced in the 1404 * original string 1405 * @param newSub the character with which to replace the 1406 * <code>oldSub</code> character 1407 * @return a string representing the original string with all occurrences of 1408 * the <code>oldSub</code> character replaced with the 1409 * <code>newSub</code> character, or <code>null</code> if the 1410 * original string is <code>null</code> 1411 */ 1412 public static String replace(String s, char oldSub, char newSub) { 1413 if (s == null) { 1414 return null; 1415 } 1416 1417 return s.replace(oldSub, newSub); 1418 } 1419 1420 /** 1421 * Replaces all occurrences of the character with the new string. 1422 * 1423 * @param s the original string 1424 * @param oldSub the character to be searched for and replaced in the 1425 * original string 1426 * @param newSub the string with which to replace the <code>oldSub</code> 1427 * character 1428 * @return a string representing the original string with all occurrences of 1429 * the <code>oldSub</code> character replaced with the string 1430 * <code>newSub</code>, or <code>null</code> if the original string 1431 * is <code>null</code> 1432 */ 1433 public static String replace(String s, char oldSub, String newSub) { 1434 if ((s == null) || (newSub == null)) { 1435 return null; 1436 } 1437 1438 // The number 5 is arbitrary and is used as extra padding to reduce 1439 // buffer expansion 1440 1441 StringBundler sb = new StringBundler(s.length() + 5 * newSub.length()); 1442 1443 char[] chars = s.toCharArray(); 1444 1445 for (char c : chars) { 1446 if (c == oldSub) { 1447 sb.append(newSub); 1448 } 1449 else { 1450 sb.append(c); 1451 } 1452 } 1453 1454 return sb.toString(); 1455 } 1456 1457 /** 1458 * Replaces all occurrences of the string with the new string. 1459 * 1460 * @param s the original string 1461 * @param oldSub the string to be searched for and replaced in the original 1462 * string 1463 * @param newSub the string with which to replace the <code>oldSub</code> 1464 * string 1465 * @return a string representing the original string with all occurrences of 1466 * the <code>oldSub</code> string replaced with the string 1467 * <code>newSub</code>, or <code>null</code> if the original string 1468 * is <code>null</code> 1469 */ 1470 public static String replace(String s, String oldSub, String newSub) { 1471 return replace(s, oldSub, newSub, 0); 1472 } 1473 1474 /** 1475 * Replaces all occurrences of the string with the new string, starting from 1476 * the specified index. 1477 * 1478 * @param s the original string 1479 * @param oldSub the string to be searched for and replaced in the original 1480 * string 1481 * @param newSub the string with which to replace the <code>oldSub</code> 1482 * string 1483 * @param fromIndex the index of the original string from which to begin 1484 * searching 1485 * @return a string representing the original string with all occurrences of 1486 * the <code>oldSub</code> string occurring after the specified 1487 * index replaced with the string <code>newSub</code>, or 1488 * <code>null</code> if the original string is <code>null</code> 1489 */ 1490 public static String replace( 1491 String s, String oldSub, String newSub, int fromIndex) { 1492 1493 if (s == null) { 1494 return null; 1495 } 1496 1497 if ((oldSub == null) || oldSub.equals(StringPool.BLANK)) { 1498 return s; 1499 } 1500 1501 if (newSub == null) { 1502 newSub = StringPool.BLANK; 1503 } 1504 1505 int y = s.indexOf(oldSub, fromIndex); 1506 1507 if (y >= 0) { 1508 StringBundler sb = new StringBundler(); 1509 1510 int length = oldSub.length(); 1511 int x = 0; 1512 1513 while (x <= y) { 1514 sb.append(s.substring(x, y)); 1515 sb.append(newSub); 1516 1517 x = y + length; 1518 y = s.indexOf(oldSub, x); 1519 } 1520 1521 sb.append(s.substring(x)); 1522 1523 return sb.toString(); 1524 } 1525 else { 1526 return s; 1527 } 1528 } 1529 1530 public static String replace( 1531 String s, String begin, String end, Map<String, String> values) { 1532 1533 StringBundler sb = replaceToStringBundler(s, begin, end, values); 1534 1535 return sb.toString(); 1536 } 1537 1538 /** 1539 * Replaces all occurrences of the elements of the string array with the 1540 * corresponding elements of the new string array. 1541 * 1542 * @param s the original string 1543 * @param oldSubs the strings to be searched for and replaced in the 1544 * original string 1545 * @param newSubs the strings with which to replace the 1546 * <code>oldSubs</code> strings 1547 * @return a string representing the original string with all occurrences of 1548 * the <code>oldSubs</code> strings replaced with the corresponding 1549 * <code>newSubs</code> strings, or <code>null</code> if the 1550 * original string, the <code>oldSubs</code> array, or the 1551 * <code>newSubs</code> is <code>null</code> 1552 */ 1553 public static String replace(String s, String[] oldSubs, String[] newSubs) { 1554 if ((s == null) || (oldSubs == null) || (newSubs == null)) { 1555 return null; 1556 } 1557 1558 if (oldSubs.length != newSubs.length) { 1559 return s; 1560 } 1561 1562 for (int i = 0; i < oldSubs.length; i++) { 1563 s = replace(s, oldSubs[i], newSubs[i]); 1564 } 1565 1566 return s; 1567 } 1568 1569 /** 1570 * Replaces all occurrences of the elements of the string array with the 1571 * corresponding elements of the new string array, optionally replacing only 1572 * substrings that are surrounded by word boundaries. 1573 * 1574 * <p> 1575 * Examples: 1576 * </p> 1577 * 1578 * <p> 1579 * <pre> 1580 * <code> 1581 * replace("redorangeyellow", {"red", "orange", "yellow"}, {"RED","ORANGE", "YELLOW"}, false) returns "REDORANGEYELLOW" 1582 * replace("redorangeyellow", {"red", "orange", "yellow"}, {"RED","ORANGE", "YELLOW"}, true) returns "redorangeyellow" 1583 * replace("redorange yellow", {"red", "orange", "yellow"}, {"RED","ORANGE", "YELLOW"}, false) returns "REDORANGE YELLOW" 1584 * replace("redorange yellow", {"red", "orange", "yellow"}, {"RED","ORANGE", "YELLOW"}, true) returns "redorange YELLOW" 1585 * replace("red orange yellow", {"red", "orange", "yellow"}, {"RED","ORANGE", "YELLOW"}, false) returns "RED ORANGE YELLOW" 1586 * replace("redorange.yellow", {"red", "orange", "yellow"}, {"RED","ORANGE", * "YELLOW"}, true) returns "redorange.YELLOW" 1587 * </code> 1588 * </pre> 1589 * </p> 1590 * 1591 * @param s the original string 1592 * @param oldSubs the strings to be searched for and replaced in the 1593 * original string 1594 * @param newSubs the strings with which to replace the 1595 * <code>oldSubs</code> strings 1596 * @param exactMatch whether or not to replace only substrings of 1597 * <code>s</code> that are surrounded by word boundaries 1598 * @return if <code>exactMatch</code> is <code>true</code>, a string 1599 * representing the original string with all occurrences of the 1600 * <code>oldSubs</code> strings that are surrounded by word 1601 * boundaries replaced with the corresponding <code>newSubs</code> 1602 * strings, or else a string representing the original string with 1603 * all occurrences of the <code>oldSubs</code> strings replaced with 1604 * the corresponding <code>newSubs</code> strings, or 1605 * <code>null</code> if the original string, the 1606 * <code>oldSubs</code> array, or the <code>newSubs</code is 1607 * <code>null</code> 1608 */ 1609 public static String replace( 1610 String s, String[] oldSubs, String[] newSubs, boolean exactMatch) { 1611 1612 if ((s == null) || (oldSubs == null) || (newSubs == null)) { 1613 return null; 1614 } 1615 1616 if (oldSubs.length != newSubs.length) { 1617 return s; 1618 } 1619 1620 if (!exactMatch) { 1621 return replace(s, oldSubs, newSubs); 1622 } 1623 1624 for (int i = 0; i < oldSubs.length; i++) { 1625 s = s.replaceAll("\\b" + oldSubs[i] + "\\b", newSubs[i]); 1626 } 1627 1628 return s; 1629 } 1630 1631 /** 1632 * Replaces the first occurrence of the character with the new character. 1633 * 1634 * @param s the original string 1635 * @param oldSub the character whose first occurrence in the original 1636 * string is to be searched for and replaced 1637 * @param newSub the character with which to replace the first occurrence 1638 * of the <code>oldSub</code> character 1639 * @return a string representing the original string except with the first 1640 * occurrence of the character <code>oldSub</code> replaced with the 1641 * character <code>newSub</code> 1642 */ 1643 public static String replaceFirst(String s, char oldSub, char newSub) { 1644 if (s == null) { 1645 return null; 1646 } 1647 1648 return replaceFirst(s, String.valueOf(oldSub), String.valueOf(newSub)); 1649 } 1650 1651 /** 1652 * Replaces the first occurrence of the character with the new string. 1653 * 1654 * @param s the original string 1655 * @param oldSub the character whose first occurrence in the original 1656 * string is to be searched for and replaced 1657 * @param newSub the string with which to replace the first occurrence of 1658 * the <code>oldSub</code> character 1659 * @return a string representing the original string except with the first 1660 * occurrence of the character <code>oldSub</code> replaced with the 1661 * string <code>newSub</code> 1662 */ 1663 public static String replaceFirst(String s, char oldSub, String newSub) { 1664 if ((s == null) || (newSub == null)) { 1665 return null; 1666 } 1667 1668 return replaceFirst(s, String.valueOf(oldSub), newSub); 1669 } 1670 1671 /** 1672 * Replaces the first occurrence of the string with the new string. 1673 * 1674 * @param s the original string 1675 * @param oldSub the string whose first occurrence in the original string 1676 * is to be searched for and replaced 1677 * @param newSub the string with which to replace the first occurrence of 1678 * the <code>oldSub</code> string 1679 * @return a string representing the original string except with the first 1680 * occurrence of the string <code>oldSub</code> replaced with the 1681 * string <code>newSub</code> 1682 */ 1683 public static String replaceFirst(String s, String oldSub, String newSub) { 1684 if ((s == null) || (oldSub == null) || (newSub == null)) { 1685 return null; 1686 } 1687 1688 if (oldSub.equals(newSub)) { 1689 return s; 1690 } 1691 1692 int y = s.indexOf(oldSub); 1693 1694 if (y >= 0) { 1695 return s.substring(0, y).concat(newSub).concat( 1696 s.substring(y + oldSub.length())); 1697 } 1698 else { 1699 return s; 1700 } 1701 } 1702 1703 /** 1704 * Replaces the first occurrences of the elements of the string array with 1705 * the corresponding elements of the new string array. 1706 * 1707 * @param s the original string 1708 * @param oldSubs the strings whose first occurrences are to be searched 1709 * for and replaced in the original string 1710 * @param newSubs the strings with which to replace the first occurrences 1711 * of the <code>oldSubs</code> strings 1712 * @return a string representing the original string with the first 1713 * occurrences of the <code>oldSubs</code> strings replaced with the 1714 * corresponding <code>newSubs</code> strings, or <code>null</code> 1715 * if the original string, the <code>oldSubs</code> array, or the 1716 * <code>newSubs</code is <code>null</code> 1717 */ 1718 public static String replaceFirst( 1719 String s, String[] oldSubs, String[] newSubs) { 1720 1721 if ((s == null) || (oldSubs == null) || (newSubs == null)) { 1722 return null; 1723 } 1724 1725 if (oldSubs.length != newSubs.length) { 1726 return s; 1727 } 1728 1729 for (int i = 0; i < oldSubs.length; i++) { 1730 s = replaceFirst(s, oldSubs[i], newSubs[i]); 1731 } 1732 1733 return s; 1734 } 1735 1736 /** 1737 * Replaces the last occurrence of the character with the new character. 1738 * 1739 * @param s the original string 1740 * @param oldSub the character whose last occurrence in the original string 1741 * is to be searched for and replaced 1742 * @param newSub the character with which to replace the last occurrence of 1743 * the <code>oldSub</code> character 1744 * @return a string representing the original string except with the first 1745 * occurrence of the character <code>oldSub</code> replaced with the 1746 * character <code>newSub</code> 1747 */ 1748 public static String replaceLast(String s, char oldSub, char newSub) { 1749 if (s == null) { 1750 return null; 1751 } 1752 1753 return replaceLast(s, String.valueOf(oldSub), String.valueOf(newSub)); 1754 } 1755 1756 /** 1757 * Replaces the last occurrence of the character with the new string. 1758 * 1759 * @param s the original string 1760 * @param oldSub the character whose last occurrence in the original string 1761 * is to be searched for and replaced 1762 * @param newSub the string with which to replace the last occurrence of 1763 * the <code>oldSub</code> character 1764 * @return a string representing the original string except with the last 1765 * occurrence of the character <code>oldSub</code> replaced with the 1766 * string <code>newSub</code> 1767 */ 1768 public static String replaceLast(String s, char oldSub, String newSub) { 1769 if ((s == null) || (newSub == null)) { 1770 return null; 1771 } 1772 1773 return replaceLast(s, String.valueOf(oldSub), newSub); 1774 } 1775 1776 /** 1777 * Replaces the last occurrence of the string <code>oldSub</code> in the 1778 * string <code>s</code> with the string <code>newSub</code>. 1779 * 1780 * @param s the original string 1781 * @param oldSub the string whose last occurrence in the original string is 1782 * to be searched for and replaced 1783 * @param newSub the string with which to replace the last occurrence of 1784 * the <code>oldSub</code> string 1785 * @return a string representing the original string except with the last 1786 * occurrence of the string <code>oldSub</code> replaced with the 1787 * string <code>newSub</code> 1788 */ 1789 public static String replaceLast(String s, String oldSub, String newSub) { 1790 if ((s == null) || (oldSub == null) || (newSub == null)) { 1791 return null; 1792 } 1793 1794 if (oldSub.equals(newSub)) { 1795 return s; 1796 } 1797 1798 int y = s.lastIndexOf(oldSub); 1799 1800 if (y >= 0) { 1801 return s.substring(0, y).concat(newSub).concat( 1802 s.substring(y + oldSub.length())); 1803 } 1804 else { 1805 return s; 1806 } 1807 } 1808 1809 /** 1810 * Replaces the last occurrences of the elements of the string array with 1811 * the corresponding elements of the new string array. 1812 * 1813 * @param s the original string 1814 * @param oldSubs the strings whose last occurrences are to be searched for 1815 * and replaced in the original string 1816 * @param newSubs the strings with which to replace the last occurrences of 1817 * the <code>oldSubs</code> strings 1818 * @return a string representing the original string with the last 1819 * occurrences of the <code>oldSubs</code> strings replaced with the 1820 * corresponding <code>newSubs</code> strings, or <code>null</code> 1821 * if the original string, the <code>oldSubs</code> array, or the 1822 * <code>newSubs</code is <code>null</code> 1823 */ 1824 public static String replaceLast( 1825 String s, String[] oldSubs, String[] newSubs) { 1826 1827 if ((s == null) || (oldSubs == null) || (newSubs == null)) { 1828 return null; 1829 } 1830 1831 if (oldSubs.length != newSubs.length) { 1832 return s; 1833 } 1834 1835 for (int i = 0; i < oldSubs.length; i++) { 1836 s = replaceLast(s, oldSubs[i], newSubs[i]); 1837 } 1838 1839 return s; 1840 } 1841 1842 public static StringBundler replaceToStringBundler( 1843 String s, String begin, String end, Map<String, String> values) { 1844 1845 if ((s == null) || (begin == null) || (end == null) || 1846 (values == null) || (values.size() == 0)) { 1847 1848 return new StringBundler(s); 1849 } 1850 1851 StringBundler sb = new StringBundler(values.size() * 2 + 1); 1852 1853 int pos = 0; 1854 1855 while (true) { 1856 int x = s.indexOf(begin, pos); 1857 int y = s.indexOf(end, x + begin.length()); 1858 1859 if ((x == -1) || (y == -1)) { 1860 sb.append(s.substring(pos)); 1861 1862 break; 1863 } 1864 else { 1865 sb.append(s.substring(pos, x)); 1866 1867 String oldValue = s.substring(x + begin.length(), y); 1868 1869 String newValue = values.get(oldValue); 1870 1871 if (newValue == null) { 1872 newValue = oldValue; 1873 } 1874 1875 sb.append(newValue); 1876 1877 pos = y + end.length(); 1878 } 1879 } 1880 1881 return sb; 1882 } 1883 1884 public static StringBundler replaceWithStringBundler( 1885 String s, String begin, String end, Map<String, StringBundler> values) { 1886 1887 if ((s == null) || (begin == null) || (end == null) || 1888 (values == null) || (values.size() == 0)) { 1889 1890 return new StringBundler(s); 1891 } 1892 1893 int size = values.size() + 1; 1894 1895 for (StringBundler valueSB : values.values()) { 1896 size += valueSB.index(); 1897 } 1898 1899 StringBundler sb = new StringBundler(size); 1900 1901 int pos = 0; 1902 1903 while (true) { 1904 int x = s.indexOf(begin, pos); 1905 int y = s.indexOf(end, x + begin.length()); 1906 1907 if ((x == -1) || (y == -1)) { 1908 sb.append(s.substring(pos)); 1909 1910 break; 1911 } 1912 else { 1913 sb.append(s.substring(pos, x)); 1914 1915 String oldValue = s.substring(x + begin.length(), y); 1916 1917 StringBundler newValue = values.get(oldValue); 1918 1919 if (newValue == null) { 1920 sb.append(oldValue); 1921 } 1922 else { 1923 sb.append(newValue); 1924 } 1925 1926 pos = y + end.length(); 1927 } 1928 } 1929 1930 return sb; 1931 } 1932 1933 /** 1934 * Reverses the order of the characters of the string. 1935 * 1936 * @param s the original string 1937 * @return a string representing the original string with characters in 1938 * reverse order 1939 */ 1940 public static String reverse(String s) { 1941 if (s == null) { 1942 return null; 1943 } 1944 1945 char[] chars = s.toCharArray(); 1946 char[] reverse = new char[chars.length]; 1947 1948 for (int i = 0; i < chars.length; i++) { 1949 reverse[i] = chars[chars.length - i - 1]; 1950 } 1951 1952 return new String(reverse); 1953 } 1954 1955 /** 1956 * Replaces all double slashes of the string with single slashes. 1957 * 1958 * <p> 1959 * Example: 1960 * </p> 1961 * 1962 * <p> 1963 * <pre> 1964 * <code> 1965 * safePath("http://www.liferay.com") returns "http:/www.liferay.com" 1966 * </code> 1967 * </pre> 1968 * </p> 1969 * 1970 * @param path the original string 1971 * @return a string representing the original string with all double slashes 1972 * replaced with single slashes 1973 */ 1974 public static String safePath(String path) { 1975 return replace(path, StringPool.DOUBLE_SLASH, StringPool.SLASH); 1976 } 1977 1978 /** 1979 * Returns a string representing the original string appended with suffix 1980 * "..." and then shortened to 20 characters. 1981 * 1982 * <p> 1983 * The suffix is only added if the original string exceeds 20 characters. If 1984 * the original string exceeds 20 characters and it contains whitespace, the 1985 * string is shortened at the first whitespace character. 1986 * </p> 1987 * 1988 * <p> 1989 * Examples: 1990 * </p> 1991 * 1992 * <p> 1993 * <pre> 1994 * <code> 1995 * shorten("12345678901234567890xyz") returns "12345678901234567..." 1996 * shorten("1 345678901234567890xyz") returns "1..." 1997 * shorten(" 2345678901234567890xyz") returns "..." 1998 * shorten("12345678901234567890") returns "12345678901234567890" 1999 * shorten(" 2345678901234567890") returns " 2345678901234567890" 2000 * </code> 2001 * </pre> 2002 * </p> 2003 * 2004 * @param s the original string 2005 * @return a string representing the original string shortened to 20 2006 * characters, with suffix "..." appended to it 2007 */ 2008 public static String shorten(String s) { 2009 return shorten(s, 20); 2010 } 2011 2012 /** 2013 * Returns a string representing the original string appended with suffix 2014 * "..." and then shortened to the specified length. 2015 * 2016 * <p> 2017 * The suffix is only added if the original string exceeds the specified 2018 * length. If the original string exceeds the specified length and it 2019 * contains whitespace, the string is shortened at the first whitespace 2020 * character. 2021 * </p> 2022 * 2023 * <p> 2024 * Examples: 2025 * </p> 2026 * 2027 * <p> 2028 * <pre> 2029 * <code> 2030 * shorten("123456789", 8) returns "12345..." 2031 * shorten("1 3456789", 8) returns "1..." 2032 * shorten(" 23456789", 8) returns "..." 2033 * shorten("12345678", 8) returns "12345678" 2034 * shorten(" 1234567", 8) returns " 1234567" 2035 * </code> 2036 * </pre> 2037 * </p> 2038 * 2039 * @param s the original string 2040 * @param length the number of characters to limit from the original string 2041 * @return a string representing the original string shortened to the 2042 * specified length, with suffix "..." appended to it 2043 */ 2044 public static String shorten(String s, int length) { 2045 return shorten(s, length, "..."); 2046 } 2047 2048 /** 2049 * Returns a string representing the original string appended with the 2050 * specified suffix and then shortened to the specified length. 2051 * 2052 * <p> 2053 * The suffix is only added if the original string exceeds the specified 2054 * length. If the original string exceeds the specified length and it 2055 * contains whitespace, the string is shortened at the first whitespace 2056 * character. 2057 * </p> 2058 * 2059 * <p> 2060 * Examples: 2061 * </p> 2062 * 2063 * <p> 2064 * <pre> 2065 * <code> 2066 * shorten("12345678901234", 13, "... etc.") returns "12345... etc." 2067 * shorten("1 345678901234", 13, "... etc.") returns "1... etc." 2068 * shorten(" 2345678901234", 13, "... etc.") returns "... etc." 2069 * shorten("1234567890123", 13, "... etc.") returns "1234567890123" 2070 * shorten(" 123456789012", 13, "... etc.") returns " 123456789012" 2071 * </code> 2072 * </pre> 2073 * </p> 2074 * 2075 * @param s the original string 2076 * @param length the number of characters to limit from the original string 2077 * @param suffix the suffix to append 2078 * @return a string representing the original string shortened to the 2079 * specified length, with the specified suffix appended to it 2080 */ 2081 public static String shorten(String s, int length, String suffix) { 2082 if ((s == null) || (suffix == null)) { 2083 return null; 2084 } 2085 2086 if (s.length() <= length) { 2087 return s; 2088 } 2089 2090 if (length < suffix.length()) { 2091 return s.substring(0, length); 2092 } 2093 2094 int curLength = length; 2095 2096 for (int j = (curLength - suffix.length()); j >= 0; j--) { 2097 if (Character.isWhitespace(s.charAt(j))) { 2098 curLength = j; 2099 2100 break; 2101 } 2102 } 2103 2104 if (curLength == length) { 2105 curLength = length - suffix.length(); 2106 } 2107 2108 String temp = s.substring(0, curLength); 2109 2110 return temp.concat(suffix); 2111 } 2112 2113 /** 2114 * Returns a string representing the original string appended with the 2115 * specified suffix and then shortened to 20 characters. 2116 * 2117 * <p> 2118 * The suffix is only added if the original string exceeds 20 characters. If 2119 * the original string exceeds 20 characters and it contains whitespace, the 2120 * string is shortened at the first whitespace character. 2121 * </p> 2122 * 2123 * <p> 2124 * Examples: 2125 * </p> 2126 * 2127 * <p> 2128 * <pre> 2129 * <code> 2130 * shorten("12345678901234567890xyz", "... etc.") returns "123456789012... etc." 2131 * shorten("1 345678901234567890xyz", "... etc.") returns "1... etc." 2132 * shorten(" 2345678901234567890xyz", "... etc.") returns "... etc." 2133 * shorten("12345678901234567890", "... etc.") returns "12345678901234567890" 2134 * shorten(" 2345678901234567890", "... etc.") returns " 2345678901234567890" 2135 * </code> 2136 * </pre> 2137 * </p> 2138 * 2139 * @param s the original string 2140 * @param suffix the suffix to append 2141 * @return a string representing the original string shortened to 20 2142 * characters, with the specified suffix appended to it 2143 */ 2144 public static String shorten(String s, String suffix) { 2145 return shorten(s, 20, suffix); 2146 } 2147 2148 /** 2149 * Splits string <code>s</code> around comma characters. 2150 * 2151 * <p> 2152 * Example: 2153 * </p> 2154 * 2155 * <p> 2156 * <pre> 2157 * <code> 2158 * split("Alice,Bob,Charlie") returns {"Alice", "Bob", "Charlie"} 2159 * split("Alice, Bob, Charlie") returns {"Alice", " Bob", " Charlie"} 2160 * </code> 2161 * </pre> 2162 * </p> 2163 * 2164 * @param s the string to split 2165 * @return the array of strings resulting from splitting string 2166 * <code>s</code> around comma characters, or an empty string array 2167 * if <code>s</code> is <code>null</code> or <code>s</code> is empty 2168 */ 2169 public static String[] split(String s) { 2170 return split(s, CharPool.COMMA); 2171 } 2172 2173 /** 2174 * Splits the string <code>s</code> around comma characters returning the 2175 * boolean values of the substrings. 2176 * 2177 * @param s the string to split 2178 * @param x the default value to use for a substring in case an exception 2179 * occurs in getting the boolean value for that substring 2180 * @return the array of boolean values resulting from splitting string 2181 * <code>s</code> around comma characters, or an empty array if 2182 * <code>s</code> is <code>null</code> 2183 */ 2184 public static boolean[] split(String s, boolean x) { 2185 return split(s, StringPool.COMMA, x); 2186 } 2187 2188 /** 2189 * Splits the string <code>s</code> around the specified delimiter. 2190 * 2191 * <p> 2192 * Example: 2193 * </p> 2194 * 2195 * <p> 2196 * <pre> 2197 * <code> 2198 * splitLines("First;Second;Third", ';') returns {"First","Second","Third"} 2199 * </code> 2200 * </pre> 2201 * </p> 2202 * 2203 * @param s the string to split 2204 * @param delimiter the delimiter 2205 * @return the array of strings resulting from splitting string 2206 * <code>s</code> around the specified delimiter character, or an 2207 * empty string array if <code>s</code> is <code>null</code> or if 2208 * <code>s</code> is empty 2209 */ 2210 public static String[] split(String s, char delimiter) { 2211 if (Validator.isNull(s)) { 2212 return _emptyStringArray; 2213 } 2214 2215 s = s.trim(); 2216 2217 if (s.length() == 0) { 2218 return _emptyStringArray; 2219 } 2220 2221 if ((delimiter == CharPool.RETURN) || 2222 (delimiter == CharPool.NEW_LINE)) { 2223 2224 return splitLines(s); 2225 } 2226 2227 List<String> nodeValues = new ArrayList<String>(); 2228 2229 int offset = 0; 2230 int pos = s.indexOf(delimiter, offset); 2231 2232 while (pos != -1) { 2233 nodeValues.add(s.substring(offset, pos)); 2234 2235 offset = pos + 1; 2236 pos = s.indexOf(delimiter, offset); 2237 } 2238 2239 if (offset < s.length()) { 2240 nodeValues.add(s.substring(offset)); 2241 } 2242 2243 return nodeValues.toArray(new String[nodeValues.size()]); 2244 } 2245 2246 /** 2247 * Splits the string <code>s</code> around comma characters returning the 2248 * double-precision decimal values of the substrings. 2249 * 2250 * @param s the string to split 2251 * @param x the default value to use for a substring in case an exception 2252 * occurs in getting the double-precision decimal value for that 2253 * substring 2254 * @return the array of double-precision decimal values resulting from 2255 * splitting string <code>s</code> around comma characters, or an 2256 * empty array if <code>s</code> is <code>null</code> 2257 */ 2258 public static double[] split(String s, double x) { 2259 return split(s, StringPool.COMMA, x); 2260 } 2261 2262 /** 2263 * Splits the string <code>s</code> around comma characters returning the 2264 * decimal values of the substrings. 2265 * 2266 * @param s the string to split 2267 * @param x the default value to use for a substring in case an exception 2268 * occurs in getting the decimal value for that substring 2269 * @return the array of decimal values resulting from splitting string 2270 * <code>s</code> around comma characters, or an empty array if 2271 * <code>s</code> is <code>null</code> 2272 */ 2273 public static float[] split(String s, float x) { 2274 return split(s, StringPool.COMMA, x); 2275 } 2276 2277 /** 2278 * Splits the string <code>s</code> around comma characters returning the 2279 * integer values of the substrings. 2280 * 2281 * @param s the string to split 2282 * @param x the default value to use for a substring in case an exception 2283 * occurs in getting the integer value for that substring 2284 * @return the array of integer values resulting from splitting string 2285 * <code>s</code> around comma characters, or an empty array if 2286 * <code>s</code> is <code>null</code> 2287 */ 2288 public static int[] split(String s, int x) { 2289 return split(s, StringPool.COMMA, x); 2290 } 2291 2292 /** 2293 * Splits the string <code>s</code> around comma characters returning the 2294 * long integer values of the substrings. 2295 * 2296 * @param s the string to split 2297 * @param x the default value to use for a substring in case an exception 2298 * occurs in getting the long integer value for that substring 2299 * @return the array of long integer values resulting from splitting string 2300 * <code>s</code> around comma characters, or an empty array if 2301 * <code>s</code> is <code>null</code> 2302 */ 2303 public static long[] split(String s, long x) { 2304 return split(s, StringPool.COMMA, x); 2305 } 2306 2307 /** 2308 * Splits the string <code>s</code> around comma characters returning the 2309 * short integer values of the substrings. 2310 * 2311 * @param s the string to split 2312 * @param x the default value to use for a substring in case an exception 2313 * occurs in getting the short integer value for that substring 2314 * @return the array of short integer values resulting from splitting string 2315 * <code>s</code> around comma characters, or an empty array if 2316 * <code>s</code> is <code>null</code> 2317 */ 2318 public static short[] split(String s, short x) { 2319 return split(s, StringPool.COMMA, x); 2320 } 2321 2322 /** 2323 * Splits the string <code>s</code> around the specified delimiter string. 2324 * 2325 * <p> 2326 * Example: 2327 * </p> 2328 * 2329 * <p> 2330 * <pre> 2331 * <code> 2332 * splitLines("oneandtwoandthreeandfour", "and") returns {"one","two","three","four"} 2333 * </code> 2334 * </pre> 2335 * </p> 2336 * 2337 * @param s the string to split 2338 * @param delimiter the delimiter 2339 * @return the array of strings resulting from splitting string 2340 * <code>s</code> around the specified delimiter string, or an empty 2341 * string array if <code>s</code> is <code>null</code> or equals the 2342 * delimiter 2343 */ 2344 public static String[] split(String s, String delimiter) { 2345 if (Validator.isNull(s) || (delimiter == null) || 2346 delimiter.equals(StringPool.BLANK)) { 2347 2348 return _emptyStringArray; 2349 } 2350 2351 s = s.trim(); 2352 2353 if (s.equals(delimiter)) { 2354 return _emptyStringArray; 2355 } 2356 2357 if (delimiter.length() == 1) { 2358 return split(s, delimiter.charAt(0)); 2359 } 2360 2361 List<String> nodeValues = new ArrayList<String>(); 2362 2363 int offset = 0; 2364 int pos = s.indexOf(delimiter, offset); 2365 2366 while (pos != -1) { 2367 nodeValues.add(s.substring(offset, pos)); 2368 2369 offset = pos + delimiter.length(); 2370 pos = s.indexOf(delimiter, offset); 2371 } 2372 2373 if (offset < s.length()) { 2374 nodeValues.add(s.substring(offset)); 2375 } 2376 2377 return nodeValues.toArray(new String[nodeValues.size()]); 2378 } 2379 2380 /** 2381 * Splits the string <code>s</code> around the specified delimiter returning 2382 * the boolean values of the substrings. 2383 * 2384 * @param s the string to split 2385 * @param delimiter the delimiter 2386 * @param x the default value to use for a substring in case an exception 2387 * occurs in getting the boolean value for that substring 2388 * @return the array of booleans resulting from splitting string 2389 * <code>s</code> around the specified delimiter string, or an empty 2390 * array if <code>s</code> is <code>null</code> 2391 */ 2392 public static boolean[] split(String s, String delimiter, boolean x) { 2393 String[] array = split(s, delimiter); 2394 boolean[] newArray = new boolean[array.length]; 2395 2396 for (int i = 0; i < array.length; i++) { 2397 boolean value = x; 2398 2399 try { 2400 value = Boolean.valueOf(array[i]).booleanValue(); 2401 } 2402 catch (Exception e) { 2403 } 2404 2405 newArray[i] = value; 2406 } 2407 2408 return newArray; 2409 } 2410 2411 /** 2412 * Splits the string <code>s</code> around the specified delimiter returning 2413 * the double-precision decimal values of the substrings. 2414 * 2415 * @param s the string to split 2416 * @param delimiter the delimiter 2417 * @param x the default value to use for a substring in case an exception 2418 * occurs in getting the double-precision decimal value for that 2419 * substring 2420 * @return the array of double-precision decimal values resulting from 2421 * splitting string <code>s</code> around the specified delimiter 2422 * string, or an empty array if <code>s</code> is <code>null</code> 2423 */ 2424 public static double[] split(String s, String delimiter, double x) { 2425 String[] array = split(s, delimiter); 2426 double[] newArray = new double[array.length]; 2427 2428 for (int i = 0; i < array.length; i++) { 2429 double value = x; 2430 2431 try { 2432 value = Double.parseDouble(array[i]); 2433 } 2434 catch (Exception e) { 2435 } 2436 2437 newArray[i] = value; 2438 } 2439 2440 return newArray; 2441 } 2442 2443 /** 2444 * Splits the string <code>s</code> around the specified delimiter returning 2445 * the decimal values of the substrings. 2446 * 2447 * @param s the string to split 2448 * @param delimiter the delimiter 2449 * @param x the default value to use for a substring in case an exception 2450 * occurs in getting the decimal value for that substring 2451 * @return the array of decimal values resulting from splitting string 2452 * <code>s</code> around the specified delimiter string, or an empty 2453 * array if <code>s</code> is <code>null</code> 2454 */ 2455 public static float[] split(String s, String delimiter, float x) { 2456 String[] array = split(s, delimiter); 2457 float[] newArray = new float[array.length]; 2458 2459 for (int i = 0; i < array.length; i++) { 2460 float value = x; 2461 2462 try { 2463 value = Float.parseFloat(array[i]); 2464 } 2465 catch (Exception e) { 2466 } 2467 2468 newArray[i] = value; 2469 } 2470 2471 return newArray; 2472 } 2473 2474 /** 2475 * Splits the string <code>s</code> around the specified delimiter returning 2476 * the integer values of the substrings. 2477 * 2478 * @param s the string to split 2479 * @param delimiter the delimiter 2480 * @param x the default value to use for a substring in case an exception 2481 * occurs in getting the integer value for that substring 2482 * @return the array of integer values resulting from splitting string 2483 * <code>s</code> around the specified delimiter string, or an empty 2484 * array if <code>s</code> is <code>null</code> 2485 */ 2486 public static int[] split(String s, String delimiter, int x) { 2487 String[] array = split(s, delimiter); 2488 int[] newArray = new int[array.length]; 2489 2490 for (int i = 0; i < array.length; i++) { 2491 int value = x; 2492 2493 try { 2494 value = Integer.parseInt(array[i]); 2495 } 2496 catch (Exception e) { 2497 } 2498 2499 newArray[i] = value; 2500 } 2501 2502 return newArray; 2503 } 2504 2505 /** 2506 * Splits the string <code>s</code> around the specified delimiter returning 2507 * the long integer values of the substrings. 2508 * 2509 * @param s the string to split 2510 * @param delimiter the delimiter 2511 * @param x the default value to use for a substring in case an exception 2512 * occurs in getting the long integer value for that substring 2513 * @return the array of long integer values resulting from splitting string 2514 * <code>s</code> around the specified delimiter string, or an empty 2515 * array if <code>s</code> is <code>null</code> 2516 */ 2517 public static long[] split(String s, String delimiter, long x) { 2518 String[] array = split(s, delimiter); 2519 long[] newArray = new long[array.length]; 2520 2521 for (int i = 0; i < array.length; i++) { 2522 long value = x; 2523 2524 try { 2525 value = Long.parseLong(array[i]); 2526 } 2527 catch (Exception e) { 2528 } 2529 2530 newArray[i] = value; 2531 } 2532 2533 return newArray; 2534 } 2535 2536 /** 2537 * Splits the string <code>s</code> around the specified delimiter returning 2538 * the short integer values of the substrings. 2539 * 2540 * @param s the string to split 2541 * @param delimiter the delimiter 2542 * @param x the default value to use for a substring in case an exception 2543 * occurs in getting the short integer value for that substring 2544 * @return the array of short integer values resulting from splitting string 2545 * <code>s</code> around the specified delimiter string, or an empty 2546 * array if <code>s</code> is <code>null</code> 2547 */ 2548 public static short[] split(String s, String delimiter, short x) { 2549 String[] array = split(s, delimiter); 2550 short[] newArray = new short[array.length]; 2551 2552 for (int i = 0; i < array.length; i++) { 2553 short value = x; 2554 2555 try { 2556 value = Short.parseShort(array[i]); 2557 } 2558 catch (Exception e) { 2559 } 2560 2561 newArray[i] = value; 2562 } 2563 2564 return newArray; 2565 } 2566 2567 /** 2568 * Splits string <code>s</code> around return and newline characters. 2569 * 2570 * <p> 2571 * Example: 2572 * </p> 2573 * 2574 * <p> 2575 * <pre> 2576 * <code> 2577 * splitLines("Red\rBlue\nGreen") returns {"Red","Blue","Green"} 2578 * </code> 2579 * </pre> 2580 * </p> 2581 * 2582 * @param s the string to split 2583 * @return the array of strings resulting from splitting string 2584 * <code>s</code> around return and newline characters, or an empty 2585 * string array if string <code>s</code> is <code>null</code> 2586 */ 2587 public static String[] splitLines(String s) { 2588 if (Validator.isNull(s)) { 2589 return _emptyStringArray; 2590 } 2591 2592 s = s.trim(); 2593 2594 List<String> lines = new ArrayList<String>(); 2595 2596 int lastIndex = 0; 2597 2598 while (true) { 2599 int returnIndex = s.indexOf(CharPool.RETURN, lastIndex); 2600 int newLineIndex = s.indexOf(CharPool.NEW_LINE, lastIndex); 2601 2602 if ((returnIndex == -1) && (newLineIndex == -1)) { 2603 break; 2604 } 2605 2606 if (returnIndex == -1) { 2607 lines.add(s.substring(lastIndex, newLineIndex)); 2608 2609 lastIndex = newLineIndex + 1; 2610 } 2611 else if (newLineIndex == -1) { 2612 lines.add(s.substring(lastIndex, returnIndex)); 2613 2614 lastIndex = returnIndex + 1; 2615 } 2616 else if (newLineIndex < returnIndex) { 2617 lines.add(s.substring(lastIndex, newLineIndex)); 2618 2619 lastIndex = newLineIndex + 1; 2620 } 2621 else { 2622 lines.add(s.substring(lastIndex, returnIndex)); 2623 2624 lastIndex = returnIndex + 1; 2625 2626 if (lastIndex == newLineIndex) { 2627 lastIndex++; 2628 } 2629 } 2630 } 2631 2632 if (lastIndex < s.length()) { 2633 lines.add(s.substring(lastIndex)); 2634 } 2635 2636 return lines.toArray(new String[lines.size()]); 2637 } 2638 2639 /** 2640 * Returns <code>true</code> if, ignoring case, the string starts with the 2641 * specified character. 2642 * 2643 * @param s the string 2644 * @param begin the character against which the initial character of the 2645 * string is to be compared 2646 * @return <code>true</code> if, ignoring case, the string starts with the 2647 * specified character; <code>false</code> otherwise 2648 */ 2649 public static boolean startsWith(String s, char begin) { 2650 return startsWith(s, (new Character(begin)).toString()); 2651 } 2652 2653 /** 2654 * Returns <code>true</code> if, ignoring case, the string starts with the 2655 * specified start string. 2656 * 2657 * @param s the original string 2658 * @param start the string against which the beginning of string 2659 * <code>s</code> are to be compared 2660 * @return <code>true</code> if, ignoring case, the string starts with the 2661 * specified start string; <code>false</code> otherwise 2662 */ 2663 public static boolean startsWith(String s, String start) { 2664 if ((s == null) || (start == null)) { 2665 return false; 2666 } 2667 2668 if (start.length() > s.length()) { 2669 return false; 2670 } 2671 2672 String temp = s.substring(0, start.length()); 2673 2674 if (temp.equalsIgnoreCase(start)) { 2675 return true; 2676 } 2677 else { 2678 return false; 2679 } 2680 } 2681 2682 /** 2683 * Returns the number of starting characters that <code>s1</code> and 2684 * <code>s2</code> have in common before their characters deviate. 2685 * 2686 * @param s1 string 1 2687 * @param s2 string 2 2688 * @return the number of starting characters that <code>s1</code> and 2689 * <code>s2</code> have in common before their characters deviate 2690 */ 2691 public static int startsWithWeight(String s1, String s2) { 2692 if ((s1 == null) || (s2 == null)) { 2693 return 0; 2694 } 2695 2696 char[] chars1 = s1.toCharArray(); 2697 char[] chars2 = s2.toCharArray(); 2698 2699 int i = 0; 2700 2701 for (; (i < chars1.length) && (i < chars2.length); i++) { 2702 if (chars1[i] != chars2[i]) { 2703 break; 2704 } 2705 } 2706 2707 return i; 2708 } 2709 2710 /** 2711 * Returns a string representing the string <code>s</code> with all 2712 * occurrences of the specified character removed. 2713 * 2714 * <p> 2715 * Example: 2716 * </p> 2717 * 2718 * <p> 2719 * <pre> 2720 * <code> 2721 * strip("Mississipi", 'i') returns "Mssssp" 2722 * </code> 2723 * </pre> 2724 * </p> 2725 * 2726 * @param s the string from which to strip all occurrences the character 2727 * @param remove the character to strip from the string 2728 * @return a string representing the string <code>s</code> with all 2729 * occurrences of the specified character removed, or 2730 * <code>null</code> if <code>s</code> is <code>null</code> 2731 */ 2732 public static String strip(String s, char remove) { 2733 if (s == null) { 2734 return null; 2735 } 2736 2737 int x = s.indexOf(remove); 2738 2739 if (x < 0) { 2740 return s; 2741 } 2742 2743 int y = 0; 2744 2745 StringBundler sb = new StringBundler(s.length()); 2746 2747 while (x >= 0) { 2748 sb.append(s.subSequence(y, x)); 2749 2750 y = x + 1; 2751 2752 x = s.indexOf(remove, y); 2753 } 2754 2755 sb.append(s.substring(y)); 2756 2757 return sb.toString(); 2758 } 2759 2760 /** 2761 * Returns a string representing the combination of the substring of 2762 * <code>s</code> up to but not including the string <code>begin</code> 2763 * concatenated with the substring of <code>s</code> after but not including 2764 * the string <code>end</code>. 2765 * 2766 * <p> 2767 * Example: 2768 * <p> 2769 * 2770 * <p> 2771 * <pre> 2772 * <code> 2773 * stripBetween("One small step for man, one giant leap for mankind", "step", "giant ") returns "One small leap for mankind" 2774 * </code> 2775 * </pre> 2776 * </p> 2777 * 2778 * @param s the from which to strip a substring 2779 * @param begin the beginning characters of the substring to be removed 2780 * @param end the ending characters of the substring to be removed 2781 * @return a string representing the combination of the substring of 2782 * <code>s</code> up to but not including the string 2783 * <code>begin</code> concatenated with the substring of 2784 * <code>s</code> after but not including the string 2785 * <code>end</code>, or the original string if the value of 2786 * <code>s</code>, <code>begin</code>, or <code>end</code> are 2787 * <code>null</code> 2788 */ 2789 public static String stripBetween(String s, String begin, String end) { 2790 if ((s == null) || (begin == null) || (end == null)) { 2791 return s; 2792 } 2793 2794 StringBundler sb = new StringBundler(s.length()); 2795 2796 int pos = 0; 2797 2798 while (true) { 2799 int x = s.indexOf(begin, pos); 2800 int y = s.indexOf(end, x + begin.length()); 2801 2802 if ((x == -1) || (y == -1)) { 2803 sb.append(s.substring(pos)); 2804 2805 break; 2806 } 2807 else { 2808 sb.append(s.substring(pos, x)); 2809 2810 pos = y + end.length(); 2811 } 2812 } 2813 2814 return sb.toString(); 2815 } 2816 2817 /** 2818 * Returns a string representing the Unicode character codes of the 2819 * characters comprising the string <code>s</code>. 2820 * 2821 * <p> 2822 * Example: 2823 * </p> 2824 * 2825 * <p> 2826 * <pre> 2827 * <code> 2828 * toCharCode("a") returns "97" 2829 * toCharCode("b") returns "98" 2830 * toCharCode("c") returns "99" 2831 * toCharCode("What's for lunch?") returns "87104971163911532102111114321081171109910463" 2832 * </code> 2833 * </pre> 2834 * </p> 2835 * 2836 * @param s the string whose character codes are to be represented 2837 * @return a string representing the Unicode character codes of the 2838 * characters comprising the string <code>s</code> 2839 */ 2840 public static String toCharCode(String s) { 2841 StringBundler sb = new StringBundler(s.length()); 2842 2843 for (int i = 0; i < s.length(); i++) { 2844 sb.append(s.codePointAt(i)); 2845 } 2846 2847 return sb.toString(); 2848 } 2849 2850 public static String toHexString(int i) { 2851 char[] buffer = new char[8]; 2852 2853 int index = 8; 2854 2855 do { 2856 buffer[--index] = _HEX_DIGITS[i & 15]; 2857 2858 i >>>= 4; 2859 } 2860 while (i != 0); 2861 2862 return new String(buffer, index, 8 - index); 2863 } 2864 2865 public static String toHexString(long l) { 2866 char[] buffer = new char[16]; 2867 2868 int index = 16; 2869 2870 do { 2871 buffer[--index] = _HEX_DIGITS[(int) (l & 15)]; 2872 2873 l >>>= 4; 2874 } 2875 while (l != 0); 2876 2877 return new String(buffer, index, 16 - index); 2878 } 2879 2880 public static String toHexString(Object obj) { 2881 if (obj instanceof Integer) { 2882 return toHexString(((Integer)obj).intValue()); 2883 } 2884 else if (obj instanceof Long) { 2885 return toHexString(((Long)obj).longValue()); 2886 } 2887 else { 2888 return String.valueOf(obj); 2889 } 2890 } 2891 2892 /** 2893 * Trims all leading and trailing whitespace from the string. 2894 * 2895 * @param s the original string 2896 * @return a string representing the original string with all leading and 2897 * trailing whitespace removed 2898 */ 2899 public static String trim(String s) { 2900 if (s == null) { 2901 return null; 2902 } 2903 2904 if (s.length() == 0) { 2905 return s; 2906 } 2907 2908 int len = s.length(); 2909 2910 int x = len; 2911 2912 for (int i = 0; i < len; i++) { 2913 char c = s.charAt(i); 2914 2915 if (!Character.isWhitespace(c)) { 2916 x = i; 2917 2918 break; 2919 } 2920 } 2921 2922 if (x == len) { 2923 return StringPool.BLANK; 2924 } 2925 2926 int y = x + 1; 2927 2928 for (int i = len - 1; i > x; i--) { 2929 char c = s.charAt(i); 2930 2931 if (!Character.isWhitespace(c)) { 2932 y = i + 1; 2933 2934 break; 2935 } 2936 } 2937 2938 if ((x == 0) && (y == len)) { 2939 return s; 2940 } 2941 2942 return s.substring(x, y); 2943 } 2944 2945 /** 2946 * Trims leading and trailing whitespace from the string, up to but not 2947 * including the whitespace character specified by <code>c</code>. 2948 * 2949 * <p> 2950 * Examples: 2951 * </p> 2952 * 2953 * <p> 2954 * <pre> 2955 * <code> 2956 * trim(" \tHey\t ", '\t') returns "\tHey\t" 2957 * trim(" \t Hey \t ", '\t') returns "\t Hey \t" 2958 * </code> 2959 * </pre> 2960 * </p> 2961 * 2962 * @param s the original string 2963 * @param c the whitespace character to limit trimming 2964 * @return a string representing the original string with leading and 2965 * trailing whitespace removed, up to but not including the 2966 * whitespace character specified by <code>c</code> 2967 */ 2968 public static String trim(String s, char c) { 2969 return trim(s, new char[] {c}); 2970 } 2971 2972 /** 2973 * Trims leading and trailing whitespace from the string, up to but not 2974 * including the whitespace characters specified by <code>exceptions</code>. 2975 * 2976 * @param s the original string 2977 * @param exceptions the whitespace characters to limit trimming 2978 * @return a string representing the original string with leading and 2979 * trailing whitespace removed, up to but not including the 2980 * whitespace characters specified by <code>exceptions</code> 2981 */ 2982 public static String trim(String s, char[] exceptions) { 2983 if (s == null) { 2984 return null; 2985 } 2986 2987 if (s.length() == 0) { 2988 return s; 2989 } 2990 2991 if ((exceptions == null) || (exceptions.length == 0)) { 2992 return trim(s); 2993 } 2994 2995 int len = s.length(); 2996 int x = len; 2997 2998 for (int i = 0; i < len; i++) { 2999 char c = s.charAt(i); 3000 3001 if (!_isTrimable(c, exceptions)) { 3002 x = i; 3003 3004 break; 3005 } 3006 } 3007 3008 if (x == len) { 3009 return StringPool.BLANK; 3010 } 3011 3012 int y = x + 1; 3013 3014 for (int i = len - 1; i > x; i--) { 3015 char c = s.charAt(i); 3016 3017 if (!_isTrimable(c, exceptions)) { 3018 y = i + 1; 3019 3020 break; 3021 } 3022 } 3023 3024 if ((x == 0) && (y == len)) { 3025 return s; 3026 } 3027 else { 3028 return s.substring(x, y); 3029 } 3030 } 3031 3032 /** 3033 * Trims all leading whitespace from the string. 3034 * 3035 * @param s the original string 3036 * @return a string representing the original string with all leading 3037 * whitespace removed 3038 */ 3039 public static String trimLeading(String s) { 3040 if (s == null) { 3041 return null; 3042 } 3043 3044 if (s.length() == 0) { 3045 return s; 3046 } 3047 3048 int len = s.length(); 3049 int x = len; 3050 3051 for (int i = 0; i < len; i++) { 3052 char c = s.charAt(i); 3053 3054 if (!Character.isWhitespace(c)) { 3055 x = i; 3056 3057 break; 3058 } 3059 } 3060 3061 if (x == len) { 3062 return StringPool.BLANK; 3063 } 3064 else if (x == 0) { 3065 return s; 3066 } 3067 else { 3068 return s.substring(x); 3069 } 3070 } 3071 3072 /** 3073 * Trims leading whitespace from the string, up to but not including the 3074 * whitespace character specified by <code>c</code>. 3075 * 3076 * @param s the original string 3077 * @param c the whitespace character to limit trimming 3078 * @return a string representing the original string with leading whitespace 3079 * removed, up to but not including the whitespace character 3080 * specified by <code>c</code> 3081 */ 3082 public static String trimLeading(String s, char c) { 3083 return trimLeading(s, new char[] {c}); 3084 } 3085 3086 /** 3087 * Trims leading whitespace from the string, up to but not including the 3088 * whitespace characters specified by <code>exceptions</code>. 3089 * 3090 * @param s the original string 3091 * @param exceptions the whitespace characters to limit trimming 3092 * @return a string representing the original string with leading whitespace 3093 * removed, up to but not including the whitespace characters 3094 * specified by <code>exceptions</code> 3095 */ 3096 public static String trimLeading(String s, char[] exceptions) { 3097 if (s == null) { 3098 return null; 3099 } 3100 3101 if (s.length() == 0) { 3102 return s; 3103 } 3104 3105 if ((exceptions == null) || (exceptions.length == 0)) { 3106 return trimLeading(s); 3107 } 3108 3109 int len = s.length(); 3110 int x = len; 3111 3112 for (int i = 0; i < len; i++) { 3113 char c = s.charAt(i); 3114 3115 if (!_isTrimable(c, exceptions)) { 3116 x = i; 3117 3118 break; 3119 } 3120 } 3121 3122 if (x == len) { 3123 return StringPool.BLANK; 3124 } 3125 else if (x == 0) { 3126 return s; 3127 } 3128 else { 3129 return s.substring(x); 3130 } 3131 } 3132 3133 /** 3134 * Trims all trailing whitespace from the string. 3135 * 3136 * @param s the original string 3137 * @return a string representing the original string with all trailing 3138 * whitespace removed 3139 */ 3140 public static String trimTrailing(String s) { 3141 if (s == null) { 3142 return null; 3143 } 3144 3145 if (s.length() == 0) { 3146 return s; 3147 } 3148 3149 int len = s.length(); 3150 int x = 0; 3151 3152 for (int i = len - 1; i >= 0; i--) { 3153 char c = s.charAt(i); 3154 3155 if (!Character.isWhitespace(c)) { 3156 x = i + 1; 3157 3158 break; 3159 } 3160 } 3161 3162 if (x == 0) { 3163 return StringPool.BLANK; 3164 } 3165 else if (x == len) { 3166 return s; 3167 } 3168 else { 3169 return s.substring(0, x); 3170 } 3171 } 3172 3173 /** 3174 * Trims trailing whitespace from the string, up to but not including the 3175 * whitespace character specified by <code>c</code>. 3176 * 3177 * @param s the original string 3178 * @param c the whitespace character to limit trimming 3179 * @return a string representing the original string with trailing 3180 * whitespace removed, up to but not including the whitespace 3181 * character specified by <code>c</code> 3182 */ 3183 public static String trimTrailing(String s, char c) { 3184 return trimTrailing(s, new char[] {c}); 3185 } 3186 3187 /** 3188 * Trims trailing whitespace from the string, up to but not including the 3189 * whitespace characters specified by <code>exceptions</code>. 3190 * 3191 * @param s the original string 3192 * @param exceptions the whitespace characters to limit trimming 3193 * @return a string representing the original string with trailing 3194 * whitespace removed, up to but not including the whitespace 3195 * characters specified by <code>exceptions</code> 3196 */ 3197 public static String trimTrailing(String s, char[] exceptions) { 3198 if (s == null) { 3199 return null; 3200 } 3201 3202 if (s.length() == 0) { 3203 return s; 3204 } 3205 3206 if ((exceptions == null) || (exceptions.length == 0)) { 3207 return trimTrailing(s); 3208 } 3209 3210 int len = s.length(); 3211 int x = 0; 3212 3213 for (int i = len - 1; i >= 0; i--) { 3214 char c = s.charAt(i); 3215 3216 if (!_isTrimable(c, exceptions)) { 3217 x = i + 1; 3218 3219 break; 3220 } 3221 } 3222 3223 if (x == 0) { 3224 return StringPool.BLANK; 3225 } 3226 else if (x == len) { 3227 return s; 3228 } 3229 else { 3230 return s.substring(0, x); 3231 } 3232 } 3233 3234 /** 3235 * Removes leading and trailing double and single quotation marks from the 3236 * string. 3237 * 3238 * @param s the original string 3239 * @return a string representing the original string with leading and 3240 * trailing double and single quotation marks removed, or the 3241 * original string if the original string is a <code>null</code> or 3242 * empty 3243 */ 3244 public static String unquote(String s) { 3245 if (Validator.isNull(s)) { 3246 return s; 3247 } 3248 3249 if ((s.charAt(0) == CharPool.APOSTROPHE) && 3250 (s.charAt(s.length() - 1) == CharPool.APOSTROPHE)) { 3251 3252 return s.substring(1, s.length() - 1); 3253 } 3254 else if ((s.charAt(0) == CharPool.QUOTE) && 3255 (s.charAt(s.length() - 1) == CharPool.QUOTE)) { 3256 3257 return s.substring(1, s.length() - 1); 3258 } 3259 3260 return s; 3261 } 3262 3263 /** 3264 * Converts all of the characters in the string to upper case. 3265 * 3266 * @param s the string to convert 3267 * @return the string, converted to upper-case, or <code>null</code> if the 3268 * string is <code>null</code> 3269 * @see String#toUpperCase() 3270 */ 3271 public static String upperCase(String s) { 3272 if (s == null) { 3273 return null; 3274 } 3275 else { 3276 return s.toUpperCase(); 3277 } 3278 } 3279 3280 /** 3281 * Converts the first character of the string to upper case. 3282 * 3283 * @param s the string whose first character is to be converted 3284 * @return the string, with its first character converted to upper-case 3285 */ 3286 public static String upperCaseFirstLetter(String s) { 3287 char[] chars = s.toCharArray(); 3288 3289 if ((chars[0] >= 97) && (chars[0] <= 122)) { 3290 chars[0] = (char)(chars[0] - 32); 3291 } 3292 3293 return new String(chars); 3294 } 3295 3296 /** 3297 * Returns the string value of the object. 3298 * 3299 * @param obj the object whose string value is to be returned 3300 * @return the string value of the object 3301 * @see String#valueOf(Object obj) 3302 */ 3303 public static String valueOf(Object obj) { 3304 return String.valueOf(obj); 3305 } 3306 3307 public static String wrap(String text) { 3308 return wrap(text, 80, StringPool.NEW_LINE); 3309 } 3310 3311 public static String wrap(String text, int width, String lineSeparator) { 3312 try { 3313 return _wrap(text, width, lineSeparator); 3314 } 3315 catch (IOException ioe) { 3316 _log.error(ioe.getMessage()); 3317 3318 return text; 3319 } 3320 } 3321 3322 private static String _highlight( 3323 String s, Pattern pattern, String highlight1, String highlight2) { 3324 3325 StringTokenizer st = new StringTokenizer(s); 3326 3327 if (st.countTokens() == 0) { 3328 return StringPool.BLANK; 3329 } 3330 3331 StringBundler sb = new StringBundler(2 * st.countTokens() - 1); 3332 3333 while (st.hasMoreTokens()) { 3334 String token = st.nextToken(); 3335 3336 Matcher matcher = pattern.matcher(token); 3337 3338 if (matcher.find()) { 3339 StringBuffer hightlighted = new StringBuffer(); 3340 3341 do { 3342 matcher.appendReplacement( 3343 hightlighted, highlight1 + matcher.group() + 3344 highlight2); 3345 } 3346 while (matcher.find()); 3347 3348 matcher.appendTail(hightlighted); 3349 3350 sb.append(hightlighted); 3351 } 3352 else { 3353 sb.append(token); 3354 } 3355 3356 if (st.hasMoreTokens()) { 3357 sb.append(StringPool.SPACE); 3358 } 3359 } 3360 3361 return sb.toString(); 3362 } 3363 3364 /** 3365 * Returns <code>false</code> if the character is not whitespace or is equal 3366 * to any of the exception characters. 3367 * 3368 * @param c the character whose trim-ability is to be determined 3369 * @param exceptions the whitespace characters to exclude from trimming 3370 * @return <code>false</code> if the character is not whitespace or is equal 3371 * to any of the exception characters; <code>true</code> otherwise 3372 */ 3373 private static boolean _isTrimable(char c, char[] exceptions) { 3374 for (char exception : exceptions) { 3375 if (c == exception) { 3376 return false; 3377 } 3378 } 3379 3380 return Character.isWhitespace(c); 3381 } 3382 3383 private static String _wrap(String text, int width, String lineSeparator) 3384 throws IOException { 3385 3386 if (text == null) { 3387 return null; 3388 } 3389 3390 StringBundler sb = new StringBundler(); 3391 3392 UnsyncBufferedReader unsyncBufferedReader = new UnsyncBufferedReader( 3393 new UnsyncStringReader(text)); 3394 3395 String s = StringPool.BLANK; 3396 3397 while ((s = unsyncBufferedReader.readLine()) != null) { 3398 if (s.length() == 0) { 3399 sb.append(lineSeparator); 3400 3401 continue; 3402 } 3403 3404 int lineLength = 0; 3405 3406 String[] tokens = s.split(StringPool.SPACE); 3407 3408 for (String token : tokens) { 3409 if ((lineLength + token.length() + 1) > width) { 3410 if (lineLength > 0) { 3411 sb.append(lineSeparator); 3412 } 3413 3414 if (token.length() > width) { 3415 int pos = token.indexOf(CharPool.OPEN_PARENTHESIS); 3416 3417 if (pos != -1) { 3418 sb.append(token.substring(0, pos + 1)); 3419 sb.append(lineSeparator); 3420 3421 token = token.substring(pos + 1); 3422 3423 sb.append(token); 3424 3425 lineLength = token.length(); 3426 } 3427 else { 3428 sb.append(token); 3429 3430 lineLength = token.length(); 3431 } 3432 } 3433 else { 3434 sb.append(token); 3435 3436 lineLength = token.length(); 3437 } 3438 } 3439 else { 3440 if (lineLength > 0) { 3441 sb.append(StringPool.SPACE); 3442 3443 lineLength++; 3444 } 3445 3446 sb.append(token); 3447 3448 lineLength += token.length(); 3449 } 3450 } 3451 3452 sb.append(lineSeparator); 3453 } 3454 3455 return sb.toString(); 3456 } 3457 3458 private static final char[] _HEX_DIGITS = { 3459 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 3460 'e', 'f' 3461 }; 3462 3463 private static Log _log = LogFactoryUtil.getLog(StringUtil.class); 3464 3465 private static String[] _emptyStringArray = new String[0]; 3466 3467 }