1 /* ==================================================================== 2 * The Apache Software License, Version 1.1 3 * 4 * Copyright (c) 2002 The Apache Software Foundation. All rights 5 * reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 19 * 3. The end-user documentation included with the redistribution, if 20 * any, must include the following acknowlegement: 21 * "This product includes software developed by the 22 * Apache Software Foundation (http://www.apache.org/)." 23 * Alternately, this acknowlegement may appear in the software itself, 24 * if and wherever such third-party acknowlegements normally appear. 25 * 26 * 4. The names "The Jakarta Project", "Commons", and "Apache Software 27 * Foundation" must not be used to endorse or promote products derived 28 * from this software without prior written permission. For written 29 * permission, please contact apache@apache.org. 30 * 31 * 5. Products derived from this software may not be called "Apache" 32 * nor may "Apache" appear in their names without prior written 33 * permission of the Apache Software Foundation. 34 * 35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 46 * SUCH DAMAGE. 47 * ==================================================================== 48 * 49 * This software consists of voluntary contributions made by many 50 * individuals on behalf of the Apache Software Foundation. For more 51 * information on the Apache Software Foundation, please see 52 * <http://www.apache.org/>. 53 */ 54 package org.apache.maven.it.util; 55 56 import java.util.Iterator; 57 import java.util.Map; 58 import java.util.StringTokenizer; 59 60 /** 61 * <p>Common <code>String</code> manipulation routines.</p> 62 * 63 * <p>Originally from 64 * <a href="http://jakarta.apache.org/turbine/">Turbine</a> and the 65 * GenerationJavaCore library.</p> 66 * 67 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> 68 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> 69 * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a> 70 * @author <a href="mailto:bayard@generationjava.com">Henri Yandell</a> 71 * @author <a href="mailto:ed@apache.org">Ed Korthof</a> 72 * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a> 73 * @author Stephen Colebourne 74 * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a> 75 * @author Holger Krauth 76 * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a> 77 * @since 1.0 78 * @version $Id: StringUtils.java 661727 2008-05-30 14:21:49Z bentmann $ 79 */ 80 public class StringUtils 81 { 82 83 /** 84 * <p><code>StringUtils</code> instances should NOT be constructed in 85 * standard programming. Instead, the class should be used as 86 * <code>StringUtils.trim(" foo ");</code>.</p> 87 * 88 * <p>This constructor is public to permit tools that require a JavaBean 89 * manager to operate.</p> 90 */ 91 public StringUtils() 92 { 93 } 94 95 // Empty 96 //-------------------------------------------------------------------------- 97 98 /** 99 * <p>Removes control characters, including whitespace, from both 100 * ends of this String, handling <code>null</code> by returning 101 * an empty String.</p> 102 * 103 * @see java.lang.String#trim() 104 * @param str the String to check 105 * @return the trimmed text (never <code>null</code>) 106 */ 107 public static String clean( String str ) 108 { 109 return ( str == null ? "" : str.trim() ); 110 } 111 112 /** 113 * <p>Removes control characters, including whitespace, from both 114 * ends of this String, handling <code>null</code> by returning 115 * <code>null</code>.</p> 116 * 117 * @see java.lang.String#trim() 118 * @param str the String to check 119 * @return the trimmed text (or <code>null</code>) 120 */ 121 public static String trim( String str ) 122 { 123 return ( str == null ? null : str.trim() ); 124 } 125 126 /** 127 * <p>Deletes all whitespaces from a String.</p> 128 * 129 * <p>Whitespace is defined by 130 * {@link Character#isWhitespace(char)}.</p> 131 * 132 * @param str String target to delete whitespace from 133 * @return the String without whitespaces 134 * @throws NullPointerException 135 */ 136 public static String deleteWhitespace( String str ) 137 { 138 StringBuffer buffer = new StringBuffer(); 139 int sz = str.length(); 140 for ( int i = 0; i < sz; i++ ) 141 { 142 if ( !Character.isWhitespace( str.charAt( i ) ) ) 143 { 144 buffer.append( str.charAt( i ) ); 145 } 146 } 147 return buffer.toString(); 148 } 149 150 /** 151 * <p>Checks if a String is non <code>null</code> and is 152 * not empty (<code>length > 0</code>).</p> 153 * 154 * @param str the String to check 155 * @return true if the String is non-null, and not length zero 156 */ 157 public static boolean isNotEmpty( String str ) 158 { 159 return ( str != null && str.length() > 0 ); 160 } 161 162 /** 163 * <p>Checks if a (trimmed) String is <code>null</code> or empty.</p> 164 * 165 * @param str the String to check 166 * @return <code>true</code> if the String is <code>null</code>, or 167 * length zero once trimmed 168 */ 169 public static boolean isEmpty( String str ) 170 { 171 return ( str == null || str.trim().length() == 0 ); 172 } 173 174 // Equals and IndexOf 175 //-------------------------------------------------------------------------- 176 177 /** 178 * <p>Compares two Strings, returning <code>true</code> if they are equal.</p> 179 * 180 * <p><code>null</code>s are handled without exceptions. Two <code>null</code> 181 * references are considered to be equal. The comparison is case sensitive.</p> 182 * 183 * @see java.lang.String#equals(Object) 184 * @param str1 the first string 185 * @param str2 the second string 186 * @return <code>true</code> if the Strings are equal, case sensitive, or 187 * both <code>null</code> 188 */ 189 public static boolean equals( String str1, String str2 ) 190 { 191 return ( str1 == null ? str2 == null : str1.equals( str2 ) ); 192 } 193 194 /** 195 * <p>Compares two Strings, returning <code>true</code> if they are equal ignoring 196 * the case.</p> 197 * 198 * <p><code>Nulls</code> are handled without exceptions. Two <code>null</code> 199 * references are considered equal. Comparison is case insensitive.</p> 200 * 201 * @see java.lang.String#equalsIgnoreCase(String) 202 * @param str1 the first string 203 * @param str2 the second string 204 * @return <code>true</code> if the Strings are equal, case insensitive, or 205 * both <code>null</code> 206 */ 207 public static boolean equalsIgnoreCase( String str1, String str2 ) 208 { 209 return ( str1 == null ? str2 == null : str1.equalsIgnoreCase( str2 ) ); 210 } 211 212 /** 213 * <p>Find the first index of any of a set of potential substrings.</p> 214 * 215 * <p><code>null</code> String will return <code>-1</code>.</p> 216 * 217 * @param str the String to check 218 * @param searchStrs the Strings to search for 219 * @return the first index of any of the searchStrs in str 220 * @throws NullPointerException if any of searchStrs[i] is <code>null</code> 221 */ 222 public static int indexOfAny( String str, String[] searchStrs ) 223 { 224 if ( ( str == null ) || ( searchStrs == null ) ) 225 { 226 return -1; 227 } 228 int sz = searchStrs.length; 229 230 // String's can't have a MAX_VALUEth index. 231 int ret = Integer.MAX_VALUE; 232 233 int tmp = 0; 234 for ( int i = 0; i < sz; i++ ) 235 { 236 tmp = str.indexOf( searchStrs[i] ); 237 if ( tmp == -1 ) 238 { 239 continue; 240 } 241 242 if ( tmp < ret ) 243 { 244 ret = tmp; 245 } 246 } 247 248 return ( ret == Integer.MAX_VALUE ) ? -1 : ret; 249 } 250 251 /** 252 * <p>Find the latest index of any of a set of potential substrings.</p> 253 * 254 * <p><code>null</code> string will return <code>-1</code>.</p> 255 * 256 * @param str the String to check 257 * @param searchStrs the Strings to search for 258 * @return the last index of any of the Strings 259 * @throws NullPointerException if any of searchStrs[i] is <code>null</code> 260 */ 261 public static int lastIndexOfAny( String str, String[] searchStrs ) 262 { 263 if ( ( str == null ) || ( searchStrs == null ) ) 264 { 265 return -1; 266 } 267 int sz = searchStrs.length; 268 int ret = -1; 269 int tmp = 0; 270 for ( int i = 0; i < sz; i++ ) 271 { 272 tmp = str.lastIndexOf( searchStrs[i] ); 273 if ( tmp > ret ) 274 { 275 ret = tmp; 276 } 277 } 278 return ret; 279 } 280 281 // Substring 282 //-------------------------------------------------------------------------- 283 284 /** 285 * <p>Gets a substring from the specified string avoiding exceptions.</p> 286 * 287 * <p>A negative start position can be used to start <code>n</code> 288 * characters from the end of the String.</p> 289 * 290 * @param str the String to get the substring from 291 * @param start the position to start from, negative means 292 * count back from the end of the String by this many characters 293 * @return substring from start position 294 */ 295 public static String substring( String str, int start ) 296 { 297 if ( str == null ) 298 { 299 return null; 300 } 301 302 // handle negatives, which means last n characters 303 if ( start < 0 ) 304 { 305 start = str.length() + start; // remember start is negative 306 } 307 308 if ( start < 0 ) 309 { 310 start = 0; 311 } 312 if ( start > str.length() ) 313 { 314 return ""; 315 } 316 317 return str.substring( start ); 318 } 319 320 /** 321 * <p>Gets a substring from the specified String avoiding exceptions.</p> 322 * 323 * <p>A negative start position can be used to start/end <code>n</code> 324 * characters from the end of the String.</p> 325 * 326 * @param str the String to get the substring from 327 * @param start the position to start from, negative means 328 * count back from the end of the string by this many characters 329 * @param end the position to end at (exclusive), negative means 330 * count back from the end of the String by this many characters 331 * @return substring from start position to end positon 332 */ 333 public static String substring( String str, int start, int end ) 334 { 335 if ( str == null ) 336 { 337 return null; 338 } 339 340 // handle negatives 341 if ( end < 0 ) 342 { 343 end = str.length() + end; // remember end is negative 344 } 345 if ( start < 0 ) 346 { 347 start = str.length() + start; // remember start is negative 348 } 349 350 // check length next 351 if ( end > str.length() ) 352 { 353 // check this works. 354 end = str.length(); 355 } 356 357 // if start is greater than end, return "" 358 if ( start > end ) 359 { 360 return ""; 361 } 362 363 if ( start < 0 ) 364 { 365 start = 0; 366 } 367 if ( end < 0 ) 368 { 369 end = 0; 370 } 371 372 return str.substring( start, end ); 373 } 374 375 /** 376 * <p>Gets the leftmost <code>n</code> characters of a String.</p> 377 * 378 * <p>If <code>n</code> characters are not available, or the 379 * String is <code>null</code>, the String will be returned without 380 * an exception.</p> 381 * 382 * @param str the String to get the leftmost characters from 383 * @param len the length of the required String 384 * @return the leftmost characters 385 * @throws IllegalArgumentException if len is less than zero 386 */ 387 public static String left( String str, int len ) 388 { 389 if ( len < 0 ) 390 { 391 throw new IllegalArgumentException( "Requested String length " + len + " is less than zero" ); 392 } 393 if ( ( str == null ) || ( str.length() <= len ) ) 394 { 395 return str; 396 } 397 else 398 { 399 return str.substring( 0, len ); 400 } 401 } 402 403 /** 404 * <p>Gets the rightmost <code>n</code> characters of a String.</p> 405 * 406 * <p>If <code>n</code> characters are not available, or the String 407 * is <code>null</code>, the String will be returned without an 408 * exception.</p> 409 * 410 * @param str the String to get the rightmost characters from 411 * @param len the length of the required String 412 * @return the leftmost characters 413 * @throws IllegalArgumentException if len is less than zero 414 */ 415 public static String right( String str, int len ) 416 { 417 if ( len < 0 ) 418 { 419 throw new IllegalArgumentException( "Requested String length " + len + " is less than zero" ); 420 } 421 if ( ( str == null ) || ( str.length() <= len ) ) 422 { 423 return str; 424 } 425 else 426 { 427 return str.substring( str.length() - len ); 428 } 429 } 430 431 /** 432 * <p>Gets <code>n</code> characters from the middle of a String.</p> 433 * 434 * <p>If <code>n</code> characters are not available, the remainder 435 * of the String will be returned without an exception. If the 436 * String is <code>null</code>, <code>null</code> will be returned.</p> 437 * 438 * @param str the String to get the characters from 439 * @param pos the position to start from 440 * @param len the length of the required String 441 * @return the leftmost characters 442 * @throws IndexOutOfBoundsException if pos is out of bounds 443 * @throws IllegalArgumentException if len is less than zero 444 */ 445 public static String mid( String str, int pos, int len ) 446 { 447 if ( ( pos < 0 ) || 448 ( str != null && pos > str.length() ) ) 449 { 450 throw new StringIndexOutOfBoundsException( "String index " + pos + " is out of bounds" ); 451 } 452 if ( len < 0 ) 453 { 454 throw new IllegalArgumentException( "Requested String length " + len + " is less than zero" ); 455 } 456 if ( str == null ) 457 { 458 return null; 459 } 460 if ( str.length() <= ( pos + len ) ) 461 { 462 return str.substring( pos ); 463 } 464 else 465 { 466 return str.substring( pos, pos + len ); 467 } 468 } 469 470 // Splitting 471 //-------------------------------------------------------------------------- 472 473 /** 474 * <p>Splits the provided text into a array, using whitespace as the 475 * separator.</p> 476 * 477 * <p>The separator is not included in the returned String array.</p> 478 * 479 * @param str the String to parse 480 * @return an array of parsed Strings 481 */ 482 public static String[] split( String str ) 483 { 484 return split( str, null, -1 ); 485 } 486 487 /** 488 * @see #split(String, String, int) 489 */ 490 public static String[] split( String text, String separator ) 491 { 492 return split( text, separator, -1 ); 493 } 494 495 /** 496 * <p>Splits the provided text into a array, based on a given separator.</p> 497 * 498 * <p>The separator is not included in the returned String array. The 499 * maximum number of splits to perfom can be controlled. A <code>null</code> 500 * separator will cause parsing to be on whitespace.</p> 501 * 502 * <p>This is useful for quickly splitting a String directly into 503 * an array of tokens, instead of an enumeration of tokens (as 504 * <code>StringTokenizer</code> does).</p> 505 * 506 * @param str The string to parse. 507 * @param separator Characters used as the delimiters. If 508 * <code>null</code>, splits on whitespace. 509 * @param max The maximum number of elements to include in the 510 * array. A zero or negative value implies no limit. 511 * @return an array of parsed Strings 512 */ 513 public static String[] split( String str, String separator, int max ) 514 { 515 StringTokenizer tok = null; 516 if ( separator == null ) 517 { 518 // Null separator means we're using StringTokenizer's default 519 // delimiter, which comprises all whitespace characters. 520 tok = new StringTokenizer( str ); 521 } 522 else 523 { 524 tok = new StringTokenizer( str, separator ); 525 } 526 527 int listSize = tok.countTokens(); 528 if ( max > 0 && listSize > max ) 529 { 530 listSize = max; 531 } 532 533 String[] list = new String[listSize]; 534 int i = 0; 535 int lastTokenBegin = 0; 536 int lastTokenEnd = 0; 537 while ( tok.hasMoreTokens() ) 538 { 539 if ( max > 0 && i == listSize - 1 ) 540 { 541 // In the situation where we hit the max yet have 542 // tokens left over in our input, the last list 543 // element gets all remaining text. 544 String endToken = tok.nextToken(); 545 lastTokenBegin = str.indexOf( endToken, lastTokenEnd ); 546 list[i] = str.substring( lastTokenBegin ); 547 break; 548 } 549 else 550 { 551 list[i] = tok.nextToken(); 552 lastTokenBegin = str.indexOf( list[i], lastTokenEnd ); 553 lastTokenEnd = lastTokenBegin + list[i].length(); 554 } 555 i++; 556 } 557 return list; 558 } 559 560 // Joining 561 //-------------------------------------------------------------------------- 562 /** 563 * <p>Concatenates elements of an array into a single String.</p> 564 * 565 * <p>The difference from join is that concatenate has no delimiter.</p> 566 * 567 * @param array the array of values to concatenate. 568 * @return the concatenated string. 569 */ 570 public static String concatenate( Object[] array ) 571 { 572 return join( array, "" ); 573 } 574 575 /** 576 * <p>Joins the elements of the provided array into a single String 577 * containing the provided list of elements.</p> 578 * 579 * <p>No delimiter is added before or after the list. A 580 * <code>null</code> separator is the same as a blank String.</p> 581 * 582 * @param array the array of values to join together 583 * @param separator the separator character to use 584 * @return the joined String 585 */ 586 public static String join( Object[] array, String separator ) 587 { 588 if ( separator == null ) 589 { 590 separator = ""; 591 } 592 int arraySize = array.length; 593 int bufSize = ( arraySize == 0 ? 0 : ( array[0].toString().length() + 594 separator.length() ) * arraySize ); 595 StringBuffer buf = new StringBuffer( bufSize ); 596 597 for ( int i = 0; i < arraySize; i++ ) 598 { 599 if ( i > 0 ) 600 { 601 buf.append( separator ); 602 } 603 buf.append( array[i] ); 604 } 605 return buf.toString(); 606 } 607 608 /** 609 * <p>Joins the elements of the provided <code>Iterator</code> into 610 * a single String containing the provided elements.</p> 611 * 612 * <p>No delimiter is added before or after the list. A 613 * <code>null</code> separator is the same as a blank String.</p> 614 * 615 * @param iterator the <code>Iterator</code> of values to join together 616 * @param separator the separator character to use 617 * @return the joined String 618 */ 619 public static String join( Iterator iterator, String separator ) 620 { 621 if ( separator == null ) 622 { 623 separator = ""; 624 } 625 StringBuffer buf = new StringBuffer( 256 ); // Java default is 16, probably too small 626 while ( iterator.hasNext() ) 627 { 628 buf.append( iterator.next() ); 629 if ( iterator.hasNext() ) 630 { 631 buf.append( separator ); 632 } 633 } 634 return buf.toString(); 635 } 636 637 638 639 // Replacing 640 //-------------------------------------------------------------------------- 641 642 /** 643 * <p>Replace a char with another char inside a larger String, once.</p> 644 * 645 * <p>A <code>null</code> reference passed to this method is a no-op.</p> 646 * 647 * @see #replace(String text, char repl, char with, int max) 648 * @param text text to search and replace in 649 * @param repl char to search for 650 * @param with char to replace with 651 * @return the text with any replacements processed 652 */ 653 public static String replaceOnce( String text, char repl, char with ) 654 { 655 return replace( text, repl, with, 1 ); 656 } 657 658 /** 659 * <p>Replace all occurances of a char within another char.</p> 660 * 661 * <p>A <code>null</code> reference passed to this method is a no-op.</p> 662 * 663 * @see #replace(String text, char repl, char with, int max) 664 * @param text text to search and replace in 665 * @param repl char to search for 666 * @param with char to replace with 667 * @return the text with any replacements processed 668 */ 669 public static String replace( String text, char repl, char with ) 670 { 671 return replace( text, repl, with, -1 ); 672 } 673 674 /** 675 * <p>Replace a char with another char inside a larger String, 676 * for the first <code>max</code> values of the search char.</p> 677 * 678 * <p>A <code>null</code> reference passed to this method is a no-op.</p> 679 * 680 * @param text text to search and replace in 681 * @param repl char to search for 682 * @param with char to replace with 683 * @param max maximum number of values to replace, or <code>-1</code> if no maximum 684 * @return the text with any replacements processed 685 */ 686 public static String replace( String text, char repl, char with, int max ) 687 { 688 return replace( text, String.valueOf( repl ), String.valueOf( with ), max ); 689 } 690 691 /** 692 * <p>Replace a String with another String inside a larger String, once.</p> 693 * 694 * <p>A <code>null</code> reference passed to this method is a no-op.</p> 695 * 696 * @see #replace(String text, String repl, String with, int max) 697 * @param text text to search and replace in 698 * @param repl String to search for 699 * @param with String to replace with 700 * @return the text with any replacements processed 701 */ 702 public static String replaceOnce( String text, String repl, String with ) 703 { 704 return replace( text, repl, with, 1 ); 705 } 706 707 /** 708 * <p>Replace all occurances of a String within another String.</p> 709 * 710 * <p>A <code>null</code> reference passed to this method is a no-op.</p> 711 * 712 * @see #replace(String text, String repl, String with, int max) 713 * @param text text to search and replace in 714 * @param repl String to search for 715 * @param with String to replace with 716 * @return the text with any replacements processed 717 */ 718 public static String replace( String text, String repl, String with ) 719 { 720 return replace( text, repl, with, -1 ); 721 } 722 723 /** 724 * <p>Replace a String with another String inside a larger String, 725 * for the first <code>max</code> values of the search String.</p> 726 * 727 * <p>A <code>null</code> reference passed to this method is a no-op.</p> 728 * 729 * @param text text to search and replace in 730 * @param repl String to search for 731 * @param with String to replace with 732 * @param max maximum number of values to replace, or <code>-1</code> if no maximum 733 * @return the text with any replacements processed 734 */ 735 public static String replace( String text, String repl, String with, int max ) 736 { 737 if ( text == null || repl == null || with == null || repl.length() == 0 ) 738 { 739 return text; 740 } 741 742 StringBuffer buf = new StringBuffer( text.length() ); 743 int start = 0, end = 0; 744 while ( ( end = text.indexOf( repl, start ) ) != -1 ) 745 { 746 buf.append( text.substring( start, end ) ).append( with ); 747 start = end + repl.length(); 748 749 if ( --max == 0 ) 750 { 751 break; 752 } 753 } 754 buf.append( text.substring( start ) ); 755 return buf.toString(); 756 } 757 758 /** 759 * <p>Overlay a part of a String with another String.</p> 760 * 761 * @param text String to do overlaying in 762 * @param overlay String to overlay 763 * @param start int to start overlaying at 764 * @param end int to stop overlaying before 765 * @return String with overlayed text 766 * @throws NullPointerException if text or overlay is <code>null</code> 767 */ 768 public static String overlayString( String text, String overlay, int start, int end ) 769 { 770 return new StringBuffer( start + overlay.length() + text.length() - end + 1 ) 771 .append( text.substring( 0, start ) ) 772 .append( overlay ) 773 .append( text.substring( end ) ) 774 .toString(); 775 } 776 777 // Centering 778 //-------------------------------------------------------------------------- 779 780 /** 781 * <p>Center a String in a larger String of size <code>n</code>.<p> 782 * 783 * <p>Uses spaces as the value to buffer the String with. 784 * Equivalent to <code>center(str, size, " ")</code>.</p> 785 * 786 * @param str String to center 787 * @param size int size of new String 788 * @return String containing centered String 789 * @throws NullPointerException if str is <code>null</code> 790 */ 791 public static String center( String str, int size ) 792 { 793 return center( str, size, " " ); 794 } 795 796 /** 797 * <p>Center a String in a larger String of size <code>n</code>.</p> 798 * 799 * <p>Uses a supplied String as the value to buffer the String with.</p> 800 * 801 * @param str String to center 802 * @param size int size of new String 803 * @param delim String to buffer the new String with 804 * @return String containing centered String 805 * @throws NullPointerException if str or delim is <code>null</code> 806 * @throws ArithmeticException if delim is the empty String 807 */ 808 public static String center( String str, int size, String delim ) 809 { 810 int sz = str.length(); 811 int p = size - sz; 812 if ( p < 1 ) 813 { 814 return str; 815 } 816 str = leftPad( str, sz + p / 2, delim ); 817 str = rightPad( str, size, delim ); 818 return str; 819 } 820 821 // Chomping 822 //-------------------------------------------------------------------------- 823 824 /** 825 * <p>Remove the last newline, and everything after it from a String.</p> 826 * 827 * @param str String to chomp the newline from 828 * @return String without chomped newline 829 * @throws NullPointerException if str is <code>null</code> 830 */ 831 public static String chomp( String str ) 832 { 833 return chomp( str, "\n" ); 834 } 835 836 /** 837 * <p>Remove the last value of a supplied String, and everything after 838 * it from a String.</p> 839 * 840 * @param str String to chomp from 841 * @param sep String to chomp 842 * @return String without chomped ending 843 * @throws NullPointerException if str or sep is <code>null</code> 844 */ 845 public static String chomp( String str, String sep ) 846 { 847 int idx = str.lastIndexOf( sep ); 848 if ( idx != -1 ) 849 { 850 return str.substring( 0, idx ); 851 } 852 else 853 { 854 return str; 855 } 856 } 857 858 /** 859 * <p>Remove a newline if and only if it is at the end 860 * of the supplied String.</p> 861 * 862 * @param str String to chomp from 863 * @return String without chomped ending 864 * @throws NullPointerException if str is <code>null</code> 865 */ 866 public static String chompLast( String str ) 867 { 868 return chompLast( str, "\n" ); 869 } 870 871 /** 872 * <p>Remove a value if and only if the String ends with that value.</p> 873 * 874 * @param str String to chomp from 875 * @param sep String to chomp 876 * @return String without chomped ending 877 * @throws NullPointerException if str or sep is <code>null</code> 878 */ 879 public static String chompLast( String str, String sep ) 880 { 881 if ( str.length() == 0 ) 882 { 883 return str; 884 } 885 String sub = str.substring( str.length() - sep.length() ); 886 if ( sep.equals( sub ) ) 887 { 888 return str.substring( 0, str.length() - sep.length() ); 889 } 890 else 891 { 892 return str; 893 } 894 } 895 896 /** 897 * <p>Remove everything and return the last value of a supplied String, and 898 * everything after it from a String.</p> 899 * 900 * @param str String to chomp from 901 * @param sep String to chomp 902 * @return String chomped 903 * @throws NullPointerException if str or sep is <code>null</code> 904 */ 905 public static String getChomp( String str, String sep ) 906 { 907 int idx = str.lastIndexOf( sep ); 908 if ( idx == str.length() - sep.length() ) 909 { 910 return sep; 911 } 912 else if ( idx != -1 ) 913 { 914 return str.substring( idx ); 915 } 916 else 917 { 918 return ""; 919 } 920 } 921 922 /** 923 * <p>Remove the first value of a supplied String, and everything before it 924 * from a String.</p> 925 * 926 * @param str String to chomp from 927 * @param sep String to chomp 928 * @return String without chomped beginning 929 * @throws NullPointerException if str or sep is <code>null</code> 930 */ 931 public static String prechomp( String str, String sep ) 932 { 933 int idx = str.indexOf( sep ); 934 if ( idx != -1 ) 935 { 936 return str.substring( idx + sep.length() ); 937 } 938 else 939 { 940 return str; 941 } 942 } 943 944 /** 945 * <p>Remove and return everything before the first value of a 946 * supplied String from another String.</p> 947 * 948 * @param str String to chomp from 949 * @param sep String to chomp 950 * @return String prechomped 951 * @throws NullPointerException if str or sep is <code>null</code> 952 */ 953 public static String getPrechomp( String str, String sep ) 954 { 955 int idx = str.indexOf( sep ); 956 if ( idx != -1 ) 957 { 958 return str.substring( 0, idx + sep.length() ); 959 } 960 else 961 { 962 return ""; 963 } 964 } 965 966 // Chopping 967 //-------------------------------------------------------------------------- 968 969 /** 970 * <p>Remove the last character from a String.</p> 971 * 972 * <p>If the String ends in <code>\r\n</code>, then remove both 973 * of them.</p> 974 * 975 * @param str String to chop last character from 976 * @return String without last character 977 * @throws NullPointerException if str is <code>null</code> 978 */ 979 public static String chop( String str ) 980 { 981 if ( "".equals( str ) ) 982 { 983 return ""; 984 } 985 if ( str.length() == 1 ) 986 { 987 return ""; 988 } 989 int lastIdx = str.length() - 1; 990 String ret = str.substring( 0, lastIdx ); 991 char last = str.charAt( lastIdx ); 992 if ( last == '\n' ) 993 { 994 if ( ret.charAt( lastIdx - 1 ) == '\r' ) 995 { 996 return ret.substring( 0, lastIdx - 1 ); 997 } 998 } 999 return ret; 1000 } 1001 1002 /** 1003 * <p>Remove <code>\n</code> from end of a String if it's there. 1004 * If a <code>\r</code> precedes it, then remove that too.</p> 1005 * 1006 * @param str String to chop a newline from 1007 * @return String without newline 1008 * @throws NullPointerException if str is <code>null</code> 1009 */ 1010 public static String chopNewline( String str ) 1011 { 1012 int lastIdx = str.length() - 1; 1013 char last = str.charAt( lastIdx ); 1014 if ( last == '\n' ) 1015 { 1016 if ( str.charAt( lastIdx - 1 ) == '\r' ) 1017 { 1018 lastIdx--; 1019 } 1020 } 1021 else 1022 { 1023 lastIdx++; 1024 } 1025 return str.substring( 0, lastIdx ); 1026 } 1027 1028 1029 // Conversion 1030 //-------------------------------------------------------------------------- 1031 1032 // spec 3.10.6 1033 /** 1034 * <p>Escapes any values it finds into their String form.</p> 1035 * 1036 * <p>So a tab becomes the characters <code>'\\'</code> and 1037 * <code>'t'</code>.</p> 1038 * 1039 * @param str String to escape values in 1040 * @return String with escaped values 1041 * @throws NullPointerException if str is <code>null</code> 1042 */ 1043 public static String escape( String str ) 1044 { 1045 // improved with code from cybertiger@cyberiantiger.org 1046 // unicode from him, and defaul for < 32's. 1047 int sz = str.length(); 1048 StringBuffer buffer = new StringBuffer( 2 * sz ); 1049 for ( int i = 0; i < sz; i++ ) 1050 { 1051 char ch = str.charAt( i ); 1052 1053 // handle unicode 1054 if ( ch > 0xfff ) 1055 { 1056 buffer.append( "\\u" + Integer.toHexString( ch ) ); 1057 } 1058 else if ( ch > 0xff ) 1059 { 1060 buffer.append( "\\u0" + Integer.toHexString( ch ) ); 1061 } 1062 else if ( ch > 0x7f ) 1063 { 1064 buffer.append( "\\u00" + Integer.toHexString( ch ) ); 1065 } 1066 else if ( ch < 32 ) 1067 { 1068 switch ( ch ) 1069 { 1070 case '\b': 1071 buffer.append( '\\' ); 1072 buffer.append( 'b' ); 1073 break; 1074 case '\n': 1075 buffer.append( '\\' ); 1076 buffer.append( 'n' ); 1077 break; 1078 case '\t': 1079 buffer.append( '\\' ); 1080 buffer.append( 't' ); 1081 break; 1082 case '\f': 1083 buffer.append( '\\' ); 1084 buffer.append( 'f' ); 1085 break; 1086 case '\r': 1087 buffer.append( '\\' ); 1088 buffer.append( 'r' ); 1089 break; 1090 default : 1091 if ( ch > 0xf ) 1092 { 1093 buffer.append( "\\u00" + Integer.toHexString( ch ) ); 1094 } 1095 else 1096 { 1097 buffer.append( "\\u000" + Integer.toHexString( ch ) ); 1098 } 1099 break; 1100 } 1101 } 1102 else 1103 { 1104 switch ( ch ) 1105 { 1106 case '\'': 1107 buffer.append( '\\' ); 1108 buffer.append( '\'' ); 1109 break; 1110 case '"': 1111 buffer.append( '\\' ); 1112 buffer.append( '"' ); 1113 break; 1114 case '\\': 1115 buffer.append( '\\' ); 1116 buffer.append( '\\' ); 1117 break; 1118 default : 1119 buffer.append( ch ); 1120 break; 1121 } 1122 } 1123 } 1124 return buffer.toString(); 1125 } 1126 1127 // Padding 1128 //-------------------------------------------------------------------------- 1129 1130 /** 1131 * <p>Repeat a String <code>n</code> times to form a 1132 * new string.</p> 1133 * 1134 * @param str String to repeat 1135 * @param repeat number of times to repeat str 1136 * @return String with repeated String 1137 * @throws NegativeArraySizeException if <code>repeat < 0</code> 1138 * @throws NullPointerException if str is <code>null</code> 1139 */ 1140 public static String repeat( String str, int repeat ) 1141 { 1142 StringBuffer buffer = new StringBuffer( repeat * str.length() ); 1143 for ( int i = 0; i < repeat; i++ ) 1144 { 1145 buffer.append( str ); 1146 } 1147 return buffer.toString(); 1148 } 1149 1150 /** 1151 * <p>Right pad a String with spaces.</p> 1152 * 1153 * <p>The String is padded to the size of <code>n</code>.</p> 1154 * 1155 * @param str String to repeat 1156 * @param size number of times to repeat str 1157 * @return right padded String 1158 * @throws NullPointerException if str is <code>null</code> 1159 */ 1160 public static String rightPad( String str, int size ) 1161 { 1162 return rightPad( str, size, " " ); 1163 } 1164 1165 /** 1166 * <p>Right pad a String with a specified string.</p> 1167 * 1168 * <p>The String is padded to the size of <code>n</code>.</p> 1169 * 1170 * @param str String to pad out 1171 * @param size size to pad to 1172 * @param delim String to pad with 1173 * @return right padded String 1174 * @throws NullPointerException if str or delim is <code>null</code> 1175 * @throws ArithmeticException if delim is the empty String 1176 */ 1177 public static String rightPad( String str, int size, String delim ) 1178 { 1179 size = ( size - str.length() ) / delim.length(); 1180 if ( size > 0 ) 1181 { 1182 str += repeat( delim, size ); 1183 } 1184 return str; 1185 } 1186 1187 /** 1188 * <p>Left pad a String with spaces.</p> 1189 * 1190 * <p>The String is padded to the size of <code>n</code>.</p> 1191 * 1192 * @param str String to pad out 1193 * @param size size to pad to 1194 * @return left padded String 1195 * @throws NullPointerException if str or delim is <code>null</code> 1196 */ 1197 public static String leftPad( String str, int size ) 1198 { 1199 return leftPad( str, size, " " ); 1200 } 1201 1202 /** 1203 * Left pad a String with a specified string. Pad to a size of n. 1204 * 1205 * @param str String to pad out 1206 * @param size size to pad to 1207 * @param delim String to pad with 1208 * @return left padded String 1209 * @throws NullPointerException if str or delim is null 1210 * @throws ArithmeticException if delim is the empty string 1211 */ 1212 public static String leftPad( String str, int size, String delim ) 1213 { 1214 size = ( size - str.length() ) / delim.length(); 1215 if ( size > 0 ) 1216 { 1217 str = repeat( delim, size ) + str; 1218 } 1219 return str; 1220 } 1221 1222 // Stripping 1223 //-------------------------------------------------------------------------- 1224 1225 /** 1226 * <p>Remove whitespace from the front and back of a String.</p> 1227 * 1228 * @param str the String to remove whitespace from 1229 * @return the stripped String 1230 */ 1231 public static String strip( String str ) 1232 { 1233 return strip( str, null ); 1234 } 1235 1236 /** 1237 * <p>Remove a specified String from the front and back of a 1238 * String.</p> 1239 * 1240 * <p>If whitespace is wanted to be removed, used the 1241 * {@link #strip(java.lang.String)} method.</p> 1242 * 1243 * @param str the String to remove a string from 1244 * @param delim the String to remove at start and end 1245 * @return the stripped String 1246 */ 1247 public static String strip( String str, String delim ) 1248 { 1249 str = stripStart( str, delim ); 1250 return stripEnd( str, delim ); 1251 } 1252 1253 /** 1254 * <p>Strip whitespace from the front and back of every String 1255 * in the array.</p> 1256 * 1257 * @param strs the Strings to remove whitespace from 1258 * @return the stripped Strings 1259 */ 1260 public static String[] stripAll( String[] strs ) 1261 { 1262 return stripAll( strs, null ); 1263 } 1264 1265 /** 1266 * <p>Strip the specified delimiter from the front and back of 1267 * every String in the array.</p> 1268 * 1269 * @param strs the Strings to remove a String from 1270 * @param delimiter the String to remove at start and end 1271 * @return the stripped Strings 1272 */ 1273 public static String[] stripAll( String[] strs, String delimiter ) 1274 { 1275 if ( ( strs == null ) || ( strs.length == 0 ) ) 1276 { 1277 return strs; 1278 } 1279 int sz = strs.length; 1280 String[] newArr = new String[sz]; 1281 for ( int i = 0; i < sz; i++ ) 1282 { 1283 newArr[i] = strip( strs[i], delimiter ); 1284 } 1285 return newArr; 1286 } 1287 1288 /** 1289 * <p>Strip any of a supplied String from the end of a String.</p> 1290 * 1291 * <p>If the strip String is <code>null</code>, whitespace is 1292 * stripped.</p> 1293 * 1294 * @param str the String to remove characters from 1295 * @param strip the String to remove 1296 * @return the stripped String 1297 */ 1298 public static String stripEnd( String str, String strip ) 1299 { 1300 if ( str == null ) 1301 { 1302 return null; 1303 } 1304 int end = str.length(); 1305 1306 if ( strip == null ) 1307 { 1308 while ( ( end != 0 ) && Character.isWhitespace( str.charAt( end - 1 ) ) ) 1309 { 1310 end--; 1311 } 1312 } 1313 else 1314 { 1315 while ( ( end != 0 ) && ( strip.indexOf( str.charAt( end - 1 ) ) != -1 ) ) 1316 { 1317 end--; 1318 } 1319 } 1320 return str.substring( 0, end ); 1321 } 1322 1323 /** 1324 * <p>Strip any of a supplied String from the start of a String.</p> 1325 * 1326 * <p>If the strip String is <code>null</code>, whitespace is 1327 * stripped.</p> 1328 * 1329 * @param str the String to remove characters from 1330 * @param strip the String to remove 1331 * @return the stripped String 1332 */ 1333 public static String stripStart( String str, String strip ) 1334 { 1335 if ( str == null ) 1336 { 1337 return null; 1338 } 1339 1340 int start = 0; 1341 1342 int sz = str.length(); 1343 1344 if ( strip == null ) 1345 { 1346 while ( ( start != sz ) && Character.isWhitespace( str.charAt( start ) ) ) 1347 { 1348 start++; 1349 } 1350 } 1351 else 1352 { 1353 while ( ( start != sz ) && ( strip.indexOf( str.charAt( start ) ) != -1 ) ) 1354 { 1355 start++; 1356 } 1357 } 1358 return str.substring( start ); 1359 } 1360 1361 // Case conversion 1362 //-------------------------------------------------------------------------- 1363 1364 /** 1365 * <p>Convert a String to upper case, <code>null</code> String 1366 * returns <code>null</code>.</p> 1367 * 1368 * @param str the String to uppercase 1369 * @return the upper cased String 1370 */ 1371 public static String upperCase( String str ) 1372 { 1373 if ( str == null ) 1374 { 1375 return null; 1376 } 1377 return str.toUpperCase(); 1378 } 1379 1380 /** 1381 * <p>Convert a String to lower case, <code>null</code> String 1382 * returns <code>null</code>.</p> 1383 * 1384 * @param str the string to lowercase 1385 * @return the lower cased String 1386 */ 1387 public static String lowerCase( String str ) 1388 { 1389 if ( str == null ) 1390 { 1391 return null; 1392 } 1393 return str.toLowerCase(); 1394 } 1395 1396 /** 1397 * <p>Uncapitalise a String.</p> 1398 * 1399 * <p>That is, convert the first character into lower-case. 1400 * <code>null</code> is returned as <code>null</code>.</p> 1401 * 1402 * @param str the String to uncapitalise 1403 * @return uncapitalised String 1404 */ 1405 public static String uncapitalise( String str ) 1406 { 1407 if ( str == null ) 1408 { 1409 return null; 1410 } 1411 else if ( str.length() == 0 ) 1412 { 1413 return ""; 1414 } 1415 else 1416 { 1417 return new StringBuffer( str.length() ) 1418 .append( Character.toLowerCase( str.charAt( 0 ) ) ) 1419 .append( str.substring( 1 ) ) 1420 .toString(); 1421 } 1422 } 1423 1424 /** 1425 * <p>Capitalise a String.</p> 1426 * 1427 * <p>That is, convert the first character into title-case. 1428 * <code>null</code> is returned as <code>null</code>.</p> 1429 * 1430 * @param str the String to capitalise 1431 * @return capitalised String 1432 */ 1433 public static String capitalise( String str ) 1434 { 1435 if ( str == null ) 1436 { 1437 return null; 1438 } 1439 else if ( str.length() == 0 ) 1440 { 1441 return ""; 1442 } 1443 else 1444 { 1445 return new StringBuffer( str.length() ) 1446 .append( Character.toTitleCase( str.charAt( 0 ) ) ) 1447 .append( str.substring( 1 ) ) 1448 .toString(); 1449 } 1450 } 1451 1452 /** 1453 * <p>Swaps the case of String.</p> 1454 * 1455 * <p>Properly looks after making sure the start of words 1456 * are Titlecase and not Uppercase.</p> 1457 * 1458 * <p><code>null</code> is returned as <code>null</code>.</p> 1459 * 1460 * @param str the String to swap the case of 1461 * @return the modified String 1462 */ 1463 public static String swapCase( String str ) 1464 { 1465 if ( str == null ) 1466 { 1467 return null; 1468 } 1469 int sz = str.length(); 1470 StringBuffer buffer = new StringBuffer( sz ); 1471 1472 boolean whitespace = false; 1473 char ch = 0; 1474 char tmp = 0; 1475 1476 for ( int i = 0; i < sz; i++ ) 1477 { 1478 ch = str.charAt( i ); 1479 if ( Character.isUpperCase( ch ) ) 1480 { 1481 tmp = Character.toLowerCase( ch ); 1482 } 1483 else if ( Character.isTitleCase( ch ) ) 1484 { 1485 tmp = Character.toLowerCase( ch ); 1486 } 1487 else if ( Character.isLowerCase( ch ) ) 1488 { 1489 if ( whitespace ) 1490 { 1491 tmp = Character.toTitleCase( ch ); 1492 } 1493 else 1494 { 1495 tmp = Character.toUpperCase( ch ); 1496 } 1497 } 1498 else 1499 { 1500 tmp = ch; 1501 } 1502 buffer.append( tmp ); 1503 whitespace = Character.isWhitespace( ch ); 1504 } 1505 return buffer.toString(); 1506 } 1507 1508 1509 /** 1510 * <p>Capitalise all the words in a String.</p> 1511 * 1512 * <p>Uses {@link Character#isWhitespace(char)} as a 1513 * separator between words.</p> 1514 * 1515 * <p><code>null</code> will return <code>null</code>.</p> 1516 * 1517 * @param str the String to capitalise 1518 * @return capitalised String 1519 */ 1520 public static String capitaliseAllWords( String str ) 1521 { 1522 if ( str == null ) 1523 { 1524 return null; 1525 } 1526 int sz = str.length(); 1527 StringBuffer buffer = new StringBuffer( sz ); 1528 boolean space = true; 1529 for ( int i = 0; i < sz; i++ ) 1530 { 1531 char ch = str.charAt( i ); 1532 if ( Character.isWhitespace( ch ) ) 1533 { 1534 buffer.append( ch ); 1535 space = true; 1536 } 1537 else if ( space ) 1538 { 1539 buffer.append( Character.toTitleCase( ch ) ); 1540 space = false; 1541 } 1542 else 1543 { 1544 buffer.append( ch ); 1545 } 1546 } 1547 return buffer.toString(); 1548 } 1549 1550 /** 1551 * <p>Uncapitalise all the words in a string.</p> 1552 * 1553 * <p>Uses {@link Character#isWhitespace(char)} as a 1554 * separator between words.</p> 1555 * 1556 * <p><code>null</code> will return <code>null</code>.</p> 1557 * 1558 * @param str the string to uncapitalise 1559 * @return uncapitalised string 1560 */ 1561 public static String uncapitaliseAllWords( String str ) 1562 { 1563 if ( str == null ) 1564 { 1565 return null; 1566 } 1567 int sz = str.length(); 1568 StringBuffer buffer = new StringBuffer( sz ); 1569 boolean space = true; 1570 for ( int i = 0; i < sz; i++ ) 1571 { 1572 char ch = str.charAt( i ); 1573 if ( Character.isWhitespace( ch ) ) 1574 { 1575 buffer.append( ch ); 1576 space = true; 1577 } 1578 else if ( space ) 1579 { 1580 buffer.append( Character.toLowerCase( ch ) ); 1581 space = false; 1582 } 1583 else 1584 { 1585 buffer.append( ch ); 1586 } 1587 } 1588 return buffer.toString(); 1589 } 1590 1591 // Nested extraction 1592 //-------------------------------------------------------------------------- 1593 1594 /** 1595 * <p>Get the String that is nested in between two instances of the 1596 * same String.</p> 1597 * 1598 * <p>If <code>str</code> is <code>null</code>, will 1599 * return <code>null</code>.</p> 1600 * 1601 * @param str the String containing nested-string 1602 * @param tag the String before and after nested-string 1603 * @return the String that was nested, or <code>null</code> 1604 * @throws NullPointerException if tag is <code>null</code> 1605 */ 1606 public static String getNestedString( String str, String tag ) 1607 { 1608 return getNestedString( str, tag, tag ); 1609 } 1610 1611 /** 1612 * <p>Get the String that is nested in between two Strings.</p> 1613 * 1614 * @param str the String containing nested-string 1615 * @param open the String before nested-string 1616 * @param close the String after nested-string 1617 * @return the String that was nested, or <code>null</code> 1618 * @throws NullPointerException if open or close is <code>null</code> 1619 */ 1620 public static String getNestedString( String str, String open, String close ) 1621 { 1622 if ( str == null ) 1623 { 1624 return null; 1625 } 1626 int start = str.indexOf( open ); 1627 if ( start != -1 ) 1628 { 1629 int end = str.indexOf( close, start + open.length() ); 1630 if ( end != -1 ) 1631 { 1632 return str.substring( start + open.length(), end ); 1633 } 1634 } 1635 return null; 1636 } 1637 1638 /** 1639 * <p>How many times is the substring in the larger String.</p> 1640 * 1641 * <p><code>null</code> returns <code>0</code>.</p> 1642 * 1643 * @param str the String to check 1644 * @param sub the substring to count 1645 * @return the number of occurances, 0 if the String is <code>null</code> 1646 * @throws NullPointerException if sub is <code>null</code> 1647 */ 1648 public static int countMatches( String str, String sub ) 1649 { 1650 if ( sub.equals( "" ) ) 1651 { 1652 return 0; 1653 } 1654 if ( str == null ) 1655 { 1656 return 0; 1657 } 1658 int count = 0; 1659 int idx = 0; 1660 while ( ( idx = str.indexOf( sub, idx ) ) != -1 ) 1661 { 1662 count++; 1663 idx += sub.length(); 1664 } 1665 return count; 1666 } 1667 1668 // Character Tests 1669 //-------------------------------------------------------------------------- 1670 1671 /** 1672 * <p>Checks if the String contains only unicode letters.</p> 1673 * 1674 * <p><code>null</code> will return <code>false</code>. 1675 * An empty String will return <code>true</code>.</p> 1676 * 1677 * @param str the String to check 1678 * @return <code>true</code> if only contains letters, and is non-null 1679 */ 1680 public static boolean isAlpha( String str ) 1681 { 1682 if ( str == null ) 1683 { 1684 return false; 1685 } 1686 int sz = str.length(); 1687 for ( int i = 0; i < sz; i++ ) 1688 { 1689 if ( Character.isLetter( str.charAt( i ) ) == false ) 1690 { 1691 return false; 1692 } 1693 } 1694 return true; 1695 } 1696 1697 /** 1698 * <p>Checks if the String contains only whitespace.</p> 1699 * 1700 * <p><code>null</code> will return <code>false</code>. An 1701 * empty String will return <code>true</code>.</p> 1702 * 1703 * @param str the String to check 1704 * @return <code>true</code> if only contains whitespace, and is non-null 1705 */ 1706 public static boolean isWhitespace( String str ) 1707 { 1708 if ( str == null ) 1709 { 1710 return false; 1711 } 1712 int sz = str.length(); 1713 for ( int i = 0; i < sz; i++ ) 1714 { 1715 if ( ( Character.isWhitespace( str.charAt( i ) ) == false ) ) 1716 { 1717 return false; 1718 } 1719 } 1720 return true; 1721 } 1722 1723 /** 1724 * <p>Checks if the String contains only unicode letters and 1725 * space (<code>' '</code>).</p> 1726 * 1727 * <p><code>null</code> will return <code>false</code>. An 1728 * empty String will return <code>true</code>.</p> 1729 * 1730 * @param str the String to check 1731 * @return <code>true</code> if only contains letters and space, 1732 * and is non-null 1733 */ 1734 public static boolean isAlphaSpace( String str ) 1735 { 1736 if ( str == null ) 1737 { 1738 return false; 1739 } 1740 int sz = str.length(); 1741 for ( int i = 0; i < sz; i++ ) 1742 { 1743 if ( ( Character.isLetter( str.charAt( i ) ) == false ) && 1744 ( str.charAt( i ) != ' ' ) ) 1745 { 1746 return false; 1747 } 1748 } 1749 return true; 1750 } 1751 1752 /** 1753 * <p>Checks if the String contains only unicode letters or digits.</p> 1754 * 1755 * <p><code>null</code> will return <code>false</code>. An empty 1756 * String will return <code>true</code>.</p> 1757 * 1758 * @param str the String to check 1759 * @return <code>true</code> if only contains letters or digits, 1760 * and is non-null 1761 */ 1762 public static boolean isAlphanumeric( String str ) 1763 { 1764 if ( str == null ) 1765 { 1766 return false; 1767 } 1768 int sz = str.length(); 1769 for ( int i = 0; i < sz; i++ ) 1770 { 1771 if ( Character.isLetterOrDigit( str.charAt( i ) ) == false ) 1772 { 1773 return false; 1774 } 1775 } 1776 return true; 1777 } 1778 1779 /** 1780 * <p>Checks if the String contains only unicode letters, digits 1781 * or space (<code>' '</code>).</p> 1782 * 1783 * <p><code>null</code> will return <code>false</code>. An empty 1784 * String will return <code>true</code>.</p> 1785 * 1786 * @param str the String to check 1787 * @return <code>true</code> if only contains letters, digits or space, 1788 * and is non-null 1789 */ 1790 public static boolean isAlphanumericSpace( String str ) 1791 { 1792 if ( str == null ) 1793 { 1794 return false; 1795 } 1796 int sz = str.length(); 1797 for ( int i = 0; i < sz; i++ ) 1798 { 1799 if ( ( Character.isLetterOrDigit( str.charAt( i ) ) == false ) && 1800 ( str.charAt( i ) != ' ' ) ) 1801 { 1802 return false; 1803 } 1804 } 1805 return true; 1806 } 1807 1808 /** 1809 * <p>Checks if the String contains only unicode digits.</p> 1810 * 1811 * <p><code>null</code> will return <code>false</code>. 1812 * An empty String will return <code>true</code>.</p> 1813 * 1814 * @param str the String to check 1815 * @return <code>true</code> if only contains digits, and is non-null 1816 */ 1817 public static boolean isNumeric( String str ) 1818 { 1819 if ( str == null ) 1820 { 1821 return false; 1822 } 1823 int sz = str.length(); 1824 for ( int i = 0; i < sz; i++ ) 1825 { 1826 if ( Character.isDigit( str.charAt( i ) ) == false ) 1827 { 1828 return false; 1829 } 1830 } 1831 return true; 1832 } 1833 1834 /** 1835 * <p>Checks if the String contains only unicode digits or space 1836 * (<code>' '</code>).</p> 1837 * 1838 * <p><code>null</code> will return <code>false</code>. An empty 1839 * String will return <code>true</code>.</p> 1840 * 1841 * @param str the String to check 1842 * @return <code>true</code> if only contains digits or space, 1843 * and is non-null 1844 */ 1845 public static boolean isNumericSpace( String str ) 1846 { 1847 if ( str == null ) 1848 { 1849 return false; 1850 } 1851 int sz = str.length(); 1852 for ( int i = 0; i < sz; i++ ) 1853 { 1854 if ( ( Character.isDigit( str.charAt( i ) ) == false ) && 1855 ( str.charAt( i ) != ' ' ) ) 1856 { 1857 return false; 1858 } 1859 } 1860 return true; 1861 } 1862 1863 // Defaults 1864 //-------------------------------------------------------------------------- 1865 1866 /** 1867 * <p>Returns either the passed in <code>Object</code> as a String, 1868 * or, if the <code>Object</code> is <code>null</code>, an empty 1869 * String.</p> 1870 * 1871 * @param obj the Object to check 1872 * @return the passed in Object's toString, or blank if it was 1873 * <code>null</code> 1874 */ 1875 public static String defaultString( Object obj ) 1876 { 1877 return defaultString( obj, "" ); 1878 } 1879 1880 /** 1881 * <p>Returns either the passed in <code>Object</code> as a String, 1882 * or, if the <code>Object</code> is <code>null</code>, a passed 1883 * in default String.</p> 1884 * 1885 * @param obj the Object to check 1886 * @param defaultString the default String to return if str is 1887 * <code>null</code> 1888 * @return the passed in string, or the default if it was 1889 * <code>null</code> 1890 */ 1891 public static String defaultString( Object obj, String defaultString ) 1892 { 1893 return ( obj == null ) ? defaultString : obj.toString(); 1894 } 1895 1896 // Reversing 1897 //-------------------------------------------------------------------------- 1898 1899 /** 1900 * <p>Reverse a String.</p> 1901 * 1902 * <p><code>null</code> String returns <code>null</code>.</p> 1903 * 1904 * @param str the String to reverse 1905 * @return the reversed String 1906 */ 1907 public static String reverse( String str ) 1908 { 1909 if ( str == null ) 1910 { 1911 return null; 1912 } 1913 return new StringBuffer( str ).reverse().toString(); 1914 } 1915 1916 /** 1917 * <p>Reverses a String that is delimited by a specific character.</p> 1918 * 1919 * <p>The Strings between the delimiters are not reversed. 1920 * Thus java.lang.String becomes String.lang.java (if the delimiter 1921 * is <code>'.'</code>).</p> 1922 * 1923 * @param str the String to reverse 1924 * @param delimiter the delimiter to use 1925 * @return the reversed String 1926 */ 1927 public static String reverseDelimitedString( String str, String delimiter ) 1928 { 1929 // could implement manually, but simple way is to reuse other, 1930 // probably slower, methods. 1931 String[] strs = split( str, delimiter ); 1932 reverseArray( strs ); 1933 return join( strs, delimiter ); 1934 } 1935 1936 /** 1937 * <p>Reverses an array.</p> 1938 * 1939 * <p>TAKEN FROM CollectionsUtils.</p> 1940 * 1941 * @param array the array to reverse 1942 */ 1943 private static void reverseArray( Object[] array ) 1944 { 1945 int i = 0; 1946 int j = array.length - 1; 1947 Object tmp; 1948 1949 while ( j > i ) 1950 { 1951 tmp = array[j]; 1952 array[j] = array[i]; 1953 array[i] = tmp; 1954 j--; 1955 i++; 1956 } 1957 } 1958 1959 // Abbreviating 1960 //-------------------------------------------------------------------------- 1961 1962 /** 1963 * Turn "Now is the time for all good men" into "Now is the time for..." 1964 * <p> 1965 * Specifically: 1966 * <p> 1967 * If str is less than max characters long, return it. 1968 * Else abbreviate it to (substring(str, 0, max-3) + "..."). 1969 * If maxWidth is less than 3, throw an IllegalArgumentException. 1970 * In no case will it return a string of length greater than maxWidth. 1971 * 1972 * @param maxWidth maximum length of result string 1973 **/ 1974 public static String abbreviate( String s, int maxWidth ) 1975 { 1976 return abbreviate( s, 0, maxWidth ); 1977 } 1978 1979 /** 1980 * Turn "Now is the time for all good men" into "...is the time for..." 1981 * <p> 1982 * Works like abbreviate(String, int), but allows you to specify a "left edge" 1983 * offset. Note that this left edge is not necessarily going to be the leftmost 1984 * character in the result, or the first 1985 * character following the ellipses, but it will appear somewhere in the result. 1986 * In no case will it return a string of length greater than maxWidth. 1987 * 1988 * @param offset left edge of source string 1989 * @param maxWidth maximum length of result string 1990 **/ 1991 public static String abbreviate( String s, int offset, int maxWidth ) 1992 { 1993 if ( maxWidth < 4 ) 1994 throw new IllegalArgumentException( "Minimum abbreviation width is 4" ); 1995 if ( s.length() <= maxWidth ) 1996 return s; 1997 if ( offset > s.length() ) 1998 offset = s.length(); 1999 if ( ( s.length() - offset ) < ( maxWidth - 3 ) ) 2000 offset = s.length() - ( maxWidth - 3 ); 2001 if ( offset <= 4 ) 2002 return s.substring( 0, maxWidth - 3 ) + "..."; 2003 if ( maxWidth < 7 ) 2004 throw new IllegalArgumentException( "Minimum abbreviation width with offset is 7" ); 2005 if ( ( offset + ( maxWidth - 3 ) ) < s.length() ) 2006 return "..." + abbreviate( s.substring( offset ), maxWidth - 3 ); 2007 return "..." + s.substring( s.length() - ( maxWidth - 3 ) ); 2008 } 2009 2010 // Difference 2011 //-------------------------------------------------------------------------- 2012 2013 /** 2014 * Compare two strings, and return the portion where they differ. 2015 * (More precisely, return the remainder of the second string, 2016 * starting from where it's different from the first.) 2017 * <p> 2018 * E.g. strdiff("i am a machine", "i am a robot") -> "robot" 2019 * 2020 * @return the portion of s2 where it differs from s1; returns the empty string ("") if they are equal 2021 **/ 2022 public static String difference( String s1, String s2 ) 2023 { 2024 int at = differenceAt( s1, s2 ); 2025 if ( at == -1 ) 2026 return ""; 2027 return s2.substring( at ); 2028 } 2029 2030 /** 2031 * Compare two strings, and return the index at which the strings begin to differ. 2032 * <p> 2033 * E.g. strdiff("i am a machine", "i am a robot") -> 7 2034 * </p> 2035 * 2036 * @return the index where s2 and s1 begin to differ; -1 if they are equal 2037 **/ 2038 public static int differenceAt( String s1, String s2 ) 2039 { 2040 int i; 2041 for ( i = 0; i < s1.length() && i < s2.length(); ++i ) 2042 { 2043 if ( s1.charAt( i ) != s2.charAt( i ) ) 2044 { 2045 break; 2046 } 2047 } 2048 if ( i < s2.length() || i < s1.length() ) 2049 { 2050 return i; 2051 } 2052 return -1; 2053 } 2054 2055 public static String interpolate( String text, Map namespace ) 2056 { 2057 Iterator keys = namespace.keySet().iterator(); 2058 2059 while ( keys.hasNext() ) 2060 { 2061 String key = keys.next().toString(); 2062 2063 Object obj = namespace.get( key ); 2064 2065 if ( obj == null ) 2066 { 2067 throw new NullPointerException( "The value of the key '" + key + "' is null." ); 2068 } 2069 2070 String value = obj.toString(); 2071 2072 text = StringUtils.replace( text, "${" + key + "}", value ); 2073 2074 if ( key.indexOf( " " ) == -1 ) 2075 { 2076 text = StringUtils.replace( text, "$" + key, value ); 2077 } 2078 } 2079 return text; 2080 } 2081 2082 public static String removeAndHump( String data, String replaceThis ) 2083 { 2084 String temp; 2085 2086 StringBuffer out = new StringBuffer(); 2087 2088 temp = data; 2089 2090 StringTokenizer st = new StringTokenizer( temp, replaceThis ); 2091 2092 while ( st.hasMoreTokens() ) 2093 { 2094 String element = (String) st.nextElement(); 2095 2096 out.append( capitalizeFirstLetter( element ) ); 2097 } 2098 2099 return out.toString(); 2100 } 2101 2102 public static String capitalizeFirstLetter( String data ) 2103 { 2104 char firstLetter = Character.toTitleCase( data.substring( 0, 1 ).charAt( 0 ) ); 2105 2106 String restLetters = data.substring( 1 ); 2107 2108 return firstLetter + restLetters; 2109 } 2110 2111 public static String lowercaseFirstLetter( String data ) 2112 { 2113 char firstLetter = Character.toLowerCase( data.substring( 0, 1 ).charAt( 0 ) ); 2114 2115 String restLetters = data.substring( 1 ); 2116 2117 return firstLetter + restLetters; 2118 } 2119 2120 public static String addAndDeHump( String view ) 2121 { 2122 StringBuffer sb = new StringBuffer(); 2123 2124 for ( int i = 0; i < view.length(); i++ ) 2125 { 2126 if ( i != 0 && Character.isUpperCase( view.charAt( i ) ) ) 2127 { 2128 sb.append( '-' ); 2129 } 2130 2131 sb.append( view.charAt( i ) ); 2132 } 2133 2134 return sb.toString().trim().toLowerCase(); 2135 } 2136 }