KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > go > trove > net > CheckedSocket


1 /* ====================================================================
2  * Trove - Copyright (c) 1997-2000 Walt Disney Internet Group
3  * ====================================================================
4  * The Tea Software License, Version 1.1
5  *
6  * Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Walt Disney Internet Group (http://opensource.go.com/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact opensource@dig.com.
31  *
32  * 5. Products derived from this software may not be called "Tea",
33  * "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
34  * "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
35  * written permission of the Walt Disney Internet Group.
36  *
37  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40  * DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
41  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
42  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
43  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
44  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48  * ====================================================================
49  *
50  * For more information about Tea, please see http://opensource.go.com/.
51  */

52
53 package com.go.trove.net;
54
55 import java.io.*;
56 import java.net.*;
57 import java.util.*;
58
59 /******************************************************************************
60  * A socket that tracks if any I/O exceptions have occured and ensures that
61  * plain I/O exceptions are thrown as SocketExceptions. InterruptedIOExceptions
62  * do not affect the exception count, and they are not converted to
63  * SocketExceptions.
64  * <p>
65  * All socket exceptions thrown will actually be instances of
66  * {@link CheckedSocketException}, which subclasses SocketException. The error
67  * messages will contain additional information, and the original exception
68  * and socket can be obtained from it.
69  *
70  * @author Brian S O'Neill
71  * @version
72  * <!--$$Revision:--> 10 <!-- $-->, <!--$$JustDate:--> 01/03/16 <!-- $-->
73  */

