1 45 package org.exolab.jms.net.multiplexer; 46 47 import java.io.EOFException ; 48 import java.io.IOException ; 49 import java.io.ObjectInputStream ; 50 import java.io.ObjectOutputStream ; 51 import java.rmi.MarshalException ; 52 import java.rmi.RemoteException ; 53 import java.rmi.UnmarshalException ; 54 55 import org.apache.commons.logging.Log; 56 import org.apache.commons.logging.LogFactory; 57 58 import org.exolab.jms.net.connector.Request; 59 import org.exolab.jms.net.connector.Response; 60 61 62 69 class Channel implements Constants { 70 71 74 private int _id; 75 76 79 private Multiplexer _multiplexer; 80 81 84 private MultiplexInputStream _in; 85 86 89 private MultiplexOutputStream _out; 90 91 94 private final Object _lock = new Object (); 95 96 99 private volatile boolean _closed = false; 100 101 104 private static final Log _log = LogFactory.getLog(Channel.class); 105 106 107 115 public Channel(int id, Multiplexer multiplexer, 116 MultiplexInputStream in, MultiplexOutputStream out) { 117 _id = id; 118 _multiplexer = multiplexer; 119 _in = in; 120 _out = out; 121 } 122 123 128 public int getId() { 129 return _id; 130 } 131 132 139 public Response invoke(Request request) throws RemoteException { 140 if (_log.isDebugEnabled()) { 141 _log.debug("invoke() [channel=" + _id + "]"); 142 } 143 Response response; 144 ObjectOutputStream out = null; 145 try { 146 _out.setType(REQUEST); 148 149 out = new ObjectOutputStream (_out); 151 request.write(out); 152 } catch (IOException exception) { 153 throw new MarshalException ("Failed to marshal call", exception); 154 } catch (Exception exception) { 155 throw new MarshalException ("Failed to marshal call", exception); 156 } finally { 157 if (out != null) { 158 try { 159 out.close(); 160 } catch (IOException ignore) { 161 } 162 } 163 } 164 165 ObjectInputStream in = null; 167 try { 168 in = new ObjectInputStream (_in); 169 response = Response.read(in, request.getMethod()); 170 } catch (ClassNotFoundException exception) { 171 throw new UnmarshalException ("Failed to unmarshal response", 172 exception); 173 } catch (IOException exception) { 174 throw new UnmarshalException ("Failed to unmarshal response", 175 exception); 176 } finally { 177 try { 178 if (in != null) { 179 in.close(); 180 } 181 } catch (IOException ignore) { 182 } 183 } 184 if (_log.isDebugEnabled()) { 185 _log.debug("invoke() [channel=" + _id + "] - end"); 186 } 187 return response; 188 } 189 190 195 public void ping() throws IOException { 196 if (_log.isDebugEnabled()) { 197 _log.debug("ping [channel=" + _id + "]"); 198 } 199 synchronized (_lock) { 200 _multiplexer.send(PING_REQUEST, _id); 201 checkDisconnection(); 202 try { 203 _lock.wait(); 204 } catch (InterruptedException exception) { 205 throw new IOException (exception.getMessage()); 206 } 207 checkDisconnection(); 208 } 209 if (_log.isDebugEnabled()) { 210 _log.debug("ping [channel=" + _id + "] - end"); 211 } 212 } 213 214 221 public synchronized Request readRequest() throws IOException { 222 Request request; 223 ObjectInputStream in = new ObjectInputStream (_in); 224 request = Request.read(in); 225 return request; 226 } 227 228 235 public synchronized void writeResponse(Response response) 236 throws IOException { 237 _out.setType(RESPONSE); 239 240 ObjectOutputStream out = new ObjectOutputStream (_out); 242 try { 243 response.write(out); 244 } finally { 245 out.close(); 246 } 247 } 248 249 254 public void handlePingRequest() throws IOException { 255 _multiplexer.send(PING_RESPONSE, _id); 256 } 257 258 261 public void handlePingResponse() { 262 notifyLock(); 263 } 264 265 268 public void disconnected() { 269 if (_log.isDebugEnabled()) { 270 _log.debug("disconnected [channel=" + _id + "]"); 271 } 272 _closed = true; 273 _in.disconnected(); 274 _out.disconnected(); 275 notifyLock(); } 277 278 283 public MultiplexInputStream getMultiplexInputStream() { 284 return _in; 285 } 286 287 292 public MultiplexOutputStream getMultiplexOutputStream() { 293 return _out; 294 } 295 296 299 public void release() { 300 notifyLock(); 301 _multiplexer.release(this); 302 } 303 304 309 public void close() throws IOException { 310 if (_multiplexer != null) { 311 _closed = true; 312 notifyLock(); 313 try { 314 _multiplexer.close(this); 315 } finally { 316 _multiplexer = null; 317 318 try { 319 _in.destroy(); 320 } catch (IOException ignore) { 321 } 323 try { 324 _out.close(); 325 } catch (IOException ignore) { 326 } 328 } 329 } 330 } 331 332 335 public void destroy() { 336 try { 337 close(); 338 } catch (IOException exception) { 339 } 341 } 342 343 348 public String toString() { 349 return "Channel[id=" + _id + ", out=" + _out + ", in=" + _in + " ]"; 350 } 351 352 355 private void notifyLock() { 356 synchronized (_lock) { 357 _lock.notifyAll(); 358 } 359 } 360 361 366 private void checkDisconnection() throws EOFException { 367 if (_closed) { 368 throw new EOFException ("Channel disconnected"); 370 } 371 } 372 } 373 | Popular Tags |