KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cactus > internal > client > connector > http > AutoReadHttpURLConnection


1 /*
2  * ========================================================================
3  *
4  * Copyright 2001-2004 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * ========================================================================
19  */

20 package org.apache.cactus.internal.client.connector.http;
21
22 import java.io.BufferedReader JavaDoc;
23 import java.io.ByteArrayInputStream JavaDoc;
24 import java.io.ByteArrayOutputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.io.InputStreamReader JavaDoc;
28 import java.io.OutputStream JavaDoc;
29
30 import java.net.HttpURLConnection JavaDoc;
31 import java.net.ProtocolException JavaDoc;
32 import java.net.URL JavaDoc;
33
34 import java.security.Permission JavaDoc;
35
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38
39 /**
40  * Wrapper class for the real <code>HttpURLConnection</code> to the test servlet
41  * that reads the complete input stream into an internal buffer on
42  * the first call to getInputStream(). This is to ensure that the test servlet
43  * is not blocked on i/o when the test caller asks for the results.
44  * <p>
45  * The wrapper returns the buffered input stream from getInputStream and
46  * delegates the rest of the calls.
47  * <p>
48  * This class is final so we don't have to provide access to protected instance
49  * variables and methods of the wrapped connection.
50  *
51  * @version $Id: AutoReadHttpURLConnection.java,v 1.2 2004/06/19 15:10:53 vmassol Exp $
52  */

