/** * Discover node information in standard {@link DiscoverInfo} format. * * @return The discovery information about the node. * @throws XMPPErrorException * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException */ public DiscoverInfo discoverInfo() throws NoResponseException, XMPPErrorException, NotConnectedException { DiscoverInfo info = new DiscoverInfo(); info.setTo(to); info.setNode(getId()); return (DiscoverInfo) con.createPacketCollectorAndSend(info).nextResultOrThrow(); }
/** * Returns true if XMPP Carbons are supported by the server. * * @return true if supported */ public boolean isSupportedByServer() { Connection connection = weakRefConnection.get(); try { DiscoverInfo result = ServiceDiscoveryManager.getInstanceFor(connection) .discoverInfo(connection.getServiceName()); return result.containsFeature(CarbonExtension.NAMESPACE); } catch (XMPPException e) { return false; } }
/** * The workgroup service may be configured to send email. This queries the Workgroup Service to * see if the email service has been configured and is available. * * @return true if the email service is available, otherwise return false. */ public boolean isEmailAvailable() { ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection); try { String workgroupService = StringUtils.parseServer(workgroupJID); DiscoverInfo infoResult = discoManager.discoverInfo(workgroupService); return infoResult.containsFeature("jive:email:provider"); } catch (XMPPException e) { return false; } }
/** * Add discover info response data. * * @see <a href="http://xmpp.org/extensions/xep-0030.html#info-basic">XEP-30 Basic Protocol; * Example 2</a> * @param response the discover info response packet */ public void addDiscoverInfoTo(DiscoverInfo response) { // First add the identities of the connection response.addIdentities(getIdentities()); // Add the registered features to the response synchronized (features) { for (Iterator<String> it = getFeatures(); it.hasNext(); ) { response.addFeature(it.next()); } response.addExtension(extendedInfo); } }
/** * 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 XMPPErrorException if the operation failed for some reason. * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException */ public DiscoverInfo discoverInfo(String entityID, String node) throws NoResponseException, XMPPErrorException, NotConnectedException { // Discover the entity's info DiscoverInfo disco = new DiscoverInfo(); disco.setType(IQ.Type.get); disco.setTo(entityID); disco.setNode(node); Packet result = connection().createPacketCollectorAndSend(disco).nextResultOrThrow(); return (DiscoverInfo) result; }
/** * Add discover info response data. * * @see <a href="http://xmpp.org/extensions/xep-0030.html#info-basic">XEP-30 Basic Protocol; * Example 2</a> * @param response the discover info response packet */ public void addDiscoverInfoTo(DiscoverInfo response) { // First add the identities of the connection response.addIdentities(getIdentities()); // Add the registered features to the response synchronized (features) { for (String feature : getFeatures()) { response.addFeature(feature); } response.addExtension(extendedInfo); } }
/** * 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 { Connection connection = ServiceDiscoveryManager.this.connection.get(); if (connection == null) throw new XMPPException("Connection instance already gc'ed"); // Discover the entity's info DiscoverInfo disco = new DiscoverInfo(); disco.setType(IQ.Type.GET); disco.setTo(entityID); disco.setNode(node); Packet result = connection.createPacketCollectorAndSend(disco).nextResultOrThrow(); return (DiscoverInfo) result; }
@Test(expected = SmackException.class) public void getConfigFormWithTimeout() throws XMPPException, SmackException { ThreadedDummyConnection con = new ThreadedDummyConnection(); PubSubManager mgr = new PubSubManager(con); DiscoverInfo info = new DiscoverInfo(); Identity ident = new Identity("pubsub", null, "leaf"); info.addIdentity(ident); con.addIQReply(info); Node node = mgr.getNode("princely_musings"); SmackConfiguration.setDefaultPacketReplyTimeout(100); con.setTimeout(); node.getNodeConfiguration(); }
/** * Returns the address of the multiple recipients service. To obtain such address service * discovery is going to be used on the connected server and if none was found then another * attempt will be tried on the server items. The discovered information is going to be cached for * 24 hours. * * @param connection the connection to use for disco. The connected server is going to be queried. * @return the address of the multiple recipients service or <tt>null</tt> if none was found. */ private static String getMultipleRecipienServiceAddress(Connection connection) { String serviceName = connection.getServiceName(); String serviceAddress = (String) services.get(serviceName); if (serviceAddress == null) { synchronized (services) { serviceAddress = (String) services.get(serviceName); if (serviceAddress == null) { // Send the disco packet to the server itself try { DiscoverInfo info = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(serviceName); // Check if the server supports JEP-33 if (info.containsFeature("http://jabber.org/protocol/address")) { serviceAddress = serviceName; } else { // Get the disco items and send the disco packet to each server item DiscoverItems items = ServiceDiscoveryManager.getInstanceFor(connection).discoverItems(serviceName); for (Iterator<DiscoverItems.Item> it = items.getItems(); it.hasNext(); ) { DiscoverItems.Item item = it.next(); info = ServiceDiscoveryManager.getInstanceFor(connection) .discoverInfo(item.getEntityID(), item.getNode()); if (info.containsFeature("http://jabber.org/protocol/address")) { serviceAddress = serviceName; break; } } } // Cache the discovered information services.put(serviceName, serviceAddress == null ? "" : serviceAddress); } catch (XMPPException e) { LOGGER.log(Level.SEVERE, "Error occurred retrieving multiple recipients service", e); } } } } return "".equals(serviceAddress) ? null : serviceAddress; }
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()); } }
@Test public void getConfigFormWithInsufficientPriviliges() throws XMPPException, SmackException, IOException, InterruptedException { ThreadedDummyConnection con = ThreadedDummyConnection.newInstance(); PubSubManager mgr = new PubSubManager(con, PubSubManagerTest.DUMMY_PUBSUB_SERVICE); DiscoverInfo info = new DiscoverInfo(); Identity ident = new Identity("pubsub", null, "leaf"); info.addIdentity(ident); con.addIQReply(info); Node node = mgr.getNode("princely_musings"); PubSub errorIq = new PubSub(); XMPPError error = new XMPPError(Condition.forbidden); errorIq.setError(error); con.addIQReply(errorIq); try { node.getNodeConfiguration(); } catch (XMPPErrorException e) { Assert.assertEquals(XMPPError.Type.AUTH, e.getXMPPError().getType()); } }
/** * Copy constructor. * * @param d */ public DiscoverInfo(DiscoverInfo d) { super(d); // Set node setNode(d.getNode()); // Copy features for (Feature f : d.features) { addFeature(f.clone()); } // Copy identities for (Identity i : d.identities) { addIdentity(i.clone()); } }
/** * Returns true if the server supports publishing of items. A client may wish to publish items to * the server so that the server can provide items associated to the client. These items will be * returned by the server whenever the server receives a disco request targeted to the bare * address of the client (i.e. [email protected]). * * @param DiscoverInfo the discover info packet to check. * @return true if the server supports publishing of items. */ public static boolean canPublishItems(DiscoverInfo info) { return info.containsFeature("http://jabber.org/protocol/disco#publish"); }
/** * Find all services under the users service that provide a given feature. * * @param feature the feature to search for * @param stopOnFirst if true, stop searching after the first service was found * @param useCache if true, query a cache first to avoid network I/O * @return a possible empty list of services providing the given feature * @throws NoResponseException * @throws XMPPErrorException * @throws NotConnectedException */ public List<String> findServices(String feature, boolean stopOnFirst, boolean useCache) throws NoResponseException, XMPPErrorException, NotConnectedException { List<String> serviceAddresses = null; String serviceName = connection().getServiceName(); if (useCache) { serviceAddresses = (List<String>) services.get(feature); if (serviceAddresses != null) { return serviceAddresses; } } serviceAddresses = new LinkedList<String>(); // Send the disco packet to the server itself DiscoverInfo info; try { info = discoverInfo(serviceName); } catch (XMPPErrorException e) { // Be extra robust here: Return the empty linked list and log this situation LOGGER.log(Level.WARNING, "Could not discover information about service", e); return serviceAddresses; } // Check if the server supports XEP-33 if (info.containsFeature(feature)) { serviceAddresses.add(serviceName); if (stopOnFirst) { if (useCache) { // Cache the discovered information services.put(feature, serviceAddresses); } return serviceAddresses; } } DiscoverItems items; try { // Get the disco items and send the disco packet to each server item items = discoverItems(serviceName); } catch (XMPPErrorException e) { LOGGER.log(Level.WARNING, "Could not discover items about service", e); return serviceAddresses; } for (DiscoverItems.Item item : items.getItems()) { try { // TODO is it OK here in all cases to query without the node attribute? // MultipleRecipientManager queried initially also with the node attribute, but this // could be simply a fault instead of intentional. info = discoverInfo(item.getEntityID()); } catch (XMPPErrorException | NoResponseException e) { // Don't throw this exceptions if one of the server's items fail LOGGER.log( Level.WARNING, "Exception while discovering info for feature " + feature + " of " + item.getEntityID() + " node: " + item.getNode(), e); continue; } if (info.containsFeature(feature)) { serviceAddresses.add(item.getEntityID()); if (stopOnFirst) { break; } } } if (useCache) { // Cache the discovered information services.put(feature, serviceAddresses); } return serviceAddresses; }
/** * Queries the remote entity for it's features and returns true if the given feature is found. * * @param jid the JID of the remote entity * @param feature * @return true if the entity supports the feature, false otherwise * @throws XMPPErrorException * @throws NoResponseException * @throws NotConnectedException */ public boolean supportsFeature(String jid, String feature) throws NoResponseException, XMPPErrorException, NotConnectedException { DiscoverInfo result = discoverInfo(jid); return result.containsFeature(feature); }