~ubuntu-branches/ubuntu/raring/libjboss-remoting-java/raring

« back to all changes in this revision

Viewing changes to src/main/org/jboss/remoting/transport/multiplex/VirtualSocket.java

  • Committer: Package Import Robot
  • Author(s): Torsten Werner
  • Date: 2011-09-09 14:01:03 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: package-import@ubuntu.com-20110909140103-hqokx61534tas9rg
Tags: 2.5.3.SP1-1
* Newer but not newest upstream release. Do not build samples.
* Change debian/watch to upstream's svn repo.
* Add patch to fix compile error caused by tomcat update.
  (Closes: #628303)
* Switch to source format 3.0.
* Switch to debhelper level 7.
* Remove useless Depends.
* Update Standards-Version: 3.9.2.
* Update README.source.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
* JBoss, Home of Professional Open Source
 
3
* Copyright 2005, JBoss Inc., and individual contributors as indicated
 
4
* by the @authors tag. See the copyright.txt in the distribution for a
 
5
* full listing of individual contributors.
 
6
*
 
7
* This is free software; you can redistribute it and/or modify it
 
8
* under the terms of the GNU Lesser General Public License as
 
9
* published by the Free Software Foundation; either version 2.1 of
 
10
* the License, or (at your option) any later version.
 
11
*
 
12
* This software is distributed in the hope that it will be useful,
 
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
15
* Lesser General Public License for more details.
 
16
*
 
17
* You should have received a copy of the GNU Lesser General Public
 
18
* License along with this software; if not, write to the Free
 
19
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 
20
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 
21
*/
 
22
 
 
23
/*
 
24
 * Created on Jul 22, 2005
 
25
 */
 
26
 
 
27
package org.jboss.remoting.transport.multiplex;
 
28
 
 
29
import org.jboss.logging.Logger;
 
30
 
 
31
import java.io.IOException;
 
32
import java.io.InputStream;
 
33
import java.io.OutputStream;
 
34
import java.net.InetAddress;
 
35
import java.net.InetSocketAddress;
 
36
import java.net.Socket;
 
37
import java.net.SocketAddress;
 
38
import java.net.SocketException;
 
39
import java.net.SocketImpl;
 
40
import java.net.SocketTimeoutException;
 
41
import java.net.UnknownHostException;
 
42
import java.nio.channels.SocketChannel;
 
43
import java.util.HashMap;
 
44
import java.util.HashSet;
 
45
import java.util.Iterator;
 
46
import java.util.Map;
 
47
import java.util.Set;
 
48
 
 
49
/**
 
50
 * <code>VirtualSocket</code> represents an endpoint on a virtual connection created by the
 
51
 * Multiplex system.  It extends <code>java.net.Socket</code> and reimplements nearly all of
 
52
 * the methods in <code>java.net.Socket</code>.  For information about method behavior, please
 
53
 * see the <code>java.net.Socket</code> javadoc.  For more information about the nature of
 
54
 * virtual sockets, please see the Multiplex documentation at the labs.jboss.org
 
55
 * web site.
 
56
 *
 
57
 * <p>
 
58
 * Copyright (c) 2005
 
59
 * <p>
 
60
 * @author <a href="mailto:r.sigal@computer.org">Ron Sigal</a>
 
61
 * 
 
62
 * @deprecated As of release 2.4.0 the multiplex transport will no longer be actively supported.
 
63
 */
 
64
public class VirtualSocket extends Socket
 
65
{
 
66
   protected static final Logger log = Logger.getLogger(VirtualSocket.class);
 
67
   protected static Thread closingThread;
 
68
 
 
69
   private Map configuration = new HashMap();
 
70
   private MultiplexingManager manager;
 
71
   private Protocol protocol;
 
72
   private Socket actualSocket;
 
73
   private SocketId remoteSocketId;
 
74
   private SocketId localSocketId;
 
75
   private MultiplexingInputStream inputStream;
 
76
   private MultiplexingOutputStream outputStream;
 
77
   private Set disconnectListeners = new HashSet();
 
78
 
 
79
   private boolean bound = false;
 
80
   private boolean closed = false;
 
81
   private boolean connected = false;
 
82
   private boolean inputShutdown = false;
 
83
   private boolean outputShutdown = false;
 
84
   private boolean receivedDisconnectMessage = false;
 
85
 
 
86
   private int     timeout;
 
87
   private Socket  dummySocket;
 
88
 
 
89
   private boolean functional = true;
 
90
 
 
91
   private boolean trace;
 
92
   private boolean debug;
 
93
   private boolean info;
 
94
 
 
95
 
 
96
   /**
 
97
    * A class that implements <code>DisconnectListener</code> can register to
 
98
    * be notified if the remote peer of this <code>VirtualSocket</code> has
 
99
    * disconnected.
 
100
    */
 
101
   public interface DisconnectListener
 
102
   {
 
103
      void notifyDisconnected(VirtualSocket virtualSocket);
 
104
   }
 
105
 
 
106
 
 
107
   public VirtualSocket(MultiplexingManager manager, SocketId remoteSocketId, Map configuration) throws IOException
 
108
   {
 
109
      this.manager = manager;
 
110
      this.actualSocket = manager.getSocket();
 
111
      this.remoteSocketId = remoteSocketId;
 
112
      this.configuration.putAll(configuration);
 
113
      protocol = manager.getProtocol();
 
114
      localSocketId = new SocketId();
 
115
      inputStream = manager.registerSocket(this);
 
116
//      outputStream = new MultiplexingOutputStream(manager, this, remoteSocketId);
 
117
      outputStream = manager.getAnOutputStream(this, remoteSocketId);
 
118
      bound = true;
 
119
      connected = true;
 
120
 
 
121
      trace = log.isTraceEnabled();
 
122
      debug = log.isDebugEnabled();
 
123
      info = log.isInfoEnabled();
 
124
      if (debug) log.debug("created virtual socket on port: " + localSocketId.getPort());
 
125
   }
 
126
 
 
127
 
 
128
   public VirtualSocket(Map configuration)
 
129
   {
 
130
      this.configuration.putAll(configuration);
 
131
   }
 
132
 
 
133
 
 
134
//////////////////////////////////////////////////////////////////////////////////////////////////
 
135
///           The following constructors duplicate those of the parent class Socket           '///
 
136
//////////////////////////////////////////////////////////////////////////////////////////////////
 
137
 
 
138
/**
 
139
 * See superclass javadoc.
 
140
 */
 
141
   public VirtualSocket()
 
142
   {
 
143
      log.debug("created unbound virtual socket");
 
144
   }
 
145
 
 
146
 
 
147
/**
 
148
 * See superclass javadoc.
 
149
 */
 
150
   public VirtualSocket(String host, int port) throws UnknownHostException, IOException
 
151
   {
 
152
      InetSocketAddress address = null;
 
153
 
 
154
      if (host == null)
 
155
         address = new InetSocketAddress(InetAddress.getByName(null), port);
 
156
      else
 
157
         address = new InetSocketAddress(host, port);
 
158
 
 
159
      connect(address);
 
160
      if (debug) log.debug("created virtual socket on port: " + localSocketId.getPort());
 
161
   }
 
162
 
 
163
 
 
164
/**
 
165
 * See superclass javadoc.
 
166
 * @param host
 
167
 * @param port
 
168
 * @param stream
 
169
 * @throws java.io.IOException
 
170
 */
 
171
   public VirtualSocket(String host, int port, boolean stream) throws IOException
 
172
   {
 
173
      if (!stream)
 
174
      {
 
175
         throw new SocketException("Deprecated: use DataGramSocket instead of stream = false");
 
176
      }
 
177
 
 
178
      InetSocketAddress address = null;
 
179
 
 
180
      if (host == null)
 
181
         address = new InetSocketAddress(InetAddress.getByName(null), port);
 
182
      else
 
183
         address = new InetSocketAddress(host, port);
 
184
 
 
185
      connect(address);
 
186
      if (debug) log.debug("created virtual socket on port: " + localSocketId.getPort());
 
187
   }
 
188
 
 
189
 
 
190
/**
 
191
 * See superclass javadoc.
 
192
 * @param address
 
193
 * @param port
 
194
 * @throws java.io.IOException
 
195
 */
 
196
   public VirtualSocket(InetAddress address, int port) throws IOException
 
197
   {
 
198
      connect(new InetSocketAddress(address, port));
 
199
      if (debug) log.debug("created virtual socket on port: " + localSocketId.getPort());
 
200
   }
 
201
 
 
202
 
 
203
/**
 
204
 * See superclass javadoc.
 
205
 * @param host
 
206
 * @param port
 
207
 * @param stream
 
208
 * @throws java.io.IOException
 
209
 */
 
210
   public VirtualSocket(InetAddress host, int port, boolean stream) throws IOException
 
211
   {
 
212
      if (!stream)
 
213
      {
 
214
         throw new SocketException("Deprecated: use DataGramSocket instead of stream = false");
 
215
      }
 
216
 
 
217
      connect(new InetSocketAddress(host, port));
 
218
      if (debug) log.debug("created virtual socket on port: " + localSocketId.getPort());
 
219
   }
 
220
 
 
221
 
 
222
/**
 
223
 * This constuctor is not implemented.
 
224
 * <p>
 
225
 * @param impl
 
226
 * @throws java.net.SocketException in all cases
 
227
 */
 
228
   public VirtualSocket(SocketImpl impl) throws SocketException
 
229
   {
 
230
      throw new SocketException("VirtualSocket does not use SocketImpl");
 
231
   }
 
232
 
 
233
 
 
234
/**
 
235
 * See superclass javadoc.
 
236
 * @param host
 
237
 * @param port
 
238
 * @param localAddr
 
239
 * @param localPort
 
240
 * @throws java.io.IOException
 
241
 */
 
242
   public VirtualSocket(String host, int port, InetAddress localAddr, int localPort) throws IOException
 
243
   {
 
244
      this(InetAddress.getByName(host), port, localAddr, localPort);
 
245
   }
 
246
 
 
247
 
 
248
/**
 
249
 * See superclass javadoc.
 
250
 * @param address
 
251
 * @param port
 
252
 * @param localAddr
 
253
 * @param localPort
 
254
 * @throws java.io.IOException
 
255
 */
 
256
   public VirtualSocket(InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException
 
257
   {
 
258
      this();
 
259
      connect(new InetSocketAddress(address, port), new InetSocketAddress(localAddr, localPort), 0);
 
260
      if (debug) log.debug("created virtual socket on port: " + localSocketId.getPort());
 
261
   }
 
262
 
 
263
 
 
264
 
 
265
//////////////////////////////////////////////////////////////////////////////////////////////////
 
266
///                     The following methods are required of all Socket's                    '///
 
267
//////////////////////////////////////////////////////////////////////////////////////////////////
 
268
 
 
269
 
 
270
   /*************************************************************************************************
 
271
    * public methods in Socket class
 
272
    *
 
273
      ok: public void connect(SocketAddress endpoint) throws IOException;
 
274
      ok: public void connect(SocketAddress endpoint, int timeout) throws IOException;
 
275
      ok: public void bind(SocketAddress bindpoint) throws IOException;
 
276
      ok: public InetAddress getInetAddress();
 
277
      ok: public InetAddress getLocalAddress();
 
278
      ok: public int getPort();
 
279
      ok: public int getLocalPort();
 
280
      ok: public SocketAddress getRemoteSocketAddress();
 
281
      ok: public SocketAddress getLocalSocketAddress();
 
282
      ok: public SocketChannel getChannel();
 
283
      ok: public InputStream getInputStream() throws IOException;
 
284
      ok: public OutputStream getOutputStream() throws IOException;
 
285
      ok: public void setTcpNoDelay(boolean on) throws SocketException;
 
286
      ok: public boolean getTcpNoDelay() throws SocketException;
 
287
      ok: public void setSoLinger(boolean on, int linger) throws SocketException;
 
288
      ok: public int getSoLinger() throws SocketException;
 
289
      ok: public void sendUrgentData(int data) throws IOException;
 
290
      ok: public void setOOBInline(boolean on) throws SocketException;
 
291
      ok: public boolean getOOBInline() throws SocketException;
 
292
      ok: public void setSoTimeout(int timeout) throws SocketException;
 
293
      ok: public int getSoTimeout() throws SocketException;
 
294
      ok: public void setSendBufferSize(int size) throws SocketException;
 
295
      ok: public int getSendBufferSize() throws SocketException;
 
296
      ok: public void setReceiveBufferSize(int size) throws SocketException;
 
297
      ok: public int getReceiveBufferSize() throws SocketException;
 
298
      ok: public void setKeepAlive(boolean on) throws SocketException;
 
299
      ok: public boolean getKeepAlive() throws SocketException;
 
300
      ok: public void setTrafficClass(int tc) throws SocketException;
 
301
      ok: public int getTrafficClass() throws SocketException;
 
302
      ok: public void setReuseAddress(boolean on) throws SocketException;
 
303
      ok: public boolean getReuseAddress() throws SocketException;
 
304
      ok: public void close() throws IOException;
 
305
      ok: public void shutdownInput() throws IOException;
 
306
      ok: public void shutdownOutput() throws IOException;
 
307
      ok: public String toString();
 
308
      ok: public boolean isConnected();
 
309
      ok: public boolean isBound();
 
310
      ok: public boolean isClosed();
 
311
      ok: public boolean isInputShutdown();
 
312
      ok: public boolean isOutputShutdown();
 
313
   *************************************************************************************************/
 
314
 
 
315
 
 
316
/**
 
317
 * See superclass javadoc.
 
318
 */
 
319
   public void bind(SocketAddress address) throws IOException
 
320
   {
 
321
      if (isClosed())
 
322
         throw new SocketException("Socket is closed");
 
323
 
 
324
      if (isBound())
 
325
         throw new SocketException("Already bound");
 
326
 
 
327
      if (address != null && (!(address instanceof InetSocketAddress)))
 
328
         throw new IllegalArgumentException("Unsupported address type");
 
329
 
 
330
      InetSocketAddress inetAddress = (InetSocketAddress) address;
 
331
 
 
332
      if (inetAddress != null && inetAddress.isUnresolved())
 
333
         throw new SocketException("Unresolved address");
 
334
 
 
335
      manager = MultiplexingManager.getaManagerByLocalAddress(inetAddress, configuration);
 
336
      actualSocket = manager.getSocket();
 
337
      localSocketId = new SocketId();
 
338
      if (debug) log.debug("bound virtual socket to port: " + localSocketId.getPort());
 
339
      bound = true;
 
340
   }
 
341
 
 
342
 
 
343
/**
 
344
 * See superclass javadoc.
 
345
 */
 
346
   public void close() throws IOException
 
347
   {
 
348
      if (closed)
 
349
         return;
 
350
 
 
351
      log.debug("closing: " + localSocketId);
 
352
      closed = true;
 
353
 
 
354
      if (connected && !receivedDisconnectMessage)
 
355
         protocol.disconnect(remoteSocketId);
 
356
 
 
357
      if (inputStream != null)
 
358
         inputStream.close();
 
359
 
 
360
      if (outputStream != null)
 
361
      {
 
362
         outputStream.flush();
 
363
         outputStream.close();
 
364
      }
 
365
 
 
366
      if (localSocketId != null)
 
367
         localSocketId.releasePort();
 
368
 
 
369
      // This VirtualSocket might have been unregistered when connect() failed.
 
370
      if (manager.isSocketRegistered(this.localSocketId))
 
371
      {
 
372
         MultiplexingManager.addToPendingActions(new PendingClose(this));
 
373
      }
 
374
 
 
375
      if (debug) log.debug("virtual socket closed on port: " + localSocketId.getPort());
 
376
   }
 
377
 
 
378
 
 
379
   /**
 
380
    * See superclass javadoc.
 
381
    */
 
382
   public void connect(SocketAddress socketAddress) throws IOException
 
383
   {
 
384
      connect(socketAddress, null, timeout);
 
385
   }
 
386
 
 
387
 
 
388
/**
 
389
 * See superclass javadoc.
 
390
 */
 
391
   public void connect(SocketAddress socketAddress, int timeout) throws IOException
 
392
   {
 
393
      connect(socketAddress, null, timeout);
 
394
   }
 
395
 
 
396
 
 
397
/**
 
398
 * See superclass javadoc.
 
399
 */
 
400
   public SocketChannel getChannel()
 
401
   {
 
402
      return null;
 
403
   }
 
404
 
 
405
 
 
406
/**
 
407
 * See superclass javadoc.
 
408
 */
 
409
   public InetAddress getInetAddress()
 
410
   {
 
411
      if (actualSocket == null)
 
412
         return null;
 
413
 
 
414
      return actualSocket.getInetAddress();
 
415
   }
 
416
 
 
417
 
 
418
/**
 
419
 * See superclass javadoc.
 
420
 */
 
421
   public InputStream getInputStream() throws IOException
 
422
   {
 
423
      if (isClosed())
 
424
         throw new SocketException("Socket is closed");
 
425
 
 
426
      if (actualSocket == null || !connected)
 
427
         throw new SocketException("Socket is not connected");
 
428
 
 
429
      if (isInputShutdown())
 
430
         throw new SocketException("Socket input is shutdown");
 
431
 
 
432
      return inputStream;
 
433
   }
 
434
 
 
435
 
 
436
/**
 
437
 * See superclass javadoc.
 
438
 */
 
439
   public boolean getKeepAlive() throws SocketException
 
440
   {
 
441
      if (actualSocket == null)
 
442
         return false;
 
443
 
 
444
      return actualSocket.getKeepAlive();
 
445
   }
 
446
 
 
447
 
 
448
/**
 
449
 * See superclass javadoc.
 
450
 * Note. <code>Socket.getLocalAddress()</code> returns "wildcard" address for an unbound socket.
 
451
 */
 
452
   public InetAddress getLocalAddress()
 
453
   {
 
454
      if (actualSocket == null)
 
455
      {
 
456
         if (dummySocket == null)
 
457
            dummySocket = new Socket();
 
458
 
 
459
         return dummySocket.getLocalAddress();
 
460
      }
 
461
 
 
462
      // The following is a workaround for a problem in NIO sockets, which sometimes
 
463
      // return "0.0.0.0" instead of "127.0.0.1".
 
464
      InetAddress address = actualSocket.getLocalAddress();
 
465
      try
 
466
      {
 
467
         if ("0.0.0.0".equals(address.getHostAddress()))
 
468
            return InetAddress.getByName("localhost");
 
469
      }
 
470
      catch (UnknownHostException e)
 
471
      {
 
472
         return address;
 
473
      }
 
474
 
 
475
      return address;
 
476
   }
 
477
 
 
478
 
 
479
/**
 
480
 * See superclass javadoc.
 
481
 */
 
482
   public int getLocalPort()
 
483
   {
 
484
      if (actualSocket == null)
 
485
         return -1;
 
486
 
 
487
      return actualSocket.getLocalPort();
 
488
   }
 
489
 
 
490
 
 
491
/**
 
492
 * See superclass javadoc.
 
493
 */
 
494
   public SocketAddress getLocalSocketAddress()
 
495
   {
 
496
      if (actualSocket == null)
 
497
         return null;
 
498
 
 
499
      SocketAddress address = actualSocket.getLocalSocketAddress();
 
500
      InetSocketAddress socketAddress = null;
 
501
 
 
502
      // The following is a workaround for a problem in NIO sockets, which sometimes
 
503
      // return "0.0.0.0" instead of "127.0.0.1".
 
504
      if (address instanceof InetSocketAddress)
 
505
      {
 
506
         socketAddress = (InetSocketAddress) address;
 
507
         if ("0.0.0.0".equals(socketAddress.getHostName()) ||
 
508
             socketAddress.getAddress() == null)
 
509
            return new InetSocketAddress("localhost", socketAddress.getPort());
 
510
      }
 
511
 
 
512
      return address;
 
513
   }
 
514
 
 
515
 
 
516
/**
 
517
 * See superclass javadoc.
 
518
 */
 
519
   public boolean getOOBInline() throws SocketException
 
520
   {
 
521
      return false;
 
522
   }
 
523
 
 
524
 
 
525
/**
 
526
 * See superclass javadoc.
 
527
 */
 
528
   public OutputStream getOutputStream() throws IOException
 
529
   {
 
530
      if (isClosed())
 
531
         throw new SocketException("Socket is closed");
 
532
 
 
533
      if (actualSocket == null || !connected)
 
534
         throw new SocketException("Socket is not connected");
 
535
 
 
536
      if (isOutputShutdown())
 
537
         throw new SocketException("Socket output is shutdown");
 
538
 
 
539
      // TODO: return distinct output streams? See PlainSocketImpl.
 
540
      //return new SocketOutputStream(this);
 
541
      return outputStream;
 
542
   }
 
543
 
 
544
 
 
545
/**
 
546
 * See superclass javadoc.
 
547
 */
 
548
   public int getPort()
 
549
   {
 
550
      if (actualSocket == null)
 
551
         return 0;
 
552
 
 
553
      return actualSocket.getPort();
 
554
   }
 
555
 
 
556
 
 
557
/**
 
558
 * See superclass javadoc.
 
559
 */
 
560
   public int getReceiveBufferSize() throws SocketException
 
561
   {
 
562
      if (actualSocket == null)
 
563
      {
 
564
         if (dummySocket == null)
 
565
            dummySocket = new Socket();
 
566
 
 
567
         return dummySocket.getReceiveBufferSize();
 
568
      }
 
569
 
 
570
      return actualSocket.getReceiveBufferSize();
 
571
   }
 
572
 
 
573
 
 
574
/**
 
575
 * See superclass javadoc.
 
576
 */
 
577
   public SocketAddress getRemoteSocketAddress()
 
578
   {
 
579
      if (actualSocket == null)
 
580
         return null;
 
581
 
 
582
      return actualSocket.getRemoteSocketAddress();
 
583
   }
 
584
 
 
585
 
 
586
/**
 
587
 * See superclass javadoc.
 
588
 */
 
589
   public boolean getReuseAddress() throws SocketException
 
590
   {
 
591
      if (actualSocket == null)
 
592
         return false;
 
593
 
 
594
      return actualSocket.getReuseAddress();
 
595
   }
 
596
 
 
597
 
 
598
/**
 
599
 * See superclass javadoc.
 
600
 */
 
601
   public int getSendBufferSize() throws SocketException
 
602
   {
 
603
      if (actualSocket == null)
 
604
      {
 
605
         if (dummySocket == null)
 
606
            dummySocket = new Socket();
 
607
 
 
608
         return dummySocket.getSendBufferSize();
 
609
      }
 
610
 
 
611
      return actualSocket.getSendBufferSize();
 
612
   }
 
613
 
 
614
 
 
615
/**
 
616
 * See superclass javadoc.
 
617
 */
 
618
   public int getSoLinger() throws SocketException
 
619
   {
 
620
      if (actualSocket == null)
 
621
         return -1;
 
622
 
 
623
      return actualSocket.getSoLinger();
 
624
   }
 
625
 
 
626
 
 
627
/**
 
628
 * See superclass javadoc.
 
629
 */
 
630
   public int getSoTimeout() throws SocketException
 
631
   {
 
632
      if (isClosed())
 
633
         throw new SocketException("Socket is closed");
 
634
 
 
635
      return timeout;
 
636
   }
 
637
 
 
638
 
 
639
/**
 
640
 * See superclass javadoc.
 
641
 */
 
642
   public boolean getTcpNoDelay() throws SocketException
 
643
   {
 
644
      if (actualSocket == null)
 
645
         return false;
 
646
 
 
647
      return actualSocket.getTcpNoDelay();
 
648
   }
 
649
 
 
650
 
 
651
/**
 
652
 * See superclass javadoc.
 
653
 */
 
654
   public int getTrafficClass() throws SocketException
 
655
   {
 
656
      if (actualSocket == null)
 
657
         return 0;
 
658
 
 
659
      return actualSocket.getTrafficClass();
 
660
   }
 
661
 
 
662
 
 
663
 /**
 
664
 * See superclass javadoc.
 
665
 */
 
666
   public boolean isBound()
 
667
   {
 
668
      return bound;
 
669
   }
 
670
 
 
671
 
 
672
/**
 
673
 * See superclass javadoc.
 
674
 */
 
675
   public boolean isClosed()
 
676
   {
 
677
      return closed;
 
678
   }
 
679
 
 
680
 
 
681
/**
 
682
 * See superclass javadoc.
 
683
 */
 
684
   public boolean isConnected()
 
685
   {
 
686
      return connected;
 
687
   }
 
688
 
 
689
 
 
690
/**
 
691
 * See superclass javadoc.
 
692
 */
 
693
   public boolean isInputShutdown()
 
694
   {
 
695
      return inputShutdown;
 
696
   }
 
697
 
 
698
 
 
699
/**
 
700
 * See superclass javadoc.
 
701
 */
 
702
   public boolean isOutputShutdown()
 
703
   {
 
704
      return outputShutdown;
 
705
   }
 
706
 
 
707
 
 
708
/**
 
709
 * This method is not implemented.
 
710
 * <p>
 
711
 * See superclass javadoc.
 
712
 */
 
713
   public void sendUrgentData(int data) throws IOException
 
714
   {
 
715
      log.warn("sendUrgentData() called: ignored");
 
716
 
 
717
      if (isClosed())
 
718
         throw new IOException("Socket Closed");
 
719
   }
 
720
 
 
721
 
 
722
/**
 
723
 * See superclass javadoc.
 
724
 */
 
725
   public void setKeepAlive(boolean on) throws SocketException
 
726
   {
 
727
      if (actualSocket != null)
 
728
         actualSocket.setKeepAlive(on);
 
729
   }
 
730
 
 
731
 
 
732
/**
 
733
 *
 
734
 */
 
735
   public void setOOBInline(boolean on) throws SocketException
 
736
   {
 
737
      log.warn("setOOBInLine() called: ignored");
 
738
 
 
739
      if (isClosed())
 
740
         throw new SocketException("Socket is closed");
 
741
   }
 
742
 
 
743
 
 
744
/**
 
745
 * See superclass javadoc.
 
746
 */
 
747
   public void setReceiveBufferSize(int size) throws SocketException
 
748
   {
 
749
      if (actualSocket != null)
 
750
         actualSocket.setReceiveBufferSize(size);
 
751
   }
 
752
 
 
753
 
 
754
/**
 
755
 * See superclass javadoc.
 
756
 */
 
757
   public void setReuseAddress(boolean on) throws SocketException
 
758
   {
 
759
      if (actualSocket != null)
 
760
         actualSocket.setReuseAddress(on);
 
761
   }
 
762
 
 
763
 
 
764
/**
 
765
 * See superclass javadoc.
 
766
 */
 
767
   public void setSendBufferSize(int size) throws SocketException
 
768
   {
 
769
      if (actualSocket != null)
 
770
         actualSocket.setSendBufferSize(size);
 
771
   }
 
772
 
 
773
 
 
774
/**
 
775
 * See superclass javadoc.
 
776
 */
 
777
   public void setSoLinger(boolean on, int linger) throws SocketException
 
778
   {
 
779
      if (actualSocket != null)
 
780
         actualSocket.setSoLinger(on, linger);
 
781
   }
 
782
 
 
783
 
 
784
/**
 
785
 * See superclass javadoc.
 
786
 */
 
787
   public void setSoTimeout(int timeout) throws SocketException
 
788
   {
 
789
      if (isClosed())
 
790
         throw new SocketException("Socket is closed");
 
791
 
 
792
      if (timeout < 0)
 
793
         throw new IllegalArgumentException("timeout can't be negative");
 
794
 
 
795
      this.timeout = timeout;
 
796
 
 
797
      if (inputStream != null)
 
798
         inputStream.setTimeout(timeout);
 
799
   }
 
800
 
 
801
 
 
802
/**
 
803
 * See superclass javadoc.
 
804
 */
 
805
   public void setTcpNoDelay(boolean on) throws SocketException
 
806
   {
 
807
      if (actualSocket != null)
 
808
         actualSocket.setTcpNoDelay(on);
 
809
   }
 
810
 
 
811
 
 
812
/**
 
813
 * See superclass javadoc.
 
814
 */
 
815
   public void setTrafficClass(int tc) throws SocketException
 
816
   {
 
817
      if (actualSocket != null)
 
818
         actualSocket.setTrafficClass(tc);
 
819
   }
 
820
 
 
821
 
 
822
/**
 
823
 * See superclass javadoc.
 
824
 */
 
825
   public void shutdownInput() throws IOException
 
826
   {
 
827
      if (isClosed())
 
828
         throw new SocketException("Socket is closed");
 
829
 
 
830
      if (!isConnected())
 
831
         throw new SocketException("Socket is not connected");
 
832
 
 
833
      if (isInputShutdown())
 
834
         throw new SocketException("Socket input is already shutdown");
 
835
 
 
836
      inputStream.setEOF();
 
837
      inputShutdown = true;
 
838
      //         protocol.notifyInputShutdown(localSocketId);
 
839
   }
 
840
 
 
841
 
 
842
/**
 
843
* See superclass javadoc.
 
844
*/
 
845
   public void shutdownOutput() throws IOException
 
846
   {
 
847
      if (isClosed())
 
848
         throw new SocketException("Socket is closed");
 
849
 
 
850
      if (!isConnected())
 
851
         throw new SocketException("Socket is not connected");
 
852
 
 
853
      if (isOutputShutdown())
 
854
         throw new SocketException("Socket output is already shutdown");
 
855
 
 
856
      outputStream.shutdown();
 
857
      outputShutdown = true;
 
858
      protocol.notifyOutputShutdown(remoteSocketId);
 
859
   }
 
860
 
 
861
 
 
862
/**
 
863
 * See superclass javadoc.
 
864
 */
 
865
   public String toString()
 
866
   {
 
867
      StringBuffer answer = new StringBuffer().append("VirtualSocket[");
 
868
 
 
869
      if (actualSocket == null)
 
870
         answer.append("unbound");
 
871
      else
 
872
         answer.append(actualSocket.toString());
 
873
 
 
874
      return answer.append("]").toString();
 
875
   }
 
876
 
 
877
//////////////////////////////////////////////////////////////////////////////////////////////////
 
878
///                     The following methods are specific to VirtualSockets                   ///
 
879
//////////////////////////////////////////////////////////////////////////////////////////////////
 
880
 
 
881
/**
 
882
 *
 
883
 */
 
884
   public void addDisconnectListener(DisconnectListener listener)
 
885
   {
 
886
      disconnectListeners.add(listener);
 
887
   }
 
888
 
 
889
 
 
890
/**
 
891
 *
 
892
 */
 
893
   public void connect(SocketAddress remoteAddress, SocketAddress localAddress, int timeout) throws IOException
 
894
   {
 
895
      log.debug("entering connect()");
 
896
      long start = System.currentTimeMillis();
 
897
      int timeLeft = 0;
 
898
 
 
899
      if (remoteAddress == null)
 
900
         throw new IllegalArgumentException("connect: The address can't be null");
 
901
 
 
902
      if (timeout < 0)
 
903
         throw new IllegalArgumentException("connect: timeout can't be negative");
 
904
 
 
905
      if (isClosed())
 
906
         throw new SocketException("Socket is closed");
 
907
 
 
908
      if (isConnected())
 
909
         throw new SocketException("already connected");
 
910
 
 
911
      if (!(remoteAddress instanceof InetSocketAddress))
 
912
         throw new IllegalArgumentException("Unsupported address type");
 
913
 
 
914
      InetSocketAddress remoteInetSocketAddress = (InetSocketAddress) remoteAddress;
 
915
      SecurityManager security = System.getSecurityManager();
 
916
 
 
917
      if (security != null)
 
918
      {
 
919
         if (remoteInetSocketAddress.isUnresolved())
 
920
            security.checkConnect(remoteInetSocketAddress.getHostName(), remoteInetSocketAddress.getPort());
 
921
         else
 
922
            security.checkConnect(remoteInetSocketAddress.getAddress().getHostAddress(), remoteInetSocketAddress.getPort());
 
923
      }
 
924
 
 
925
      if (timeout > 0)
 
926
         if ((timeLeft = timeout - (int) (System.currentTimeMillis() - start)) <= 0)
 
927
            throw new SocketTimeoutException("connect timed out");
 
928
 
 
929
      if (manager == null)
 
930
      {
 
931
         if (localAddress == null)
 
932
            manager = MultiplexingManager.getaShareableManager(remoteInetSocketAddress, timeLeft, configuration);
 
933
         else
 
934
         {
 
935
            InetSocketAddress localInetSocketAddress = (InetSocketAddress) localAddress;
 
936
            manager = MultiplexingManager.getaShareableManagerByAddressPair(remoteInetSocketAddress,
 
937
                                                                            localInetSocketAddress,
 
938
                                                                            timeLeft,
 
939
                                                                            configuration);
 
940
         }
 
941
      }
 
942
 
 
943
      try
 
944
      {
 
945
         if (timeout > 0)
 
946
            if ((timeLeft = timeout - (int) (System.currentTimeMillis() - start)) <= 0)
 
947
               throw new SocketTimeoutException("connect timed out");
 
948
 
 
949
         manager.connect(remoteInetSocketAddress, timeLeft);
 
950
         actualSocket = manager.getSocket();
 
951
         protocol = manager.getProtocol();
 
952
 
 
953
         if (!bound)
 
954
         {
 
955
            localSocketId = new SocketId();
 
956
            bound = true;
 
957
         }
 
958
 
 
959
         inputStream = manager.registerSocket(this);
 
960
         inputStream.setTimeout(timeout);
 
961
 
 
962
         if (timeout > 0)
 
963
            if ((timeLeft = timeout - (int) (System.currentTimeMillis() - start)) <= 0)
 
964
               throw new SocketTimeoutException("connect timed out");
 
965
 
 
966
         remoteSocketId = protocol.connect(inputStream, localSocketId, timeLeft);
 
967
         outputStream = new MultiplexingOutputStream(manager, this, remoteSocketId);
 
968
      }
 
969
      catch (IOException e)
 
970
      {
 
971
         // Calling unRegisterSocket() will lead to this VirtualSocket being closed.
 
972
         try
 
973
         {
 
974
            manager.unRegisterSocket(this);
 
975
         }
 
976
         catch (IOException ignored)
 
977
         {
 
978
            // May not be registered yet.
 
979
         }
 
980
 
 
981
         if (e instanceof SocketTimeoutException)
 
982
            throw new SocketTimeoutException("connect timed out");
 
983
 
 
984
         throw e;
 
985
      }
 
986
      finally
 
987
      {
 
988
         if (inputStream != null)
 
989
            inputStream.setTimeout(this.timeout);
 
990
      }
 
991
 
 
992
      connected = true;
 
993
   }
 
994
 
 
995
 
 
996
   public MultiplexingManager getMultiplexingManager()
 
997
   {
 
998
      return manager;
 
999
   }
 
1000
 
 
1001
 
 
1002
   public int getVirtualPort()
 
1003
   {
 
1004
      return remoteSocketId.getPort();
 
1005
   }
 
1006
 
 
1007
 
 
1008
   public int getLocalVirtualPort()
 
1009
   {
 
1010
      return localSocketId.getPort();
 
1011
   }
 
1012
 
 
1013
 
 
1014
/**
 
1015
 *
 
1016
 * @return
 
1017
 */
 
1018
   public SocketId getLocalSocketId()
 
1019
   {
 
1020
      return localSocketId;
 
1021
   }
 
1022
 
 
1023
 
 
1024
/**
 
1025
 * @return
 
1026
 */
 
1027
   public Socket getRealSocket()
 
1028
   {
 
1029
      return actualSocket;
 
1030
   }
 
1031
 
 
1032
 
 
1033
/**
 
1034
 *
 
1035
 * @return
 
1036
 */
 
1037
   public SocketId getRemoteSocketId()
 
1038
   {
 
1039
      return localSocketId;
 
1040
   }
 
1041
 
 
1042
 
 
1043
   /**
 
1044
    * Returns true if and only if has not received notification of error state
 
1045
    * on actual connection.
 
1046
    *
 
1047
    * @return true if and only if has not received notification of error state
 
1048
    *         on actual connection
 
1049
    */
 
1050
   public boolean isFunctional()
 
1051
   {
 
1052
      return functional;
 
1053
   }
 
1054
 
 
1055
/**
 
1056
 *
 
1057
 * @param listener
 
1058
 */
 
1059
   public void removeDisconnectListener(DisconnectListener listener)
 
1060
   {
 
1061
      if (!disconnectListeners.remove(listener))
 
1062
         log.error("attempt to remove unregistered DisconnectListener: " + listener);
 
1063
   }
 
1064
 
 
1065
 
 
1066
/**
 
1067
 * @param configuration
 
1068
 */
 
1069
   public void setConfiguration(Map configuration)
 
1070
   {
 
1071
      this.configuration.putAll(configuration);
 
1072
   }
 
1073
//////////////////////////////////////////////////////////////////////////////////////////////////
 
1074
///                              Protected getters and setters                                '///
 
1075
//////////////////////////////////////////////////////////////////////////////////////////////////
 
1076
 
 
1077
/**
 
1078
 * @return Returns the actualSocket.
 
1079
 */
 
1080
   protected Socket getActualSocket()
 
1081
   {
 
1082
      return actualSocket;
 
1083
   }
 
1084
 
 
1085
/**
 
1086
 * @param actualSocket The actualSocket to set.
 
1087
 */
 
1088
   protected void setActualSocket(Socket actualSocket)
 
1089
   {
 
1090
      this.actualSocket = actualSocket;
 
1091
   }
 
1092
 
 
1093
// in socket API section
 
1094
///**
 
1095
// * @return Returns the bound.
 
1096
// */
 
1097
//   public boolean isBound()
 
1098
//   {
 
1099
//      return bound;
 
1100
//   }
 
1101
 
 
1102
/**
 
1103
 * @param bound The bound to set.
 
1104
 */
 
1105
   protected void setBound(boolean bound)
 
1106
   {
 
1107
      this.bound = bound;
 
1108
   }
 
1109
 
 
1110
/**
 
1111
 * @param closed The closed to set.
 
1112
 */
 
1113
   protected void setClosed(boolean closed)
 
1114
   {
 
1115
      this.closed = closed;
 
1116
   }
 
1117
 
 
1118
/**
 
1119
 * @param connected The connected to set.
 
1120
 */
 
1121
   protected void setConnected(boolean connected)
 
1122
   {
 
1123
      this.connected = connected;
 
1124
   }
 
1125
 
 
1126
/**
 
1127
 * @param inputShutdown The inputShutdown to set.
 
1128
 */
 
1129
   protected void setInputShutdown(boolean inputShutdown)
 
1130
   {
 
1131
      this.inputShutdown = inputShutdown;
 
1132
   }
 
1133
 
 
1134
/**
 
1135
 * @param inputStream The inputStream to set.
 
1136
 */
 
1137
   protected void setInputStream(MultiplexingInputStream inputStream)
 
1138
   {
 
1139
      this.inputStream = inputStream;
 
1140
   }
 
1141
 
 
1142
/**
 
1143
 * @param localSocketId The localSocketId to set.
 
1144
 */
 
1145
   protected void setLocalSocketId(SocketId localSocketId)
 
1146
   {
 
1147
      this.localSocketId = localSocketId;
 
1148
   }
 
1149
 
 
1150
/**
 
1151
 *
 
1152
 * @return
 
1153
 */
 
1154
   protected MultiplexingManager getManager()
 
1155
   {
 
1156
      return manager;
 
1157
   }
 
1158
 
 
1159
/**
 
1160
 * @param manager The manager to set.
 
1161
 */
 
1162
   protected void setManager(MultiplexingManager manager)
 
1163
   {
 
1164
      this.manager = manager;
 
1165
   }
 
1166
 
 
1167
/**
 
1168
 * @param outputShutdown The outputShutdown to set.
 
1169
 */
 
1170
   protected void setOutputShutdown(boolean outputShutdown)
 
1171
   {
 
1172
      this.outputShutdown = outputShutdown;
 
1173
   }
 
1174
 
 
1175
/**
 
1176
 * @param outputStream The outputStream to set.
 
1177
 */
 
1178
   protected void setOutputStream(MultiplexingOutputStream outputStream)
 
1179
   {
 
1180
      this.outputStream = outputStream;
 
1181
   }
 
1182
 
 
1183
/**
 
1184
 * @return Returns the protocol.
 
1185
 */
 
1186
   protected Protocol getProtocol()
 
1187
   {
 
1188
      return protocol;
 
1189
   }
 
1190
 
 
1191
/**
 
1192
 * @param protocol The protocol to set.
 
1193
 */
 
1194
   protected void setProtocol(Protocol protocol)
 
1195
   {
 
1196
      this.protocol = protocol;
 
1197
   }
 
1198
 
 
1199
/**
 
1200
 *
 
1201
 * @return
 
1202
 */
 
1203
   protected boolean hasReceivedDisconnectMessage()
 
1204
   {
 
1205
      return receivedDisconnectMessage;
 
1206
   }
 
1207
 
 
1208
/**
 
1209
 *
 
1210
 * @param receivedDisconnectMessage
 
1211
 */
 
1212
   protected void setReceivedDisconnectMessage(boolean receivedDisconnectMessage)
 
1213
   {
 
1214
      this.receivedDisconnectMessage = receivedDisconnectMessage;
 
1215
   }
 
1216
 
 
1217
/**
 
1218
 * @param remoteSocketId The remoteSocketId to set.
 
1219
 */
 
1220
   protected void setRemoteSocketId(SocketId remoteSocketId)
 
1221
   {
 
1222
      this.remoteSocketId = remoteSocketId;
 
1223
   }
 
1224
 
 
1225
 
 
1226
 
 
1227
//////////////////////////////////////////////////////////////////////////////////////////////////
 
1228
///                                  Other protected methods                                  '///
 
1229
//////////////////////////////////////////////////////////////////////////////////////////////////
 
1230
 
 
1231
 
 
1232
/**
 
1233
 *
 
1234
 */
 
1235
   protected void doClose()
 
1236
   {
 
1237
      if (debug) log.debug("doClose()" + this.localSocketId.getPort());
 
1238
      try
 
1239
      {
 
1240
//         if (connected && !receivedDisconnectMessage)
 
1241
//            protocol.disconnect(remoteSocketId);
 
1242
 
 
1243
         // This VirtualSocket might have been unregistered when connect() failed.
 
1244
         if (manager.isSocketRegistered(getLocalSocketId()))
 
1245
            manager.unRegisterSocket(this);
 
1246
 
 
1247
         if (debug) log.debug("virtual socket closed on port: " + remoteSocketId.getPort());
 
1248
      }
 
1249
      catch (Exception e)
 
1250
      {
 
1251
         log.error("error closing socket: " + this);
 
1252
         log.error(e);
 
1253
      }
 
1254
   }
 
1255
 
 
1256
 
 
1257
 
 
1258
/**
 
1259
 *
 
1260
 * @throws IOException
 
1261
 */
 
1262
   protected void handleRemoteOutputShutDown() throws IOException
 
1263
   {
 
1264
      // already closed ?
 
1265
      try
 
1266
      {
 
1267
         inputStream.handleRemoteShutdown();
 
1268
      }
 
1269
      catch (NullPointerException ignored)
 
1270
      {
 
1271
      }
 
1272
   }
 
1273
 
 
1274
 
 
1275
   /**
 
1276
    *
 
1277
    * @throws IOException
 
1278
    */
 
1279
   protected void handleRemoteDisconnect() throws IOException
 
1280
   {
 
1281
      if (isClosed())
 
1282
         return;
 
1283
 
 
1284
      if (debug) log.debug("remote virtual socket disconnecting: local port: " + getLocalVirtualPort());
 
1285
      receivedDisconnectMessage = true;
 
1286
 
 
1287
      // already closed ?
 
1288
      if (inputStream != null)
 
1289
         inputStream.handleRemoteShutdown();
 
1290
 
 
1291
      // already closed ?
 
1292
      if (outputStream != null)
 
1293
      {
 
1294
         outputStream.flush();
 
1295
         outputStream.handleRemoteDisconnect();
 
1296
      }
 
1297
 
 
1298
      MultiplexingManager.addToPendingActions(new PendingRemoteDisconnect(this));
 
1299
 
 
1300
      log.debug("handleRemoteDisconnect(): done.");
 
1301
      // TODO
 
1302
      //     connected = false;
 
1303
      //     inputShutdown = true;
 
1304
      //     outputShutdown = true;
 
1305
   }
 
1306
 
 
1307
 
 
1308
   /**
 
1309
    * Indicate error condition on actual connection.
 
1310
    */
 
1311
   protected void notifyOfException()
 
1312
   {
 
1313
      functional = false;
 
1314
   }
 
1315
 
 
1316
   protected class PendingRemoteDisconnect extends PendingAction
 
1317
   {
 
1318
      public PendingRemoteDisconnect(Object o)
 
1319
      {
 
1320
         super(o);
 
1321
      }
 
1322
 
 
1323
      void doAction()
 
1324
      {
 
1325
         VirtualSocket vs = (VirtualSocket) o;
 
1326
         Set disconnectListeners = vs.disconnectListeners;
 
1327
 
 
1328
         Iterator it = disconnectListeners.iterator();
 
1329
         while (it.hasNext())
 
1330
            ((DisconnectListener) it.next()).notifyDisconnected(vs);
 
1331
      }
 
1332
   }
 
1333
 
 
1334
 
 
1335
   protected class PendingClose extends PendingAction
 
1336
   {
 
1337
      public PendingClose(Object o)
 
1338
      {
 
1339
         super(o);
 
1340
      }
 
1341
 
 
1342
      public void doAction()
 
1343
      {
 
1344
         ((VirtualSocket)o).doClose();
 
1345
      }
 
1346
   }
 
1347
}
 
 
b'\\ No newline at end of file'