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 }
064 catch(IOException exc)
065 {
066 log.error("Exception while reading from stream", exc);
067 }
068 return byteStream.toByteArray();
069 }
070
071 /**
072 * Returns the contents of the reader as a string.
073 * @param reader the <code>Reader</code>
074 * @return the reader content as <code>String</code>
075 */
076 public static String getReaderAsString(Reader reader)
077 {
078 return getReaderAsString(reader, -1);
079 }
080
081 /**
082 * Returns the contents of the reader as a string.
083 * @param reader the <code>Reader</code>
084 * @param length the number of chars to copy, if length < 0,
085 * the number is unlimited
086 * @return the reader content as <code>String</code>
087 */
088 public static String getReaderAsString(Reader reader, int length)
089 {
090 if(length == 0) return "";
091 boolean checkLength = true;
092 if(length < 0)
093 {
094 length = Integer.MAX_VALUE;
095 checkLength = false;
096 }
097 StringBuffer buffer = new StringBuffer();
098 try
099 {
100 int nextValue = reader.read();
101 if(checkLength) length--;
102 while(-1 != nextValue && length >= 0)
103 {
104 buffer.append((char)nextValue);
105 nextValue = reader.read();
106 if(checkLength) length--;
107 }
108 }
109 catch(IOException exc)
110 {
111 log.error("Exception while reading from reader", exc);
112 }
113 return buffer.toString();
114 }
115
116 /**
117 * Returns a copy of the specified stream. If the specified stream supports
118 * marking, it will be reseted after the copy.
119 * @param sourceStream the stream to copy
120 * @return a copy of the stream
121 */
122 public static InputStream copyStream(InputStream sourceStream)
123 {
124 try
125 {
126 if(sourceStream.markSupported()) sourceStream.mark(sourceStream.available());
127 byte[] sourceData = getStreamAsByteArray(sourceStream);
128 if(sourceStream.markSupported()) sourceStream.reset();
129 return new ByteArrayInputStream(sourceData);
130 }
131 catch(IOException exc)
132 {
133 log.error("Exception while copying stream", exc);
134 return null;
135 }
136 }
137
138 /**
139 * Returns a copy of the specified reader. If the specified reader supports
140 * marking, it will be reseted after the copy.
141 * @param sourceReader the stream to reader
142 * @return a copy of the reader
143 */
144 public static Reader copyReader(Reader sourceReader)
145 {
146 try
147 {
148 if(sourceReader.markSupported()) sourceReader.mark(Integer.MAX_VALUE);
149 String sourceData = getReaderAsString(sourceReader);
150 if(sourceReader.markSupported()) sourceReader.reset();
151 return new StringReader(sourceData);
152 }
153 catch(IOException exc)
154 {
155 log.error("Exception while copying reader", exc);
156 return null;
157 }
158 }
159
160 /**
161 * Compares the content of the streams. If the streams support
162 * marking, they will be reseted after the comparison.
163 * @param sourceStream the source stream
164 * @param targetStream the target stream
165 * @return <code>true</code>, if the streams are identical, <code>false</code> otherwise
166 */
167 public static boolean compareStreams(InputStream sourceStream, InputStream targetStream)
168 {
169 try
170 {
171 if(sourceStream.markSupported()) sourceStream.mark(sourceStream.available());
172 if(targetStream.markSupported()) targetStream.mark(targetStream.available());
173 byte[] sourceArray = getStreamAsByteArray(sourceStream);
174 byte[] targetArray = getStreamAsByteArray(targetStream);
175 if(sourceStream.markSupported()) sourceStream.reset();
176 if(targetStream.markSupported()) targetStream.reset();
177 return Arrays.equals(sourceArray, targetArray);
178 }
179 catch(IOException exc)
180 {
181 log.error("Exception while comparing streams", exc);
182 return false;
183 }
184 }
185
186 /**
187 * Compares the content of the readers. If the readers support
188 * marking, they will be reseted after the comparison.
189 * @param sourceReader the source stream
190 * @param targetReader the target stream
191 * @return <code>true</code>, if the streams are identical, <code>false</code> otherwise
192 */
193 public static boolean compareReaders(Reader sourceReader, Reader targetReader)
194 {
195 try
196 {
197 if(sourceReader.markSupported()) sourceReader.mark(Integer.MAX_VALUE);
198 if(targetReader.markSupported()) targetReader.mark(Integer.MAX_VALUE);
199 String sourceString = getReaderAsString(sourceReader);
200 String targetString = getReaderAsString(targetReader);
201 if(sourceReader.markSupported()) sourceReader.reset();
202 if(targetReader.markSupported()) targetReader.reset();
203 return sourceString.equals(targetString);
204 }
205 catch(IOException exc)
206 {
207 log.error("Exception while comparing readers", exc);
208 return false;
209 }
210 }
211
212 /**
213 * Reads the lines from the specified reader and adds them to a <code>List</code>.
214 * @param reader the reader
215 * @return the <code>List</code> with the lines
216 */
217 public static List getLinesFromReader(Reader reader)
218 {
219 List resultList = new ArrayList();
220 try
221 {
222 BufferedReader bufferedReader = new BufferedReader(reader);
223 String line = bufferedReader.readLine();
224 while(line != null)
225 {
226 resultList.add(line);
227 line = bufferedReader.readLine();
228 }
229 }
230 catch(IOException exc)
231 {
232 throw new NestedApplicationException(exc);
233 }
234 return resultList;
235 }
236 }