View Javadoc

1   package au.com.loftinspace.tcpreflector;
2   
3   import au.com.loftinspace.tcpreflector.packet.PacketListener;
4   
5   import java.net.InetSocketAddress;
6   import java.io.IOException;
7   import java.util.List;
8   import java.util.Iterator;
9   import java.util.ArrayList;
10  
11  /***
12   * The TcpReflectorExecutor is a convenience class for the starting and stopping
13   * of TcpReflector instances. If you do not require thread level control of the TcpReflector
14   * then this is the object for you.
15   *
16   * <br>Typical unit test usage would be:</br>
17   * <font face="courier new" size="2" color="darkgreen">
18   * TcpReflectorExecutor executor = new TcpReflectorExecutor(tcpReflector);<br>
19   * executor.start(); // blocks until tcpReflector has initialised.<br>
20   * // perform socket communications<br>
21   * executor.stop(); // block until tcpReflector has terminated.<br>
22   * try {<br>
23   *     // perform socket communciations<br>
24   *     fail("Expected SomeExpectedIOBasedException);<br>
25   * } catch(SomeExpectedIOBasedException e) {<br>
26   * }<br>
27   * executor.start(); // blocks until tcpReflector has initialised again.<br>
28   * // perform socket communications and ensure reconnection is OK.<br>
29   * </font>
30   *
31   * Author: Jem Mawson
32   * Date: 22/07/2004
33   * Time: 22:10:35
34   */
35  public class TcpReflectorExecutor {
36  
37      private TcpReflector reflector;
38      private Thread reflectorThread;
39      private int port;
40      private InetSocketAddress destination;
41      private List listeners;
42  
43      /***
44       * Constructs a new instance of an executor.
45       * @param listeningPort
46       *      The local port number to connect to the TcpReflector.
47       * @param destination
48       *      The destination internet address for connections.
49       * @param packetListeners
50       *      A list of PacketListeners to be added to the TcpReflector.
51       */
52      public TcpReflectorExecutor(int listeningPort, InetSocketAddress destination,
53                                  List packetListeners) {
54  
55          this(listeningPort, destination);
56          validateListenerInstances(packetListeners);
57          this.listeners = packetListeners;
58      }
59  
60      public TcpReflectorExecutor(int listeningPort, InetSocketAddress destination) {
61          if (destination == null) {
62              throw new IllegalArgumentException("Destination address cannot be null");
63          }
64          this.port = listeningPort;
65          this.destination = destination;
66      }
67  
68      public synchronized void allowConnections(boolean allow) throws IOException {
69          if (allow) {
70              allowConnections();
71          } else {
72              disallowConnections();
73          }
74      }
75  
76      /***
77       * Whether the reflector should allow
78       * @param comms
79       */
80      public synchronized void allowResponsePassage(boolean comms) {
81          if (reflector != null) {
82              reflector.setResponseReflective(comms);
83          }
84      }
85  
86      private void allowConnections() throws IOException {
87          if (reflector == null) {
88              reflector = new TcpReflector(port, destination);
89              addListeners();
90              reflectorThread = new Thread(reflector, constructName());
91              reflectorThread.setDaemon(true);
92              reflectorThread.start();
93          }
94  
95          while (!reflectorThread.isAlive()) {
96              try {
97                  Thread.sleep(100L);
98              } catch (InterruptedException e) {
99              }
100         }
101     }
102 
103     private void disallowConnections() {
104         if (reflector != null) {
105             reflector.shutdown();
106             try {
107                 reflectorThread.join();
108             } catch (InterruptedException e) {
109             } finally {
110                 reflector = null;
111             }
112         }
113     }
114 
115 
116     private String constructName() {
117         StringBuffer name = new StringBuffer(64);
118         name.append("TcpReflector_");
119         name.append(System.currentTimeMillis());
120         name.append(" {");
121         name.append(reflector.getDestination().getHostName());
122         name.append(":");
123         name.append(reflector.getDestination().getPort());
124         name.append("}");
125         return name.toString();
126     }
127 
128     private void validateListenerInstances(List packetListeners) {
129         for (Iterator iterator = packetListeners.iterator(); iterator.hasNext();) {
130             if (!(iterator.next() instanceof PacketListener)) {
131                 throw new IllegalArgumentException("PacketListeners list must contain only " +
132                         "instances of PacketListener. " + packetListeners);
133             }
134         }
135     }
136 
137     private void addListeners() {
138         if (listeners != null) {
139             for (Iterator iterator = listeners.iterator(); iterator.hasNext();) {
140                 reflector.addListener((PacketListener) iterator.next());
141             }
142         }
143     }
144 }