001/*
002 * Copyright (c) 2010-2024 Mark Allen, Norbert Bartels.
003 *
004 * Permission is hereby granted, free of charge, to any person obtaining a copy
005 * of this software and associated documentation files (the "Software"), to deal
006 * in the Software without restriction, including without limitation the rights
007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008 * copies of the Software, and to permit persons to whom the Software is
009 * furnished to do so, subject to the following conditions:
010 *
011 * The above copyright notice and this permission notice shall be included in
012 * all copies or substantial portions of the Software.
013 *
014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
020 * THE SOFTWARE.
021 */
022package com.restfb.util;
023
024import java.io.BufferedReader;
025import java.io.IOException;
026import java.io.InputStream;
027import java.io.InputStreamReader;
028import java.nio.charset.Charset;
029import java.nio.charset.StandardCharsets;
030import java.util.Objects;
031import java.util.Optional;
032import java.util.stream.Collectors;
033
034/**
035 * A collection of string-handling utility methods.
036 *
037 * @author <a href="http://restfb.com">Mark Allen</a>
038 * @since 1.6
039 */
040public final class StringUtils {
041
042  /**
043   * Default charset to use for encoding/decoding strings.
044   */
045  public static final Charset ENCODING_CHARSET = StandardCharsets.UTF_8;
046
047  /**
048   * Prevents instantiation.
049   */
050  private StringUtils() {
051    // Prevents instantiation
052  }
053
054  /**
055   * Is {@code string} blank (null or only whitespace)?
056   *
057   * @param string
058   *          The string to check.
059   * @return {@code true} if {@code string} is blank, {@code false} otherwise.
060   */
061  public static boolean isBlank(String string) {
062    return string == null || string.trim().isEmpty();
063  }
064
065  /**
066   * Is {@code string} not blank (null or only whitespace)?
067   *
068   * @param string
069   *          The string to check.
070   * @return {@code true} if {@code string} is not blank, {@code false} otherwise.
071   */
072  public static boolean isNotBlank(String string) {
073    return !isBlank(string);
074  }
075
076  /**
077   * Returns a trimmed version of {@code string}, or {@code null} if {@code string} is {@code null} or the trimmed
078   * version is a blank string.
079   *
080   * @param string
081   *          The string to trim.
082   * @return A trimmed version of {@code string}, or {@code null} if {@code string} is {@code null} or the trimmed
083   *         version is a blank string.
084   */
085  public static String trimToNull(String string) {
086    if (isBlank(string)) {
087      return null;
088    }
089    return string.trim();
090  }
091
092  /**
093   * Returns a trimmed version of {@code string}, or an empty string if {@code string} is {@code null} or the trimmed
094   * version is a blank string.
095   *
096   * @param string
097   *          The string to trim.
098   * @return A trimmed version of {@code string}, or an empty string if {@code string} is {@code null} or the trimmed
099   *         version is a blank string.
100   */
101  public static String trimToEmpty(String string) {
102    if (isBlank(string)) {
103      return "";
104    }
105    return string.trim();
106  }
107
108  /**
109   * Converts {@code string} to a byte array.
110   * <p>
111   * Assumes {@code string} is in {@link StringUtils#ENCODING_CHARSET} format.
112   *
113   * @param string
114   *          The string to convert to a byte array.
115   * @return A byte array representation of {@code string}.
116   * @throws NullPointerException
117   *           If {@code string} is {@code null}.
118   * @throws IllegalStateException
119   *           If unable to convert because the JVM doesn't support {@link StringUtils#ENCODING_CHARSET}.
120   */
121  public static byte[] toBytes(String string) {
122    Objects.requireNonNull(string, "Parameter 'string' cannot be null.");
123    return string.getBytes(ENCODING_CHARSET);
124  }
125
126  /**
127   * Converts {@code data} to a string in {@link #ENCODING_CHARSET} format.
128   *
129   * @param data
130   *          The data to convert to a string.
131   * @return A string representation of {@code data}.
132   *
133   * @throws NullPointerException
134   *           If {@code data} is {@code null}.
135   * @throws IllegalStateException
136   *           If unable to convert because the JVM doesn't support {@link StringUtils#ENCODING_CHARSET}.
137   * @since 1.6.13
138   */
139  public static String toString(byte[] data) {
140    Objects.requireNonNull(data, "Parameter 'data' cannot be null.");
141    return new String(data, ENCODING_CHARSET);
142  }
143
144  /**
145   * Builds and returns a string representation of the given {@code inputStream} .
146   *
147   * @param inputStream
148   *          The stream from which a string representation is built.
149   *
150   * @return A string representation of the given {@code inputStream}.
151   * @throws IOException
152   *           If an error occurs while processing the {@code inputStream}.
153   */
154  public static String fromInputStream(InputStream inputStream) throws IOException {
155    if (inputStream == null) {
156      return null;
157    }
158
159    try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, ENCODING_CHARSET))) {
160      return reader.lines().collect(Collectors.joining("\n"));
161    }
162  }
163
164  /**
165   * Returns an {@code Integer} representation of the given {@code string}, or {@code null} if it's not a valid
166   * {@code Integer}.
167   *
168   * @param string
169   *          The string to process.
170   * @return The {@code Integer} representation of {@code string}, or {@code null} if {@code string} is {@code null} or
171   *         not a valid {@code Integer}.
172   */
173  public static Integer toInteger(String string) {
174    try {
175      return Optional.ofNullable(string).map(Integer::parseInt).orElse(null);
176    } catch (Exception e) {
177      return null;
178    }
179  }
180}