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}