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 || "".equals(string.trim());
063  }
064
065  /**
066   * Returns a trimmed version of {@code string}, or {@code null} if {@code string} is {@code null} or the trimmed
067   * version is a blank string.
068   *
069   * @param string
070   *          The string to trim.
071   * @return A trimmed version of {@code string}, or {@code null} if {@code string} is {@code null} or the trimmed
072   *         version is a blank string.
073   */
074  public static String trimToNull(String string) {
075    if (isBlank(string)) {
076      return null;
077    }
078    return string.trim();
079  }
080
081  /**
082   * Returns a trimmed version of {@code string}, or an empty string if {@code string} is {@code null} or the trimmed
083   * version is a blank string.
084   *
085   * @param string
086   *          The string to trim.
087   * @return A trimmed version of {@code string}, or an empty string if {@code string} is {@code null} or the trimmed
088   *         version is a blank string.
089   */
090  public static String trimToEmpty(String string) {
091    if (isBlank(string)) {
092      return "";
093    }
094    return string.trim();
095  }
096
097  /**
098   * Converts {@code string} to a byte array.
099   * <p>
100   * Assumes {@code string} is in {@link StringUtils#ENCODING_CHARSET} format.
101   *
102   * @param string
103   *          The string to convert to a byte array.
104   * @return A byte array representation of {@code string}.
105   * @throws NullPointerException
106   *           If {@code string} is {@code null}.
107   * @throws IllegalStateException
108   *           If unable to convert because the JVM doesn't support {@link StringUtils#ENCODING_CHARSET}.
109   */
110  public static byte[] toBytes(String string) {
111    Objects.requireNonNull(string, "Parameter 'string' cannot be null.");
112    return string.getBytes(ENCODING_CHARSET);
113  }
114
115  /**
116   * Converts {@code data} to a string in {@link #ENCODING_CHARSET} format.
117   *
118   * @param data
119   *          The data to convert to a string.
120   * @return A string representation of {@code data}.
121   *
122   * @throws NullPointerException
123   *           If {@code data} is {@code null}.
124   * @throws IllegalStateException
125   *           If unable to convert because the JVM doesn't support {@link StringUtils#ENCODING_CHARSET}.
126   * @since 1.6.13
127   */
128  public static String toString(byte[] data) {
129    Objects.requireNonNull(data, "Parameter 'data' cannot be null.");
130    return new String(data, ENCODING_CHARSET);
131  }
132
133  /**
134   * Builds and returns a string representation of the given {@code inputStream} .
135   *
136   * @param inputStream
137   *          The stream from which a string representation is built.
138   *
139   * @return A string representation of the given {@code inputStream}.
140   * @throws IOException
141   *           If an error occurs while processing the {@code inputStream}.
142   */
143  public static String fromInputStream(InputStream inputStream) throws IOException {
144    if (inputStream == null) {
145      return null;
146    }
147
148    try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, ENCODING_CHARSET))) {
149      return reader.lines().collect(Collectors.joining("\n"));
150    }
151  }
152
153  /**
154   * Returns an {@code Integer} representation of the given {@code string}, or {@code null} if it's not a valid
155   * {@code Integer}.
156   *
157   * @param string
158   *          The string to process.
159   * @return The {@code Integer} representation of {@code string}, or {@code null} if {@code string} is {@code null} or
160   *         not a valid {@code Integer}.
161   */
162  public static Integer toInteger(String string) {
163    try {
164      return Optional.ofNullable(string).map(Integer::parseInt).orElse(null);
165    } catch (Exception e) {
166      return null;
167    }
168  }
169}