1 20 21 package org.jivesoftware.smackx; 22 23 import java.util.*; 24 25 import org.jivesoftware.smack.*; 26 import org.jivesoftware.smack.filter.*; 27 import org.jivesoftware.smack.packet.*; 28 import org.jivesoftware.smackx.packet.*; 29 30 41 public class ServiceDiscoveryManager { 42 43 private static String identityName = "Smack"; 44 private static String identityType = "pc"; 45 46 private static Map instances = new Hashtable(); 47 48 private XMPPConnection connection; 49 private List features = new ArrayList(); 50 private Map nodeInformationProviders = new Hashtable(); 51 52 static { 54 XMPPConnection.addConnectionListener(new ConnectionEstablishedListener() { 55 public void connectionEstablished(XMPPConnection connection) { 56 new ServiceDiscoveryManager(connection); 57 } 58 }); 59 } 60 61 68 public ServiceDiscoveryManager(XMPPConnection connection) { 69 this.connection = connection; 70 init(); 71 } 72 73 79 public static ServiceDiscoveryManager getInstanceFor(XMPPConnection connection) { 80 return (ServiceDiscoveryManager) instances.get(connection); 81 } 82 83 90 public static String getIdentityName() { 91 return identityName; 92 } 93 94 101 public static void setIdentityName(String name) { 102 identityName = name; 103 } 104 105 113 public static String getIdentityType() { 114 return identityType; 115 } 116 117 125 public static void setIdentityType(String type) { 126 identityType = type; 127 } 128 129 133 private void init() { 134 instances.put(connection, this); 136 connection.addConnectionListener(new ConnectionListener() { 139 public void connectionClosed() { 140 instances.remove(connection); 142 } 143 144 public void connectionClosedOnError(Exception e) { 145 instances.remove(connection); 147 } 148 }); 149 150 PacketFilter packetFilter = new PacketTypeFilter(DiscoverItems.class); 152 PacketListener packetListener = new PacketListener() { 153 public void processPacket(Packet packet) { 154 DiscoverItems discoverItems = (DiscoverItems) packet; 155 if (discoverItems != null && discoverItems.getType() == IQ.Type.GET) { 157 DiscoverItems response = new DiscoverItems(); 158 response.setType(IQ.Type.RESULT); 159 response.setTo(discoverItems.getFrom()); 160 response.setPacketID(discoverItems.getPacketID()); 161 162 if (getNodeInformationProvider(discoverItems.getNode()) != null) { 165 Iterator items = 166 getNodeInformationProvider(discoverItems.getNode()).getNodeItems(); 167 while (items.hasNext()) { 168 response.addItem((DiscoverItems.Item) items.next()); 169 } 170 } 171 connection.sendPacket(response); 172 } 173 } 174 }; 175 connection.addPacketListener(packetListener, packetFilter); 176 177 packetFilter = new PacketTypeFilter(DiscoverInfo.class); 180 packetListener = new PacketListener() { 181 public void processPacket(Packet packet) { 182 DiscoverInfo discoverInfo = (DiscoverInfo) packet; 183 if (discoverInfo != null && discoverInfo.getType() == IQ.Type.GET) { 185 DiscoverInfo response = new DiscoverInfo(); 186 response.setType(IQ.Type.RESULT); 187 response.setTo(discoverInfo.getFrom()); 188 response.setPacketID(discoverInfo.getPacketID()); 189 if (discoverInfo.getNode() == null) { 191 DiscoverInfo.Identity identity = new DiscoverInfo.Identity("client", 193 getIdentityName()); 194 identity.setType(getIdentityType()); 195 response.addIdentity(identity); 196 synchronized (features) { 198 for (Iterator it = getFeatures(); it.hasNext();) { 199 response.addFeature((String ) it.next()); 200 } 201 } 202 } 203 else { 204 response.setType(IQ.Type.ERROR); 206 response.setError(new XMPPError(404, "item-not-found")); 207 } 208 connection.sendPacket(response); 209 } 210 } 211 }; 212 connection.addPacketListener(packetListener, packetFilter); 213 } 214 215 226 private NodeInformationProvider getNodeInformationProvider(String node) { 227 if (node == null) { 228 return null; 229 } 230 return (NodeInformationProvider) nodeInformationProviders.get(node); 231 } 232 233 246 public void setNodeInformationProvider(String node, NodeInformationProvider listener) { 247 nodeInformationProviders.put(node, listener); 248 } 249 250 260 public void removeNodeInformationProvider(String node) { 261 nodeInformationProviders.remove(node); 262 } 263 264 269 public Iterator getFeatures() { 270 synchronized (features) { 271 return Collections.unmodifiableList(new ArrayList(features)).iterator(); 272 } 273 } 274 275 286 public void addFeature(String feature) { 287 synchronized (features) { 288 features.add(feature); 289 } 290 } 291 292 300 public void removeFeature(String feature) { 301 synchronized (features) { 302 features.remove(feature); 303 } 304 } 305 306 312 public boolean includesFeature(String feature) { 313 synchronized (features) { 314 return features.contains(feature); 315 } 316 } 317 318 325 public DiscoverInfo discoverInfo(String entityID) throws XMPPException { 326 return discoverInfo(entityID, null); 327 } 328 329 339 public DiscoverInfo discoverInfo(String entityID, String node) throws XMPPException { 340 DiscoverInfo disco = new DiscoverInfo(); 342 disco.setType(IQ.Type.GET); 343 disco.setTo(entityID); 344 disco.setNode(node); 345 346 PacketCollector collector = 348 connection.createPacketCollector(new PacketIDFilter(disco.getPacketID())); 349 350 connection.sendPacket(disco); 351 352 IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); 354 collector.cancel(); 356 if (result == null) { 357 throw new XMPPException("No response from the server."); 358 } 359 if (result.getType() == IQ.Type.ERROR) { 360 throw new XMPPException(result.getError()); 361 } 362 return (DiscoverInfo) result; 363 } 364 365 372 public DiscoverItems discoverItems(String entityID) throws XMPPException { 373 return discoverItems(entityID, null); 374 } 375 376 386 public DiscoverItems discoverItems(String entityID, String node) throws XMPPException { 387 DiscoverItems disco = new DiscoverItems(); 389 disco.setType(IQ.Type.GET); 390 disco.setTo(entityID); 391 disco.setNode(node); 392 393 PacketCollector collector = 395 connection.createPacketCollector(new PacketIDFilter(disco.getPacketID())); 396 397 connection.sendPacket(disco); 398 399 IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); 401 collector.cancel(); 403 if (result == null) { 404 throw new XMPPException("No response from the server."); 405 } 406 if (result.getType() == IQ.Type.ERROR) { 407 throw new XMPPException(result.getError()); 408 } 409 return (DiscoverItems) result; 410 } 411 412 422 public boolean canPublishItems(String entityID) throws XMPPException { 423 DiscoverInfo info = discoverInfo(entityID); 424 return info.containsFeature("http://jabber.org/protocol/disco#publish"); 425 } 426 427 437 public void publishItems(String entityID, DiscoverItems discoverItems) 438 throws XMPPException { 439 publishItems(entityID, null, discoverItems); 440 } 441 442 453 public void publishItems(String entityID, String node, DiscoverItems discoverItems) 454 throws XMPPException { 455 discoverItems.setType(IQ.Type.SET); 456 discoverItems.setTo(entityID); 457 discoverItems.setNode(node); 458 459 PacketCollector collector = 461 connection.createPacketCollector(new PacketIDFilter(discoverItems.getPacketID())); 462 463 connection.sendPacket(discoverItems); 464 465 IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); 467 collector.cancel(); 469 if (result == null) { 470 throw new XMPPException("No response from the server."); 471 } 472 if (result.getType() == IQ.Type.ERROR) { 473 throw new XMPPException(result.getError()); 474 } 475 } 476 } | Popular Tags |