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