Java: Hopefully working HubListeners.
[doldaconnect.git] / lib / java / dolda / dolcon / HubManager.java
CommitLineData
7ff32e0f
FT
1package dolda.dolcon;
2
3import java.util.*;
4import dolda.dolcon.protocol.*;
5
6class HubManager implements NotifyListener {
7 private Set<HubListener> hubls = new HashSet<HubListener>();
8 private Set<HubListener> delayed = new HashSet<HubListener>();
9 private Map<Integer, Hub> hubs = new TreeMap<Integer, Hub>();
10 private String state = "none";
11 private Session sess;
12
13 HubManager(Session sess) {
14 this.sess = sess;
15 }
16
17 private int atoi(String a) {
18 return(Integer.parseInt(a));
19 }
20
21 private void addall(final HubListener ls) {
22 for(final Hub hub : hubs.values()) {
23 sess.dispatch(new Runnable() {
24 public void run() {
25 ls.added(hub);
26 }
27 });
28 }
29 }
30
31 private void fetchhubs() {
32 synchronized(this) {
33 if(state != "none")
34 return;
35 state = "fetch";
36 }
37 Command cmd = new Command("lsnodes");
38 cmd.new Listener() {
39 public void done(Response r) {
40 if(r.code != 200)
41 return;
42 for(List<String> line : r.lines) {
43 Hub h = new Hub(atoi(line.get(0)), line.get(1));
44 h.name = line.get(2);
45 h.numpeers = atoi(line.get(3));
46 h.state = new String[] {"syn", "hs", "est", "dead"}[atoi(line.get(4))];
47 h.gid = line.get(5);
48 hubs.put(h.id, h);
49 }
50 synchronized(HubManager.this) {
51 state = "";
52 HubManager.this.notifyAll();
53 for(HubListener ls : delayed) {
54 addall(ls);
55 }
56 }
57 }
58
59 public void error(Exception e) {
60 synchronized(HubManager.this) {
61 state = "closed";
62 }
63 }
64 };
65 sess.conn.qcmd(new Command("notify", "fn:act", "on"), cmd);
66 sess.conn.addNotifyListener(this);
67 }
68
69 public Collection<Hub> gethubs() throws InterruptedException {
70 fetchhubs();
71 synchronized(this) {
72 while((state != "") && (state != "closed"))
73 wait();
74 }
75 Collection<Hub> ret = new LinkedList<Hub>();
76 synchronized(hubs) {
77 for(Hub h : hubs.values())
78 ret.add(h.copy());
79 }
80 return(ret);
81 }
82
83 public void addls(HubListener hl, boolean addexisting) {
84 fetchhubs();
85 synchronized(hubls) {
86 hubls.add(hl);
87 }
88 if(addexisting) {
89 synchronized(this) {
90 if(state != "")
91 delayed.add(hl);
92 else
93 addall(hl);
94 }
95 }
96 }
97
98 public void rmls(HubListener hl) {
99 synchronized(sess) {
100 synchronized(hubls) {
101 hubls.remove(hl);
102 if(hubls.isEmpty()) {
103 synchronized(hubs) {
104 hubs.clear();
105 }
106 state = "closed";
107 sess.conn.removeNotifyListener(this);
108 sess.hm = null;
109 }
110 }
111 }
112 }
113
114 public void notified(Response resp) {
115 synchronized(this) {
116 if(state != "")
117 return;
118 }
119 if(resp.code == 604) {
120 final Hub h = new Hub(atoi(resp.token(0, 0)), resp.token(0, 1));
121 synchronized(hubs) {
122 hubs.put(h.id, h);
123 }
124 sess.dispatch(new Runnable() {
125 public void run() {
126 synchronized(hubls) {
127 for(HubListener ls : hubls)
128 ls.added(h);
129 }
130 }
131 });
132 } else if(resp.code == 603) {
133 final Hub h;
134 synchronized(hubs) {
135 h = hubs.remove(atoi(resp.token(0, 0)));
136 }
137 sess.dispatch(new Runnable() {
138 public void run() {
139 synchronized(hubls) {
140 for(HubListener ls : hubls)
141 ls.removed(h);
142 }
143 }
144 });
145 } else if(resp.code == 601) {
146 final Hub h;
147 final String state = new String[] {"syn", "hs", "est", "dead"}[atoi(resp.token(0, 1))];
148 synchronized(hubs) {
149 h = hubs.get(atoi(resp.token(0, 0)));
150 }
151 h.state = state;
152 sess.dispatch(new Runnable() {
153 public void run() {
154 synchronized(h.ls) {
155 for(Hub.Listener ls : h.ls) {
156 ls.chState(h);
157 }
158 }
159 }
160 });
161 } else if(resp.code == 602) {
162 final Hub h;
163 final String name = resp.token(0, 1);
164 synchronized(hubs) {
165 h = hubs.get(atoi(resp.token(0, 0)));
166 }
167 h.name = name;
168 sess.dispatch(new Runnable() {
169 public void run() {
170 synchronized(h.ls) {
171 for(Hub.Listener ls : h.ls) {
172 ls.chName(h);
173 }
174 }
175 }
176 });
177 } else if(resp.code == 605) {
178 final Hub h;
179 final int np = atoi(resp.token(0, 1));
180 synchronized(hubs) {
181 h = hubs.get(atoi(resp.token(0, 0)));
182 }
183 h.numpeers = np;
184 sess.dispatch(new Runnable() {
185 public void run() {
186 synchronized(h.ls) {
187 for(Hub.Listener ls : h.ls) {
188 ls.chNumPeers(h);
189 }
190 }
191 }
192 });
193 }
194 }
195}