View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.util;
18  
19  import java.util.Iterator;
20  import java.util.Locale;
21  import java.util.Objects;
22  
23  /**
24   * <em>Consider this class private.</em>
25   * 
26   * @see <a href="http://commons.apache.org/proper/commons-lang/">Apache Commons Lang</a>
27   */
28  public final class Strings {
29  
30      private static final ThreadLocal<StringBuilder> tempStr = ThreadLocal.withInitial(StringBuilder::new);
31  
32      /**
33       * The empty string.
34       */
35      public static final String EMPTY = "";
36      
37      /**
38       * The empty array.
39       */
40      public static final String[] EMPTY_ARRAY = {};
41      
42      /**
43       * OS-dependent line separator, defaults to {@code "\n"} if the system property {@code ""line.separator"} cannot be
44       * read.
45       */
46      public static final String LINE_SEPARATOR = PropertiesUtil.getProperties().getStringProperty("line.separator",
47              "\n");
48  
49      /**
50       * Returns a double quoted string.
51       * 
52       * @param str a String
53       * @return {@code "str"}
54       */
55      public static String dquote(final String str) {
56          return Chars.DQUOTE + str + Chars.DQUOTE;
57      }
58      
59      /**
60       * Checks if a String is blank. A blank string is one that is either
61       * {@code null}, empty, or all characters are {@link Character#isWhitespace(char)}.
62       *
63       * @param s the String to check, may be {@code null}
64       * @return {@code true} if the String is {@code null}, empty, or or all characters are {@link Character#isWhitespace(char)}
65       */
66      public static boolean isBlank(final String s) {
67          if (s == null || s.isEmpty()) {
68              return true;
69          }
70          for (int i = 0; i < s.length(); i++) {
71              char c = s.charAt(i);
72              if (!Character.isWhitespace(c)) {
73                  return false;
74              }
75          }
76          return true;
77      }
78  
79      /**
80       * <p>
81       * Checks if a CharSequence is empty ("") or null.
82       * </p>
83       *
84       * <pre>
85       * Strings.isEmpty(null)      = true
86       * Strings.isEmpty("")        = true
87       * Strings.isEmpty(" ")       = false
88       * Strings.isEmpty("bob")     = false
89       * Strings.isEmpty("  bob  ") = false
90       * </pre>
91       *
92       * <p>
93       * NOTE: This method changed in Lang version 2.0. It no longer trims the CharSequence. That functionality is
94       * available in isBlank().
95       * </p>
96       *
97       * <p>
98       * Copied from Apache Commons Lang org.apache.commons.lang3.StringUtils.isEmpty(CharSequence)
99       * </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 &lt;= 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 &lt;= 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 &lt;= 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 }