/** * Tests that IQ packets can be sent to/from room occupants. This case will try to discover * information about other room occupants. */ public void testPrivateIQ() { try { // User2 joins the new room MultiUserChat muc2 = new MultiUserChat(getConnection(1), room); muc2.join("testbot2"); // User2 discovers information about User1 DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(getConnection(1)) .discoverInfo(room + "/testbot", null); assertNotNull("No info was discovered from room occupant", info); assertEquals("Wrong IQ type", IQ.Type.result, info.getType()); assertEquals("Wrong IQ sender", room + "/testbot", info.getFrom()); // User2 leaves the room muc2.leave(); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } }
public void testEntityCaps() throws XMPPException, InterruptedException { dropWholeEntityCapsCache(); sdm1.addFeature(DISCOVER_TEST_FEATURE); Thread.sleep(3000); DiscoverInfo info = sdm0.discoverInfo(con1.getUser()); assertTrue(info.containsFeature(DISCOVER_TEST_FEATURE)); String u1ver = EntityCapsManager.getNodeVersionByJid(con1.getUser()); assertNotNull(u1ver); DiscoverInfo entityInfo = EntityCapsManager.caps.get(u1ver); assertNotNull(entityInfo); assertEquals(info.toXML(), entityInfo.toXML()); }
/** * Tests info discovery of a Smack client. */ public void testSmackInfo() { ServiceDiscoveryManager discoManager = ServiceDiscoveryManager .getInstanceFor(getConnection(0)); try { // Discover the information of another Smack client DiscoverInfo info = discoManager.discoverInfo(getFullJID(1)); // Check the identity of the Smack client Iterator<Identity> identities = info.getIdentities(); assertTrue("No identities were found", identities.hasNext()); Identity identity = identities.next(); assertEquals("Name in identity is wrong", discoManager.getIdentityName(), identity.getName()); assertEquals("Category in identity is wrong", "client", identity.getCategory()); assertEquals("Type in identity is wrong", discoManager.getIdentityType(), identity.getType()); assertFalse("More identities were found", identities.hasNext()); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } }
/** * Returns a collection with the XMPP addresses of the Multi-User Chat services. * * @param connection the XMPP connection to use for discovering Multi-User Chat services. * @return a collection with the XMPP addresses of the Multi-User Chat services. * @throws XMPPException if an error occured while trying to discover MUC services. */ public static Collection<String> getServiceNames(Connection connection) throws XMPPException { final List<String> answer = new ArrayList<String>(); ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection); DiscoverItems items = discoManager.discoverItems(connection.getServiceName()); for (Iterator<DiscoverItems.Item> it = items.getItems(); it.hasNext();) { DiscoverItems.Item item = it.next(); try { DiscoverInfo info = discoManager.discoverInfo(item.getEntityID()); if (info.containsFeature("http://jabber.org/protocol/muc")) { answer.add(item.getEntityID()); } } catch (XMPPException e) { // Trouble finding info in some cases. This is a workaround for // discovering info on remote servers. } } return answer; }
/** * Returns the reserved room nickname for the user in the room. A user may have a reserved * nickname, for example through explicit room registration or database integration. In such * cases it may be desirable for the user to discover the reserved nickname before attempting * to enter the room. * * @return the reserved room nickname or <tt>null</tt> if none. */ public String getReservedNickname() { try { DiscoverInfo result = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo( room, "x-roomuser-item"); // Look for an Identity that holds the reserved nickname and return its name for (Iterator<DiscoverInfo.Identity> identities = result.getIdentities(); identities.hasNext();) { DiscoverInfo.Identity identity = identities.next(); return identity.getName(); } // If no Identity was found then the user does not have a reserved room nickname return null; } catch (XMPPException e) { e.printStackTrace(); return null; } }
RoomInfo(DiscoverInfo info) { super(); this.room = info.getFrom(); // Get the information based on the discovered features this.membersOnly = info.containsFeature("muc_membersonly"); this.moderated = info.containsFeature("muc_moderated"); this.nonanonymous = info.containsFeature("muc_nonanonymous"); this.passwordProtected = info.containsFeature("muc_passwordprotected"); this.persistent = info.containsFeature("muc_persistent"); // Get the information based on the discovered extended information Form form = Form.getFormFrom(info); if (form != null) { this.description = form.getField("muc#roominfo_description").getValues().next(); Iterator<String> values = form.getField("muc#roominfo_subject").getValues(); if (values.hasNext()) { this.subject = values.next(); } else { this.subject = ""; } this.occupantsCount = Integer.parseInt(form.getField("muc#roominfo_occupants").getValues() .next()); } }
/** * Retrieves the requested node, if it exists. It will throw an * exception if it does not. * * @param id - The unique id of the node * @return the node * @throws XMPPException The node does not exist */ public Node getNode(String id) throws XMPPException { Node node = nodeMap.get(id); if (node == null) { DiscoverInfo info = new DiscoverInfo(); info.setTo(to); info.setNode(id); DiscoverInfo infoReply = (DiscoverInfo)SyncPacketSend.getReply(con, info); if (infoReply.getIdentities().next().getType().equals(NodeType.leaf.toString())) node = new LeafNode(con, id); else node = new CollectionNode(con, id); node.setTo(to); nodeMap.put(id, node); } return node; }
/** * Returns the discovered information of a given XMPP entity addressed by its JID and * note attribute. Use this message only when trying to query information which is not * directly addressable. * * @param entityID the address of the XMPP entity. * @param node the attribute that supplements the 'jid' attribute. * @return the discovered information. * @throws XMPPException if the operation failed for some reason. */ public DiscoverInfo discoverInfo(String entityID, String node) throws XMPPException { // Discover the entity's info DiscoverInfo disco = new DiscoverInfo(); disco.setType(IQ.Type.GET); disco.setTo(entityID); disco.setNode(node); // Create a packet collector to listen for a response. PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(disco.getPacketID())); connection.sendPacket(disco); // Wait up to 5 seconds for a result. IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); // Stop queuing results collector.cancel(); if (result == null) { throw new XMPPException("No response from the server."); } if (result.getType() == IQ.Type.ERROR) { throw new XMPPException(result.getError()); } return (DiscoverInfo) result; }
RoomInfo(DiscoverInfo info) { super(); this.room = info.getFrom(); // Get the information based on the discovered features this.membersOnly = info.containsFeature("muc_membersonly"); this.moderated = info.containsFeature("muc_moderated"); this.nonanonymous = info.containsFeature("muc_nonanonymous"); this.passwordProtected = info.containsFeature("muc_passwordprotected"); this.persistent = info.containsFeature("muc_persistent"); // Get the information based on the discovered extended information Form form = Form.getFormFrom(info); if (form != null) { FormField descField = form.getField("muc#roominfo_description"); this.description = ( descField == null || !(descField.getValues().hasNext()) )? "" : descField.getValues().next(); FormField subjField = form.getField("muc#roominfo_subject"); this.subject = ( subjField == null || !(subjField.getValues().hasNext()) ) ? "" : subjField.getValues().next(); FormField occCountField = form.getField("muc#roominfo_occupants"); this.occupantsCount = occCountField == null ? -1 : Integer.parseInt(occCountField.getValues() .next()); } }
/** * Retrieves the requested node, if it exists. It will throw an * exception if it does not. * * @param id - The unique id of the node * @return the node * @throws XMPPException The node does not exist */ public <T extends Node> T getNode(String id) throws XMPPException { Node node = nodeMap.get(id); if (node == null) { DiscoverInfo info = new DiscoverInfo(); info.setTo(to); info.setNode(id); DiscoverInfo infoReply = (DiscoverInfo)SyncPacketSend.getReply(con, info); if (infoReply.getIdentities().next().getType().equals(NodeType.leaf.toString())) node = new LeafNode(con, id); else node = new CollectionNode(con, id); node.setTo(to); nodeMap.put(id, node); } return (T) node; }
/** * Verify DisoverInfo and Caps Node as defined in XEP-0115 5.4 Processing * Method * * @see <a href="http://xmpp.org/extensions/xep-0115.html#ver-proc">XEP-0115 * 5.4 Processing Method</a> * * @param capsNode * the caps node (i.e. node#ver) * @param info * @return true if it's valid and should be cache, false if not */ public static boolean verifyDiscoverInfoVersion(String ver, String hash, DiscoverInfo info) { // step 3.3 check for duplicate identities if (info.containsDuplicateIdentities()) return false; // step 3.4 check for duplicate features if (info.containsDuplicateFeatures()) return false; // step 3.5 check for well-formed packet extensions if (verifyPacketExtensions(info)) return false; String calculatedVer = generateVerificationString(info, hash); if (!ver.equals(calculatedVer)) return false; return true; }
/** * * @param info * @return true if the packet extensions is ill-formed */ protected static boolean verifyPacketExtensions(DiscoverInfo info) { List<FormField> foundFormTypes = new LinkedList<FormField>(); for (Iterator<PacketExtension> i = info.getExtensions().iterator(); i.hasNext();) { PacketExtension pe = i.next(); if (pe.getNamespace().equals(Form.NAMESPACE)) { DataForm df = (DataForm) pe; for (Iterator<FormField> it = df.getFields(); it.hasNext();) { FormField f = it.next(); if (f.getVariable().equals("FORM_TYPE")) { for (FormField fft : foundFormTypes) { if (f.equals(fft)) return true; } foundFormTypes.add(f); } } } } return false; }
/** * Discovers {@link DiscoveryInfo} and {@link DiscoveryInfo.Identity} of a gateway * and creates a {@link Gateway} object representing this gateway. * @param itemJID * @throws XMPPException */ private void discoverGateway(String itemJID) throws XMPPException{ DiscoverInfo info = sdManager.discoverInfo(itemJID); Iterator<Identity> i = info.getIdentities(); while(i.hasNext()){ Identity identity = i.next(); String category = identity.getCategory(); if(category.toLowerCase().equals("gateway")){ gateways.put(itemJID, new Gateway(connection,itemJID)); if(itemJID.contains(connection.getHost())){ localGateways.put(itemJID, new Gateway(connection,itemJID,info,identity)); } else{ nonLocalGateways.put(itemJID, new Gateway(connection,itemJID,info,identity)); } break; } } }
/** * Returns a collection with the XMPP addresses of the Multi-User Chat * services. * * @param connection * the XMPP connection to use for discovering Multi-User Chat * services. * @return a collection with the XMPP addresses of the Multi-User Chat * services. * @throws XMPPException * if an error occured while trying to discover MUC services. */ public static Collection<String> getServiceNames(Connection connection) throws XMPPException { final List<String> answer = new ArrayList<String>(); ServiceDiscoveryManager discoManager = ServiceDiscoveryManager .getInstanceFor(connection); DiscoverItems items = discoManager.discoverItems(connection .getServiceName()); for (Iterator<DiscoverItems.Item> it = items.getItems(); it.hasNext();) { DiscoverItems.Item item = it.next(); try { DiscoverInfo info = discoManager.discoverInfo(item .getEntityID()); if (info.containsFeature("http://jabber.org/protocol/muc")) { answer.add(item.getEntityID()); } } catch (XMPPException e) { // Trouble finding info in some cases. This is a workaround for // discovering info on remote servers. } } return answer; }
/** * Returns the reserved room nickname for the user in the room. A user may * have a reserved nickname, for example through explicit room registration * or database integration. In such cases it may be desirable for the user * to discover the reserved nickname before attempting to enter the room. * * @return the reserved room nickname or <tt>null</tt> if none. */ public String getReservedNickname() { try { DiscoverInfo result = ServiceDiscoveryManager.getInstanceFor( connection).discoverInfo(room, "x-roomuser-item"); // Look for an Identity that holds the reserved nickname and return // its name for (Iterator<DiscoverInfo.Identity> identities = result .getIdentities(); identities.hasNext();) { DiscoverInfo.Identity identity = identities.next(); return identity.getName(); } // If no Identity was found then the user does not have a reserved // room nickname return null; } catch (XMPPException e) { e.printStackTrace(); return null; } }
RoomInfo(DiscoverInfo info) { super(); this.room = info.getFrom(); // Get the information based on the discovered features this.membersOnly = info.containsFeature("muc_membersonly"); this.moderated = info.containsFeature("muc_moderated"); this.nonanonymous = info.containsFeature("muc_nonanonymous"); this.passwordProtected = info.containsFeature("muc_passwordprotected"); this.persistent = info.containsFeature("muc_persistent"); // Get the information based on the discovered extended information Form form = Form.getFormFrom(info); if (form != null) { FormField descField = form.getField("muc#roominfo_description"); this.description = (descField == null || !(descField.getValues() .hasNext())) ? "" : descField.getValues().next(); FormField subjField = form.getField("muc#roominfo_subject"); this.subject = (subjField == null || !(subjField.getValues() .hasNext())) ? "" : subjField.getValues().next(); FormField occCountField = form.getField("muc#roominfo_occupants"); this.occupantsCount = occCountField == null ? -1 : Integer .parseInt(occCountField.getValues().next()); } }
/** * Retrieves the requested node, if it exists. It will throw an exception if * it does not. * * @param id * - The unique id of the node * @return the node * @throws XMPPException * The node does not exist */ public Node getNode(String id) throws XMPPException { Node node = nodeMap.get(id); if (node == null) { DiscoverInfo info = new DiscoverInfo(); info.setTo(to); info.setNode(id); DiscoverInfo infoReply = (DiscoverInfo) SyncPacketSend.getReply( con, info); if (infoReply.getIdentities().next().getType() .equals(NodeType.leaf.toString())) node = new LeafNode(con, id); else node = new CollectionNode(con, id); node.setTo(to); nodeMap.put(id, node); } return node; }
/** * Add discover info response data. * * @param response * the discover info response packet */ public void addDiscoverInfoTo(DiscoverInfo response) { // Set this client identity DiscoverInfo.Identity identity = new DiscoverInfo.Identity("client", getIdentityName()); identity.setType(getIdentityType()); response.addIdentity(identity); // Add the registered features to the response synchronized (features) { for (Iterator<String> it = getFeatures(); it.hasNext();) { response.addFeature(it.next()); } if (extendedInfo != null) { response.addExtension(extendedInfo); } } }
/** * Discovers {@link DiscoveryInfo} and {@link DiscoveryInfo.Identity} of a * gateway and creates a {@link Gateway} object representing this gateway. * * @param itemJID * @throws XMPPException */ private void discoverGateway(String itemJID) throws XMPPException { DiscoverInfo info = sdManager.discoverInfo(itemJID); Iterator<Identity> i = info.getIdentities(); while (i.hasNext()) { Identity identity = i.next(); String category = identity.getCategory(); if (category.toLowerCase().equals("gateway")) { gateways.put(itemJID, new Gateway(connection, itemJID)); if (itemJID.contains(connection.getHost())) { localGateways.put(itemJID, new Gateway(connection, itemJID, info, identity)); } else { nonLocalGateways.put(itemJID, new Gateway(connection, itemJID, info, identity)); } break; } } }
/** * Retrieves the configuration of the space. * @param space The space to get the configuration for. * @return The parsed result or, if there was an error, null. * @throws SpaceManagementException Thrown when no response was received from the server. */ private SpaceConfiguration getSpaceConfiguration(Space space) throws SpaceManagementException{ if (space == null){ throw new IllegalArgumentException("The given space must not be null"); } ServiceDiscoveryManager discoveryManager = ServiceDiscoveryManager.getInstanceFor(connection); DiscoverInfo info; try { info = discoveryManager.discoverInfo(SERVICE_PREFIX + space.getDomain(), space.getId()); } catch (XMPPException e) { if (e.getXMPPError().getCode() == 404) { return null; } else { throw new SpaceManagementException("The Server didn't respond.", Type.OTHER, e); } } Element config = parsePacketToElement(info); return parseSpaceConfiguration(config); }
/** * Returns the discovered information of a given XMPP entity addressed by its JID and * note attribute. Use this message only when trying to query information which is not * directly addressable. * * @see <a href="http://xmpp.org/extensions/xep-0030.html#info-basic">XEP-30 Basic Protocol</a> * @see <a href="http://xmpp.org/extensions/xep-0030.html#info-nodes">XEP-30 Info Nodes</a> * * @param entityID the address of the XMPP entity. * @param node the optional attribute that supplements the 'jid' attribute. * @return the discovered information. * @throws XMPPException if the operation failed for some reason. */ public DiscoverInfo discoverInfo(String entityID, String node) throws XMPPException { // Discover the entity's info DiscoverInfo disco = new DiscoverInfo(); disco.setType(IQ.Type.GET); disco.setTo(entityID); disco.setNode(node); // Create a packet collector to listen for a response. PacketCollector collector = connection.createPacketCollector(new PacketIDFilter(disco.getPacketID())); connection.sendPacket(disco); // Wait up to 5 seconds for a result. IQ result = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); // Stop queuing results collector.cancel(); if (result == null) { throw new XMPPException("No response from the server."); } if (result.getType() == IQ.Type.ERROR) { throw new XMPPException(result.getError()); } return (DiscoverInfo) result; }
/** * Checks if the user is registered with a gateway. * * @param con the XMPPConnection. * @param transport the transport. * @return true if the user is registered with the transport. */ public static boolean isRegistered(XMPPConnection con, Transport transport) { if (!con.isConnected()) { return false; } ServiceDiscoveryManager discoveryManager = ServiceDiscoveryManager.getInstanceFor(con); try { DiscoverInfo info = discoveryManager.discoverInfo(transport.getServiceName()); return info.containsFeature("jabber:iq:registered"); } catch (XMPPException e) { Log.error(e); } return false; }
private Collection<String> getConferenceServices(String server) throws Exception { List<String> answer = new ArrayList<String>(); ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(SparkManager.getConnection()); DiscoverItems items = discoManager.discoverItems(server); for (Iterator<DiscoverItems.Item> it = items.getItems(); it.hasNext();) { DiscoverItems.Item item = (DiscoverItems.Item)it.next(); if (item.getEntityID().startsWith("conference") || item.getEntityID().startsWith("private")) { answer.add(item.getEntityID()); } else { try { DiscoverInfo info = discoManager.discoverInfo(item.getEntityID()); if (info.containsFeature("http://jabber.org/protocol/muc")) { answer.add(item.getEntityID()); } } catch (XMPPException e) { Log.error("Problem when loading conference service.", e); } } } return answer; }
/** * Discover the features provided by the server. */ private void discoverServerFeatures() { try { // jid et server ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(mAdaptee); DiscoverInfo info = sdm.discoverInfo(mAdaptee.getServiceName()); Iterator<DiscoverInfo.Identity> it = info.getIdentities(); while (it.hasNext()) { DiscoverInfo.Identity identity = it.next(); if ("pubsub".equals(identity.getCategory()) && "pep".equals(identity.getType())) { initPEP(); } } } catch (XMPPException e) { Log.w(TAG, "Unable to discover server features", e); } }
/** * Tests info discovery of a Smack client. */ public void testSmackInfo() { ServiceDiscoveryManager discoManager = ServiceDiscoveryManager .getInstanceFor(getConnection(0)); try { // Discover the information of another Smack client DiscoverInfo info = discoManager.discoverInfo(getFullJID(1)); // Check the identity of the Smack client Iterator<Identity> identities = info.getIdentities(); assertTrue("No identities were found", identities.hasNext()); Identity identity = identities.next(); assertEquals("Name in identity is wrong", ServiceDiscoveryManager.getIdentityName(), identity.getName()); assertEquals("Category in identity is wrong", "client", identity.getCategory()); assertEquals("Type in identity is wrong", ServiceDiscoveryManager.getIdentityType(), identity.getType()); assertFalse("More identities were found", identities.hasNext()); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } }
/** * Add discover info response data. * * @param response the discover info response packet */ public void addDiscoverInfoTo(DiscoverInfo response) { // Set this client identity DiscoverInfo.Identity identity = new DiscoverInfo.Identity("client", getIdentityName()); identity.setType(getIdentityType()); response.addIdentity(identity); // Add the registered features to the response synchronized (features) { // Add Entity Capabilities (XEP-0115) feature node. response.addFeature("http://jabber.org/protocol/caps"); for (Iterator<String> it = getFeatures(); it.hasNext();) { response.addFeature(it.next()); } if (extendedInfo != null) { response.addExtension(extendedInfo); } } }