001/**
002 * The MIT License (MIT)
003 *
004 * Copyright (c) 2017 tools4j.org (Marco Terzer)
005 *
006 * Permission is hereby granted, free of charge, to any person obtaining a copy
007 * of this software and associated documentation files (the "Software"), to deal
008 * in the Software without restriction, including without limitation the rights
009 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
010 * copies of the Software, and to permit persons to whom the Software is
011 * furnished to do so, subject to the following conditions:
012 *
013 * The above copyright notice and this permission notice shall be included in all
014 * copies or substantial portions of the Software.
015 *
016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
019 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
020 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
022 * SOFTWARE.
023 */
024package org.tools4j.spockito;
025
026import java.util.Arrays;
027import java.util.regex.Pattern;
028
029/**
030 * Contains static utility methods dealing with strings.
031 */
032final class Strings {
033
034    static final Pattern UNESCAPED_COMMA = Pattern.compile("(?<=[^\\\\]),");
035    static final Pattern UNESCAPED_SEMICOLON = Pattern.compile("(?<=[^\\\\]);");
036    static final Pattern UNESCAPED_COLON = Pattern.compile("(?<=[^\\\\]):");
037    static final Pattern UNESCAPED_EQUAL = Pattern.compile("(?<=[^\\\\])=");
038
039    static String firstCharToUpperCase(final String value) {
040        return value.length() > 0 ? Character.toUpperCase(value.charAt(0)) + value.substring(1) : value;
041    }
042
043    static String removeSurroundingPipes(final String s) {
044        return removeStartAndEndChars(s, '|', '|');
045    }
046
047    static String removeStartAndEndChars(final String s, final char startQuoteChar, final char endQuoteChar) {
048        final int len = s.length();
049        if (len >= 2 && s.charAt(0) == startQuoteChar && s.charAt(len - 1) == endQuoteChar) {
050            return s.substring(1, len - 1);
051        }
052        return s;
053    }
054
055    static boolean allCharsMatchingAnyOf(final String s, final char ch1, final char ch2) {
056        final int len = s.length();
057        for (int i = 0; i < len; i++) {
058            if (s.charAt(i) != ch1 && s.charAt(i) != ch2) {
059                return false;
060            }
061        }
062        return true;
063    }
064
065    static String unescape(final String s) {
066        return unescape(s, ',', ';', '|', '=', '\\','\'');
067    }
068
069    static String unescape(final String s, final char... escapedChars) {
070        int index = s.indexOf('\\');
071        if (index < 0) {
072            return s;
073        }
074        final StringBuilder sb = new StringBuilder(s);
075        while (index >= 0 && index + 1 < sb.length()) {
076            final char ch = sb.charAt(index + 1);
077            if (isCharAnyOf(ch, escapedChars)) {
078                sb.delete(index, index + 1);
079                index = sb.indexOf("\\", index + 1);
080            } else {
081                index = sb.indexOf("\\", index + 2);
082            }
083        }
084        return s.length() == sb.length() ? s : sb.toString();
085    }
086
087    static boolean isCharAnyOf(final char ch, final char... chars) {
088        for (final char c : chars) {
089            if (ch == c) {
090                return true;
091            }
092        }
093        return false;
094    }
095
096    static String[] split(final String s, final Pattern delimRegex1, final Pattern delimRegex2) {
097        String[] parts = delimRegex1.split(s);
098        if (parts.length == 1 && s.equals(parts[0])) {
099            //delimiter was not contained in string, try second delimiter
100            parts = delimRegex2.split(s);
101            if (parts.length == 1 && s.equals(parts[0])) {
102                //delimiter was not contained in string, we're done
103                return parts;
104            }
105        }
106        if (!s.startsWith(parts[0])) {
107            //must be delimiter at the start of the string, meaning we have an empty string at the start
108            final String[] newParts = new String[parts.length + 1];
109            System.arraycopy(parts, 0, newParts, 1, parts.length);
110            newParts[0] = "";
111            parts = newParts;
112        }
113        if (!s.endsWith(parts[parts.length - 1])) {
114            //must be delimiter at the end of the string, meaning we have an empty string at the end
115            parts = Arrays.copyOf(parts, parts.length + 1);
116            parts[parts.length - 1] = "";
117        }
118        return parts;
119    }
120
121    private Strings() {
122        throw new RuntimeException("No Strings for you!");
123    }
124}