From: Fredrik Tolf <fredrik@dolda2000.com>
Date: Tue, 29 Jan 2008 16:08:32 +0000 (+0100)
Subject: Java: Began work on hub listeners.
X-Git-Url: http://git.dolda2000.com/gitweb/?a=commitdiff_plain;h=e90ca845da9e7104c8c1cf88964bdc1880561e44;p=doldaconnect.git

Java: Began work on hub listeners.
---

diff --git a/lib/java/dolda/dolcon/Hub.java b/lib/java/dolda/dolcon/Hub.java
new file mode 100644
index 0000000..125f172
--- /dev/null
+++ b/lib/java/dolda/dolcon/Hub.java
@@ -0,0 +1,35 @@
+package dolda.dolcon;
+
+public class Hub {
+    int id, numpeers;
+    String fnet, name, gid;
+    String state;
+    
+    public Hub(int id) {
+	this.id = id;
+    }
+    
+    public int getId() {
+	return(id);
+    }
+    
+    public String getGid() {
+	return(gid);
+    }
+    
+    public String getFnet() {
+	return(fnet);
+    }
+    
+    public String getName() {
+	return(name);
+    }
+    
+    public int getNumPeers() {
+	return(numpeers);
+    }
+    
+    public String getState() {
+	return(state);
+    }
+}
diff --git a/lib/java/dolda/dolcon/HubListener.java b/lib/java/dolda/dolcon/HubListener.java
new file mode 100644
index 0000000..67ef183
--- /dev/null
+++ b/lib/java/dolda/dolcon/HubListener.java
@@ -0,0 +1,6 @@
+package dolda.dolcon;
+
+public interface HubListener {
+    void added(Hub hub);
+    void removed(Hub hub);
+}
diff --git a/lib/java/dolda/dolcon/Session.java b/lib/java/dolda/dolcon/Session.java
index 7f3cece..de6ea18 100644
--- a/lib/java/dolda/dolcon/Session.java
+++ b/lib/java/dolda/dolcon/Session.java
@@ -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();
     }
 }
diff --git a/lib/java/dolda/dolcon/protocol/Connection.java b/lib/java/dolda/dolcon/protocol/Connection.java
index 54aea90..b596639 100644
--- a/lib/java/dolda/dolcon/protocol/Connection.java
+++ b/lib/java/dolda/dolcon/protocol/Connection.java
@@ -183,9 +183,10 @@ public class Connection {
 	}
     }
 
-    public void qcmd(Command cmd) {
+    public void qcmd(Command... cmds) {
 	synchronized(queue) {
-	    queue.offer(cmd);
+	    for(Command cmd : cmds)
+		queue.offer(cmd);
 	    queue.notifyAll();
 	}
     }