From 98708d67a2e1ba30200a2076d0be93388d570cf0 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 21 Feb 2018 19:55:01 +0100 Subject: [PATCH] Make ServiceDiscoveryManager.findService() consider all services with the same matching feature announced. Consider for example PubSub where usually the service itself announces the PubSub feature as part of PEP, and where an additional PubSub component exists. The old logic will just lookup the first matching service with a PubSub feature announcement and check if for a matching identiy. If we look for a real PubSub service, but stumble first over user's service with PEP, then findService() will return 'null' although there would have been a valid PubSub service. Fixes SMACK-805. --- .../smackx/disco/ServiceDiscoveryManager.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java index 0b861eaf1..e4dc18f3c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software. + * Copyright 2003-2007 Jive Software, 2018 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,6 +43,7 @@ import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.util.Objects; +import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.caps.EntityCapsManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; @@ -66,6 +67,7 @@ import org.jxmpp.util.cache.ExpirationCache; * * * @author Gaston Dombiak + * @author Florian Schmaus */ public final class ServiceDiscoveryManager extends Manager { @@ -875,20 +877,26 @@ public final class ServiceDiscoveryManager extends Manager { public DomainBareJid findService(String feature, boolean useCache, String category, String type) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - List services = findServicesDiscoverInfo(feature, true, useCache); + boolean noCategory = StringUtils.isNullOrEmpty(category); + boolean noType = StringUtils.isNullOrEmpty(type); + if (noType != noCategory) { + throw new IllegalArgumentException("Must specify either both, category and type, or none"); + } + + List services = findServicesDiscoverInfo(feature, false, useCache); if (services.isEmpty()) { return null; } - DiscoverInfo info = services.get(0); - if (category != null && type != null) { - if (!info.hasIdentity(category, type)) { - return null; + + if (!noCategory && !noType) { + for (DiscoverInfo info : services) { + if (info.hasIdentity(category, type)) { + return info.getFrom().asDomainBareJid(); + } } } - else if (category != null || type != null) { - throw new IllegalArgumentException("Must specify either both, category and type, or none"); - } - return info.getFrom().asDomainBareJid(); + + return services.get(0).getFrom().asDomainBareJid(); } public DomainBareJid findService(String feature, boolean useCache) throws NoResponseException,