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  
18  package org.apache.any23.util;
19  
20  import org.apache.commons.io.ByteOrderMark;
21  import org.apache.commons.io.input.BOMInputStream;
22  import org.apache.xerces.impl.io.MalformedByteSequenceException;
23  import org.slf4j.Logger;
24  import org.slf4j.LoggerFactory;
25  import org.w3c.dom.Document;
26  import org.xml.sax.SAXException;
27  
28  import java.io.BufferedReader;
29  import java.io.ByteArrayInputStream;
30  import java.io.ByteArrayOutputStream;
31  import java.io.Closeable;
32  import java.io.IOException;
33  import java.io.InputStream;
34  import java.io.InputStreamReader;
35  import java.util.ArrayList;
36  import java.util.List;
37  
38  import javax.xml.parsers.DocumentBuilder;
39  import javax.xml.parsers.DocumentBuilderFactory;
40  import javax.xml.parsers.ParserConfigurationException;
41  import javax.xml.transform.Result;
42  import javax.xml.transform.Source;
43  import javax.xml.transform.TransformerConfigurationException;
44  import javax.xml.transform.TransformerException;
45  import javax.xml.transform.TransformerFactory;
46  import javax.xml.transform.TransformerFactoryConfigurationError;
47  import javax.xml.transform.dom.DOMSource;
48  import javax.xml.transform.stream.StreamResult;
49  
50  /**
51   * Contains general utility functions for handling streams.
52   *
53   * @author Michele Mostarda (mostarda@fbk.eu)
54   */
55  public class StreamUtils {
56  
57      private static final Logger logger = LoggerFactory.getLogger(StreamUtils.class);
58  
59      private StreamUtils(){}
60  
61      /**
62       * Returns all the lines read from an input stream.
63       *
64       * @param is input stream.
65       * @return list of not <code>null</code> lines.
66       * @throws IOException if an error occurs while consuming the <code>is</code> stream.
67       */
68      public static String[] asLines(InputStream is) throws IOException {
69          final BufferedReader br = new BufferedReader(new InputStreamReader(is));
70          final List<String> lines = new ArrayList<String>();
71          try {
72              String line;
73              while ((line = br.readLine()) != null) {
74                  lines.add(line);
75              }
76              return lines.toArray( new String[ lines.size() ] );
77          } finally {
78              closeGracefully(br);
79          }
80      }
81  
82      /**
83       * Returns the string content of a stream.
84       *
85       * @param is input stream.
86       * @param preserveNL preserves new line chars.
87       * @return the string content.
88       * @throws IOException if an error occurs while consuming the <code>is</code> stream.
89       */
90      public static String asString(InputStream is, boolean preserveNL) throws IOException {
91          if (is == null) {
92              throw new NullPointerException("input stream is null.");
93          }
94          final BufferedReader br = new BufferedReader(new InputStreamReader(is));
95          try {
96              final StringBuilder content = new StringBuilder();
97              String line;
98              while ((line = br.readLine()) != null) {
99                  content.append(line);
100                 if(preserveNL) content.append('\n');
101             }
102             return content.toString();
103         } finally {
104             closeGracefully(br);
105         }
106     }
107 
108     /**
109      * Returns the string content of a stream, new line chars will be removed.
110      *
111      * @param is input stream.
112      * @return the string content.
113      * @throws IOException if an error occurs while consuming the <code>is</code> stream.
114      */
115     public static String asString(InputStream is) throws IOException {
116         return asString(is, false);
117     }
118 
119     /**
120      * Closes the closable interface and reports error if any.
121      *
122      * @param closable the closable object to be closed.
123      */
124     public static void closeGracefully(Closeable closable) {
125         if (closable != null) {
126             try {
127                 closable.close();
128             } catch (Exception e) {
129                 logger.error("Error while closing object " + closable, e);
130             }
131         }
132     }
133 
134     /**
135      * Converts a {@link org.w3c.dom.Document} to an
136      * {@link java.io.InputStream}
137      * @throws TransformerFactoryConfigurationError 
138      * @throws TransformerConfigurationException 
139      */
140     public static InputStream documentToInputStream(Document doc) 
141             throws TransformerConfigurationException, TransformerFactoryConfigurationError {
142         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
143         Source xmlSource = new DOMSource(doc);
144         Result outputTarget = new StreamResult(outputStream);
145         try {
146             TransformerFactory.newInstance().newTransformer().transform(xmlSource, outputTarget);
147         } catch (TransformerException e) {
148             logger.error("Error during transformation: {}", e);
149         }
150         return new ByteArrayInputStream(outputStream.toByteArray());
151     }
152 
153     public static Document inputStreamToDocument(InputStream is) throws MalformedByteSequenceException {
154         DocumentBuilderFactory factory = null;
155         DocumentBuilder builder = null;
156         Document doc = null;
157 
158         try {
159             factory = DocumentBuilderFactory.newInstance();
160             builder = factory.newDocumentBuilder();
161         } catch (ParserConfigurationException e) {
162             logger.error("Error converting InputStream to Document: {}", e);
163         }
164 
165         try {
166             BOMInputStream bomIn = new BOMInputStream(is, ByteOrderMark.UTF_8, ByteOrderMark.UTF_16BE,
167                     ByteOrderMark.UTF_16LE, ByteOrderMark.UTF_32BE, ByteOrderMark.UTF_32LE);
168             if (bomIn.hasBOM()) {
169                 @SuppressWarnings("unused")
170                 int firstNonBOMByte = bomIn.read(); // Skips BOM
171             }
172             doc = builder.parse(bomIn);
173         } catch (SAXException | IOException e) {
174             logger.error("Error converting InputStream to Document: {}", e);
175         }
176         return doc;
177     }
178 }