001/*
002 * Copyright 2021 Global Biodiversity Information Facility (GBIF)
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.gbif.utils.file;
017
018import java.io.ByteArrayOutputStream;
019import java.io.IOException;
020import java.io.InputStream;
021import java.io.UnsupportedEncodingException;
022import java.net.URL;
023import java.nio.charset.Charset;
024import java.nio.charset.StandardCharsets;
025
026import org.slf4j.Logger;
027import org.slf4j.LoggerFactory;
028
029public class InputStreamUtils {
030
031  private static final Logger LOG = LoggerFactory.getLogger(InputStreamUtils.class);
032
033  public InputStream classpathStream(String path) {
034    InputStream in = null;
035    // relative path. Use classpath instead
036    URL url = getClass().getClassLoader().getResource(path);
037    if (url != null) {
038      try {
039        in = url.openStream();
040      } catch (IOException e) {
041        LOG.warn("Cant open classpath input stream " + path, e);
042      }
043    }
044    return in;
045  }
046
047  /**
048   * Converts an entire InputStream to a single String with UTF8 as the character encoding.
049   *
050   * @param source source input stream to convert
051   *
052   * @return the string representing the entire input stream
053   */
054  public String readEntireStream(InputStream source) {
055    return readEntireStream(source, FileUtils.UTF8);
056  }
057
058  /**
059   * Converts an entire InputStream to a single String with explicitly provided character encoding.
060   *
061   * @param source   source input stream to convert
062   * @param encoding the stream's character encoding
063   *
064   * @return the string representing the entire input stream
065   */
066  public String readEntireStream(InputStream source, String encoding) {
067    if (!Charset.isSupported(encoding)) {
068      throw new IllegalArgumentException("Unsupported encoding " + encoding);
069    };
070
071    ByteArrayOutputStream result = new ByteArrayOutputStream();
072
073    try {
074      byte[] buffer = new byte[1024];
075      int length;
076      while ((length = source.read(buffer)) != -1) {
077        result.write(buffer, 0, length);
078      }
079    } catch (IOException e) {
080      LOG.error("Caught exception", e);
081    } finally {
082      try {
083        source.close();
084      } catch (IOException e) {
085        LOG.error("Caught exception", e);
086      }
087    }
088
089    // StandardCharsets.UTF_8.name() > JDK 7
090    try {
091      return result.toString(StandardCharsets.UTF_8.name());
092    } catch (UnsupportedEncodingException e) {
093      throw new IllegalArgumentException("Could not decode stream as " + encoding);
094    }
095  }
096}