001/*
002 * Copyright (C) 2014 Jörg Prante
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.xbib.elasticsearch.plugin.jdbc.util;
017
018import java.util.Arrays;
019import java.util.Iterator;
020import java.util.List;
021
022public final class Strings {
023
024    public static final String EMPTY = "";
025
026    private Strings() {
027        throw new UnsupportedOperationException();
028    }
029
030    /**
031     * <p>Gives a string consisting of the given character repeated the given number of
032     * times.</p>
033     *
034     * @param ch    the character to repeat
035     * @param count how many times to repeat the character
036     * @return the resultant string
037     */
038    public static String repeat(char ch, int count) {
039        StringBuilder buffer = new StringBuilder();
040
041        for (int i = 0; i < count; ++i) {
042            buffer.append(ch);
043        }
044
045        return buffer.toString();
046    }
047
048    /**
049     * <p>Tells whether the given string is either {@code} or consists solely of
050     * whitespace characters.</p>
051     *
052     * @param target string to check
053     * @return {@code true} if the target string is null or empty
054     */
055    public static boolean isNullOrEmpty(String target) {
056        return target == null || EMPTY.equals(target);
057    }
058
059    /**
060     * Gives a string consisting of the elements of a given array of strings, each
061     * separated by a given separator string.
062     *
063     * @param pieces    the strings to join
064     * @param separator the separator
065     * @return the joined string
066     */
067    public static String join(String[] pieces, String separator) {
068        return join(Arrays.asList(pieces), separator);
069    }
070
071    /**
072     * Gives a string consisting of the string representations of the elements of a
073     * given array of objects, each separated by a given separator string.
074     *
075     * @param pieces    the elements whose string representations are to be joined
076     * @param separator the separator
077     * @return the joined string
078     */
079    public static String join(List<String> pieces, String separator) {
080        StringBuilder buffer = new StringBuilder();
081
082        for (Iterator<String> iter = pieces.iterator(); iter.hasNext(); ) {
083            buffer.append(iter.next());
084
085            if (iter.hasNext()) {
086                buffer.append(separator);
087            }
088        }
089
090        return buffer.toString();
091    }
092
093    /**
094     * <p>Replaces a String with another String inside a larger String, once.</p>
095     * <p/>
096     * <p>A <code>null</code> reference passed to this method is a no-op.</p>
097     * <p/>
098     * <pre>
099     * StringUtils.replaceOnce(null, *, *)        = null
100     * StringUtils.replaceOnce("", *, *)          = ""
101     * StringUtils.replaceOnce("any", null, *)    = "any"
102     * StringUtils.replaceOnce("any", *, null)    = "any"
103     * StringUtils.replaceOnce("any", "", *)      = "any"
104     * StringUtils.replaceOnce("aba", "a", null)  = "aba"
105     * StringUtils.replaceOnce("aba", "a", "")    = "ba"
106     * StringUtils.replaceOnce("aba", "a", "z")   = "zba"
107     * </pre>
108     *
109     * @param text         text to search and replace in, may be null
110     * @param searchString the String to search for, may be null
111     * @param replacement  the String to replace with, may be null
112     * @return the text with any replacements processed,
113     * <code>null</code> if null String input
114     * @see #replace(String text, String searchString, String replacement, int max)
115     */
116    public static String replaceOnce(String text, String searchString, String replacement) {
117        return replace(text, searchString, replacement, 1);
118    }
119
120    /**
121     * <p>Replaces all occurrences of a String within another String.</p>
122     * <p/>
123     * <p>A <code>null</code> reference passed to this method is a no-op.</p>
124     * <p/>
125     * <pre>
126     * StringUtils.replace(null, *, *)        = null
127     * StringUtils.replace("", *, *)          = ""
128     * StringUtils.replace("any", null, *)    = "any"
129     * StringUtils.replace("any", *, null)    = "any"
130     * StringUtils.replace("any", "", *)      = "any"
131     * StringUtils.replace("aba", "a", null)  = "aba"
132     * StringUtils.replace("aba", "a", "")    = "b"
133     * StringUtils.replace("aba", "a", "z")   = "zbz"
134     * </pre>
135     *
136     * @param text         text to search and replace in, may be null
137     * @param searchString the String to search for, may be null
138     * @param replacement  the String to replace it with, may be null
139     * @return the text with any replacements processed,
140     * <code>null</code> if null String input
141     * @see #replace(String text, String searchString, String replacement, int max)
142     */
143    public static String replace(String text, String searchString, String replacement) {
144        return replace(text, searchString, replacement, -1);
145    }
146
147    /**
148     * <p>Replaces a String with another String inside a larger String,
149     * for the first <code>max</code> values of the search String.</p>
150     * <p/>
151     * <p>A <code>null</code> reference passed to this method is a no-op.</p>
152     * <p/>
153     * <pre>
154     * StringUtils.replace(null, *, *, *)         = null
155     * StringUtils.replace("", *, *, *)           = ""
156     * StringUtils.replace("any", null, *, *)     = "any"
157     * StringUtils.replace("any", *, null, *)     = "any"
158     * StringUtils.replace("any", "", *, *)       = "any"
159     * StringUtils.replace("any", *, *, 0)        = "any"
160     * StringUtils.replace("abaa", "a", null, -1) = "abaa"
161     * StringUtils.replace("abaa", "a", "", -1)   = "b"
162     * StringUtils.replace("abaa", "a", "z", 0)   = "abaa"
163     * StringUtils.replace("abaa", "a", "z", 1)   = "zbaa"
164     * StringUtils.replace("abaa", "a", "z", 2)   = "zbza"
165     * StringUtils.replace("abaa", "a", "z", -1)  = "zbzz"
166     * </pre>
167     *
168     * @param text         text to search and replace in, may be null
169     * @param searchString the String to search for, may be null
170     * @param replacement  the String to replace it with, may be null
171     * @param max          maximum number of values to replace, or <code>-1</code> if no maximum
172     * @return the text with any replacements processed,
173     * <code>null</code> if null String input
174     */
175    public static String replace(String text, String searchString, String replacement, int max) {
176        if (isNullOrEmpty(text) || isNullOrEmpty(searchString) || replacement == null || max == 0) {
177            return text;
178        }
179        int start = 0;
180        int end = text.indexOf(searchString, start);
181        if (end == -1) {
182            return text;
183        }
184        int replLength = searchString.length();
185        int increase = replacement.length() - replLength;
186        increase = (increase < 0 ? 0 : increase);
187        increase *= (max < 0 ? 16 : (max > 64 ? 64 : max));
188        StringBuilder buf = new StringBuilder(text.length() + increase);
189        while (end != -1) {
190            buf.append(text.substring(start, end)).append(replacement);
191            start = end + replLength;
192            if (--max == 0) {
193                break;
194            }
195            end = text.indexOf(searchString, start);
196        }
197        buf.append(text.substring(start));
198        return buf.toString();
199    }
200
201}