001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache license, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the license for the specific language governing permissions and 015 * limitations under the license. 016 */ 017package org.apache.logging.log4j.util; 018 019import java.util.Iterator; 020import java.util.Locale; 021import java.util.Objects; 022 023/** 024 * <em>Consider this class private.</em> 025 * 026 * @see <a href="http://commons.apache.org/proper/commons-lang/">Apache Commons Lang</a> 027 */ 028public final class Strings { 029 030 private static final ThreadLocal<StringBuilder> tempStr = ThreadLocal.withInitial(StringBuilder::new); 031 032 /** 033 * The empty string. 034 */ 035 public static final String EMPTY = ""; 036 037 /** 038 * The empty array. 039 */ 040 public static final String[] EMPTY_ARRAY = {}; 041 042 /** 043 * OS-dependent line separator, defaults to {@code "\n"} if the system property {@code ""line.separator"} cannot be 044 * read. 045 */ 046 public static final String LINE_SEPARATOR = PropertiesUtil.getProperties().getStringProperty("line.separator", 047 "\n"); 048 049 /** 050 * Returns a double quoted string. 051 * 052 * @param str a String 053 * @return {@code "str"} 054 */ 055 public static String dquote(final String str) { 056 return Chars.DQUOTE + str + Chars.DQUOTE; 057 } 058 059 /** 060 * Checks if a String is blank. A blank string is one that is either 061 * {@code null}, empty, or all characters are {@link Character#isWhitespace(char)}. 062 * 063 * @param s the String to check, may be {@code null} 064 * @return {@code true} if the String is {@code null}, empty, or or all characters are {@link Character#isWhitespace(char)} 065 */ 066 public static boolean isBlank(final String s) { 067 if (s == null || s.isEmpty()) { 068 return true; 069 } 070 for (int i = 0; i < s.length(); i++) { 071 char c = s.charAt(i); 072 if (!Character.isWhitespace(c)) { 073 return false; 074 } 075 } 076 return true; 077 } 078 079 /** 080 * <p> 081 * Checks if a CharSequence is empty ("") or null. 082 * </p> 083 * 084 * <pre> 085 * Strings.isEmpty(null) = true 086 * Strings.isEmpty("") = true 087 * Strings.isEmpty(" ") = false 088 * Strings.isEmpty("bob") = false 089 * Strings.isEmpty(" bob ") = false 090 * </pre> 091 * 092 * <p> 093 * NOTE: This method changed in Lang version 2.0. It no longer trims the CharSequence. That functionality is 094 * available in isBlank(). 095 * </p> 096 * 097 * <p> 098 * Copied from Apache Commons Lang org.apache.commons.lang3.StringUtils.isEmpty(CharSequence) 099 * </p> 100 * 101 * @param cs the CharSequence to check, may be null 102 * @return {@code true} if the CharSequence is empty or null 103 */ 104 public static boolean isEmpty(final CharSequence cs) { 105 return cs == null || cs.length() == 0; 106 } 107 108 /** 109 * Checks if a String is not blank. The opposite of {@link #isBlank(String)}. 110 * 111 * @param s the String to check, may be {@code null} 112 * @return {@code true} if the String is non-{@code null} and has content after being trimmed. 113 */ 114 public static boolean isNotBlank(final String s) { 115 return !isBlank(s); 116 } 117 118 /** 119 * <p> 120 * Checks if a CharSequence is not empty ("") and not null. 121 * </p> 122 * 123 * <pre> 124 * Strings.isNotEmpty(null) = false 125 * Strings.isNotEmpty("") = false 126 * Strings.isNotEmpty(" ") = true 127 * Strings.isNotEmpty("bob") = true 128 * Strings.isNotEmpty(" bob ") = true 129 * </pre> 130 * 131 * <p> 132 * Copied from Apache Commons Lang org.apache.commons.lang3.StringUtils.isNotEmpty(CharSequence) 133 * </p> 134 * 135 * @param cs the CharSequence to check, may be null 136 * @return {@code true} if the CharSequence is not empty and not null 137 */ 138 public static boolean isNotEmpty(final CharSequence cs) { 139 return !isEmpty(cs); 140 } 141 142 /** 143 * <p>Joins the elements of the provided {@code Iterable} into 144 * a single String containing the provided elements.</p> 145 * 146 * <p>No delimiter is added before or after the list. Null objects or empty 147 * strings within the iteration are represented by empty strings.</p> 148 * 149 * @param iterable the {@code Iterable} providing the values to join together, may be null 150 * @param separator the separator character to use 151 * @return the joined String, {@code null} if null iterator input 152 */ 153 public static String join(final Iterable<?> iterable, final char separator) { 154 if (iterable == null) { 155 return null; 156 } 157 return join(iterable.iterator(), separator); 158 } 159 160 /** 161 * <p>Joins the elements of the provided {@code Iterator} into 162 * a single String containing the provided elements.</p> 163 * 164 * <p>No delimiter is added before or after the list. Null objects or empty 165 * strings within the iteration are represented by empty strings.</p> 166 * 167 * @param iterator the {@code Iterator} of values to join together, may be null 168 * @param separator the separator character to use 169 * @return the joined String, {@code null} if null iterator input 170 */ 171 public static String join(final Iterator<?> iterator, final char separator) { 172 173 // handle null, zero and one elements before building a buffer 174 if (iterator == null) { 175 return null; 176 } 177 if (!iterator.hasNext()) { 178 return EMPTY; 179 } 180 final Object first = iterator.next(); 181 if (!iterator.hasNext()) { 182 return Objects.toString(first, EMPTY); 183 } 184 185 // two or more elements 186 final StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small 187 if (first != null) { 188 buf.append(first); 189 } 190 191 while (iterator.hasNext()) { 192 buf.append(separator); 193 final Object obj = iterator.next(); 194 if (obj != null) { 195 buf.append(obj); 196 } 197 } 198 199 return buf.toString(); 200 } 201 202 /** 203 * <p>Gets the leftmost {@code len} characters of a String.</p> 204 * 205 * <p>If {@code len} characters are not available, or the 206 * String is {@code null}, the String will be returned without 207 * an exception. An empty String is returned if len is negative.</p> 208 * 209 * <pre> 210 * StringUtils.left(null, *) = null 211 * StringUtils.left(*, -ve) = "" 212 * StringUtils.left("", *) = "" 213 * StringUtils.left("abc", 0) = "" 214 * StringUtils.left("abc", 2) = "ab" 215 * StringUtils.left("abc", 4) = "abc" 216 * </pre> 217 * 218 * <p> 219 * Copied from Apache Commons Lang org.apache.commons.lang3.StringUtils. 220 * </p> 221 * 222 * @param str the String to get the leftmost characters from, may be null 223 * @param len the length of the required String 224 * @return the leftmost characters, {@code null} if null String input 225 */ 226 public static String left(final String str, final int len) { 227 if (str == null) { 228 return null; 229 } 230 if (len < 0) { 231 return EMPTY; 232 } 233 if (str.length() <= len) { 234 return str; 235 } 236 return str.substring(0, len); 237 } 238 239 /** 240 * Returns a quoted string. 241 * 242 * @param str a String 243 * @return {@code 'str'} 244 */ 245 public static String quote(final String str) { 246 return Chars.QUOTE + str + Chars.QUOTE; 247 } 248 249 /** 250 * <p> 251 * Removes control characters (char <= 32) from both ends of this String returning {@code null} if the String is 252 * empty ("") after the trim or if it is {@code null}. 253 * 254 * <p> 255 * The String is trimmed using {@link String#trim()}. Trim removes start and end characters <= 32. 256 * </p> 257 * 258 * <pre> 259 * Strings.trimToNull(null) = null 260 * Strings.trimToNull("") = null 261 * Strings.trimToNull(" ") = null 262 * Strings.trimToNull("abc") = "abc" 263 * Strings.trimToNull(" abc ") = "abc" 264 * </pre> 265 * 266 * <p> 267 * Copied from Apache Commons Lang org.apache.commons.lang3.StringUtils.trimToNull(String) 268 * </p> 269 * 270 * @param str the String to be trimmed, may be null 271 * @return the trimmed String, {@code null} if only chars <= 32, empty or null String input 272 */ 273 public static String trimToNull(final String str) { 274 final String ts = str == null ? null : str.trim(); 275 return isEmpty(ts) ? null : ts; 276 } 277 278 private Strings() { 279 // empty 280 } 281 282 /** 283 * Shorthand for {@code str.toUpperCase(Locale.ROOT);} 284 * @param str The string to upper case. 285 * @return a new string 286 * @see String#toLowerCase(Locale) 287 */ 288 public static String toRootUpperCase(final String str) { 289 return str.toUpperCase(Locale.ROOT); 290 } 291 292 /** 293 * Concatenates 2 Strings without allocation. 294 * @param str1 the first string. 295 * @param str2 the second string. 296 * @return the concatenated String. 297 */ 298 public static String concat(String str1, String str2) { 299 if (isEmpty(str1)) { 300 return str2; 301 } else if (isEmpty(str2)) { 302 return str1; 303 } 304 StringBuilder sb = tempStr.get(); 305 try { 306 return sb.append(str1).append(str2).toString(); 307 } finally { 308 sb.setLength(0); 309 } 310 } 311 312 /** 313 * Creates a new string repeating given {@code str} {@code count} times. 314 * @param str input string 315 * @param count the repetition count 316 * @return the new string 317 * @throws IllegalArgumentException if either {@code str} is null or {@code count} is negative 318 */ 319 public static String repeat(final String str, final int count) { 320 Objects.requireNonNull(str, "str"); 321 if (count < 0) { 322 throw new IllegalArgumentException("count"); 323 } 324 StringBuilder sb = tempStr.get(); 325 try { 326 for (int index = 0; index < count; index++) { 327 sb.append(str); 328 } 329 return sb.toString(); 330 } finally { 331 sb.setLength(0); 332 } 333 } 334 335}