53 final class AutoReadHttpURLConnection extends HttpURLConnection JavaDoc
54 {
55     /**
56      * The logger
57      */

58     private static final Log LOGGER =
59         LogFactory.getLog(AutoReadHttpURLConnection.class);
60
61     /**
62      * Default size of array for copying data.
63      */

64     private static final int DEFAULT_CHUNK_SIZE = 16384;
65
66     /**
67      * The wrapped connection.
68      */

69     private HttpURLConnection JavaDoc delegate;
70
71     /**
72      * The read input stream.
73      */

74     private InputStream JavaDoc streamBuffer;
75
76     /**
77      * Constructs a an <code>AutoReadHttpURLConnection</code> object from an
78      * <code>HttpURLConnection</code>.
79      *
80      * @param theConnection the original connection to wrap
81      */

82     AutoReadHttpURLConnection(HttpURLConnection JavaDoc theConnection)
83     {
84         super(null);
85         this.delegate = theConnection;
86     }
87
88     /**
89      * Returns an input stream containing the fully read contents of
90      * the wrapped connection's input stream
91      *
92      * @return the input stream
93      * @exception IOException if an error occurs when reading the input stream
94      */

95     public synchronized InputStream JavaDoc getInputStream() throws IOException JavaDoc
96     {
97         // Catch IOException to log the content of the error stream
98
try
99         {
100             if (this.streamBuffer == null)
101             {
102                 LOGGER.debug("Original connection = " + this.delegate);
103
104                 InputStream JavaDoc is = this.delegate.getInputStream();
105
106                 this.streamBuffer = getBufferedInputStream(is);
107             }
108         }
109         catch (IOException JavaDoc e)
110         {
111             logErrorStream(this.delegate.getErrorStream());
112             throw e;
113         }
114
115         return this.streamBuffer;
116     }
117
118     /**
119      * Logs the HTTP error stream (used to get more information when we fail
120      * to read from the HTTP URL connection).
121      *
122      * @param theErrorStream the error stream containing the error description
123      * @exception IOException if an error occurs when reading the input stream
124      */

125     private void logErrorStream(InputStream JavaDoc theErrorStream) throws IOException JavaDoc
126     {
127         if (theErrorStream != null)
128         {
129             // Log content of error stream
130
BufferedReader JavaDoc errorStream =
131                 new BufferedReader JavaDoc(new InputStreamReader JavaDoc(theErrorStream));
132             String JavaDoc buffer;
133
134             while ((buffer = errorStream.readLine()) != null)
135             {
136                 LOGGER.debug("ErrorStream [" + buffer + "]");
137             }
138         }
139     }
140
141     /**
142      * Fully read the HTTP Connection response stream until there is no
143      * more bytes to read.
144      *
145      * @param theInputStream the input stream to fully read
146      * @return the data read as a buffered input stream
147      * @exception IOException if an error occurs when reading the input stream
148      */

149     private InputStream JavaDoc getBufferedInputStream(InputStream JavaDoc theInputStream)
150         throws IOException JavaDoc
151     {
152         ByteArrayOutputStream JavaDoc os =
153             new ByteArrayOutputStream JavaDoc(DEFAULT_CHUNK_SIZE);
154
155         copy(theInputStream, os);
156
157         ByteArrayInputStream JavaDoc bais = new ByteArrayInputStream JavaDoc(os.toByteArray());
158
159         return bais;
160     }
161
162     /**
163      * Copies the input stream passed as parameter to the output stream also
164      * passed as parameter. The full stream is read until there is no more
165      * bytes to read.
166      *
167      * @param theInputStream the input stream to read from
168      * @param theOutputStream the output stream to write to
169      * @exception IOException if an error occurs when reading the input stream
170      */

171     private void copy(InputStream JavaDoc theInputStream, OutputStream JavaDoc theOutputStream)
172         throws IOException JavaDoc
173     {
174         // Only copy if there are data to copy ... The problem is that not
175
// all servers return a content-length header. If there is no header
176
// getContentLength() returns -1. It seems to work and it seems
177
// that all servers that return no content-length header also do
178
// not block on read() operations !
179
LOGGER.debug("Content-Length : [" + this.delegate.getContentLength()
180             + "]");
181
182         if (theInputStream != null && this.delegate.getContentLength() != 0)
183         {
184             byte[] buf = new byte[DEFAULT_CHUNK_SIZE];
185             int count;
186
187             while (-1 != (count = theInputStream.read(buf)))
188             {
189                 // log read data
190
printReadLogs(count, buf);
191                 theOutputStream.write(buf, 0, count);
192             }
193         }
194     }
195
196     /**
197      * Format log data read from socket for pretty printing (replaces
198      * asc char 10 by "\r", asc char 13 by "\n").
199      *
200      * @param theCount the number of bytes read in the buffer
201      * @param theBuffer the buffer containing the data to print
202      */

203     private void printReadLogs(int theCount, byte[] theBuffer)
204     {
205         // Log portion of read data and replace asc 10 by \r and asc
206
// 13 by /n
207
StringBuffer JavaDoc prefix = new StringBuffer JavaDoc();
208
209         for (int i = 0; i < theCount; i++)
210         {
211             if (theBuffer[i] == 10)
212             {
213                 prefix.append("\\r");
214             }
215             else if (theBuffer[i] == 13)
216             {
217                 prefix.append("\\n");
218             }
219             else
220             {
221                 prefix.append((char) theBuffer[i]);
222             }
223         }
224
225         LOGGER.debug("Read [" + theCount + "]: [" + prefix + "]");
226     }
227
228     // Delegated methods
229

230     /**
231      * @see java.net.HttpURLConnection#connect()
232      */

233     public void connect() throws IOException JavaDoc
234     {
235         this.delegate.connect();
236     }
237
238     /**
239      * @see java.net.HttpURLConnection#getAllowUserInteraction()
240      */

241     public boolean getAllowUserInteraction()
242     {
243         return this.delegate.getAllowUserInteraction();
244     }
245
246     /**
247      * @see java.net.HttpURLConnection#getContent()
248      */

249     public Object JavaDoc getContent() throws IOException JavaDoc
250     {
251         return this.delegate.getContent();
252     }
253
254     /**
255      * @see java.net.HttpURLConnection#getContentEncoding()
256      */

257     public String JavaDoc getContentEncoding()
258     {
259         return this.delegate.getContentEncoding();
260     }
261
262     /**
263      * @see java.net.HttpURLConnection#getContentLength()
264      */

265     public int getContentLength()
266     {
267         return this.delegate.getContentLength();
268     }
269
270     /**
271      * @see java.net.HttpURLConnection#getContentType()
272      */

273     public String JavaDoc getContentType()
274     {
275         return this.delegate.getContentType();
276     }
277
278     /**
279      * @see java.net.HttpURLConnection#getDate()
280      */

281     public long getDate()
282     {
283         return this.delegate.getDate();
284     }
285
286     /**
287      * @see java.net.HttpURLConnection#getDefaultUseCaches()
288      */

289     public boolean getDefaultUseCaches()
290     {
291         return this.delegate.getDefaultUseCaches();
292     }
293
294     /**
295      * @see java.net.HttpURLConnection#getDoInput()
296      */

297     public boolean getDoInput()
298     {
299         return this.delegate.getDoInput();
300     }
301
302     /**
303      * @see java.net.HttpURLConnection#getDoOutput()
304      */

305     public boolean getDoOutput()
306     {
307         return this.delegate.getDoOutput();
308     }
309
310     /**
311      * @see java.net.HttpURLConnection#getExpiration()
312      */

313     public long getExpiration()
314     {
315         return this.delegate.getExpiration();
316     }
317
318     /**
319      * @see java.net.HttpURLConnection#getHeaderField(int)
320      */

321     public String JavaDoc getHeaderField(int thePosition)
322     {
323         return this.delegate.getHeaderField(thePosition);
324     }
325
326     /**
327      * @see java.net.HttpURLConnection#getHeaderField(String)
328      */

329     public String JavaDoc getHeaderField(String JavaDoc theName)
330     {
331         return this.delegate.getHeaderField(theName);
332     }
333
334     /**
335      * @see java.net.HttpURLConnection#getHeaderFieldDate(String, long)
336      */

337     public long getHeaderFieldDate(String JavaDoc theName, long theDefaultValue)
338     {
339         return this.delegate.getHeaderFieldDate(theName, theDefaultValue);
340     }
341
342     /**
343      * @see java.net.HttpURLConnection#getHeaderFieldInt(String, int)
344      */

345     public int getHeaderFieldInt(String JavaDoc theName, int theDefaultValue)
346     {
347         return this.delegate.getHeaderFieldInt(theName, theDefaultValue);
348     }
349
350     /**
351      * @see java.net.HttpURLConnection#getHeaderFieldKey(int)
352      */

353     public String JavaDoc getHeaderFieldKey(int thePosition)
354     {
355         return this.delegate.getHeaderFieldKey(thePosition);
356     }
357
358     /**
359      * @see java.net.HttpURLConnection#getIfModifiedSince()
360      */

361     public long getIfModifiedSince()
362     {
363         return this.delegate.getIfModifiedSince();
364     }
365
366     /**
367      * @see java.net.HttpURLConnection#getLastModified()
368      */

369     public long getLastModified()
370     {
371         return this.delegate.getLastModified();
372     }
373
374     /**
375      * @see java.net.HttpURLConnection#getOutputStream()
376      */

377     public OutputStream JavaDoc getOutputStream() throws IOException JavaDoc
378     {
379         return this.delegate.getOutputStream();
380     }
381
382     /**
383      * @see java.net.HttpURLConnection#getPermission()
384      */

385     public Permission JavaDoc getPermission() throws IOException JavaDoc
386     {
387         return this.delegate.getPermission();
388     }
389
390     /**
391      * @see java.net.HttpURLConnection#getRequestProperty(String)
392      */

393     public String JavaDoc getRequestProperty(String JavaDoc theKey)
394     {
395         return this.delegate.getRequestProperty(theKey);
396     }
397
398     /**
399      * @see java.net.HttpURLConnection#getURL()
400      */

401     public URL JavaDoc getURL()
402     {
403         return this.delegate.getURL();
404     }
405
406     /**
407      * @see java.net.HttpURLConnection#getUseCaches()
408      */

409     public boolean getUseCaches()
410     {
411         return this.delegate.getUseCaches();
412     }
413
414     /**
415      * @see java.net.HttpURLConnection#setAllowUserInteraction(boolean)
416      */

417     public void setAllowUserInteraction(boolean hasInteraction)
418     {
419         this.delegate.setAllowUserInteraction(hasInteraction);
420     }
421
422     /**
423      * @see java.net.HttpURLConnection#setDefaultUseCaches(boolean)
424      */

425     public void setDefaultUseCaches(boolean isUsingDefaultCache)
426     {
427         this.delegate.setDefaultUseCaches(isUsingDefaultCache);
428     }
429
430     /**
431      * @see java.net.HttpURLConnection#setDoInput(boolean)
432      */

433     public void setDoInput(boolean isInput)
434     {
435         this.delegate.setDoInput(isInput);
436     }
437
438     /**
439      * @see java.net.HttpURLConnection#setDoOutput(boolean)
440      */

441     public void setDoOutput(boolean isOutput)
442     {
443         this.delegate.setDoOutput(isOutput);
444     }
445
446     /**
447      * @see java.net.HttpURLConnection#setIfModifiedSince(long)
448      */

449     public void setIfModifiedSince(long isModifiedSince)
450     {
451         this.delegate.setIfModifiedSince(isModifiedSince);
452     }
453
454     /**
455      * @see java.net.HttpURLConnection#setRequestProperty(String, String)
456      */

457     public void setRequestProperty(String JavaDoc theKey, String JavaDoc theValue)
458     {
459         this.delegate.setRequestProperty(theKey, theValue);
460     }
461
462     /**
463      * @see java.net.HttpURLConnection#setUseCaches(boolean)
464      */

465     public void setUseCaches(boolean isUsingCaches)
466     {
467         this.delegate.setUseCaches(isUsingCaches);
468     }
469
470     /**
471      * @see java.net.HttpURLConnection#toString()
472      */

473     public String JavaDoc toString()
474     {
475         return this.delegate.toString();
476     }
477
478     /**
479      * @see java.net.HttpURLConnection#disconnect()
480      */

481     public void disconnect()
482     {
483         this.delegate.disconnect();
484     }
485
486     /**
487      * @see java.net.HttpURLConnection#getErrorStream()
488      */

489     public InputStream JavaDoc getErrorStream()
490     {
491         return this.delegate.getErrorStream();
492     }
493
494     /**
495      * @see java.net.HttpURLConnection#getRequestMethod()
496      */

497     public String JavaDoc getRequestMethod()
498     {
499         return this.delegate.getRequestMethod();
500     }
501
502     /**
503      * @see java.net.HttpURLConnection#getResponseCode()
504      */

505     public int getResponseCode() throws IOException JavaDoc
506     {
507         return this.delegate.getResponseCode();
508     }
509
510     /**
511      * @see java.net.HttpURLConnection#getResponseMessage()
512      */

513     public String JavaDoc getResponseMessage() throws IOException JavaDoc
514     {
515         return this.delegate.getResponseMessage();
516     }
517
518     /**
519      * @see java.net.HttpURLConnection#setRequestMethod(String)
520      */

521     public void setRequestMethod(String JavaDoc theMethod) throws ProtocolException JavaDoc
522     {
523         this.delegate.setRequestMethod(theMethod);
524     }
525
526     /**
527      * @see java.net.HttpURLConnection#usingProxy()
528      */

529     public boolean usingProxy()
530     {
531         return this.delegate.usingProxy();
532     }
533 }
534
Popular Tags