1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $RCSfile$ 3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Revision$ 4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Date$ 5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Copyright 2003-2007 Jive Software. 7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * you may not use this file except in compliance with the License. 10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * You may obtain a copy of the License at 11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * http://www.apache.org/licenses/LICENSE-2.0 13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Unless required by applicable law or agreed to in writing, software 15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * distributed under the License is distributed on an "AS IS" BASIS, 16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * See the License for the specific language governing permissions and 18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * limitations under the License. 19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.jivesoftware.smackx; 22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.*; 24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.filter.PacketFilter; 25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.filter.PacketIDFilter; 26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.filter.PacketTypeFilter; 27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.IQ; 28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.Packet; 29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.PacketExtension; 30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.XMPPError; 31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.entitycaps.EntityCapsManager; 32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.packet.DiscoverInfo; 33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.packet.DiscoverInfo.Identity; 34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.packet.DiscoverItems; 35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smackx.packet.DataForm; 36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.*; 38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.concurrent.ConcurrentHashMap; 39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Manages discovery of services in XMPP entities. This class provides: 42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <ol> 43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li>A registry of supported features in this XMPP entity. 44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li>Automatic response when this XMPP entity is queried for information. 45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li>Ability to discover items and information of remote XMPP entities. 46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li>Ability to publish publicly available items. 47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * </ol> 48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Gaston Dombiak 50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic class ServiceDiscoveryManager { 52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private static final String DEFAULT_IDENTITY_NAME = "Smack"; 54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private static final String DEFAULT_IDENTITY_CATEGORY = "client"; 55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private static final String DEFAULT_IDENTITY_TYPE = "pc"; 56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private static List<DiscoverInfo.Identity> identities = new LinkedList<DiscoverInfo.Identity>(); 58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private EntityCapsManager capsManager; 60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private static Map<Connection, ServiceDiscoveryManager> instances = 62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen new ConcurrentHashMap<Connection, ServiceDiscoveryManager>(); 63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private Connection connection; 65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private final Set<String> features = new HashSet<String>(); 66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private DataForm extendedInfo = null; 67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private Map<String, NodeInformationProvider> nodeInformationProviders = 68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen new ConcurrentHashMap<String, NodeInformationProvider>(); 69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Create a new ServiceDiscoveryManager on every established connection 71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen static { 72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Connection.addConnectionCreationListener(new ConnectionCreationListener() { 73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void connectionCreated(Connection connection) { 74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen new ServiceDiscoveryManager(connection); 75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen }); 77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen identities.add(new Identity(DEFAULT_IDENTITY_CATEGORY, DEFAULT_IDENTITY_NAME, DEFAULT_IDENTITY_TYPE)); 78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Creates a new ServiceDiscoveryManager for a given Connection. This means that the 82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * service manager will respond to any service discovery request that the connection may 83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * receive. 84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param connection the connection to which a ServiceDiscoveryManager is going to be created. 86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public ServiceDiscoveryManager(Connection connection) { 88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.connection = connection; 89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen init(); 91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the ServiceDiscoveryManager instance associated with a given Connection. 95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param connection the connection used to look for the proper ServiceDiscoveryManager. 97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the ServiceDiscoveryManager associated with a given Connection. 98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static ServiceDiscoveryManager getInstanceFor(Connection connection) { 100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return instances.get(connection); 101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the name of the client that will be returned when asked for the client identity 105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * in a disco request. The name could be any value you need to identity this client. 106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the name of the client that will be returned when asked for the client identity 108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * in a disco request. 109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static String getIdentityName() { 111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverInfo.Identity identity = identities.get(0); 112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (identity != null) { 113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return identity.getName(); 114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else { 115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the name of the client that will be returned when asked for the client identity 121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * in a disco request. The name could be any value you need to identity this client. 122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name the name of the client that will be returned when asked for the client identity 124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * in a disco request. 125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static void setIdentityName(String name) { 127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverInfo.Identity identity = identities.remove(0); 128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen identity = new DiscoverInfo.Identity(DEFAULT_IDENTITY_CATEGORY, name, DEFAULT_IDENTITY_TYPE); 129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen identities.add(identity); 130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the type of client that will be returned when asked for the client identity in a 134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * disco request. The valid types are defined by the category client. Follow this link to learn 135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the possible types: <a href="http://xmpp.org/registrar/disco-categories.html#client">Jabber::Registrar</a>. 136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the type of client that will be returned when asked for the client identity in a 138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * disco request. 139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static String getIdentityType() { 141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverInfo.Identity identity = identities.get(0); 142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (identity != null) { 143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return identity.getType(); 144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else { 145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the type of client that will be returned when asked for the client identity in a 151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * disco request. The valid types are defined by the category client. Follow this link to learn 152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the possible types: <a href="http://xmpp.org/registrar/disco-categories.html#client">Jabber::Registrar</a>. 153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param type the type of client that will be returned when asked for the client identity in a 155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * disco request. 156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static void setIdentityType(String type) { 158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverInfo.Identity identity = identities.get(0); 159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (identity != null) { 160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen identity.setType(type); 161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else { 162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen identity = new DiscoverInfo.Identity(DEFAULT_IDENTITY_CATEGORY, DEFAULT_IDENTITY_NAME, type); 163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen identities.add(identity); 164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns all identities of this client as unmodifiable Collection 169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return 171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static List<DiscoverInfo.Identity> getIdentities() { 173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return Collections.unmodifiableList(identities); 174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Initializes the packet listeners of the connection that will answer to any 178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * service discovery request. 179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private void init() { 181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Register the new instance and associate it with the connection 182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen instances.put(connection, this); 183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen addFeature(DiscoverInfo.NAMESPACE); 185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen addFeature(DiscoverItems.NAMESPACE); 186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add a listener to the connection that removes the registered instance when 188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // the connection is closed 189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.addConnectionListener(new ConnectionListener() { 190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void connectionClosed() { 191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Unregister this instance since the connection has been closed 192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen instances.remove(connection); 193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void connectionClosedOnError(Exception e) { 196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // ignore 197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void reconnectionFailed(Exception e) { 200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // ignore 201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void reconnectingIn(int seconds) { 204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // ignore 205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void reconnectionSuccessful() { 208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // ignore 209d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen }); 211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Listen for disco#items requests and answer with an empty result 213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketFilter packetFilter = new PacketTypeFilter(DiscoverItems.class); 214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketListener packetListener = new PacketListener() { 215d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void processPacket(Packet packet) { 216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverItems discoverItems = (DiscoverItems) packet; 217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Send back the items defined in the client if the request is of type GET 218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (discoverItems != null && discoverItems.getType() == IQ.Type.GET) { 219d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverItems response = new DiscoverItems(); 220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.setType(IQ.Type.RESULT); 221d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.setTo(discoverItems.getFrom()); 222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.setPacketID(discoverItems.getPacketID()); 223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.setNode(discoverItems.getNode()); 224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add the defined items related to the requested node. Look for 226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // the NodeInformationProvider associated with the requested node. 227d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen NodeInformationProvider nodeInformationProvider = 228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen getNodeInformationProvider(discoverItems.getNode()); 229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (nodeInformationProvider != null) { 230d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Specified node was found, add node items 231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.addItems(nodeInformationProvider.getNodeItems()); 232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add packet extensions 233d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.addExtensions(nodeInformationProvider.getNodePacketExtensions()); 234d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if(discoverItems.getNode() != null) { 235d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Return <item-not-found/> error since client doesn't contain 236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // the specified node 237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.setType(IQ.Type.ERROR); 238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.setError(new XMPPError(XMPPError.Condition.item_not_found)); 239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.sendPacket(response); 241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen }; 244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.addPacketListener(packetListener, packetFilter); 245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Listen for disco#info requests and answer the client's supported features 247d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // To add a new feature as supported use the #addFeature message 248d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packetFilter = new PacketTypeFilter(DiscoverInfo.class); 249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packetListener = new PacketListener() { 250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void processPacket(Packet packet) { 251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverInfo discoverInfo = (DiscoverInfo) packet; 252d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Answer the client's supported features if the request is of the GET type 253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (discoverInfo != null && discoverInfo.getType() == IQ.Type.GET) { 254d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverInfo response = new DiscoverInfo(); 255d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.setType(IQ.Type.RESULT); 256d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.setTo(discoverInfo.getFrom()); 257d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.setPacketID(discoverInfo.getPacketID()); 258d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.setNode(discoverInfo.getNode()); 259d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add the client's identity and features only if "node" is null 260d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // and if the request was not send to a node. If Entity Caps are 261d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // enabled the client's identity and features are may also added 262d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // if the right node is chosen 263d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (discoverInfo.getNode() == null) { 264d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen addDiscoverInfoTo(response); 265d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 266d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else { 267d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Disco#info was sent to a node. Check if we have information of the 268d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // specified node 269d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen NodeInformationProvider nodeInformationProvider = 270d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen getNodeInformationProvider(discoverInfo.getNode()); 271d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (nodeInformationProvider != null) { 272d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Node was found. Add node features 273d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.addFeatures(nodeInformationProvider.getNodeFeatures()); 274d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add node identities 275d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.addIdentities(nodeInformationProvider.getNodeIdentities()); 276d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add packet extensions 277d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.addExtensions(nodeInformationProvider.getNodePacketExtensions()); 278d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 279d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else { 280d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Return <item-not-found/> error since specified node was not found 281d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.setType(IQ.Type.ERROR); 282d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.setError(new XMPPError(XMPPError.Condition.item_not_found)); 283d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 284d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 285d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.sendPacket(response); 286d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 287d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 288d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen }; 289d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.addPacketListener(packetListener, packetFilter); 290d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 291d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 292d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 293d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Add discover info response data. 294d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 295d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see <a href="http://xmpp.org/extensions/xep-0030.html#info-basic">XEP-30 Basic Protocol; Example 2</a> 296d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 297d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param response the discover info response packet 298d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 299d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void addDiscoverInfoTo(DiscoverInfo response) { 300d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // First add the identities of the connection 301d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.addIdentities(identities); 302d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 303d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add the registered features to the response 304d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (features) { 305d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (Iterator<String> it = getFeatures(); it.hasNext();) { 306d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.addFeature(it.next()); 307d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 308d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen response.addExtension(extendedInfo); 309d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 310d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 311d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 312d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 313d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the NodeInformationProvider responsible for providing information 314d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * (ie items) related to a given node or <tt>null</null> if none.<p> 315d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 316d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * In MUC, a node could be 'http://jabber.org/protocol/muc#rooms' which means that the 317d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * NodeInformationProvider will provide information about the rooms where the user has joined. 318d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 319d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param node the node that contains items associated with an entity not addressable as a JID. 320d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the NodeInformationProvider responsible for providing information related 321d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * to a given node. 322d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 323d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private NodeInformationProvider getNodeInformationProvider(String node) { 324d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (node == null) { 325d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 326d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 327d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return nodeInformationProviders.get(node); 328d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 329d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 330d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 331d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the NodeInformationProvider responsible for providing information 332d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * (ie items) related to a given node. Every time this client receives a disco request 333d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * regarding the items of a given node, the provider associated to that node will be the 334d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * responsible for providing the requested information.<p> 335d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 336d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * In MUC, a node could be 'http://jabber.org/protocol/muc#rooms' which means that the 337d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * NodeInformationProvider will provide information about the rooms where the user has joined. 338d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 339d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param node the node whose items will be provided by the NodeInformationProvider. 340d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param listener the NodeInformationProvider responsible for providing items related 341d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * to the node. 342d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 343d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void setNodeInformationProvider(String node, NodeInformationProvider listener) { 344d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen nodeInformationProviders.put(node, listener); 345d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 346d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 347d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 348d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Removes the NodeInformationProvider responsible for providing information 349d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * (ie items) related to a given node. This means that no more information will be 350d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * available for the specified node. 351d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 352d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * In MUC, a node could be 'http://jabber.org/protocol/muc#rooms' which means that the 353d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * NodeInformationProvider will provide information about the rooms where the user has joined. 354d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 355d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param node the node to remove the associated NodeInformationProvider. 356d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 357d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void removeNodeInformationProvider(String node) { 358d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen nodeInformationProviders.remove(node); 359d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 360d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 361d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 362d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the supported features by this XMPP entity. 363d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 364d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return an Iterator on the supported features by this XMPP entity. 365d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 366d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Iterator<String> getFeatures() { 367d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (features) { 368d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return Collections.unmodifiableList(new ArrayList<String>(features)).iterator(); 369d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 370d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 371d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 372d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 373d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the supported features by this XMPP entity. 374d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 375d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return a copy of the List on the supported features by this XMPP entity. 376d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 377d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public List<String> getFeaturesList() { 378d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (features) { 379d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return new LinkedList<String>(features); 380d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 381d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 382d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 383d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 384d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Registers that a new feature is supported by this XMPP entity. When this client is 385d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * queried for its information the registered features will be answered.<p> 386d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 387d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Since no packet is actually sent to the server it is safe to perform this operation 388d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * before logging to the server. In fact, you may want to configure the supported features 389d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * before logging to the server so that the information is already available if it is required 390d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * upon login. 391d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 392d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param feature the feature to register as supported. 393d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 394d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void addFeature(String feature) { 395d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (features) { 396d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen features.add(feature); 397d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen renewEntityCapsVersion(); 398d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 399d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 400d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 401d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 402d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Removes the specified feature from the supported features by this XMPP entity.<p> 403d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 404d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Since no packet is actually sent to the server it is safe to perform this operation 405d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * before logging to the server. 406d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 407d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param feature the feature to remove from the supported features. 408d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 409d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void removeFeature(String feature) { 410d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (features) { 411d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen features.remove(feature); 412d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen renewEntityCapsVersion(); 413d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 414d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 415d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 416d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 417d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns true if the specified feature is registered in the ServiceDiscoveryManager. 418d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 419d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param feature the feature to look for. 420d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return a boolean indicating if the specified featured is registered or not. 421d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 422d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean includesFeature(String feature) { 423d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (features) { 424d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return features.contains(feature); 425d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 426d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 427d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 428d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 429d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Registers extended discovery information of this XMPP entity. When this 430d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * client is queried for its information this data form will be returned as 431d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * specified by XEP-0128. 432d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <p> 433d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 434d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Since no packet is actually sent to the server it is safe to perform this 435d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * operation before logging to the server. In fact, you may want to 436d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * configure the extended info before logging to the server so that the 437d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * information is already available if it is required upon login. 438d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 439d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param info 440d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the data form that contains the extend service discovery 441d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * information. 442d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 443d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void setExtendedInfo(DataForm info) { 444d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen extendedInfo = info; 445d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen renewEntityCapsVersion(); 446d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 447d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 448d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 449d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the data form that is set as extended information for this Service Discovery instance (XEP-0128) 450d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 451d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see <a href="http://xmpp.org/extensions/xep-0128.html">XEP-128: Service Discovery Extensions</a> 452d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return 453d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 454d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public DataForm getExtendedInfo() { 455d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return extendedInfo; 456d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 457d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 458d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 459d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the data form as List of PacketExtensions, or null if no data form is set. 460d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * This representation is needed by some classes (e.g. EntityCapsManager, NodeInformationProvider) 461d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 462d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return 463d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 464d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public List<PacketExtension> getExtendedInfoAsList() { 465d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen List<PacketExtension> res = null; 466d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (extendedInfo != null) { 467d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen res = new ArrayList<PacketExtension>(1); 468d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen res.add(extendedInfo); 469d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 470d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return res; 471d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 472d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 473d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 474d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Removes the data form containing extended service discovery information 475d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * from the information returned by this XMPP entity.<p> 476d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 477d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Since no packet is actually sent to the server it is safe to perform this 478d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * operation before logging to the server. 479d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 480d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void removeExtendedInfo() { 481d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen extendedInfo = null; 482d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen renewEntityCapsVersion(); 483d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 484d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 485d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 486d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the discovered information of a given XMPP entity addressed by its JID. 487d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Use null as entityID to query the server 488d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 489d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param entityID the address of the XMPP entity or null. 490d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the discovered information. 491d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException if the operation failed for some reason. 492d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 493d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public DiscoverInfo discoverInfo(String entityID) throws XMPPException { 494d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (entityID == null) 495d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return discoverInfo(null, null); 496d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 497d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Check if the have it cached in the Entity Capabilities Manager 498d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverInfo info = EntityCapsManager.getDiscoverInfoByUser(entityID); 499d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 500d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (info != null) { 501d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // We were able to retrieve the information from Entity Caps and 502d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // avoided a disco request, hurray! 503d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return info; 504d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 505d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 506d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Try to get the newest node#version if it's known, otherwise null is 507d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // returned 508d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen EntityCapsManager.NodeVerHash nvh = EntityCapsManager.getNodeVerHashByJid(entityID); 509d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 510d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Discover by requesting the information from the remote entity 511d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Note that wee need to use NodeVer as argument for Node if it exists 512d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen info = discoverInfo(entityID, nvh != null ? nvh.getNodeVer() : null); 513d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 514d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // If the node version is known, store the new entry. 515d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (nvh != null) { 516d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (EntityCapsManager.verifyDiscoverInfoVersion(nvh.getVer(), nvh.getHash(), info)) 517d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen EntityCapsManager.addDiscoverInfoByNode(nvh.getNodeVer(), info); 518d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 519d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 520d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return info; 521d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 522d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 523d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 524d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the discovered information of a given XMPP entity addressed by its JID and 525d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * note attribute. Use this message only when trying to query information which is not 526d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * directly addressable. 527d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 528d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see <a href="http://xmpp.org/extensions/xep-0030.html#info-basic">XEP-30 Basic Protocol</a> 529d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see <a href="http://xmpp.org/extensions/xep-0030.html#info-nodes">XEP-30 Info Nodes</a> 530d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 531d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param entityID the address of the XMPP entity. 532d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param node the optional attribute that supplements the 'jid' attribute. 533d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the discovered information. 534d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException if the operation failed for some reason. 535d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 536d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public DiscoverInfo discoverInfo(String entityID, String node) throws XMPPException { 537d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Discover the entity's info 538d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverInfo disco = new DiscoverInfo(); 539d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen disco.setType(IQ.Type.GET); 540d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen disco.setTo(entityID); 541d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen disco.setNode(node); 542d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 543d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Create a packet collector to listen for a response. 544d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketCollector collector = 545d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.createPacketCollector(new PacketIDFilter(disco.getPacketID())); 546d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 547d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.sendPacket(disco); 548d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 549d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Wait up to 5 seconds for a result. 550d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); 551d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Stop queuing results 552d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen collector.cancel(); 553d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (result == null) { 554d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException("No response from the server."); 555d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 556d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (result.getType() == IQ.Type.ERROR) { 557d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException(result.getError()); 558d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 559d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return (DiscoverInfo) result; 560d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 561d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 562d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 563d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the discovered items of a given XMPP entity addressed by its JID. 564d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 565d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param entityID the address of the XMPP entity. 566d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the discovered information. 567d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException if the operation failed for some reason. 568d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 569d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public DiscoverItems discoverItems(String entityID) throws XMPPException { 570d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return discoverItems(entityID, null); 571d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 572d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 573d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 574d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the discovered items of a given XMPP entity addressed by its JID and 575d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * note attribute. Use this message only when trying to query information which is not 576d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * directly addressable. 577d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 578d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param entityID the address of the XMPP entity. 579d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param node the optional attribute that supplements the 'jid' attribute. 580d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the discovered items. 581d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException if the operation failed for some reason. 582d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 583d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public DiscoverItems discoverItems(String entityID, String node) throws XMPPException { 584d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Discover the entity's items 585d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverItems disco = new DiscoverItems(); 586d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen disco.setType(IQ.Type.GET); 587d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen disco.setTo(entityID); 588d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen disco.setNode(node); 589d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 590d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Create a packet collector to listen for a response. 591d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketCollector collector = 592d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.createPacketCollector(new PacketIDFilter(disco.getPacketID())); 593d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 594d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.sendPacket(disco); 595d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 596d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Wait up to 5 seconds for a result. 597d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); 598d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Stop queuing results 599d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen collector.cancel(); 600d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (result == null) { 601d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException("No response from the server."); 602d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 603d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (result.getType() == IQ.Type.ERROR) { 604d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException(result.getError()); 605d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 606d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return (DiscoverItems) result; 607d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 608d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 609d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 610d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns true if the server supports publishing of items. A client may wish to publish items 611d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * to the server so that the server can provide items associated to the client. These items will 612d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * be returned by the server whenever the server receives a disco request targeted to the bare 613d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * address of the client (i.e. user@host.com). 614d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 615d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param entityID the address of the XMPP entity. 616d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return true if the server supports publishing of items. 617d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException if the operation failed for some reason. 618d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 619d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean canPublishItems(String entityID) throws XMPPException { 620d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DiscoverInfo info = discoverInfo(entityID); 621d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return canPublishItems(info); 622d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 623d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 624d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 625d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns true if the server supports publishing of items. A client may wish to publish items 626d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * to the server so that the server can provide items associated to the client. These items will 627d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * be returned by the server whenever the server receives a disco request targeted to the bare 628d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * address of the client (i.e. user@host.com). 629d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 630d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param DiscoverInfo the discover info packet to check. 631d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return true if the server supports publishing of items. 632d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 633d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static boolean canPublishItems(DiscoverInfo info) { 634d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return info.containsFeature("http://jabber.org/protocol/disco#publish"); 635d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 636d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 637d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 638d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Publishes new items to a parent entity. The item elements to publish MUST have at least 639d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * a 'jid' attribute specifying the Entity ID of the item, and an action attribute which 640d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * specifies the action being taken for that item. Possible action values are: "update" and 641d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * "remove". 642d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 643d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param entityID the address of the XMPP entity. 644d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param discoverItems the DiscoveryItems to publish. 645d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException if the operation failed for some reason. 646d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 647d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void publishItems(String entityID, DiscoverItems discoverItems) 648d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throws XMPPException { 649d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen publishItems(entityID, null, discoverItems); 650d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 651d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 652d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 653d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Publishes new items to a parent entity and node. The item elements to publish MUST have at 654d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * least a 'jid' attribute specifying the Entity ID of the item, and an action attribute which 655d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * specifies the action being taken for that item. Possible action values are: "update" and 656d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * "remove". 657d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 658d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param entityID the address of the XMPP entity. 659d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param node the attribute that supplements the 'jid' attribute. 660d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param discoverItems the DiscoveryItems to publish. 661d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException if the operation failed for some reason. 662d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 663d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void publishItems(String entityID, String node, DiscoverItems discoverItems) 664d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throws XMPPException { 665d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen discoverItems.setType(IQ.Type.SET); 666d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen discoverItems.setTo(entityID); 667d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen discoverItems.setNode(node); 668d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 669d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Create a packet collector to listen for a response. 670d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketCollector collector = 671d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.createPacketCollector(new PacketIDFilter(discoverItems.getPacketID())); 672d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 673d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.sendPacket(discoverItems); 674d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 675d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Wait up to 5 seconds for a result. 676d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); 677d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Stop queuing results 678d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen collector.cancel(); 679d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (result == null) { 680d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException("No response from the server."); 681d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 682d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (result.getType() == IQ.Type.ERROR) { 683d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException(result.getError()); 684d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 685d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 686d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 687d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 688d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Entity Capabilities 689d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 690d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 691d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 692d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Loads the ServiceDiscoveryManager with an EntityCapsManger 693d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * that speeds up certain lookups 694d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param manager 695d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 696d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void setEntityCapsManager(EntityCapsManager manager) { 697d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen capsManager = manager; 698d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 699d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 700d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 701d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Updates the Entity Capabilities Verification String 702d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * if EntityCaps is enabled 703d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 704d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private void renewEntityCapsVersion() { 705d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (capsManager != null && capsManager.entityCapsEnabled()) 706d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen capsManager.updateLocalEntityCaps(); 707d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 708d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 709