Java: Added a session handler with authentication capability.
[doldaconnect.git] / lib / java / dolda / dolcon / protocol / Connection.java
index 20c06d6..54aea90 100644 (file)
@@ -14,13 +14,14 @@ public class Connection {
     private String aspec;
     private String state;
     private Set<ConnectListener> connls = new HashSet<ConnectListener>();
+    private Set<NotifyListener> notls = new HashSet<NotifyListener>();
     private Exception error;
     
     public interface ConnectListener {
        public void connected() throws Exception;
        public void error(Exception cause);
     }
-
+    
     public Connection(String aspec) {
        this.aspec = aspec;
        state = "idle";
@@ -41,7 +42,7 @@ public class Connection {
        }
        pending = new LinkedList<Command>();
        Command ccmd = new Command(".connect");
-       ccmd.addListener(new Command.Listener() {
+       ccmd.new Listener() {
                public void done(Response resp) throws Exception {
                    try {
                        checkver(resp);
@@ -72,7 +73,7 @@ public class Connection {
                        }
                    }
                }
-           });
+           };
        pending.offer(ccmd);
        reader = new Reader();
        writer = new Writer();
@@ -112,7 +113,7 @@ public class Connection {
            throw(new RuntimeException("Cannot call synchronous method with dispatch thread!"));
     }
         
-    public void syncConnect() throws ConnectException, ClosedException, InterruptedException {
+    public void syncConnect() throws ConnectException, InterruptedException {
        checkthread();
        final boolean[] donep = new boolean[] {false};
        final Exception[] errp = new Exception[] {null};
@@ -140,7 +141,7 @@ public class Connection {
            }
        }
        if(errp[0] != null)
-           throw(new ClosedException(errp[0]));
+           throw(new ConnectException("DC connection has been closed", errp[0]));
     }
 
     public void expectVersion(int reqver) {
@@ -162,6 +163,18 @@ public class Connection {
        return(error);
     }
 
+    public void addNotifyListener(NotifyListener l) {
+       synchronized(notls) {
+           notls.add(l);
+       }
+    }
+
+    public void removeNotifyListener(NotifyListener l) {
+       synchronized(notls) {
+           notls.remove(l);
+       }
+    }
+
     public synchronized void addConnectListener(ConnectListener l) {
        if((state != "idle") && (state != "connecting"))
            throw(new IllegalStateException("Already connected"));
@@ -170,13 +183,50 @@ public class Connection {
        }
     }
 
-    private void qcmd(Command cmd) {
+    public void qcmd(Command cmd) {
        synchronized(queue) {
            queue.offer(cmd);
            queue.notifyAll();
        }
     }
     
+    public void qcmd(String... tokens) {
+       qcmd(new Command(tokens));
+    }
+    
+    public Response ecmd(Command cmd) throws ClosedException, InterruptedException {
+       checkthread();
+       final boolean[] donep = new boolean[] {false};
+       final Response[] resp = new Response[] {null};
+       final Exception[] errp = new Exception[] {null};
+       Object l = cmd.new Listener() {
+               public synchronized void done(Response rsp) {
+                   resp[0] = rsp;
+                   donep[0] = true;
+                   notifyAll();
+               }
+               
+               public synchronized void error(Exception e) {
+                   errp[0] = e;
+                   donep[0] = true;
+                   notifyAll();
+               }
+           };
+       qcmd(cmd);
+       synchronized(l) {
+           while(!donep[0]) {
+               l.wait();
+           }
+       }
+       if(errp[0] != null)
+           throw(new ClosedException(errp[0]));
+       return(resp[0]);
+    }
+    
+    public Response ecmd(String... tokens) throws ClosedException, InterruptedException {
+       return(ecmd(new Command(tokens)));
+    }
+    
     static private class StopCondition extends Error {
        final boolean normal;
        
@@ -235,7 +285,9 @@ public class Connection {
                            out.append(' ');
                        out.append(quote(s));
                    }
+                   out.append("\r\n");
                    w.write(out.toString());
+                   w.flush();
                }
            } catch(IOException e) {
                throw(new StopCondition(e, false));
@@ -263,6 +315,12 @@ public class Connection {
                    queue.notifyAll();
                }
                resp.cmd.done(resp);
+           } else {
+               synchronized(notls) {
+                   for(NotifyListener l : notls) {
+                       l.notified(resp);
+                   }
+               }
            }
        }
 
@@ -323,7 +381,6 @@ public class Connection {
                                code = Integer.parseInt(ct.toString());
                                ct.setLength(0);
                                state = "start";
-                               continue eat;
                            } else {
                                ct.append(c);
                            }