Coverage Report - org.crosswire.common.util.StringUtil
 
Classes in this File Line Coverage Branch Coverage Complexity
StringUtil
0%
0/280
0%
0/208
9.062
 
 1  
 /**
 2  
  * Distribution License:
 3  
  * JSword is free software; you can redistribute it and/or modify it under
 4  
  * the terms of the GNU Lesser General Public License, version 2.1 or later
 5  
  * as published by the Free Software Foundation. This program is distributed
 6  
  * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 7  
  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 8  
  * See the GNU Lesser General Public License for more details.
 9  
  *
 10  
  * The License is available on the internet at:
 11  
  *      http://www.gnu.org/copyleft/lgpl.html
 12  
  * or by writing to:
 13  
  *      Free Software Foundation, Inc.
 14  
  *      59 Temple Place - Suite 330
 15  
  *      Boston, MA 02111-1307, USA
 16  
  *
 17  
  * © CrossWire Bible Society, 2005 - 2016
 18  
  *
 19  
  */
 20  
 package org.crosswire.common.util;
 21  
 
 22  
 import java.io.BufferedReader;
 23  
 import java.io.IOException;
 24  
 import java.io.Reader;
 25  
 
 26  
 /**
 27  
  * A generic class of String utilities.
 28  
  * 
 29  
  * @see gnu.lgpl.License The GNU Lesser General Public License for details.
 30  
  * @author Joe Walker
 31  
  */
 32  
 public final class StringUtil {
 33  
     /**
 34  
      * Prevent instantiation
 35  
      */
 36  0
     private StringUtil() {
 37  0
     }
 38  
 
 39  
     /**
 40  
      * The newline character
 41  
      */
 42  0
     public static final String NEWLINE = System.getProperty("line.separator", "\r\n");
 43  
 
 44  
     /**
 45  
      * Compare two strings for equality such that both can be null.
 46  
      * 
 47  
      * @param string1 the first string
 48  
      * @param string2 the second string
 49  
      * @return true when both are null or both have the same string value
 50  
      */
 51  
     public static boolean equals(String string1, String string2) {
 52  0
         if (string1 == null) {
 53  0
             return string2 == null;
 54  
         }
 55  0
         return string1.equals(string2);
 56  
     }
 57  
 
 58  
     /**
 59  
      * This method reads an InputStream <b>In its entirety</b>, and passes The
 60  
      * text back as a string. If you are reading from a source that can block
 61  
      * then be prepared for a long wait for this to return.
 62  
      * 
 63  
      * @param in
 64  
      *            The Stream to read from.
 65  
      * @return A string containing all the text from the Stream.
 66  
      * @throws IOException when an I/O error occurred
 67  
      */
 68  
     public static String read(Reader in) throws IOException {
 69  0
         StringBuilder retcode = new StringBuilder();
 70  
         // Quiet Android from complaining about using the default BufferReader buffer size.
 71  
         // The actual buffer size is undocumented. So this is a good idea any way.
 72  0
         BufferedReader din = new BufferedReader(in, 8192);
 73  
 
 74  
         while (true) {
 75  0
             String line = din.readLine();
 76  
 
 77  0
             if (line == null) {
 78  0
                 break;
 79  
             }
 80  
 
 81  0
             retcode.append(line);
 82  0
             retcode.append(NEWLINE);
 83  0
         }
 84  
 
 85  0
         return retcode.toString();
 86  
     }
 87  
 
 88  
     /**
 89  
      * This function creates a readable title from a variable name type input.
 90  
      * For example calling: StringUtil.createTitle("one_two") = "One Two"
 91  
      * StringUtil.createTitle("oneTwo") = "One Two"
 92  
      * 
 93  
      * @param variable the name of a variable
 94  
      * @return the generated title
 95  
      */
 96  
     public static String createTitle(String variable) {
 97  0
         StringBuilder retcode = new StringBuilder();
 98  0
         boolean lastlower = false;
 99  0
         boolean lastspace = true;
 100  
 
 101  0
         for (int i = 0; i < variable.length(); i++) {
 102  0
             char c = variable.charAt(i);
 103  
 
 104  0
             if (lastlower && Character.isUpperCase(c) && !lastspace) {
 105  0
                 retcode.append(' ');
 106  
             }
 107  
 
 108  0
             lastlower = !Character.isUpperCase(c);
 109  
 
 110  0
             if (lastspace) {
 111  0
                 c = Character.toUpperCase(c);
 112  
             }
 113  
 
 114  0
             if (c == '_') {
 115  0
                 c = ' ';
 116  
             }
 117  
 
 118  0
             if (!lastspace || c != ' ') {
 119  0
                 retcode.append(c);
 120  
             }
 121  
 
 122  0
             lastspace = c == ' ';
 123  
         }
 124  
 
 125  0
         return retcode.toString();
 126  
     }
 127  
 
 128  
     /**
 129  
      * For example getInitials("Java DataBase Connectivity") = "JDC" and
 130  
      * getInitials("Church of England") = "CoE".
 131  
      * 
 132  
      * @param sentence
 133  
      *            The phrase from which to get the initial letters.
 134  
      * @return The initial letters in the given words.
 135  
      */
 136  
     public static String getInitials(String sentence) {
 137  0
         String[] words = StringUtil.split(sentence);
 138  
 
 139  0
         StringBuilder retcode = new StringBuilder();
 140  0
         for (int i = 0; i < words.length; i++) {
 141  0
             String word = words[i];
 142  
 
 143  0
             char first = 0;
 144  0
             for (int j = 0; first == 0 && j < word.length(); j++) {
 145  0
                 char c = word.charAt(j);
 146  0
                 if (Character.isLetter(c)) {
 147  0
                     first = c;
 148  
                 }
 149  
             }
 150  
 
 151  0
             if (first != 0) {
 152  0
                 retcode.append(first);
 153  
             }
 154  
         }
 155  
 
 156  0
         return retcode.toString();
 157  
     }
 158  
 
 159  
     /**
 160  
      * Splits the provided text into an array, using whitespace as the
 161  
      * separator. Whitespace is defined by {@link Character#isWhitespace(char)}.
 162  
      * 
 163  
      * <p>
 164  
      * The separator is not included in the returned String array. Adjacent
 165  
      * separators are treated as one separator.
 166  
      * </p>
 167  
      * 
 168  
      * <pre>
 169  
      * StringUtil.split(null)       = []
 170  
      * StringUtil.split("")         = []
 171  
      * StringUtil.split("abc def")  = ["abc", "def"]
 172  
      * StringUtil.split("abc  def") = ["abc", "def"]
 173  
      * StringUtil.split(" abc ")    = ["abc"]
 174  
      * </pre>
 175  
      * 
 176  
      * @param str
 177  
      *            the String to parse, may be null
 178  
      * @return an array of parsed Strings, <code>null</code> if null String
 179  
      *         input
 180  
      */
 181  
     public static String[] split(String str) {
 182  0
         if (str == null) {
 183  0
             return EMPTY_STRING_ARRAY.clone();
 184  
         }
 185  
 
 186  0
         int len = str.length();
 187  0
         if (len == 0) {
 188  0
             return EMPTY_STRING_ARRAY.clone();
 189  
         }
 190  
 
 191  0
         char[] cstr = str.toCharArray();
 192  
 
 193  0
         int count = 0;
 194  0
         int start = 0;
 195  0
         int i = 0;
 196  0
         while ((i = indexOfWhitespace(cstr, start)) != -1) {
 197  
             // Don't count separator at beginning,
 198  
             // after another or at the end
 199  0
             if (i > start) {
 200  0
                 ++count;
 201  
             }
 202  0
             start = i + 1;
 203  
         }
 204  
 
 205  
         // If it didn't end with a separator then add in the last part
 206  0
         if (start < len) {
 207  0
             ++count;
 208  
         }
 209  
 
 210  
         // Create the array
 211  0
         String[] list = new String[count];
 212  
 
 213  
         // If there were no separators
 214  
         // then we have one big part
 215  0
         if (start == 0) {
 216  0
             list[0] = str;
 217  0
             return list;
 218  
         }
 219  
 
 220  0
         start = 0;
 221  0
         i = 0;
 222  0
         int x = 0;
 223  0
         while ((i = indexOfWhitespace(cstr, start)) != -1) {
 224  
             // Don't count separator at beginning,
 225  
             // after another or at the end
 226  0
             if (i > start) {
 227  0
                 list[x++] = str.substring(start, i);
 228  
             }
 229  0
             start = i + 1;
 230  
         }
 231  
         // If it didn't end with a separator then add in the last part
 232  0
         if (start < len) {
 233  0
             list[x++] = str.substring(start);
 234  
         }
 235  
 
 236  0
         return list;
 237  
     }
 238  
 
 239  
     /**
 240  
      * Splits the provided text into an array, using whitespace as the
 241  
      * separator. Whitespace is defined by {@link Character#isWhitespace(char)}.
 242  
      * 
 243  
      * <p>
 244  
      * The separator is not included in the returned String array. Adjacent
 245  
      * separators are treated as one separator.
 246  
      * </p>
 247  
      * 
 248  
      * <pre>
 249  
      * StringUtil.split(null)       = []
 250  
      * StringUtil.split("")         = []
 251  
      * StringUtil.split("abc def")  = ["abc", "def"]
 252  
      * StringUtil.split("abc  def") = ["abc", "def"]
 253  
      * StringUtil.split(" abc ")    = ["abc"]
 254  
      * </pre>
 255  
      * 
 256  
      * @param str
 257  
      *            the String to parse, may be null
 258  
      * @param max the maximum number of elements to return
 259  
      * @return an array of parsed Strings, <code>null</code> if null String
 260  
      *         input
 261  
      */
 262  
     public static String[] split(String str, int max) {
 263  0
         if (str == null) {
 264  0
             return EMPTY_STRING_ARRAY.clone();
 265  
         }
 266  
 
 267  0
         int len = str.length();
 268  0
         if (len == 0) {
 269  0
             return EMPTY_STRING_ARRAY.clone();
 270  
         }
 271  
 
 272  0
         char[] cstr = str.toCharArray();
 273  
 
 274  0
         int count = 0;
 275  0
         int start = 0;
 276  0
         int i = 0;
 277  0
         while ((i = indexOfWhitespace(cstr, start)) != -1) {
 278  
             // Don't count separator at beginning,
 279  
             // after another or at the end
 280  0
             if (i > start) {
 281  0
                 ++count;
 282  
             }
 283  0
             start = i + 1;
 284  
         }
 285  
 
 286  
         // If it didn't end with a separator then add in the last part
 287  0
         if (start < len) {
 288  0
             ++count;
 289  
         }
 290  
 
 291  
         // If there were no separators
 292  
         // then we have one big part
 293  0
         if (start == 0) {
 294  0
             String[] list = new String[count];
 295  0
             list[0] = str;
 296  0
             return list;
 297  
         }
 298  
 
 299  
         // Limit the result
 300  0
         if (max > 0 && count > max) {
 301  0
             count = max;
 302  
         }
 303  
 
 304  
         // Create the array
 305  0
         String[] list = new String[count];
 306  
 
 307  0
         start = 0;
 308  0
         i = 0;
 309  0
         int x = 0;
 310  0
         while ((i = indexOfWhitespace(cstr, start)) != -1) {
 311  
             // Don't count separator at beginning,
 312  
             // after another or at the end
 313  0
             if (i > start && x < count) {
 314  0
                 list[x++] = str.substring(start, i);
 315  
             }
 316  0
             start = i + 1;
 317  
         }
 318  
         // If it didn't end with a separator then add in the last part
 319  0
         if (start < len && x < count) {
 320  0
             list[x++] = str.substring(start);
 321  
         }
 322  
 
 323  0
         return list;
 324  
     }
 325  
 
 326  
     /**
 327  
      * Splits the provided text into an array, separator specified. This is an
 328  
      * alternative to using StringTokenizer.
 329  
      * 
 330  
      * <p>
 331  
      * The separator is not included in the returned String array. Adjacent
 332  
      * separators are treated as one separator.
 333  
      * </p>
 334  
      * 
 335  
      * <p>
 336  
      * A <code>null</code> input String returns <code>null</code>.
 337  
      * </p>
 338  
      * 
 339  
      * <pre>
 340  
      * StringUtil.split(null, *)         = []
 341  
      * StringUtil.split("", *)           = []
 342  
      * StringUtil.split("a.b.c", '.')    = ["a", "b", "c"]
 343  
      * StringUtil.split("a..b.c", '.')   = ["a", "b", "c"]
 344  
      * StringUtil.split("a:b:c", '.')    = ["a:b:c"]
 345  
      * StringUtil.split("a b c", ' ')    = ["a", "b", "c"]
 346  
      * </pre>
 347  
      * 
 348  
      * @param str
 349  
      *            the String to parse, may be null
 350  
      * @param separatorChar
 351  
      *            the character used as the delimiter
 352  
      * @return an array of parsed Strings
 353  
      */
 354  
     public static String[] split(String str, char separatorChar) {
 355  0
         if (str == null) {
 356  0
             return EMPTY_STRING_ARRAY.clone();
 357  
         }
 358  
 
 359  0
         int len = str.length();
 360  0
         if (len == 0) {
 361  0
             return EMPTY_STRING_ARRAY.clone();
 362  
         }
 363  
 
 364  
         // Determine the size of the array
 365  0
         int count = 0;
 366  0
         int start = 0;
 367  0
         int i = 0;
 368  0
         while ((i = str.indexOf(separatorChar, start)) != -1) {
 369  
             // Don't count separator at beginning,
 370  
             // after another or at the end
 371  0
             if (i > start && i < len) {
 372  0
                 ++count;
 373  
             }
 374  0
             start = i + 1;
 375  
         }
 376  
         // If it didn't end with a separator then add in the last part
 377  0
         if (start < len) {
 378  0
             ++count;
 379  
         }
 380  
 
 381  
         // Create the array
 382  0
         String[] list = new String[count];
 383  
 
 384  
         // If there were no separators
 385  
         // then we have one big part
 386  0
         if (count == 1) {
 387  0
             list[0] = str;
 388  0
             return list;
 389  
         }
 390  
 
 391  0
         start = 0;
 392  0
         i = 0;
 393  0
         int x = 0;
 394  0
         while ((i = str.indexOf(separatorChar, start)) != -1) {
 395  
             // Don't count separator at beginning,
 396  
             // after another or at the end
 397  0
             if (i > start) {
 398  0
                 list[x++] = str.substring(start, i);
 399  
             }
 400  0
             start = i + 1;
 401  
         }
 402  
         // If it didn't end with a separator then add in the last part
 403  0
         if (start < len) {
 404  0
             list[x++] = str.substring(start, len);
 405  
         }
 406  
 
 407  0
         return list;
 408  
     }
 409  
 
 410  
     /**
 411  
      * <p>
 412  
      * Splits the provided text into an array, separator specified. This is an
 413  
      * alternative to using StringTokenizer.
 414  
      * </p>
 415  
      * 
 416  
      * <p>
 417  
      * The separator is not included in the returned String array. Adjacent
 418  
      * separators are treated as one separator.
 419  
      * </p>
 420  
      * 
 421  
      * <p>
 422  
      * A <code>null</code> input String returns <code>null</code>.
 423  
      * </p>
 424  
      * 
 425  
      * <pre>
 426  
      * StringUtil.split(null, *, 2)         = []
 427  
      * StringUtil.split("", *, 2)           = []
 428  
      * StringUtil.split("a.b.c", '.', 2)    = ["a", "b"]
 429  
      * StringUtil.split("a..b.c", '.', 2)   = ["a", "b"]
 430  
      * StringUtil.split("a:b:c", '.', 2)    = ["a:b:c"]
 431  
      * StringUtil.split("a b c", ' ', 2)    = ["a", "b"]
 432  
      * </pre>
 433  
      * 
 434  
      * @param str
 435  
      *            the String to parse, may be null
 436  
      * @param separatorChar
 437  
      *            the character used as the delimiter
 438  
      * @param max
 439  
      *            the maximum number of elements to include in the array.
 440  
      *            A zero or negative value implies no limit
 441  
      * @return an array of parsed Strings
 442  
      */
 443  
     public static String[] split(String str, char separatorChar, int max) {
 444  0
         if (str == null) {
 445  0
             return EMPTY_STRING_ARRAY.clone();
 446  
         }
 447  
 
 448  0
         int len = str.length();
 449  0
         if (len == 0) {
 450  0
             return EMPTY_STRING_ARRAY.clone();
 451  
         }
 452  
 
 453  
         // Determine the size of the array
 454  0
         int count = 0;
 455  0
         int start = 0;
 456  0
         int i = 0;
 457  0
         while ((i = str.indexOf(separatorChar, start)) != -1) {
 458  
             // Don't count separator at beginning,
 459  
             // after another or at the end
 460  0
             if (i > start) {
 461  0
                 ++count;
 462  
             }
 463  0
             start = i + 1;
 464  
         }
 465  
 
 466  
         // If it didn't end with a separator then add in the last part
 467  0
         if (start < len) {
 468  0
             ++count;
 469  
         }
 470  
 
 471  
         // If there were no separators
 472  
         // then we have one big part
 473  0
         if (count == 1) {
 474  0
             String[] list = new String[count];
 475  0
             list[0] = str;
 476  0
             return list;
 477  
         }
 478  
 
 479  
         // Limit the result
 480  0
         if (max > 0 && count > max) {
 481  0
             count = max;
 482  
         }
 483  
 
 484  
         // Create the array
 485  0
         String[] list = new String[count];
 486  
 
 487  0
         start = 0;
 488  0
         i = 0;
 489  0
         int x = 0;
 490  0
         while ((i = str.indexOf(separatorChar, start)) != -1) {
 491  
             // Don't count separator at beginning,
 492  
             // after another or at the end
 493  0
             if (i > start && x < count) {
 494  0
                 list[x++] = str.substring(start, i);
 495  
             }
 496  0
             start = i + 1;
 497  
         }
 498  
         // If it didn't end with a separator then add in the last part
 499  0
         if (start < len && x < count) {
 500  0
             list[x++] = str.substring(start);
 501  
         }
 502  
 
 503  0
         return list;
 504  
     }
 505  
 
 506  
     /**
 507  
      * <p>
 508  
      * Splits the provided text into an array, separators specified. This is an
 509  
      * alternative to using StringTokenizer.
 510  
      * </p>
 511  
      * 
 512  
      * <p>
 513  
      * The separator is not included in the returned String array. Adjacent
 514  
      * separators are treated as one separator.
 515  
      * </p>
 516  
      * 
 517  
      * <p>
 518  
      * A <code>null</code> input String returns <code>null</code>. A
 519  
      * <code>null</code> separatorChars splits on whitespace.
 520  
      * </p>
 521  
      * 
 522  
      * <pre>
 523  
      * StringUtil.split(null, *)         = []
 524  
      * StringUtil.split("", *)           = []
 525  
      * StringUtil.split("abc def", null) = ["abc", "def"]
 526  
      * StringUtil.split("abc def", " ")  = ["abc", "def"]
 527  
      * StringUtil.split("abc  def", " ") = ["abc", "def"]
 528  
      * StringUtil.split("ab:cd:ef", ":") = ["ab", "cd", "ef"]
 529  
      * </pre>
 530  
      * 
 531  
      * @param str
 532  
      *            the String to parse, may be null
 533  
      * @param separatorChars
 534  
      *            the characters used as the delimiters, <code>null</code>
 535  
      *            splits on whitespace
 536  
      * @return an array of parsed Strings, <code>null</code> if null String
 537  
      *         input
 538  
      */
 539  
     public static String[] split(String str, String separatorChars) {
 540  0
         return split(str, separatorChars, -1);
 541  
     }
 542  
 
 543  
     /**
 544  
      * <p>
 545  
      * Splits the provided text into an array, separators specified. This is an
 546  
      * alternative to using StringTokenizer.
 547  
      * </p>
 548  
      * 
 549  
      * <p>
 550  
      * The separator is not included in the returned String array. Adjacent
 551  
      * separators are treated as one separator.
 552  
      * </p>
 553  
      * 
 554  
      * <p>
 555  
      * A <code>null</code> input String returns <code>null</code>. A
 556  
      * <code>null</code> separatorChars splits on whitespace.
 557  
      * </p>
 558  
      * 
 559  
      * <pre>
 560  
      * StringUtil.split(null, *, *)            = []
 561  
      * StringUtil.split("", *, *)              = []
 562  
      * StringUtil.split("ab de fg", null, 0)   = ["ab", "cd", "ef"]
 563  
      * StringUtil.split("ab   de fg", null, 0) = ["ab", "cd", "ef"]
 564  
      * StringUtil.split("ab:cd:ef", ":", 0)    = ["ab", "cd", "ef"]
 565  
      * StringUtil.split("ab:cd:ef", ":", 2)    = ["ab", "cd:ef"]
 566  
      * </pre>
 567  
      * 
 568  
      * @param str
 569  
      *            the String to parse, may be null
 570  
      * @param separatorStr
 571  
      *            the characters used as the delimiters, <code>null</code>
 572  
      *            splits on whitespace
 573  
      * @param max
 574  
      *            the maximum number of elements to include in the array. A zero
 575  
      *            or negative value implies no limit
 576  
      * @return an array of parsed Strings
 577  
      */
 578  
     public static String[] split(String str, String separatorStr, int max) {
 579  
         // Performance tuned for 2.0 (JDK1.4)
 580  
         // Direct code is quicker than StringTokenizer.
 581  
         // Also, StringTokenizer uses isSpace() not isWhitespace()
 582  
 
 583  0
        if (separatorStr == null) {
 584  0
             return split(str, max);
 585  
         }
 586  
 
 587  0
         if (separatorStr.length() == 1) {
 588  0
             return split(str, separatorStr.charAt(0), max);
 589  
         }
 590  
 
 591  0
         if (str == null) {
 592  0
             return EMPTY_STRING_ARRAY.clone();
 593  
         }
 594  
 
 595  0
         int len = str.length();
 596  0
         if (len == 0) {
 597  0
             return EMPTY_STRING_ARRAY.clone();
 598  
         }
 599  
 
 600  0
         char[] cstr = str.toCharArray();
 601  0
         char[] separatorChars = separatorStr.toCharArray();
 602  
 
 603  0
         int count = 0;
 604  0
         int start = 0;
 605  0
         int i = 0;
 606  0
         while ((i = indexOfAny(cstr, separatorChars, start)) != -1) {
 607  
             // Don't count separator at beginning,
 608  
             // after another or at the end
 609  0
             if (i > start) {
 610  0
                 ++count;
 611  
             }
 612  0
             start = i + 1;
 613  
         }
 614  
 
 615  
         // If it didn't end with a separator then add in the last part
 616  0
         if (start < len) {
 617  0
             ++count;
 618  
         }
 619  
 
 620  
         // If there were no separators
 621  
         // then we have one big part
 622  0
         if (count == 1) {
 623  0
             String[] list = new String[count];
 624  0
             list[0] = str;
 625  0
             return list;
 626  
         }
 627  
 
 628  
         // Limit the result
 629  0
         if (max > 0 && count > max) {
 630  0
             count = max;
 631  
         }
 632  
 
 633  
         // Create the array
 634  0
         String[] list = new String[count];
 635  
 
 636  0
         start = 0;
 637  0
         i = 0;
 638  0
         int x = 0;
 639  0
         while ((i = indexOfAny(cstr, separatorChars, start)) != -1) {
 640  
             // Don't count separator at beginning,
 641  
             // after another or at the end
 642  0
             if (i > start && x < count) {
 643  0
                 list[x++] = str.substring(start, i);
 644  
             }
 645  0
             start = i + 1;
 646  
         }
 647  
         // If it didn't end with a separator then add in the last part
 648  0
         if (start < len && x < count) {
 649  0
             list[x++] = str.substring(start);
 650  
         }
 651  
 
 652  0
         return list;
 653  
     }
 654  
 
 655  
     /**
 656  
      * <p>
 657  
      * Splits the provided text into an array, separator specified. This is an
 658  
      * alternative to using StringTokenizer.
 659  
      * </p>
 660  
      * 
 661  
      * <p>
 662  
      * The separator is not included in the returned String array. Adjacent
 663  
      * separators are treated individually.
 664  
      * </p>
 665  
      * 
 666  
      * <p>
 667  
      * A <code>null</code> input String returns <code>null</code>.
 668  
      * </p>
 669  
      * 
 670  
      * <pre>
 671  
      * StringUtil.splitAll(null, *)         = []
 672  
      * StringUtil.splitAll("", *)           = []
 673  
      * StringUtil.splitAll("a.b.c", '.')    = ["a", "b", "c"]
 674  
      * StringUtil.splitAll("a..b.c", '.')   = ["a", "", "b", "c"]
 675  
      * StringUtil.splitAll("a:b:c", '.')    = ["a:b:c"]
 676  
      * </pre>
 677  
      * 
 678  
      * @param str
 679  
      *            the String to parse, may be null
 680  
      * @param separatorChar
 681  
      *            the character used as the delimiter
 682  
      * @return an array of parsed Strings
 683  
      */
 684  
     public static String[] splitAll(String str, char separatorChar) {
 685  0
         if (str == null) {
 686  0
             return EMPTY_STRING_ARRAY.clone();
 687  
         }
 688  
 
 689  0
         int len = str.length();
 690  0
         if (len == 0) {
 691  0
             return EMPTY_STRING_ARRAY.clone();
 692  
         }
 693  
 
 694  
         // Determine the size of the array
 695  0
         int count = 1;
 696  0
         int start = 0;
 697  0
         int i = 0;
 698  0
         while ((i = str.indexOf(separatorChar, start)) != -1) {
 699  0
             ++count;
 700  0
             start = i + 1;
 701  
         }
 702  
 
 703  
         // Create the array
 704  0
         String[] list = new String[count];
 705  
 
 706  
         // If there were no separators
 707  
         // then we have one big part
 708  0
         if (count == 1) {
 709  0
             list[0] = str;
 710  0
             return list;
 711  
         }
 712  
 
 713  0
         start = 0;
 714  0
         i = 0;
 715  0
         for (int x = 0; x < count; x++) {
 716  0
             i = str.indexOf(separatorChar, start);
 717  0
             if (i != -1) {
 718  0
                 list[x] = str.substring(start, i);
 719  
             } else {
 720  0
                 list[x] = str.substring(start);
 721  
             }
 722  0
             start = i + 1;
 723  
         }
 724  
 
 725  0
         return list;
 726  
     }
 727  
 
 728  
     /**
 729  
      * <p>
 730  
      * Splits the provided text into an array, separator specified. This is an
 731  
      * alternative to using StringTokenizer.
 732  
      * </p>
 733  
      * 
 734  
      * <p>
 735  
      * The separator is not included in the returned String array. Adjacent
 736  
      * separators are treated individually.
 737  
      * </p>
 738  
      * 
 739  
      * <p>
 740  
      * A <code>null</code> input String returns <code>null</code>.
 741  
      * </p>
 742  
      * 
 743  
      * <pre>
 744  
      * StringUtil.splitAll(null, *, 2)         = []
 745  
      * StringUtil.splitAll("", *, 2)           = []
 746  
      * StringUtil.splitAll("a.b.c", '.', 2)    = ["a", "b"]
 747  
      * StringUtil.splitAll("a..b.c", '.', 2)   = ["a", ""]
 748  
      * StringUtil.splitAll("a:b:c", '.', 2)    = ["a:b:c"]
 749  
      * StringUtil.splitAll("a b c", ' ', 2)    = ["a", "b"]
 750  
      * </pre>
 751  
      * 
 752  
      * @param str
 753  
      *            the String to parse, may be null
 754  
      * @param separatorChar
 755  
      *            the character used as the delimiter
 756  
      * @param max
 757  
      *            the maximum number of elements to include in the array.
 758  
      *             A zero or negative value implies no limit
 759  
      * @return an array of parsed Strings
 760  
      */
 761  
     public static String[] splitAll(String str, char separatorChar, int max) {
 762  0
         if (str == null) {
 763  0
             return EMPTY_STRING_ARRAY.clone();
 764  
         }
 765  
 
 766  0
         int len = str.length();
 767  0
         if (len == 0) {
 768  0
             return EMPTY_STRING_ARRAY.clone();
 769  
         }
 770  
 
 771  
         // Determine the size of the array
 772  0
         int count = 1;
 773  0
         int start = 0;
 774  0
         int i = 0;
 775  0
         while ((i = str.indexOf(separatorChar, start)) != -1) {
 776  0
             ++count;
 777  0
             start = i + 1;
 778  
         }
 779  
 
 780  
         // If there were no separators
 781  
         // then we have one big part
 782  0
         if (count == 1) {
 783  0
             String[] list = new String[count];
 784  0
             list[0] = str;
 785  0
             return list;
 786  
         }
 787  
 
 788  
         // Limit the result
 789  0
         if (max > 0 && count > max) {
 790  0
             count = max;
 791  
         }
 792  
 
 793  
         // Create the array
 794  0
         String[] list = new String[count];
 795  
 
 796  0
         start = 0;
 797  0
         i = 0;
 798  0
         for (int x = 0; x < count; x++) {
 799  0
             i = str.indexOf(separatorChar, start);
 800  0
             if (i != -1) {
 801  0
                 list[x] = str.substring(start, i);
 802  
             } else {
 803  0
                 list[x] = str.substring(start, len);
 804  
             }
 805  0
             start = i + 1;
 806  
         }
 807  
 
 808  0
         return list;
 809  
     }
 810  
 
 811  
     /**
 812  
      * <p>
 813  
      * Joins the elements of the provided array into a single String containing
 814  
      * the provided list of elements.
 815  
      * </p>
 816  
      * 
 817  
      * <p>
 818  
      * No delimiter is added before or after the list. A <code>null</code>
 819  
      * separator is the same as an empty String (""). Null objects or empty
 820  
      * strings within the array are represented by empty strings.
 821  
      * </p>
 822  
      * 
 823  
      * <pre>
 824  
      * StringUtil.join(null, *)                = null
 825  
      * StringUtil.join([], *)                  = ""
 826  
      * StringUtil.join([null], *)              = ""
 827  
      * StringUtil.join(["a", "b", "c"], "--")  = "a--b--c"
 828  
      * StringUtil.join(["a", "b", "c"], null)  = "abc"
 829  
      * StringUtil.join(["a", "b", "c"], "")    = "abc"
 830  
      * StringUtil.join([null, "", "a"], ',')   = ",,a"
 831  
      * </pre>
 832  
      * 
 833  
      * @param array
 834  
      *            the array of values to join together, may be null
 835  
      * @param aSeparator
 836  
      *            the separator character to use, null treated as ""
 837  
      * @return the joined String, <code>null</code> if null array input
 838  
      */
 839  
     public static String join(Object[] array, String aSeparator) {
 840  0
         String separator = aSeparator;
 841  0
         if (array == null) {
 842  0
             return null;
 843  
         }
 844  0
         if (separator == null) {
 845  0
             separator = "";
 846  
         }
 847  0
         int arraySize = array.length;
 848  
 
 849  
         // ArraySize == 0: Len = 0
 850  
         // ArraySize > 0: Len = NofStrings *(len(firstString) + len(separator))
 851  
         // (Assuming that all Strings are roughly equally long)
 852  0
         int bufSize = arraySize == 0 ? 0 : arraySize * ((array[0] == null ? 16 : array[0].toString().length()) + separator.length());
 853  
 
 854  0
         StringBuilder buf = new StringBuilder(bufSize);
 855  
 
 856  0
         for (int i = 0; i < arraySize; i++) {
 857  0
             if (i > 0) {
 858  0
                 buf.append(separator);
 859  
             }
 860  0
             if (array[i] != null) {
 861  0
                 buf.append(array[i]);
 862  
             }
 863  
         }
 864  0
         return buf.toString();
 865  
     }
 866  
 
 867  
     /**
 868  
      * Find the first occurrence of a separator in the character buffer beginning
 869  
      * at the given offset.
 870  
      * 
 871  
      * @param str
 872  
      *            the String to parse, may be null
 873  
      * @param separatorChars
 874  
      *            the characters used as the delimiters, <code>null</code>
 875  
      *            splits on whitespace
 876  
      * @param offset
 877  
      *            the index of the first character to consider
 878  
      * @return the index of a separator char in the string or -1
 879  
      */
 880  
     public static int indexOfAny(char[] str, char[] separatorChars, int offset) {
 881  0
         int strlen = str.length;
 882  0
         int seplen = separatorChars.length;
 883  0
         for (int i = offset; i < strlen; i++) {
 884  0
             char ch = str[i];
 885  0
             for (int j = 0; j < seplen; j++) {
 886  0
                 if (separatorChars[j] == ch) {
 887  0
                     return i;
 888  
                 }
 889  
             }
 890  
         }
 891  0
         return -1;
 892  
     }
 893  
 
 894  
     /**
 895  
      * Find the first occurrence of a whitespace in the character buffer beginning
 896  
      * at the given offset. 
 897  
      * Whitespace is defined by {@link Character#isWhitespace(char)}.
 898  
      * 
 899  
      * @param str
 900  
      *            the String to parse, may be null
 901  
      * @param offset
 902  
      *            the index of the first character to consider
 903  
      * @return the index of a separator char in the string or -1
 904  
      */
 905  
     public static int indexOfWhitespace(char[] str, int offset) {
 906  0
         int strlen = str.length;
 907  0
         for (int i = offset; i < strlen; i++) {
 908  0
             if (Character.isWhitespace(str[i])) {
 909  0
                 return i;
 910  
             }
 911  
         }
 912  0
         return -1;
 913  
     }
 914  
 
 915  
     /**
 916  
      * An empty immutable <code>String</code> array.
 917  
      */
 918  0
     public static final String[] EMPTY_STRING_ARRAY = new String[0];
 919  
 
 920  
 }