Author: bdonlan
Date: 2005-05-22 01:36:50 -0400 (Sun, 22 May 2005)
New Revision: 706
Modified:
trunk/clients/Javer2/src/haver/Client.java
Log:
src/haver/Client.java:
* lots of docs
* SyncMonitor.block():
- detect ioLoop() termination from non-excepted disconnect
* handle_FOO(): Obsolete, removed
* handle_ACCEPT(): Incorrect, removed
Modified: trunk/clients/Javer2/src/haver/Client.java
===================================================================
--- trunk/clients/Javer2/src/haver/Client.java 2005-05-22 05:05:33 UTC (rev
705)
+++ trunk/clients/Javer2/src/haver/Client.java 2005-05-22 05:36:50 UTC (rev
706)
@@ -118,13 +118,24 @@
return out.toString();
}
+ /**
+ * Internal class for distributing callback events to all listeners
+ */
protected class CallbackDist extends Callback {
java.util.Set listeners;
+ /**
+ *
+ * @param l Listener set
+ */
public CallbackDist(Set l) {
listeners = l;
}
+ /**
+ * Returns a constant iterator over the current listeners, which will
not be
+ * affected by concurrency issues.
+ */
protected Iterator iterator() {
// Prevent concurrency issues
return new HashSet(listeners).iterator();
@@ -208,10 +219,11 @@
}
- protected void gotLine(String[] args) throws IOException {
- dist.onIncomingLine(this, args);
- }
-
+ /**
+ * Entry point for IO thread; connects to specified host and port.
+ * @param host Hostname to connect to
+ * @param port Port number to connect to
+ */
protected void run(String host, int port) {
io.setName("haver.Client input thread");
try {
@@ -246,6 +258,11 @@
}
}
+ /**
+ * Sends a command to the server.
+ * @param args Arguments of the line to send
+ * @throws java.io.IOException
+ */
protected void sendLine(String[] args) throws IOException {
if (writer != null) {
String l = encodeLine(args);
@@ -255,6 +272,11 @@
}
}
+ /**
+ * Main IO loop
+ * @param f Termination flag; ioLoop will return when f.ok is false
+ * @throws java.io.IOException
+ */
protected void ioLoop(Flag f) throws IOException {
while (io != null && f.ok) {
String l = reader.readLine();
@@ -292,10 +314,22 @@
io.start();
}
+ /**
+ * Base class for event listeners for synchronous methods
+ */
protected class SyncMonitor extends Callback {
+ /**
+ * The exception which caused the operation to fail, or null if none
+ */
public IOException fail = null;
+ /**
+ * Flag for ioLoop() termination
+ */
public Flag flag = new Flag();
+ /**
+ * Signal completion of the synchronous event
+ */
protected void done() {
flag.ok = false;
notifyAll();
@@ -310,10 +344,17 @@
done();
}
+ /**
+ * Wait until the synchronous event completes
+ * @throws java.io.IOException
+ */
public void block() throws IOException {
if (Thread.currentThread() == io) {
if (flag != null) {
ioLoop(flag);
+ if (flag.ok) {
+ throw new IOException("Unexpectedly disconnected");
+ }
} else {
removeNotify(this);
throw new IllegalStateException("Blocking in IO thread
without flag");
@@ -328,8 +369,17 @@
}
}
+ /**
+ * Event listener for syncConnect()
+ */
protected class ConnectMonitor extends SyncMonitor {
+ /**
+ * true if connection completed successfully
+ */
public boolean done = false;
+ /**
+ * Name for login
+ */
public String name;
public ConnectMonitor(String name) {
@@ -395,6 +445,11 @@
listening.remove(c);
}
+ /**
+ * Dispatch the passed line to the appropriate internal handler (if
present)
+ * @param args Arguments of line, including command.
+ * @throws java.io.IOException
+ */
protected void dispatch(String[] args) throws IOException {
String cmd = args[0].toUpperCase();
Class me = this.getClass();
@@ -421,10 +476,11 @@
}
}
- protected void handle_FOO(String[] args) {
- System.out.println("foo'd by the bar");
- }
-
+ /**
+ * Handler for server HAVER message
+ * @param args Arguments of message
+ * @throws java.io.IOException
+ */
protected void handle_HAVER(String[] args) throws IOException {
dist.onNeedIdent(this);
}
@@ -439,24 +495,41 @@
sendLine(l);
}
+ /**
+ * Handler for server HELLO message
+ * @param args Arguments of message
+ * @throws java.io.IOException
+ */
protected void handle_HELLO(String[] args) throws IOException {
dist.onAccept(this, args[1]);
}
+ /**
+ * Handler for server PING message
+ * @param args Arguments of message
+ * @throws java.io.IOException
+ */
protected void handle_PING(String[] args) throws IOException {
args[0] = "PONG";
sendLine(args);
}
- protected void handle_ACCEPT(String[] args) throws IOException {
- dist.onAccept(this, args[1]);
- }
-
+ /**
+ * Request a listing of the contents of a channel, asynchronously.
+ * @param channel Channel to list
+ * @param namespace Namespace to filter results by
+ * @throws java.io.IOException
+ */
public void requestList(String channel, String namespace) throws
IOException {
String[] cmd = {"LIST", channel, namespace};
sendLine(cmd);
}
+ /**
+ * Handler for server LIST message
+ * @param args Arguments of message
+ * @throws java.io.IOException
+ */
protected void handle_LIST(String[] args) throws IOException {
String[] list = new String[args.length - 3];
System.arraycopy(args, 3, list, 0, args.length - 3);
@@ -466,6 +539,9 @@
dist.onReceivedList(this, channel, namespace, list);
}
+ /**
+ * Event listener for syncList()
+ */
protected class ListMonitor extends SyncMonitor {
String[] list = null;
String channel;
@@ -486,6 +562,15 @@
}
}
+ /**
+ * Synchronously list a channel.
+ * @param channel Channel to list
+ * @param namespace Namespace to restrict results by
+ * @throws java.io.IOException If an IO exception occurs while this
function is being processed, it will be
+ * rethrown from here.
+ * @return An array containing the elements of the given namespace, in the
specified
+ * channel
+ */
public String[] syncList(String channel, String namespace) throws
IOException {
ListMonitor m = new ListMonitor(channel, namespace);
synchronized (m) {