summaryrefslogtreecommitdiffstats
path: root/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/com')
-rw-r--r--src/com/isode/stroke/disco/DiscoServiceWalker.java104
1 files changed, 65 insertions, 39 deletions
diff --git a/src/com/isode/stroke/disco/DiscoServiceWalker.java b/src/com/isode/stroke/disco/DiscoServiceWalker.java
index 1b5c54e..39900aa 100644
--- a/src/com/isode/stroke/disco/DiscoServiceWalker.java
+++ b/src/com/isode/stroke/disco/DiscoServiceWalker.java
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2010 Isode Limited. 2 * Copyright (c) 2010-2016 Isode Limited.
3 * All rights reserved. 3 * All rights reserved.
4 * See the COPYING file for more information. 4 * See the COPYING file for more information.
5 */ 5 */
@@ -23,9 +23,13 @@ import com.isode.stroke.signals.Slot2;
23import com.isode.stroke.signals.Signal2; 23import com.isode.stroke.signals.Signal2;
24import com.isode.stroke.signals.SignalConnection; 24import com.isode.stroke.signals.SignalConnection;
25import com.isode.stroke.base.NotNull; 25import com.isode.stroke.base.NotNull;
26
26import java.util.logging.Logger; 27import java.util.logging.Logger;
28import java.util.HashMap;
27import java.util.HashSet; 29import java.util.HashSet;
30import java.util.Map;
28import java.util.Set; 31import java.util.Set;
32
29import com.isode.stroke.base.NotNull; 33import com.isode.stroke.base.NotNull;
30 34
31/** 35/**
@@ -46,8 +50,18 @@ public class DiscoServiceWalker {
46 private SignalConnection onServiceFoundConnection; 50 private SignalConnection onServiceFoundConnection;
47 private SignalConnection onWalkAbortedConnection; 51 private SignalConnection onWalkAbortedConnection;
48 private SignalConnection onWalkCompleteConnection; 52 private SignalConnection onWalkCompleteConnection;
49 private SignalConnection onResponseDiscoInfoConnection; 53
50 private SignalConnection onResponseDiscoItemsConnection; 54 /**
55 * The discoInfo.onResponse connections for each GetDiscoInfoRequest
56 */
57 private Map<GetDiscoInfoRequest,SignalConnection> onResponseDiscoInfoConnections =
58 new HashMap<GetDiscoInfoRequest,SignalConnection>();
59
60 /**
61 * The discoItems.onResponse connections for each GetDiscoItemsRequest
62 */
63 private Map<GetDiscoItemsRequest,SignalConnection> onResponseDiscoItemsConnections =
64 new HashMap<GetDiscoItemsRequest,SignalConnection>();
51 65
52 /** Emitted for each service found. */ 66 /** Emitted for each service found. */
53 public final Signal2<JID, DiscoInfo> onServiceFound = new Signal2<JID, DiscoInfo>(); 67 public final Signal2<JID, DiscoInfo> onServiceFound = new Signal2<JID, DiscoInfo>();
@@ -99,17 +113,19 @@ public class DiscoServiceWalker {
99 * End the walk. 113 * End the walk.
100 */ 114 */
101 public void endWalk() { 115 public void endWalk() {
102 if (active_) { 116 if (active_) {
103 logger_.fine("Ending walk to" + service_ + "\n"); 117 logger_.fine("Ending walk to" + service_ + "\n");
104 for (GetDiscoInfoRequest request : pendingDiscoInfoRequests_) { 118 for (SignalConnection discoInfoConnection : onResponseDiscoInfoConnections.values()) {
105 onResponseDiscoInfoConnection.disconnect(); 119 discoInfoConnection.disconnect();
106 } 120 }
107 for (GetDiscoItemsRequest request : pendingDiscoItemsRequests_) { 121 onResponseDiscoInfoConnections.clear();
108 onResponseDiscoItemsConnection.disconnect(); 122 for (SignalConnection discoItemsConnection : onResponseDiscoItemsConnections.values()) {
109 } 123 discoItemsConnection.disconnect();
110 active_ = false; 124 }
111 onWalkAborted.emit(); 125 onResponseDiscoItemsConnections.clear();
112 } 126 active_ = false;
127 onWalkAborted.emit();
128 }
113 } 129 }
114 130
115 public boolean isActive() { 131 public boolean isActive() {
@@ -121,13 +137,14 @@ public class DiscoServiceWalker {
121 servicesBeingSearched_.add(jid); 137 servicesBeingSearched_.add(jid);
122 searchedServices_.add(jid); 138 searchedServices_.add(jid);
123 final GetDiscoInfoRequest discoInfoRequest = GetDiscoInfoRequest.create(jid, iqRouter_); 139 final GetDiscoInfoRequest discoInfoRequest = GetDiscoInfoRequest.create(jid, iqRouter_);
124 onResponseDiscoInfoConnection = discoInfoRequest.onResponse.connect(new Slot2<DiscoInfo, ErrorPayload>() { 140 SignalConnection connection = discoInfoRequest.onResponse.connect(new Slot2<DiscoInfo, ErrorPayload>() {
125 141
126 @Override 142 @Override
127 public void call(DiscoInfo info, ErrorPayload error) { 143 public void call(DiscoInfo info, ErrorPayload error) {
128 handleDiscoInfoResponse(info, error, discoInfoRequest); 144 handleDiscoInfoResponse(info, error, discoInfoRequest);
129 } 145 }
130 }); 146 });
147 onResponseDiscoInfoConnections.put(discoInfoRequest, connection);
131 pendingDiscoInfoRequests_.add(discoInfoRequest); 148 pendingDiscoInfoRequests_.add(discoInfoRequest);
132 discoInfoRequest.send(); 149 discoInfoRequest.send();
133 } 150 }
@@ -155,6 +172,10 @@ public class DiscoServiceWalker {
155 172
156 logger_.fine("Disco info response from " + request.getReceiver() + "\n"); 173 logger_.fine("Disco info response from " + request.getReceiver() + "\n");
157 174
175
176 SignalConnection connection = onResponseDiscoInfoConnections.remove(request);
177 connection.disconnect();
178
158 pendingDiscoInfoRequests_.remove(request); 179 pendingDiscoInfoRequests_.remove(request);
159 if (error != null) { 180 if (error != null) {
160 handleDiscoError(request.getReceiver(), error); 181 handleDiscoError(request.getReceiver(), error);
@@ -170,13 +191,14 @@ public class DiscoServiceWalker {
170 boolean completed = false; 191 boolean completed = false;
171 if (couldContainServices) { 192 if (couldContainServices) {
172 final GetDiscoItemsRequest discoItemsRequest = GetDiscoItemsRequest.create(request.getReceiver(), iqRouter_); 193 final GetDiscoItemsRequest discoItemsRequest = GetDiscoItemsRequest.create(request.getReceiver(), iqRouter_);
173 onResponseDiscoItemsConnection = discoItemsRequest.onResponse.connect(new Slot2<DiscoItems, ErrorPayload>() { 194 SignalConnection discoItemsConnection = discoItemsRequest.onResponse.connect(new Slot2<DiscoItems, ErrorPayload>() {
174 195
175 @Override 196 @Override
176 public void call(DiscoItems item, ErrorPayload error) { 197 public void call(DiscoItems item, ErrorPayload error) {
177 handleDiscoItemsResponse(item, error, discoItemsRequest); 198 handleDiscoItemsResponse(item, error, discoItemsRequest);
178 } 199 }
179 }); 200 });
201 onResponseDiscoItemsConnections.put(discoItemsRequest, discoItemsConnection);
180 pendingDiscoItemsRequests_.add(discoItemsRequest); 202 pendingDiscoItemsRequests_.add(discoItemsRequest);
181 discoItemsRequest.send(); 203 discoItemsRequest.send();
182 } else { 204 } else {
@@ -189,29 +211,33 @@ public class DiscoServiceWalker {
189 } 211 }
190 212
191 private void handleDiscoItemsResponse(DiscoItems items, ErrorPayload error, GetDiscoItemsRequest request) { 213 private void handleDiscoItemsResponse(DiscoItems items, ErrorPayload error, GetDiscoItemsRequest request) {
192 /* If we got canceled, don't do anything */ 214 /* If we got canceled, don't do anything */
193 if (!active_) { 215 if (!active_) {
194 return; 216 return;
195 } 217 }
196 218
197 logger_.fine("Received disco items from " + request.getReceiver() + "\n"); 219 logger_.fine("Received disco items from " + request.getReceiver() + "\n");
198 pendingDiscoItemsRequests_.remove(request); 220
199 if (error != null) { 221 SignalConnection connection = onResponseDiscoItemsConnections.remove(request);
200 handleDiscoError(request.getReceiver(), error); 222 connection.disconnect();
201 return; 223
202 } 224 pendingDiscoItemsRequests_.remove(request);
203 for (DiscoItems.Item item : items.getItems()) { 225 if (error != null) {
204 if (item.getNode().isEmpty()) { 226 handleDiscoError(request.getReceiver(), error);
205 /* Don't look at noded items. It's possible that this will exclude some services, 227 return;
206 * but I've never seen one in the wild, and it's an easy fix for not looping. 228 }
207 */ 229 for (DiscoItems.Item item : items.getItems()) {
208 if(!searchedServices_.contains(item.getJID())) { 230 if (item.getNode().isEmpty()) {
209 logger_.fine("Received disco item " + item.getJID() + "\n"); 231 /* Don't look at noded items. It's possible that this will exclude some services,
210 walkNode(item.getJID()); 232 * but I've never seen one in the wild, and it's an easy fix for not looping.
211 } 233 */
212 } 234 if(!searchedServices_.contains(item.getJID())) {
213 } 235 logger_.fine("Received disco item " + item.getJID() + "\n");
214 markNodeCompleted(request.getReceiver()); 236 walkNode(item.getJID());
237 }
238 }
239 }
240 markNodeCompleted(request.getReceiver());
215 } 241 }
216 242
217 private void handleDiscoError(JID jid, ErrorPayload error) { 243 private void handleDiscoError(JID jid, ErrorPayload error) {