Java: Hopefully working HubListeners.
[doldaconnect.git] / lib / java / dolda / dolcon / Session.java
index 7f3cece..b2ff07b 100644 (file)
@@ -4,9 +4,14 @@ import java.util.*;
 import dolda.dolcon.protocol.*;
 
 public class Session {
-    private Connection conn;
+    Connection conn;
+    private String state;
+    private boolean listening = false;
+    private Dispatcher dispatcher;
+    HubManager hm = null;
     
     public Session(String aspec, String username, List<Authenticator> auth) throws AuthException, ProtocolException, InterruptedException {
+       state = "connecting";
        conn = new Connection(aspec);
        conn.expectVersion(2);
        try {
@@ -14,7 +19,11 @@ public class Session {
        } catch(ConnectException e) {
            throw(new ProtocolException(e));
        }
+       state = "auth";
        authenticate(username, auth);
+       state = "";
+       dispatcher = new Dispatcher();
+       dispatcher.start();
     }
     
     public Session(String aspec, String username, Authenticator... auth) throws AuthException, ProtocolException, InterruptedException {
@@ -32,7 +41,6 @@ public class Session {
            String use = null;
            Authenticator au = null;
            for(Authenticator a : auth) {
-               System.out.println(a);
                use = a.handles(mechs);
                if(use != null) {
                    au = a;
@@ -58,7 +66,67 @@ public class Session {
        }
     }
     
+    private HubManager gethm() {
+       if(hm == null) {
+           hm = new HubManager(this);
+       }
+       return(hm);
+    }
+    
+    public synchronized void addHubListener(HubListener hl, boolean addexisting) {
+       gethm().addls(hl, addexisting);
+    }
+    
+    public synchronized void removeHubListener(HubListener hl) {
+       gethm().rmls(hl);
+    }
+    
+    public synchronized Collection<Hub> getHubs() throws InterruptedException {
+       return(gethm().gethubs());
+    }
+    
     public void close() {
        conn.close();
+       state = "closed";
+    }
+    
+    protected void finalize() {
+       if(state != "closed")
+           close();
+       dispatcher.interrupt();
+    }
+    
+    void dispatch(Runnable ev) {
+       dispatcher.dispatch(ev);
+    }
+
+    private static class Dispatcher extends Thread {
+       private Queue<Runnable> q = new LinkedList<Runnable>();
+       
+       private Dispatcher() {
+           setDaemon(true);
+       }
+       
+       public void dispatch(Runnable ev) {
+           synchronized(q) {
+               q.offer(ev);
+               q.notifyAll();
+           }
+       }
+       
+       public void run() {
+           while(true) {
+               try {
+                   Runnable r;
+                   synchronized(q) {
+                       while((r = q.poll()) == null)
+                           q.wait();
+                   }
+                   r.run();
+               } catch(Throwable t) {
+                   t.printStackTrace();
+               }
+           }
+       }
     }
 }