KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > ubik > net > SocketConnection


1 package org.sapia.ubik.net;
2
3 import java.io.BufferedInputStream JavaDoc;
4 import java.io.BufferedOutputStream JavaDoc;
5 import java.io.EOFException JavaDoc;
6 import java.io.IOException JavaDoc;
7 import java.io.InputStream JavaDoc;
8 import java.io.ObjectInputStream JavaDoc;
9 import java.io.ObjectOutputStream JavaDoc;
10 import java.io.OutputStream JavaDoc;
11
12 import java.net.Socket JavaDoc;
13 import java.net.SocketException JavaDoc;
14
15 import java.rmi.RemoteException JavaDoc;
16
17
18 /**
19  * A <code>Connection</code> implemented through a <code>Socket</code>.
20  *
21  * @author Yanick Duchesne
22  * <dl>
23  * <dt><b>Copyright:</b><dd>Copyright &#169; 2002-2003 <a HREF="http://www.sapia-oss.org">Sapia Open Source Software</a>. All Rights Reserved.</dd></dt>
24  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
25  * <a HREF="http://www.sapia-oss.org/license.html">license page</a> at the Sapia OSS web site</dd></dt>
26  * </dl>
27  */

28 public class SocketConnection implements Connection {
29   static final long DEFAULT_RESET_INTERVAL = 0;
30   protected Socket JavaDoc _sock;
31   protected TCPAddress _address;
32   protected ClassLoader JavaDoc _loader;
33   protected ObjectInputStream JavaDoc _is;
34   protected ObjectOutputStream JavaDoc _os;
35   protected long _lastReset = System.currentTimeMillis();
36   protected long _resetInterval = DEFAULT_RESET_INTERVAL;
37
38   public SocketConnection(Socket JavaDoc sock, ClassLoader JavaDoc loader) {
39     this(sock);
40     _loader = loader;
41   }
42
43   public SocketConnection(Socket JavaDoc sock) {
44     _sock = sock;
45     _address = new TCPAddress(sock.getInetAddress().getHostAddress(),
46         sock.getPort());
47   }
48   
49   /**
50    * Sets the interval at which this instance calls the <code>reset</code>
51    * method on the <code>ObjectOutputStream</code> that in uses internally for serializing
52    * objects.
53    * <p>
54    * This instance performs the reset at every write, insuring that no stale
55    * object is cached by the underlying <code>OutputStream</code>.
56    *
57    * @param interval the interval (in millis) at which this instance calls
58    * the <code>reset</code> method of its <code>ObjectOutputStream</code>.
59    */

60   public void setResetInterval(long interval){
61     _resetInterval = interval;
62   }
63
64   /**
65    * @see org.sapia.ubik.net.Connection#send(Object)
66    */

67   public void send(Object JavaDoc o) throws IOException JavaDoc, RemoteException JavaDoc {
68     try {
69       if (_os == null) {
70         _os = newOutputStream(new BufferedOutputStream JavaDoc(
71               _sock.getOutputStream(), 1000), _loader);
72       }
73       
74       _os.writeObject(o);
75       
76       
77       if ((System.currentTimeMillis() - _lastReset) >= DEFAULT_RESET_INTERVAL) {
78         _os.reset();
79         _lastReset = System.currentTimeMillis();
80       }
81       
82       _os.flush();
83       
84     } catch (java.net.SocketException JavaDoc e) {
85       throw new RemoteException JavaDoc("Communication with server interrupted; server probably disappeared",
86         e);
87     } catch (EOFException JavaDoc e) {
88       throw new RemoteException JavaDoc("Communication with server interrupted; server probably disappeared",
89         e);
90     }
91   }
92
93   /**
94    * @see org.sapia.ubik.net.Connection#receive()
95    */

96   public Object JavaDoc receive()
97     throws IOException JavaDoc, ClassNotFoundException JavaDoc, RemoteException JavaDoc {
98     try {
99       if (_is == null) {
100         _is = newInputStream(new BufferedInputStream JavaDoc(_sock.getInputStream(),
101               1000), _loader);
102       }
103
104       return _is.readObject();
105     } catch (EOFException JavaDoc e) {
106       throw new RemoteException JavaDoc("Communication with server interrupted; server probably disappeared",
107         e);
108     } catch (SocketException JavaDoc e) {
109       throw new RemoteException JavaDoc("Connection could not be opened; server is probably down",
110         e);
111     }
112   }
113
114   /**
115    * @see org.sapia.ubik.net.Connection#close()
116    */

117   public void close() {
118     try {
119       if (_os != null) {
120         _os.reset();
121         _os.close();
122         _os = null;
123       }
124
125       if (_is != null) {
126         _is.close();
127         _is = null;
128       }
129
130       _sock.close();
131     } catch (Throwable JavaDoc t) {
132       //noop
133
}
134   }
135
136   /**
137    * @see org.sapia.ubik.net.Connection#getServerAddress()
138    */

139   public ServerAddress getServerAddress() {
140     return _address;
141   }
142
143   /**
144    * Returns this instance's internal input stream.
145    *
146    * @return an <code>InputStream</code>.
147    */

148   public InputStream JavaDoc getInputStream() throws IOException JavaDoc {
149     return _sock.getInputStream();
150   }
151
152   /**
153    * Returns this instance's internal output stream.
154    *
155    * @return an <code>OutputStream</code>.
156    */

157   public OutputStream JavaDoc getOuputStream() throws IOException JavaDoc {
158     return _sock.getOutputStream();
159   }
160
161   /**
162    * Template method internally called by this instance; the method should create
163    * an <code>ObjectOutputStream</code> for the given parameters.
164    *
165    * @param os the <code>OutputStream</code> that the returned stream should wrap.
166    * @param the <code>ClassLoader</code> that this instance corresponds to.
167    * @return an <code>ObjectOutputStream</code>.
168    * @throws IOException if a problem occurs creating the desired object.
169    */

170   protected ObjectOutputStream JavaDoc newOutputStream(OutputStream JavaDoc os,
171     ClassLoader JavaDoc loader) throws IOException JavaDoc {
172     return new ObjectOutputStream JavaDoc(os);
173   }
174
175   /**
176    * Template method internally called by this instance; the method should create
177    * an <code>ObjectInputStream</code> for the given parameters.
178    * <p>
179    * The returned instance can use the passed in classloader to resolve the classes of the
180    * deserialized objects.
181    *
182    * @see ObjectInputStream#resolveClass(java.io.ObjectStreamClass)
183    * @param is the <code>InputStream</code> that the returned stream should wrap.
184    * @param the <code>ClassLoader</code> that this instance corresponds to.
185    * @return an <code>ObjectInputStream</code>.
186    * @throws IOException if a problem occurs creating the desired object.
187
188    */

189   protected ObjectInputStream JavaDoc newInputStream(InputStream JavaDoc is, ClassLoader JavaDoc loader)
190     throws IOException JavaDoc {
191     return new ObjectInputStream JavaDoc(is);
192   }
193 }
194
Popular Tags