<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>StringUtils.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Shiro :: Core</a> &gt; <a href="index.source.html" class="el_package">org.apache.shiro.util</a> &gt; <span class="el_source">StringUtils.java</span></div><h1>StringUtils.java</h1><pre class="source lang-java linenums">/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * &quot;License&quot;); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.shiro.util;

import java.text.ParseException;
import java.util.*;

/**
 * &lt;p&gt;Simple utility class for String operations useful across the framework.
 * &lt;p/&gt;
 * &lt;p&gt;Some methods in this class were copied from the Spring Framework so we didn't have to re-invent the wheel,
 * and in these cases, we have retained all license, copyright and author information.
 *
 * @since 0.9
 */
<span class="nc" id="L32">public class StringUtils {</span>

    //TODO - complete JavaDoc

    /**
     * Constant representing the empty string, equal to &amp;quot;&amp;quot;
     */
    public static final String EMPTY_STRING = &quot;&quot;;

    /**
     * Constant representing the default delimiter character (comma), equal to &lt;code&gt;','&lt;/code&gt;
     */
    public static final char DEFAULT_DELIMITER_CHAR = ',';

    /**
     * Constant representing the default quote character (double quote), equal to '&amp;quot;'&lt;/code&gt;
     */
    public static final char DEFAULT_QUOTE_CHAR = '&quot;';

    /**
     * Check whether the given String has actual text.
     * More specifically, returns &lt;code&gt;true&lt;/code&gt; if the string not &lt;code&gt;null&lt;/code&gt;,
     * its length is greater than 0, and it contains at least one non-whitespace character.
     * &lt;p/&gt;
     * &lt;code&gt;StringUtils.hasText(null) == false&lt;br/&gt;
     * StringUtils.hasText(&quot;&quot;) == false&lt;br/&gt;
     * StringUtils.hasText(&quot; &quot;) == false&lt;br/&gt;
     * StringUtils.hasText(&quot;12345&quot;) == true&lt;br/&gt;
     * StringUtils.hasText(&quot; 12345 &quot;) == true&lt;/code&gt;
     * &lt;p/&gt;
     * &lt;p&gt;Copied from the Spring Framework while retaining all license, copyright and author information.
     *
     * @param str the String to check (may be &lt;code&gt;null&lt;/code&gt;)
     * @return &lt;code&gt;true&lt;/code&gt; if the String is not &lt;code&gt;null&lt;/code&gt;, its length is
     *         greater than 0, and it does not contain whitespace only
     * @see java.lang.Character#isWhitespace
     */
    public static boolean hasText(String str) {
<span class="fc bfc" id="L70" title="All 2 branches covered.">        if (!hasLength(str)) {</span>
<span class="fc" id="L71">            return false;</span>
        }
<span class="fc" id="L73">        int strLen = str.length();</span>
<span class="fc bfc" id="L74" title="All 2 branches covered.">        for (int i = 0; i &lt; strLen; i++) {</span>
<span class="fc bfc" id="L75" title="All 2 branches covered.">            if (!Character.isWhitespace(str.charAt(i))) {</span>
<span class="fc" id="L76">                return true;</span>
            }
        }
<span class="fc" id="L79">        return false;</span>
    }

    /**
     * Check that the given String is neither &lt;code&gt;null&lt;/code&gt; nor of length 0.
     * Note: Will return &lt;code&gt;true&lt;/code&gt; for a String that purely consists of whitespace.
     * &lt;p/&gt;
     * &lt;code&gt;StringUtils.hasLength(null) == false&lt;br/&gt;
     * StringUtils.hasLength(&quot;&quot;) == false&lt;br/&gt;
     * StringUtils.hasLength(&quot; &quot;) == true&lt;br/&gt;
     * StringUtils.hasLength(&quot;Hello&quot;) == true&lt;/code&gt;
     * &lt;p/&gt;
     * Copied from the Spring Framework while retaining all license, copyright and author information.
     *
     * @param str the String to check (may be &lt;code&gt;null&lt;/code&gt;)
     * @return &lt;code&gt;true&lt;/code&gt; if the String is not null and has length
     * @see #hasText(String)
     */
    public static boolean hasLength(String str) {
<span class="fc bfc" id="L98" title="All 4 branches covered.">        return (str != null &amp;&amp; str.length() &gt; 0);</span>
    }


    /**
     * Test if the given String starts with the specified prefix,
     * ignoring upper/lower case.
     * &lt;p/&gt;
     * &lt;p&gt;Copied from the Spring Framework while retaining all license, copyright and author information.
     *
     * @param str    the String to check
     * @param prefix the prefix to look for
     * @return &lt;code&gt;true&lt;/code&gt; starts with the specified prefix (ignoring case), &lt;code&gt;false&lt;/code&gt; if it does not.
     * @see java.lang.String#startsWith
     */
    public static boolean startsWithIgnoreCase(String str, String prefix) {
<span class="nc bnc" id="L114" title="All 4 branches missed.">        if (str == null || prefix == null) {</span>
<span class="nc" id="L115">            return false;</span>
        }
<span class="nc bnc" id="L117" title="All 2 branches missed.">        if (str.startsWith(prefix)) {</span>
<span class="nc" id="L118">            return true;</span>
        }
<span class="nc bnc" id="L120" title="All 2 branches missed.">        if (str.length() &lt; prefix.length()) {</span>
<span class="nc" id="L121">            return false;</span>
        }
<span class="nc" id="L123">        String lcStr = str.substring(0, prefix.length()).toLowerCase();</span>
<span class="nc" id="L124">        String lcPrefix = prefix.toLowerCase();</span>
<span class="nc" id="L125">        return lcStr.equals(lcPrefix);</span>
    }

    /**
     * Returns a 'cleaned' representation of the specified argument.  'Cleaned' is defined as the following:
     * &lt;p/&gt;
     * &lt;ol&gt;
     * &lt;li&gt;If the specified &lt;code&gt;String&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt;, return &lt;code&gt;null&lt;/code&gt;&lt;/li&gt;
     * &lt;li&gt;If not &lt;code&gt;null&lt;/code&gt;, {@link String#trim() trim()} it.&lt;/li&gt;
     * &lt;li&gt;If the trimmed string is equal to the empty String (i.e. &amp;quot;&amp;quot;), return &lt;code&gt;null&lt;/code&gt;&lt;/li&gt;
     * &lt;li&gt;If the trimmed string is not the empty string, return the trimmed version&lt;/li&gt;.
     * &lt;/ol&gt;
     * &lt;p/&gt;
     * Therefore this method always ensures that any given string has trimmed text, and if it doesn't, &lt;code&gt;null&lt;/code&gt;
     * is returned.
     *
     * @param in the input String to clean.
     * @return a populated-but-trimmed String or &lt;code&gt;null&lt;/code&gt; otherwise
     */
    public static String clean(String in) {
<span class="fc" id="L145">        String out = in;</span>

<span class="fc bfc" id="L147" title="All 2 branches covered.">        if (in != null) {</span>
<span class="fc" id="L148">            out = in.trim();</span>
<span class="fc bfc" id="L149" title="All 2 branches covered.">            if (out.equals(EMPTY_STRING)) {</span>
<span class="fc" id="L150">                out = null;</span>
            }
        }

<span class="fc" id="L154">        return out;</span>
    }

    /**
     * Returns the specified array as a comma-delimited (',') string.
     *
     * @param array the array whose contents will be converted to a string.
     * @return the array's contents as a comma-delimited (',') string.
     * @since 1.0
     */
    public static String toString(Object[] array) {
<span class="fc" id="L165">        return toDelimitedString(array, &quot;,&quot;);</span>
    }

    /**
     * Returns the array's contents as a string, with each element delimited by the specified
     * {@code delimiter} argument.  Useful for {@code toString()} implementations and log messages.
     *
     * @param array     the array whose contents will be converted to a string
     * @param delimiter the delimiter to use between each element
     * @return a single string, delimited by the specified {@code delimiter}.
     * @since 1.0
     */
    public static String toDelimitedString(Object[] array, String delimiter) {
<span class="pc bpc" id="L178" title="2 of 4 branches missed.">        if (array == null || array.length == 0) {</span>
<span class="nc" id="L179">            return EMPTY_STRING;</span>
        }
<span class="fc" id="L181">        StringBuilder sb = new StringBuilder();</span>
<span class="fc bfc" id="L182" title="All 2 branches covered.">        for (int i = 0; i &lt; array.length; i++) {</span>
<span class="fc bfc" id="L183" title="All 2 branches covered.">            if (i &gt; 0) {</span>
<span class="fc" id="L184">                sb.append(delimiter);</span>
            }
<span class="fc" id="L186">            sb.append(array[i]);</span>
        }
<span class="fc" id="L188">        return sb.toString();</span>
    }

    /**
     * Returns the collection's contents as a string, with each element delimited by the specified
     * {@code delimiter} argument.  Useful for {@code toString()} implementations and log messages.
     *
     * @param c         the collection whose contents will be converted to a string
     * @param delimiter the delimiter to use between each element
     * @return a single string, delimited by the specified {@code delimiter}.
     * @since 1.2
     */
    public static String toDelimitedString(Collection c, String delimiter) {
<span class="nc bnc" id="L201" title="All 4 branches missed.">        if (c == null || c.isEmpty()) {</span>
<span class="nc" id="L202">            return EMPTY_STRING;</span>
        }
<span class="nc" id="L204">        return join(c.iterator(), delimiter);</span>
    }

    /**
     * Tokenize the given String into a String array via a StringTokenizer.
     * Trims tokens and omits empty tokens.
     * &lt;p&gt;The given delimiters string is supposed to consist of any number of
     * delimiter characters. Each of those characters can be used to separate
     * tokens. A delimiter is always a single character; for multi-character
     * delimiters, consider using &lt;code&gt;delimitedListToStringArray&lt;/code&gt;
     * &lt;p/&gt;
     * &lt;p&gt;Copied from the Spring Framework while retaining all license, copyright and author information.
     *
     * @param str        the String to tokenize
     * @param delimiters the delimiter characters, assembled as String
     *                   (each of those characters is individually considered as delimiter).
     * @return an array of the tokens
     * @see java.util.StringTokenizer
     * @see java.lang.String#trim()
     */
    public static String[] tokenizeToStringArray(String str, String delimiters) {
<span class="nc" id="L225">        return tokenizeToStringArray(str, delimiters, true, true);</span>
    }

    /**
     * Tokenize the given String into a String array via a StringTokenizer.
     * &lt;p&gt;The given delimiters string is supposed to consist of any number of
     * delimiter characters. Each of those characters can be used to separate
     * tokens. A delimiter is always a single character; for multi-character
     * delimiters, consider using &lt;code&gt;delimitedListToStringArray&lt;/code&gt;
     * &lt;p/&gt;
     * &lt;p&gt;Copied from the Spring Framework while retaining all license, copyright and author information.
     *
     * @param str               the String to tokenize
     * @param delimiters        the delimiter characters, assembled as String
     *                          (each of those characters is individually considered as delimiter)
     * @param trimTokens        trim the tokens via String's &lt;code&gt;trim&lt;/code&gt;
     * @param ignoreEmptyTokens omit empty tokens from the result array
     *                          (only applies to tokens that are empty after trimming; StringTokenizer
     *                          will not consider subsequent delimiters as token in the first place).
     * @return an array of the tokens (&lt;code&gt;null&lt;/code&gt; if the input String
     *         was &lt;code&gt;null&lt;/code&gt;)
     * @see java.util.StringTokenizer
     * @see java.lang.String#trim()
     */
    @SuppressWarnings({&quot;unchecked&quot;})
    public static String[] tokenizeToStringArray(
            String str, String delimiters, boolean trimTokens, boolean ignoreEmptyTokens) {

<span class="nc bnc" id="L253" title="All 2 branches missed.">        if (str == null) {</span>
<span class="nc" id="L254">            return null;</span>
        }
<span class="nc" id="L256">        StringTokenizer st = new StringTokenizer(str, delimiters);</span>
<span class="nc" id="L257">        List tokens = new ArrayList();</span>
<span class="nc bnc" id="L258" title="All 2 branches missed.">        while (st.hasMoreTokens()) {</span>
<span class="nc" id="L259">            String token = st.nextToken();</span>
<span class="nc bnc" id="L260" title="All 2 branches missed.">            if (trimTokens) {</span>
<span class="nc" id="L261">                token = token.trim();</span>
            }
<span class="nc bnc" id="L263" title="All 4 branches missed.">            if (!ignoreEmptyTokens || token.length() &gt; 0) {</span>
<span class="nc" id="L264">                tokens.add(token);</span>
            }
<span class="nc" id="L266">        }</span>
<span class="nc" id="L267">        return toStringArray(tokens);</span>
    }

    /**
     * Copy the given Collection into a String array.
     * The Collection must contain String elements only.
     * &lt;p/&gt;
     * &lt;p&gt;Copied from the Spring Framework while retaining all license, copyright and author information.
     *
     * @param collection the Collection to copy
     * @return the String array (&lt;code&gt;null&lt;/code&gt; if the passed-in
     *         Collection was &lt;code&gt;null&lt;/code&gt;)
     */
    @SuppressWarnings({&quot;unchecked&quot;})
    public static String[] toStringArray(Collection collection) {
<span class="nc bnc" id="L282" title="All 2 branches missed.">        if (collection == null) {</span>
<span class="nc" id="L283">            return null;</span>
        }
<span class="nc" id="L285">        return (String[]) collection.toArray(new String[collection.size()]);</span>
    }

    public static String[] splitKeyValue(String aLine) throws ParseException {
<span class="fc" id="L289">        String line = clean(aLine);</span>
<span class="pc bpc" id="L290" title="1 of 2 branches missed.">        if (line == null) {</span>
<span class="nc" id="L291">            return null;</span>
        }
<span class="fc" id="L293">        String[] split = line.split(&quot; &quot;, 2);</span>
<span class="pc bpc" id="L294" title="1 of 2 branches missed.">        if (split.length != 2) {</span>
            //fallback to checking for an equals sign
<span class="nc" id="L296">            split = line.split(&quot;=&quot;, 2);</span>
<span class="nc bnc" id="L297" title="All 2 branches missed.">            if (split.length != 2) {</span>
<span class="nc" id="L298">                String msg = &quot;Unable to determine Key/Value pair from line [&quot; + line + &quot;].  There is no space from &quot; +</span>
                        &quot;which the split location could be determined.&quot;;
<span class="nc" id="L300">                throw new ParseException(msg, 0);</span>
            }

        }

<span class="fc" id="L305">        split[0] = clean(split[0]);</span>
<span class="fc" id="L306">        split[1] = clean(split[1]);</span>
<span class="pc bpc" id="L307" title="1 of 2 branches missed.">        if (split[1].startsWith(&quot;=&quot;)) {</span>
            //they used spaces followed by an equals followed by zero or more spaces to split the key/value pair, so
            //remove the equals sign to result in only the key and values in the
<span class="fc" id="L310">            split[1] = clean(split[1].substring(1));</span>
        }

<span class="pc bpc" id="L313" title="1 of 2 branches missed.">        if (split[0] == null) {</span>
<span class="nc" id="L314">            String msg = &quot;No valid key could be found in line [&quot; + line + &quot;] to form a key/value pair.&quot;;</span>
<span class="nc" id="L315">            throw new ParseException(msg, 0);</span>
        }
<span class="pc bpc" id="L317" title="1 of 2 branches missed.">        if (split[1] == null) {</span>
<span class="nc" id="L318">            String msg = &quot;No corresponding value could be found in line [&quot; + line + &quot;] for key [&quot; + split[0] + &quot;]&quot;;</span>
<span class="nc" id="L319">            throw new ParseException(msg, 0);</span>
        }

<span class="fc" id="L322">        return split;</span>
    }

    public static String[] split(String line) {
<span class="fc" id="L326">        return split(line, DEFAULT_DELIMITER_CHAR);</span>
    }

    public static String[] split(String line, char delimiter) {
<span class="fc" id="L330">        return split(line, delimiter, DEFAULT_QUOTE_CHAR);</span>
    }

    public static String[] split(String line, char delimiter, char quoteChar) {
<span class="fc" id="L334">        return split(line, delimiter, quoteChar, quoteChar);</span>
    }

    public static String[] split(String line, char delimiter, char beginQuoteChar, char endQuoteChar) {
<span class="fc" id="L338">        return split(line, delimiter, beginQuoteChar, endQuoteChar, false, true);</span>
    }

    /**
     * Splits the specified delimited String into tokens, supporting quoted tokens so that quoted strings themselves
     * won't be tokenized.
     * &lt;p/&gt;
     * This method's implementation is very loosely based (with significant modifications) on
     * &lt;a href=&quot;http://blogs.bytecode.com.au/glen&quot;&gt;Glen Smith&lt;/a&gt;'s open-source
     * &lt;a href=&quot;http://opencsv.svn.sourceforge.net/viewvc/opencsv/trunk/src/au/com/bytecode/opencsv/CSVReader.java?&amp;view=markup&quot;&gt;CSVReader.java&lt;/a&gt;
     * file.
     * &lt;p/&gt;
     * That file is Apache 2.0 licensed as well, making Glen's code a great starting point for us to modify to
     * our needs.
     *
     * @param aLine          the String to parse
     * @param delimiter      the delimiter by which the &lt;tt&gt;line&lt;/tt&gt; argument is to be split
     * @param beginQuoteChar the character signifying the start of quoted text (so the quoted text will not be split)
     * @param endQuoteChar   the character signifying the end of quoted text
     * @param retainQuotes   if the quotes themselves should be retained when constructing the corresponding token
     * @param trimTokens     if leading and trailing whitespace should be trimmed from discovered tokens.
     * @return the tokens discovered from parsing the given delimited &lt;tt&gt;line&lt;/tt&gt;.
     */
    public static String[] split(String aLine, char delimiter, char beginQuoteChar, char endQuoteChar,
                                 boolean retainQuotes, boolean trimTokens) {
<span class="fc" id="L363">        String line = clean(aLine);</span>
<span class="fc bfc" id="L364" title="All 2 branches covered.">        if (line == null) {</span>
<span class="fc" id="L365">            return null;</span>
        }

<span class="fc" id="L368">        List&lt;String&gt; tokens = new ArrayList&lt;String&gt;();</span>
<span class="fc" id="L369">        StringBuilder sb = new StringBuilder();</span>
<span class="fc" id="L370">        boolean inQuotes = false;</span>

<span class="fc bfc" id="L372" title="All 2 branches covered.">        for (int i = 0; i &lt; line.length(); i++) {</span>

<span class="fc" id="L374">            char c = line.charAt(i);</span>
<span class="fc bfc" id="L375" title="All 2 branches covered.">            if (c == beginQuoteChar) {</span>
                // this gets complex... the quote may end a quoted block, or escape another quote.
                // do a 1-char lookahead:
<span class="fc bfc" id="L378" title="All 2 branches covered.">                if (inQuotes  // we are in quotes, therefore there can be escaped quotes in here.</span>
<span class="pc bpc" id="L379" title="1 of 2 branches missed.">                        &amp;&amp; line.length() &gt; (i + 1)  // there is indeed another character to check.</span>
<span class="fc bfc" id="L380" title="All 2 branches covered.">                        &amp;&amp; line.charAt(i + 1) == beginQuoteChar) { // ..and that char. is a quote also.</span>
                    // we have two quote chars in a row == one quote char, so consume them both and
                    // put one on the token. we do *not* exit the quoted text.
<span class="fc" id="L383">                    sb.append(line.charAt(i + 1));</span>
<span class="fc" id="L384">                    i++;</span>
                } else {
<span class="fc bfc" id="L386" title="All 2 branches covered.">                    inQuotes = !inQuotes;</span>
<span class="fc bfc" id="L387" title="All 2 branches covered.">                    if (retainQuotes) {</span>
<span class="fc" id="L388">                        sb.append(c);</span>
                    }
                }
<span class="fc bfc" id="L391" title="All 2 branches covered.">            } else if (c == endQuoteChar) {</span>
<span class="pc bpc" id="L392" title="1 of 2 branches missed.">                inQuotes = !inQuotes;</span>
<span class="fc bfc" id="L393" title="All 2 branches covered.">                if (retainQuotes) {</span>
<span class="fc" id="L394">                    sb.append(c);</span>
                }
<span class="fc bfc" id="L396" title="All 4 branches covered.">            } else if (c == delimiter &amp;&amp; !inQuotes) {</span>
<span class="fc" id="L397">                String s = sb.toString();</span>
<span class="pc bpc" id="L398" title="1 of 2 branches missed.">                if (trimTokens) {</span>
<span class="fc" id="L399">                    s = s.trim();</span>
                }
<span class="fc" id="L401">                tokens.add(s);</span>
<span class="fc" id="L402">                sb = new StringBuilder(); // start work on next token</span>
<span class="fc" id="L403">            } else {</span>
<span class="fc" id="L404">                sb.append(c);</span>
            }
        }
<span class="fc" id="L407">        String s = sb.toString();</span>
<span class="pc bpc" id="L408" title="1 of 2 branches missed.">        if (trimTokens) {</span>
<span class="fc" id="L409">            s = s.trim();</span>
        }
<span class="fc" id="L411">        tokens.add(s);</span>
<span class="fc" id="L412">        return tokens.toArray(new String[tokens.size()]);</span>
    }

    /**
     * Joins the elements of the provided {@code Iterator} into
     * a single String containing the provided elements.&lt;/p&gt;
     * &lt;p/&gt;
     * No delimiter is added before or after the list.
     * A {@code null} separator is the same as an empty String (&quot;&quot;).&lt;/p&gt;
     * &lt;p/&gt;
     * Copied from Commons Lang, version 3 (r1138702).&lt;/p&gt;
     *
     * @param iterator  the {@code Iterator} of values to join together, may be null
     * @param separator the separator character to use, null treated as &quot;&quot;
     * @return the joined String, {@code null} if null iterator input
     * @since 1.2
     */
    public static String join(Iterator&lt;?&gt; iterator, String separator) {
<span class="nc" id="L430">        final String empty = &quot;&quot;;</span>

        // handle null, zero and one elements before building a buffer
<span class="nc bnc" id="L433" title="All 2 branches missed.">        if (iterator == null) {</span>
<span class="nc" id="L434">            return null;</span>
        }
<span class="nc bnc" id="L436" title="All 2 branches missed.">        if (!iterator.hasNext()) {</span>
<span class="nc" id="L437">            return empty;</span>
        }
<span class="nc" id="L439">        Object first = iterator.next();</span>
<span class="nc bnc" id="L440" title="All 2 branches missed.">        if (!iterator.hasNext()) {</span>
<span class="nc bnc" id="L441" title="All 2 branches missed.">            return first == null ? empty : first.toString();</span>
        }

        // two or more elements
<span class="nc" id="L445">        StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small</span>
<span class="nc bnc" id="L446" title="All 2 branches missed.">        if (first != null) {</span>
<span class="nc" id="L447">            buf.append(first);</span>
        }

<span class="nc bnc" id="L450" title="All 2 branches missed.">        while (iterator.hasNext()) {</span>
<span class="nc bnc" id="L451" title="All 2 branches missed.">            if (separator != null) {</span>
<span class="nc" id="L452">                buf.append(separator);</span>
            }
<span class="nc" id="L454">            Object obj = iterator.next();</span>
<span class="nc bnc" id="L455" title="All 2 branches missed.">            if (obj != null) {</span>
<span class="nc" id="L456">                buf.append(obj);</span>
            }
<span class="nc" id="L458">        }</span>
<span class="nc" id="L459">        return buf.toString();</span>
    }

    /**
     * Splits the {@code delimited} string (delimited by the specified {@code separator} character) and returns the
     * delimited values as a {@code Set}.
     * &lt;p/&gt;
     * If either argument is {@code null}, this method returns {@code null}.
     *
     * @param delimited the string to split
     * @param separator the character that delineates individual tokens to split
     * @return the delimited values as a {@code Set}.
     * @since 1.2
     */
    public static Set&lt;String&gt; splitToSet(String delimited, String separator) {
<span class="pc bpc" id="L474" title="2 of 4 branches missed.">        if (delimited == null || separator == null) {</span>
<span class="nc" id="L475">            return null;</span>
        }
<span class="fc" id="L477">        String[] split = split(delimited, separator.charAt(0));</span>
<span class="fc" id="L478">        return CollectionUtils.asSet(split);</span>
    }

    /**
     * Returns the input argument, but ensures the first character is capitalized (if possible).
     * @param in the string to uppercase the first character.
     * @return the input argument, but with the first character capitalized (if possible).
     * @since 1.2
     */
    public static String uppercaseFirstChar(String in) {
<span class="pc bpc" id="L488" title="2 of 4 branches missed.">        if (in == null || in.length() == 0) {</span>
<span class="nc" id="L489">            return in;</span>
        }
<span class="fc" id="L491">        int length = in.length();</span>
<span class="fc" id="L492">        StringBuilder sb = new StringBuilder(length);</span>

<span class="fc" id="L494">        sb.append(Character.toUpperCase(in.charAt(0)));</span>
<span class="pc bpc" id="L495" title="1 of 2 branches missed.">        if (length &gt; 1) {</span>
<span class="fc" id="L496">            String remaining = in.substring(1);</span>
<span class="fc" id="L497">            sb.append(remaining);</span>
        }
<span class="fc" id="L499">        return sb.toString();</span>
    }

}
</pre><div class="footer"><span class="right">Created with <a href="http://www.eclemma.org/jacoco">JaCoCo</a> 0.7.7.201606060606</span></div></body></html>