Java: Began work on hub listeners.
[doldaconnect.git] / lib / java / dolda / dolcon / Session.java
index 7f3cece..de6ea18 100644 (file)
@@ -3,10 +3,17 @@ package dolda.dolcon;
 import java.util.*;
 import dolda.dolcon.protocol.*;
 
-public class Session {
+public class Session implements NotifyListener {
     private Connection conn;
+    private String state;
+    private Set<HubListener> hubls = new HashSet<HubListener>();
+    private boolean listening = false;
+    private String[] hubstate = {"none"};
+    private String[][] states = {hubstate};
+    private Map<Integer, Hub> hubs = new TreeMap<Integer, Hub>();
     
     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 +21,9 @@ public class Session {
        } catch(ConnectException e) {
            throw(new ProtocolException(e));
        }
+       state = "auth";
        authenticate(username, auth);
+       state = "";
     }
     
     public Session(String aspec, String username, Authenticator... auth) throws AuthException, ProtocolException, InterruptedException {
@@ -58,7 +67,80 @@ public class Session {
        }
     }
     
+    private void checkstates() {
+       boolean active = false;
+       for(String[] sp : states) {
+           if(sp[0] != "none") {
+               active = true;
+               break;
+           }
+       }
+       if(listening && !active)
+           conn.removeNotifyListener(this);
+       else if(!listening && active)
+           conn.addNotifyListener(this);
+    }
+
+    private int atoi(String a) {
+       return(Integer.parseInt(a));
+    }
+
+    private void fetchhubs() {
+       synchronized(hubstate) {
+           if(hubstate[0] != "none")
+               return;
+           hubstate[0] = "fetch";
+       }
+       Command cmd = new Command("lsnodes");
+       cmd.new Listener() {
+               public void done(Response r) {
+                   if(r.code != 200)
+                       return;
+                   for(List<String> line : r.lines) {
+                       Hub h = new Hub(atoi(line.get(0)));
+                       h.fnet = line.get(1).intern();
+                       h.name = line.get(2);
+                       h.numpeers = atoi(line.get(3));
+                       h.state = new String[] {"syn", "hs", "est", "dead"}[atoi(line.get(4))];
+                       h.gid = line.get(5);
+                       hubs.put(h.id, h);
+                   }
+               }
+               
+               public void error(Exception e) {
+               }
+           };
+       conn.qcmd(new Command("notify fn:act on"), cmd);
+    }
+    
+    public void addHubListener(HubListener hl, boolean addexisting) {
+       fetchhubs();
+       synchronized(hubls) {
+           hubls.add(hl);
+       }
+    }
+    
+    public void removeHubListener(HubListener hl) {
+       synchronized(hubls) {
+           hubls.remove(hl);
+           if(hubls.isEmpty()) {
+               hubs.clear();
+               hubstate[0] = "none";
+               checkstates();
+           }
+       }
+    }
+
+    public void notified(Response resp) {
+    }
+    
     public void close() {
        conn.close();
+       state = "closed";
+    }
+    
+    protected void finalize() {
+       if(state != "closed")
+           close();
     }
 }