74 public class CheckedSocket extends FilteredSocket {
75     /**
76      * Returns a new CheckedSocket instance only if the given socket isn't
77      * already one.
78      */

79     public static CheckedSocket check(Socket socket) throws SocketException {
80         if (socket instanceof CheckedSocket) {
81             return (CheckedSocket)socket;
82         }
83         else {
84             return new CheckedSocket(socket);
85         }
86     }
87
88     private int mExceptionCount;
89     private InputStream mIn;
90     private OutputStream mOut;
91
92     private Set mExceptionListeners;
93
94     protected CheckedSocket(Socket socket) throws SocketException {
95         super(socket);
96     }
97
98     /**
99      * Returns the total number of exceptions encountered while using this
100      * socket, excluding InterruptedIOExceptions. If this count is not zero,
101      * then the socket is potentially in an unrecoverable state.
102      */

103     public int getExceptionCount() {
104         return mExceptionCount;
105     }
106
107     /**
108      * Internally, the collection of listeners is saved in a set so that
109      * listener instances may be added multiple times without harm.
110      */

111     public synchronized void addExceptionListener(ExceptionListener listener) {
112         if (mExceptionListeners == null) {
113             mExceptionListeners = new HashSet();
114         }
115         mExceptionListeners.add(listener);
116     }
117
118     public synchronized void removeExceptionListener(ExceptionListener listener) {
119         if (mExceptionListeners != null) {
120             mExceptionListeners.remove(listener);
121         }
122     }
123     
124     public synchronized InputStream getInputStream() throws IOException {
125         if (mIn != null) {
126             return mIn;
127         }
128         
129         try {
130             return mIn = new Input(super.getInputStream());
131         }
132         catch (Exception JavaDoc e) {
133             throw handleIOException(e);
134         }
135     }
136
137     public synchronized OutputStream getOutputStream() throws IOException {
138         if (mOut != null) {
139             return mOut;
140         }
141         
142         try {
143             return mOut = new Output(super.getOutputStream());
144         }
145         catch (Exception JavaDoc e) {
146             throw handleIOException(e);
147         }
148     }
149
150     public void setTcpNoDelay(boolean on) throws SocketException {
151         try {
152             super.setTcpNoDelay(on);
153         }
154         catch (Exception JavaDoc e) {
155             throw handleSocketException(e);
156         }
157     }
158
159     public boolean getTcpNoDelay() throws SocketException {
160         try {
161             return super.getTcpNoDelay();
162         }
163         catch (Exception JavaDoc e) {
164             throw handleSocketException(e);
165         }
166     }
167
168     public void setSoLinger(boolean on, int linger) throws SocketException {
169         try {
170             super.setSoLinger(on, linger);
171         }
172         catch (Exception JavaDoc e) {
173             throw handleSocketException(e);
174         }
175     }
176
177     public int getSoLinger() throws SocketException {
178         try {
179             return super.getSoLinger();
180         }
181         catch (Exception JavaDoc e) {
182             throw handleSocketException(e);
183         }
184     }
185
186     public void setSoTimeout(int timeout) throws SocketException {
187         try {
188             super.setSoTimeout(timeout);
189         }
190         catch (Exception JavaDoc e) {
191             throw handleSocketException(e);
192         }
193     }
194
195     public int getSoTimeout() throws SocketException {
196         try {
197             return super.getSoTimeout();
198         }
199         catch (Exception JavaDoc e) {
200             throw handleSocketException(e);
201         }
202     }
203
204     public void setSendBufferSize(int size) throws SocketException {
205         try {
206             super.setSendBufferSize(size);
207         }
208         catch (Exception JavaDoc e) {
209             throw handleSocketException(e);
210         }
211     }
212
213     public int getSendBufferSize() throws SocketException {
214         try {
215             return super.getSendBufferSize();
216         }
217         catch (Exception JavaDoc e) {
218             throw handleSocketException(e);
219         }
220     }
221
222     public void setReceiveBufferSize(int size) throws SocketException {
223         try {
224             super.setReceiveBufferSize(size);
225         }
226         catch (Exception JavaDoc e) {
227             throw handleSocketException(e);
228         }
229     }
230
231     public int getReceiveBufferSize() throws SocketException {
232         try {
233             return super.getReceiveBufferSize();
234         }
235         catch (Exception JavaDoc e) {
236             throw handleSocketException(e);
237         }
238     }
239
240     public void close() throws IOException {
241         try {
242             super.close();
243         }
244         catch (Exception JavaDoc e) {
245             throw handleIOException(e);
246         }
247     }
248
249     public void setKeepAlive(boolean on) throws SocketException {
250         try {
251             super.setKeepAlive(on);
252         }
253         catch (Exception JavaDoc e) {
254             throw handleSocketException(e);
255         }
256     }
257
258     public boolean getKeepAlive() throws SocketException {
259         try {
260             return super.getKeepAlive();
261         }
262         catch (Exception JavaDoc e) {
263             throw handleSocketException(e);
264         }
265     }
266
267     public void shutdownInput() throws IOException {
268         try {
269             super.shutdownInput();
270         }
271         catch (Exception JavaDoc e) {
272             throw handleIOException(e);
273         }
274     }
275
276     public void shutdownOutput() throws IOException {
277         try {
278             super.shutdownOutput();
279         }
280         catch (Exception JavaDoc e) {
281             throw handleIOException(e);
282         }
283     }
284
285     /**
286      * @param e should be instance of IOException or RuntimeException.
287      */

288     IOException handleIOException(Exception JavaDoc e) {
289         if (e instanceof InterruptedIOException) {
290             return CheckedInterruptedIOException.create
291                 ((InterruptedIOException)e, mSocket);
292         }
293
294         int count;
295         synchronized (this) {
296             count = ++mExceptionCount;
297         }
298         exceptionOccurred(e, count);
299
300         if (e instanceof CheckedSocketException) {
301             return (CheckedSocketException)e;
302         }
303         else if (e instanceof NullPointerException JavaDoc) {
304             // Workaround for a bug in the Socket class that sometimes
305
// causes a NullPointerException on a closed socket.
306
return CheckedSocketException.create(e, mSocket, "Socket closed");
307         }
308         else {
309             return CheckedSocketException.create(e, mSocket);
310         }
311     }
312
313     /**
314      * @param e Should be instance of SocketException or RuntimeException.
315      */

316     SocketException handleSocketException(Exception JavaDoc e) {
317         int count;
318         synchronized (this) {
319             count = ++mExceptionCount;
320         }
321         exceptionOccurred(e, count);
322
323         if (e instanceof CheckedSocketException) {
324             return (CheckedSocketException)e;
325         }
326         else if (e instanceof NullPointerException JavaDoc) {
327             // Workaround for a bug in the Socket class that sometimes
328
// causes a NullPointerException on a closed socket.
329
return CheckedSocketException.create(e, mSocket, "Socket closed");
330         }
331         else {
332             return CheckedSocketException.create(e, mSocket);
333         }
334     }
335
336     private synchronized void exceptionOccurred(Exception JavaDoc e, int count) {
337         if (mExceptionListeners != null) {
338             Iterator it = mExceptionListeners.iterator();
339             while (it.hasNext()) {
340                 ((ExceptionListener)it.next())
341                     .exceptionOccurred(this, e, count);
342             }
343         }
344     }
345
346     public static interface ExceptionListener {
347         /**
348          * @param count new exception count, which will be one the first time
349          * this method is called.
350          */

351         public void exceptionOccurred(CheckedSocket s, Exception JavaDoc e, int count);
352     }
353
354     private class Input extends InputStream {
355         private final InputStream mStream;
356
357         public Input(InputStream in) {
358             mStream = in;
359         }
360
361         public int read() throws IOException {
362             try {
363                 return mStream.read();
364             }
365             catch (IOException e) {
366                 throw handleIOException(e);
367             }
368         }
369         
370         public int read(byte[] b) throws IOException {
371             try {
372                 return mStream.read(b);
373             }
374             catch (IOException e) {
375                 throw handleIOException(e);
376             }
377         }
378         
379         public int read(byte[] b, int off, int len) throws IOException {
380             try {
381                 return mStream.read(b, off, len);
382             }
383             catch (IOException e) {
384                 throw handleIOException(e);
385             }
386         }
387         
388         public long skip(long n) throws IOException {
389             try {
390                 return mStream.skip(n);
391             }
392             catch (IOException e) {
393                 throw handleIOException(e);
394             }
395         }
396         
397         public int available() throws IOException {
398             try {
399                 return mStream.available();
400             }
401             catch (IOException e) {
402                 throw handleIOException(e);
403             }
404         }
405         
406         public void close() throws IOException {
407             try {
408                 mStream.close();
409             }
410             catch (IOException e) {
411                 throw handleIOException(e);
412             }
413         }
414         
415         public void mark(int readlimit) {
416             mStream.mark(readlimit);
417         }
418
419         public void reset() throws IOException {
420             try {
421                 mStream.reset();
422             }
423             catch (IOException e) {
424                 throw handleIOException(e);
425             }
426         }
427
428         public boolean markSupported() {
429             return mStream.markSupported();
430         }
431     }
432
433     private class Output extends OutputStream {
434         private final OutputStream mStream;
435
436         public Output(OutputStream out) {
437             mStream = out;
438         }
439
440         public void write(int b) throws IOException {
441             try {
442                 mStream.write(b);
443             }
444             catch (IOException e) {
445                 throw handleIOException(e);
446             }
447         }
448         
449         public void write(byte[] b) throws IOException {
450             try {
451                 mStream.write(b);
452             }
453             catch (IOException e) {
454                 throw handleIOException(e);
455             }
456         }
457         
458         public void write(byte[] b, int off, int len) throws IOException {
459             try {
460                 mStream.write(b, off, len);
461             }
462             catch (IOException e) {
463                 throw handleIOException(e);
464             }
465         }
466         
467         public void flush() throws IOException {
468             try {
469                 mStream.flush();
470             }
471             catch (IOException e) {
472                 throw handleIOException(e);
473             }
474         }
475         
476         public void close() throws IOException {
477             try {
478                 mStream.close();
479             }
480             catch (IOException e) {
481                 throw handleIOException(e);
482             }
483         }
484     }
485 }
486
Popular Tags