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 }