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 }