001 package com.mockrunner.util.common;
002
003 import java.io.BufferedReader;
004 import java.io.ByteArrayInputStream;
005 import java.io.ByteArrayOutputStream;
006 import java.io.IOException;
007 import java.io.InputStream;
008 import java.io.Reader;
009 import java.io.StringReader;
010 import java.util.ArrayList;
011 import java.util.Arrays;
012 import java.util.List;
013
014 import org.apache.commons.logging.Log;
015 import org.apache.commons.logging.LogFactory;
016
017 import com.mockrunner.base.NestedApplicationException;
018
019 /**
020 * Simple util class for manipulating streams
021 */
022 public class StreamUtil
023 {
024 private final static Log log = LogFactory.getLog(StreamUtil.class);
025
026 /**
027 * Returns the contents of the input stream as byte array.
028 * @param stream the <code>InputStream</code>
029 * @return the stream content as byte array
030 */
031 public static byte[] getStreamAsByteArray(InputStream stream)
032 {
033 return getStreamAsByteArray(stream, -1);
034 }
035
036 /**
037 * Returns the contents of the input stream as byte array.
038 * @param stream the <code>InputStream</code>
039 * @param length the number of bytes to copy, if length < 0,
040 * the number is unlimited
041 * @return the stream content as byte array
042 */
043 public static byte[] getStreamAsByteArray(InputStream stream, int length)
044 {
045 if(length == 0) return new byte[0];
046 boolean checkLength = true;
047 if(length < 0)
048 {
049 length = Integer.MAX_VALUE;
050 checkLength = false;
051 }
052 ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
053 try
054 {
055 int nextValue = stream.read();
056 if(checkLength) length--;
057 while(-1 != nextValue && length >= 0)
058 {
059 byteStream.write(nextValue);
060 nextValue = stream.read();
061 if(checkLength) length--;
062 }
063 byteStream.flush();
064 }
065 catch(IOException exc)
066 {
067 log.error("Exception while reading from stream", exc);
068 }
069 return byteStream.toByteArray();
070 }
071
072 /**
073 * Returns the contents of the reader as a string.
074 * @param reader the <code>Reader</code>
075 * @return the reader content as <code>String</code>
076 */
077 public static String getReaderAsString(Reader reader)
078 {
079 return getReaderAsString(reader, -1);
080 }
081
082 /**
083 * Returns the contents of the reader as a string.
084 * @param reader the <code>Reader</code>
085 * @param length the number of chars to copy, if length < 0,
086 * the number is unlimited
087 * @return the reader content as <code>String</code>
088 */
089 public static String getReaderAsString(Reader reader, int length)
090 {
091 if(length == 0) return "";
092 boolean checkLength = true;
093 if(length < 0)
094 {
095 length = Integer.MAX_VALUE;
096 checkLength = false;
097 }
098 StringBuffer buffer = new StringBuffer();
099 try
100 {
101 int nextValue = reader.read();
102 if(checkLength) length--;
103 while(-1 != nextValue && length >= 0)
104 {
105 buffer.append((char)nextValue);
106 nextValue = reader.read();
107 if(checkLength) length--;
108 }
109 }
110 catch(IOException exc)
111 {
112 log.error("Exception while reading from reader", exc);
113 }
114 return buffer.toString();
115 }
116
117 /**
118 * Returns a copy of the specified stream. If the specified stream supports
119 * marking, it will be reset after the copy.
120 * @param sourceStream the stream to copy
121 * @return a copy of the stream
122 */
123 public static InputStream copyStream(InputStream sourceStream)
124 {
125 try
126 {
127 if(sourceStream.markSupported()) sourceStream.mark(sourceStream.available());
128 byte[] sourceData = getStreamAsByteArray(sourceStream);
129 if(sourceStream.markSupported()) sourceStream.reset();
130 return new ByteArrayInputStream(sourceData);
131 }
132 catch(IOException exc)
133 {
134 log.error("Exception while copying stream", exc);
135 return null;
136 }
137 }
138
139 /**
140 * Returns a copy of the specified reader. If the specified reader supports
141 * marking, it will be reset after the copy.
142 * @param sourceReader the stream to reader
143 * @return a copy of the reader
144 */
145 public static Reader copyReader(Reader sourceReader)
146 {
147 try
148 {
149 if(sourceReader.markSupported()) sourceReader.mark(Integer.MAX_VALUE);
150 String sourceData = getReaderAsString(sourceReader);
151 if(sourceReader.markSupported()) sourceReader.reset();
152 return new StringReader(sourceData);
153 }
154 catch(IOException exc)
155 {
156 log.error("Exception while copying reader", exc);
157 return null;
158 }
159 }
160
161 /**
162 * Compares the content of the streams. If the streams support
163 * marking, they will be reset after the comparison.
164 * @param sourceStream the source stream
165 * @param targetStream the target stream
166 * @return <code>true</code>, if the streams are identical, <code>false</code> otherwise
167 */
168 public static boolean compareStreams(InputStream sourceStream, InputStream targetStream)
169 {
170 try
171 {
172 if(sourceStream.markSupported()) sourceStream.mark(sourceStream.available());
173 if(targetStream.markSupported()) targetStream.mark(targetStream.available());
174 byte[] sourceArray = getStreamAsByteArray(sourceStream);
175 byte[] targetArray = getStreamAsByteArray(targetStream);
176 if(sourceStream.markSupported()) sourceStream.reset();
177 if(targetStream.markSupported()) targetStream.reset();
178 return Arrays.equals(sourceArray, targetArray);
179 }
180 catch(IOException exc)
181 {
182 log.error("Exception while comparing streams", exc);
183 return false;
184 }
185 }
186
187 /**
188 * Compares the content of the readers. If the readers support
189 * marking, they will be reset after the comparison.
190 * @param sourceReader the source stream
191 * @param targetReader the target stream
192 * @return <code>true</code>, if the streams are identical, <code>false</code> otherwise
193 */
194 public static boolean compareReaders(Reader sourceReader, Reader targetReader)
195 {
196 try
197 {
198 if(sourceReader.markSupported()) sourceReader.mark(Integer.MAX_VALUE);
199 if(targetReader.markSupported()) targetReader.mark(Integer.MAX_VALUE);
200 String sourceString = getReaderAsString(sourceReader);
201 String targetString = getReaderAsString(targetReader);
202 if(sourceReader.markSupported()) sourceReader.reset();
203 if(targetReader.markSupported()) targetReader.reset();
204 return sourceString.equals(targetString);
205 }
206 catch(IOException exc)
207 {
208 log.error("Exception while comparing readers", exc);
209 return false;
210 }
211 }
212
213 /**
214 * Reads the lines from the specified reader and adds them to a <code>List</code>.
215 * @param reader the reader
216 * @return the <code>List</code> with the lines
217 */
218 public static List getLinesFromReader(Reader reader)
219 {
220 List resultList = new ArrayList();
221 try
222 {
223 BufferedReader bufferedReader = new BufferedReader(reader);
224 String line = bufferedReader.readLine();
225 while(line != null)
226 {
227 resultList.add(line);
228 line = bufferedReader.readLine();
229 }
230 }
231 catch(IOException exc)
232 {
233 throw new NestedApplicationException(exc);
234 }
235 return resultList;
236 }
237 }