Commit | Line | Data |
---|---|---|
7131093c FT |
1 | package dolda.dolcon; |
2 | ||
3 | import java.util.*; | |
4 | import dolda.dolcon.protocol.*; | |
5 | ||
e90ca845 | 6 | public class Session implements NotifyListener { |
7131093c | 7 | private Connection conn; |
e90ca845 FT |
8 | private String state; |
9 | private Set<HubListener> hubls = new HashSet<HubListener>(); | |
10 | private boolean listening = false; | |
11 | private String[] hubstate = {"none"}; | |
12 | private String[][] states = {hubstate}; | |
13 | private Map<Integer, Hub> hubs = new TreeMap<Integer, Hub>(); | |
7131093c FT |
14 | |
15 | public Session(String aspec, String username, List<Authenticator> auth) throws AuthException, ProtocolException, InterruptedException { | |
e90ca845 | 16 | state = "connecting"; |
7131093c FT |
17 | conn = new Connection(aspec); |
18 | conn.expectVersion(2); | |
19 | try { | |
20 | conn.syncConnect(); | |
21 | } catch(ConnectException e) { | |
22 | throw(new ProtocolException(e)); | |
23 | } | |
e90ca845 | 24 | state = "auth"; |
7131093c | 25 | authenticate(username, auth); |
e90ca845 | 26 | state = ""; |
7131093c FT |
27 | } |
28 | ||
29 | public Session(String aspec, String username, Authenticator... auth) throws AuthException, ProtocolException, InterruptedException { | |
30 | this(aspec, username, Arrays.asList(auth)); | |
31 | } | |
32 | ||
33 | private void authenticate(String username, List<Authenticator> auth) throws AuthException, ProtocolException, InterruptedException { | |
34 | Response resp; | |
35 | ||
36 | try { | |
37 | resp = ResponseException.check(conn.ecmd("lsauth"), 200); | |
38 | List<String> mechs = new LinkedList<String>(); | |
39 | for(List<String> mech : resp.lines) | |
40 | mechs.add(mech.get(0).intern()); | |
41 | String use = null; | |
42 | Authenticator au = null; | |
43 | for(Authenticator a : auth) { | |
44 | System.out.println(a); | |
45 | use = a.handles(mechs); | |
46 | if(use != null) { | |
47 | au = a; | |
48 | break; | |
49 | } | |
50 | } | |
51 | if(use == null) | |
52 | throw(new NoMechException()); | |
53 | resp = conn.ecmd("login", use, username); | |
54 | while(true) { | |
55 | if(resp.code == 200) { | |
56 | return; | |
57 | } else if((resp.code / 100) == 3) { | |
58 | resp = conn.ecmd(au.step(resp)); | |
59 | } else if((resp.code / 100) == 5) { | |
60 | throw(new AuthException(resp.token(0, 0))); | |
61 | } else { | |
62 | throw(new ResponseException(resp, 0)); | |
63 | } | |
64 | } | |
65 | } catch(ClosedException e) { | |
66 | throw(new ProtocolException(e)); | |
67 | } | |
68 | } | |
92719bd6 | 69 | |
e90ca845 FT |
70 | private void checkstates() { |
71 | boolean active = false; | |
72 | for(String[] sp : states) { | |
73 | if(sp[0] != "none") { | |
74 | active = true; | |
75 | break; | |
76 | } | |
77 | } | |
78 | if(listening && !active) | |
79 | conn.removeNotifyListener(this); | |
80 | else if(!listening && active) | |
81 | conn.addNotifyListener(this); | |
82 | } | |
83 | ||
84 | private int atoi(String a) { | |
85 | return(Integer.parseInt(a)); | |
86 | } | |
87 | ||
88 | private void fetchhubs() { | |
89 | synchronized(hubstate) { | |
90 | if(hubstate[0] != "none") | |
91 | return; | |
92 | hubstate[0] = "fetch"; | |
93 | } | |
94 | Command cmd = new Command("lsnodes"); | |
95 | cmd.new Listener() { | |
96 | public void done(Response r) { | |
97 | if(r.code != 200) | |
98 | return; | |
99 | for(List<String> line : r.lines) { | |
100 | Hub h = new Hub(atoi(line.get(0))); | |
101 | h.fnet = line.get(1).intern(); | |
102 | h.name = line.get(2); | |
103 | h.numpeers = atoi(line.get(3)); | |
104 | h.state = new String[] {"syn", "hs", "est", "dead"}[atoi(line.get(4))]; | |
105 | h.gid = line.get(5); | |
106 | hubs.put(h.id, h); | |
107 | } | |
108 | } | |
109 | ||
110 | public void error(Exception e) { | |
111 | } | |
112 | }; | |
113 | conn.qcmd(new Command("notify fn:act on"), cmd); | |
114 | } | |
115 | ||
116 | public void addHubListener(HubListener hl, boolean addexisting) { | |
117 | fetchhubs(); | |
118 | synchronized(hubls) { | |
119 | hubls.add(hl); | |
120 | } | |
121 | } | |
122 | ||
123 | public void removeHubListener(HubListener hl) { | |
124 | synchronized(hubls) { | |
125 | hubls.remove(hl); | |
126 | if(hubls.isEmpty()) { | |
127 | hubs.clear(); | |
128 | hubstate[0] = "none"; | |
129 | checkstates(); | |
130 | } | |
131 | } | |
132 | } | |
133 | ||
134 | public void notified(Response resp) { | |
135 | } | |
136 | ||
92719bd6 FT |
137 | public void close() { |
138 | conn.close(); | |
e90ca845 FT |
139 | state = "closed"; |
140 | } | |
141 | ||
142 | protected void finalize() { | |
143 | if(state != "closed") | |
144 | close(); | |
92719bd6 | 145 | } |
7131093c | 146 | } |