source: trunk/src/org/expeditee/network/FrameShare.java@ 648

Last change on this file since 648 was 648, checked in by davidb, 11 years ago

Refactored so server can be started from the command line, in addition to part of a graphical Expeditee run

File size: 9.4 KB
Line 
1package org.expeditee.network;
2
3import java.io.BufferedReader;
4import java.io.IOException;
5import java.io.StringReader;
6import java.io.StringWriter;
7import java.net.DatagramPacket;
8import java.net.DatagramSocket;
9import java.net.InetAddress;
10import java.net.SocketException;
11import java.net.UnknownHostException;
12import java.util.Collection;
13import java.util.HashMap;
14import java.util.LinkedList;
15import java.util.Map;
16
17import org.expeditee.gui.AttributeValuePair;
18import org.expeditee.gui.Frame;
19import org.expeditee.gui.FrameIO;
20import org.expeditee.gui.MessageBay;
21import org.expeditee.io.ExpReader;
22import org.expeditee.io.ExpWriter;
23import org.expeditee.io.FrameReader;
24import org.expeditee.io.FrameWriter;
25import org.expeditee.items.Text;
26
27public class FrameShare {
28
29 public static boolean disableNetworking = false;
30
31 private static final int SOCKET_TIMEOUT = 1000;
32
33 private static Collection<DefaultServer> _servers = new LinkedList<DefaultServer>();
34
35 private static FrameShare _theSession;
36
37 private Map<String, Peer> _peers;
38
39 private int _port = Peer.DEFAULT_PORT;
40
41
42 private void startServers() throws IOException
43 {
44 _servers.add(new FrameServer(_port));
45 _servers.add(new FrameSaver(_port));
46 _servers.add(new MessageReciever(_port));
47 _servers.add(new InfServer(_port));
48 _servers.add(new InfUpdate(_port));
49
50 }
51
52 private FrameShare() {
53 _peers = new HashMap<String, Peer>();
54 }
55
56 private FrameShare(int port) {
57 this();
58 _port = port;
59
60 try {
61 startServers();
62
63 } catch (Exception e) {
64 e.printStackTrace();
65 System.err.println("Could not start servers [port: "
66 + port + "]");
67 }
68
69 }
70
71
72 private FrameShare(Frame settingsFrame)
73 {
74 this();
75
76 // Set the settings
77 for (Text item : settingsFrame.getBodyTextItems(false)) {
78
79 AttributeValuePair avp = new AttributeValuePair(item.getText());
80 if (avp.isAnnotation())
81 continue;
82
83 String attribute = avp.getAttributeOrValue().toLowerCase();
84
85 if (attribute.equals("server")) {
86 try {
87 if (avp.hasPair()) {
88 _port = avp.getIntegerValue();
89 }
90 MessageBay.displayMessage("Starting Expeditee Server on port: " + _port);
91
92 startServers();
93 } catch (Exception e) {
94 e.printStackTrace();
95 MessageBay.errorMessage("Could not start servers ["
96 + avp.toString() + "]");
97 }
98 continue;
99 }
100
101 if (!avp.hasPair())
102 continue;
103
104 try {
105 Peer peer = new Peer(avp);
106 _peers.put(attribute, peer);
107 } catch (UnknownHostException e) {
108 MessageBay.errorMessage("Could not locate peer ["
109 + avp.toString() + "]");
110 }
111 }
112
113 try {
114 for (DefaultServer server : _servers)
115 server.start();
116 } catch (Exception e) {
117 MessageBay.errorMessage("Error in PeerToPeer setup");
118 }
119 }
120
121 public void finalise() {
122 for (DefaultServer server : _servers)
123 server.close();
124 }
125
126 public static FrameShare getInstance() {
127 return _theSession;
128 }
129
130 /**
131 * TODO check each peer on a different thread.
132 *
133 * @param frameName
134 * @return
135 */
136 public Frame loadFrame(String frameName, String peerName) {
137 String result = null;
138
139 try {
140 // get a datagram socket
141 DatagramSocket socket = new DatagramSocket();
142 socket.setSoTimeout(SOCKET_TIMEOUT * 2);
143 if (peerName == null) {
144 for (Peer peer : _peers.values()) {
145 try {
146 result = getFrameContents(frameName, socket, peer);
147 if(result == null || result.length() == 0) {
148 continue;
149 }
150 peerName = peer.getName();
151 break;
152 } catch (Exception e) {
153 e.printStackTrace();
154 }
155 }
156 } else {
157 try {
158 Peer peer = _peers.get(peerName.toLowerCase());
159 if (peer != null) {
160 result = getFrameContents(frameName, socket, peer);
161 }
162 } catch (Exception e) {
163 e.printStackTrace();
164 }
165 }
166 socket.close();
167 } catch (Exception e) {
168 e.printStackTrace();
169 }
170
171 if (result == null || result.length() == 0)
172 return null;
173
174 // Now read the frame from the file contents
175 FrameReader reader = new ExpReader(frameName);
176 Frame frame = null;
177 try {
178 frame = reader.readFrame(new BufferedReader(
179 new StringReader(result)));
180 // Set the path for the frame to indicate it is NOT a local frame
181 // This allows the frame to be saved in the correct location
182 frame.setLocal(false);
183 frame.setPath(peerName);
184 } catch (IOException e) {
185 e.printStackTrace();
186 }
187
188 if (frame == null) {
189 MessageBay.errorMessage("Error: " + frameName
190 + " could not be successfully loaded.");
191 return null;
192 }
193
194 return frame;
195 }
196
197 /**
198 * @param frameName
199 * @param socket
200 * @param peer
201 * @return
202 * @throws IOException
203 */
204 private String getFrameContents(String frameName, DatagramSocket socket, Peer peer) throws IOException {
205 byte[] nameBuf = frameName.getBytes();
206 byte[] buf = new byte[FrameServer.MAX_PACKET_LENGTH];
207 // send request for a frame
208 DatagramPacket packet = new DatagramPacket(nameBuf,
209 nameBuf.length, peer.getAddress(), peer
210 .getPort());
211 socket.send(packet);
212
213 // get response
214 packet = new DatagramPacket(buf, buf.length);
215 socket.receive(packet);
216
217 // store frame contents
218 return new String(packet.getData(), 0, packet
219 .getLength());
220 }
221
222 public boolean sendMessage(String message, String peerName) {
223 Peer peer = _peers.get(peerName.toLowerCase());
224
225 if (peer == null) {
226 return false;
227 }
228
229 try {
230 // get a datagram socket
231 DatagramSocket socket = new DatagramSocket(_port - 1);
232 socket.setSoTimeout(SOCKET_TIMEOUT);
233
234 // message = peerName + " says " + message;
235 byte[] contentsBuf = message.getBytes();
236
237 try {
238 // send save request
239 DatagramPacket packet = new DatagramPacket(contentsBuf,
240 contentsBuf.length, peer.getAddress(), peer.getPort()
241 + MessageReciever.OFFSET);
242 socket.send(packet);
243 } catch (Exception e) {
244 e.printStackTrace();
245 }
246 socket.close();
247
248 } catch (IOException e) {
249 e.printStackTrace();
250 }
251 return true;
252 }
253
254 public String saveFrame(Frame toSave) {
255
256 FrameIO.setSavedProperties(toSave);
257
258 Peer peer = _peers.get(toSave.getPath().toLowerCase());
259 String fileContents = "";
260 // Now read the frame from the file contents
261 FrameWriter writer = new ExpWriter();
262 try {
263 // String tempName = new Date().toString() + ".exp";
264 // writer.setOutputLocation(tempName);
265 // Write out the file to a StringBuffer
266 StringWriter sw = new StringWriter();
267 // First write out the name of the frame
268 sw.write(toSave.getName() + "\n");
269 // Then the version
270 sw.write(toSave.getVersion() + "\n");
271 // Write out the rest of the frame
272 writer.writeFrame(toSave, sw);
273 // Now send the packet
274 fileContents = sw.getBuffer().toString();
275 byte[] contentsBuf = fileContents.getBytes();
276
277 // get a datagram socket
278 DatagramSocket socket = new DatagramSocket(_port - 2);
279 socket.setSoTimeout(SOCKET_TIMEOUT);
280
281 try {
282 // send save request
283 DatagramPacket packet = new DatagramPacket(contentsBuf,
284 contentsBuf.length, peer.getAddress(), peer.getPort()
285 + FrameSaver.OFFSET);
286 socket.send(packet);
287 } catch (Exception e) {
288 e.printStackTrace();
289 }
290 socket.close();
291
292 } catch (IOException e) {
293 e.printStackTrace();
294 }
295 toSave.setSaved();
296 return fileContents;
297 }
298
299 public String getPeerName(int port, InetAddress address) {
300 for (Peer p : _peers.values()) {
301 if (p.getPort() == port && p.getAddress().equals(address))
302 return p.getName();
303 }
304 return null;
305 }
306
307 public int getInfNumber(String peerName, String frameset, boolean update)
308 throws IOException {
309 int result = -1;
310 // get a datagram socket
311 DatagramSocket socket = null;
312 try {
313 socket = new DatagramSocket(_port - 3);
314 socket.setSoTimeout(SOCKET_TIMEOUT);
315
316 byte[] contentsBuf = frameset.getBytes();
317 Peer peer = _peers.get(peerName.toLowerCase());
318 try {
319 // send inf request
320 DatagramPacket packet = new DatagramPacket(
321 contentsBuf,
322 contentsBuf.length,
323 peer.getAddress(),
324 peer.getPort()
325 + (update ? InfUpdate.OFFSET : InfServer.OFFSET));
326 socket.send(packet);
327
328 byte[] buf = new byte[100];
329 // get response
330 packet = new DatagramPacket(buf, buf.length);
331 socket.receive(packet);
332
333 // store frame contents
334 result = Integer.parseInt(new String(packet.getData(), 0,
335 packet.getLength()));
336 peerName = peer.getName();
337
338 } catch (Exception e) {
339 e.printStackTrace();
340 }
341 socket.close();
342 } catch (SocketException e1) {
343 e1.printStackTrace();
344 }
345
346 return result;
347 }
348
349 public static void init(Frame settingsFrame) {
350 if (disableNetworking || settingsFrame == null)
351 return;
352
353 if (_theSession == null)
354 _theSession = new FrameShare(settingsFrame);
355 }
356
357 public static void init(int port) {
358
359 if (_theSession == null) {
360 _theSession = new FrameShare(port);
361 }
362 }
363
364
365 /**
366 * Start a server running on the port number supplied on the command line
367 *
368 * @param args
369 */
370 public static void main(String[] args) {
371
372 if (args.length != 1) {
373
374 // Work out the 'program name' (i.e. this class), but done in a general
375 // way in case class name is changed at a later date
376 StackTraceElement[] stack = Thread.currentThread ().getStackTrace ();
377 StackTraceElement main = stack[stack.length - 1];
378 String mainClass = main.getClassName ();
379
380 System.err.println("Usage: java " + mainClass + " port-number");
381 System.exit(1);
382 }
383
384 String port_str = args[0];
385
386 try {
387 int port = Integer.parseInt(port_str);
388
389 init(port);
390 }
391 catch (Exception e) {
392 e.printStackTrace();
393 System.exit(2);
394 }
395
396 }
397
398}
Note: See TracBrowser for help on using the repository browser.