From c4f86762cb8349ae10e9fc07746bdf19499fdd5d Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 24 Mar 2014 22:31:42 +0100 Subject: [PATCH] Reworked DiscoverInfo and DiscoverItems - Change the return type from Iterator to List - Remove the synchronized blocks --- .../address/MultipleRecipientManager.java | 3 +- .../jivesoftware/smackx/amp/AMPManager.java | 6 +- .../socks5/Socks5BytestreamManager.java | 12 +- .../smackx/caps/EntityCapsManager.java | 8 +- .../smackx/disco/ServiceDiscoveryManager.java | 37 +++--- .../smackx/disco/packet/DiscoverInfo.java | 122 ++++++++---------- .../smackx/disco/packet/DiscoverItems.java | 26 ++-- .../smackx/muc/MultiUserChat.java | 15 +-- .../smackx/offline/OfflineMessageManager.java | 3 +- .../smackx/pubsub/PubSubManager.java | 2 +- .../smackx/search/UserSearchManager.java | 5 +- .../smackx/jingle/nat/RTPBridge.java | 5 +- .../jivesoftware/smackx/jingle/nat/STUN.java | 9 +- 13 files changed, 102 insertions(+), 151 deletions(-) diff --git a/extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java b/extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java index 73774b75c..7597f0493 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java @@ -309,8 +309,7 @@ public class MultipleRecipientManager { // Get the disco items and send the disco packet to each server item DiscoverItems items = ServiceDiscoveryManager.getInstanceFor(connection).discoverItems( serviceName); - for (Iterator it = items.getItems(); it.hasNext();) { - DiscoverItems.Item item = it.next(); + for (DiscoverItems.Item item : items.getItems()) { info = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo( item.getEntityID(), item.getNode()); if (info.containsFeature("http://jabber.org/protocol/address")) { diff --git a/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPManager.java b/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPManager.java index 14bbef280..a1d887400 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/amp/AMPManager.java @@ -25,8 +25,6 @@ import org.jivesoftware.smackx.amp.packet.AMPExtension; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; -import java.util.Iterator; - /** * Manages AMP stanzas within messages. A AMPManager provides a high level access to * get and set AMP rules to messages. @@ -114,9 +112,7 @@ public class AMPManager { private static boolean isFeatureSupportedByServer(XMPPConnection connection, String featureName, String node) throws NoResponseException, XMPPErrorException, NotConnectedException { ServiceDiscoveryManager discoveryManager = ServiceDiscoveryManager.getInstanceFor(connection); DiscoverInfo info = discoveryManager.discoverInfo(connection.getServiceName(), node); - Iterator it = info.getFeatures(); - while (it.hasNext()) { - DiscoverInfo.Feature feature = it.next(); + for (DiscoverInfo.Feature feature : info.getFeatures()){ if (featureName.equals(feature.getVar())) { return true; } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java index 6a51acb4a..7f16950e5 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java @@ -21,7 +21,6 @@ import java.net.Socket; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -559,12 +558,9 @@ public final class Socks5BytestreamManager implements BytestreamManager { // get all items from XMPP server DiscoverItems discoverItems = serviceDiscoveryManager.discoverItems(this.connection.getServiceName()); - Iterator itemIterator = discoverItems.getItems(); // query all items if they are SOCKS5 proxies - while (itemIterator.hasNext()) { - Item item = itemIterator.next(); - + for (Item item : discoverItems.getItems()) { // skip blacklisted servers if (this.proxyBlacklist.contains(item.getEntityID())) { continue; @@ -580,12 +576,8 @@ public final class Socks5BytestreamManager implements BytestreamManager { continue; } - Iterator identities = proxyInfo.getIdentities(); - // item must have category "proxy" and type "bytestream" - while (identities.hasNext()) { - Identity identity = identities.next(); - + for (Identity identity : proxyInfo.getIdentities()) { if ("proxy".equalsIgnoreCase(identity.getCategory()) && "bytestreams".equalsIgnoreCase(identity.getType())) { proxies.add(item.getEntityID()); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java b/extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java index 514c7f086..fad11d8e5 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java @@ -578,8 +578,8 @@ public class EntityCapsManager extends Manager { // type MUST be included. SortedSet sortedIdentities = new TreeSet(); - for (Iterator it = discoverInfo.getIdentities(); it.hasNext();) - sortedIdentities.add(it.next()); + for (DiscoverInfo.Identity i : discoverInfo.getIdentities()) + sortedIdentities.add(i); // 3. For each identity, append the 'category/type/lang/name' to S, // followed by the '<' character. @@ -597,8 +597,8 @@ public class EntityCapsManager extends Manager { // 4. Sort the supported service discovery features. SortedSet features = new TreeSet(); - for (Iterator it = discoverInfo.getFeatures(); it.hasNext();) - features.add(it.next().getVar()); + for (Feature f : discoverInfo.getFeatures()) + features.add(f.getVar()); // 5. For each feature, append the feature to S, followed by the '<' // character diff --git a/extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java b/extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java index 26cd5c95e..8dbe98bfc 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.jivesoftware.smackx.disco; import org.jivesoftware.smack.SmackException.NoResponseException; @@ -220,6 +219,26 @@ public class ServiceDiscoveryManager extends Manager { renewEntityCapsVersion(); } + /** + * Sets the default identity the client will report. + * + * @param identity + */ + public void setIdentity(Identity identity) { + if (identity == null) throw new IllegalArgumentException("Identity can not be null"); + this.identity = identity; + renewEntityCapsVersion(); + } + + /** + * Return the default identity of the client. + * + * @return the default identity. + */ + public Identity getIdentity() { + return identity; + } + /** * Returns the type of client that will be returned when asked for the client identity in a * disco request. The valid types are defined by the category client. Follow this link to learn @@ -233,21 +252,7 @@ public class ServiceDiscoveryManager extends Manager { } /** - * Sets the type of client that will be returned when asked for the client identity in a - * disco request. The valid types are defined by the category client. Follow this link to learn - * the possible types: Jabber::Registrar. - * - * @param type the type of client that will be returned when asked for the client identity in a - * disco request. - */ - @SuppressWarnings("deprecation") - public void setIdentityType(String type) { - identity.setType(type); - renewEntityCapsVersion(); - } - - /** - * Add an identity to the client. + * Add an further identity to the client. * * @param identity */ diff --git a/extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java b/extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java index 910210901..512dfda62 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.jivesoftware.smackx.disco.packet; import org.jivesoftware.smack.packet.IQ; @@ -22,10 +21,8 @@ import org.jivesoftware.smack.util.XmlStringBuilder; import java.util.Collection; import java.util.Collections; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; /** * A DiscoverInfo IQ packet, which is used by XMPP clients to request and receive information @@ -36,12 +33,12 @@ import java.util.concurrent.CopyOnWriteArrayList; * * @author Gaston Dombiak */ -public class DiscoverInfo extends IQ { +public class DiscoverInfo extends IQ implements Cloneable { public static final String NAMESPACE = "http://jabber.org/protocol/disco#info"; - private final List features = new CopyOnWriteArrayList(); - private final List identities = new CopyOnWriteArrayList(); + private final List features = new LinkedList(); + private final List identities = new LinkedList(); private String node; public DiscoverInfo() { @@ -60,17 +57,13 @@ public class DiscoverInfo extends IQ { setNode(d.getNode()); // Copy features - synchronized (d.features) { - for (Feature f : d.features) { - addFeature(f); - } + for (Feature f : d.features) { + addFeature(f.clone()); } // Copy identities - synchronized (d.identities) { - for (Identity i : d.identities) { - addIdentity(i); - } + for (Identity i : d.identities) { + addIdentity(i.clone()); } } @@ -96,20 +89,16 @@ public class DiscoverInfo extends IQ { } private void addFeature(Feature feature) { - synchronized (features) { - features.add(feature); - } + features.add(feature); } /** * Returns the discovered features of an XMPP entity. * - * @return an Iterator on the discovered features of an XMPP entity + * @return an unmodifiable list of the discovered features of an XMPP entity */ - public Iterator getFeatures() { - synchronized (features) { - return Collections.unmodifiableList(features).iterator(); - } + public List getFeatures() { + return Collections.unmodifiableList(features); } /** @@ -118,9 +107,7 @@ public class DiscoverInfo extends IQ { * @param identity the discovered entity's identity */ public void addIdentity(Identity identity) { - synchronized (identities) { - identities.add(identity); - } + identities.add(identity); } /** @@ -130,20 +117,16 @@ public class DiscoverInfo extends IQ { */ public void addIdentities(Collection identitiesToAdd) { if (identitiesToAdd == null) return; - synchronized (identities) { - identities.addAll(identitiesToAdd); - } + identities.addAll(identitiesToAdd); } /** * Returns the discovered identities of an XMPP entity. * - * @return an Iterator on the discoveted identities + * @return an unmodifiable list of the discovered identities */ - public Iterator getIdentities() { - synchronized (identities) { - return Collections.unmodifiableList(identities).iterator(); - } + public List getIdentities() { + return Collections.unmodifiableList(identities); } /** @@ -179,8 +162,8 @@ public class DiscoverInfo extends IQ { * @return true if the requestes feature has been discovered */ public boolean containsFeature(String feature) { - for (Iterator it = getFeatures(); it.hasNext();) { - if (feature.equals(it.next().getVar())) + for (Feature f : getFeatures()) { + if (feature.equals(f.getVar())) return true; } return false; @@ -193,15 +176,11 @@ public class DiscoverInfo extends IQ { xml.xmlnsAttribute(NAMESPACE); xml.optAttribute("node", getNode()); xml.rightAngelBracket(); - synchronized (identities) { - for (Identity identity : identities) { - xml.append(identity.toXML()); - } + for (Identity identity : identities) { + xml.append(identity.toXML()); } - synchronized (features) { - for (Feature feature : features) { - xml.append(feature.toXML()); - } + for (Feature feature : features) { + xml.append(feature.toXML()); } // Add packet extensions, if any are defined. xml.append(getExtensionsXML()); @@ -243,6 +222,11 @@ public class DiscoverInfo extends IQ { return false; } + @Override + public DiscoverInfo clone() { + return new DiscoverInfo(this); + } + /** * Represents the identity of a given XMPP entity. An entity may have many identities but all * the identities SHOULD have the same name.

@@ -252,25 +236,18 @@ public class DiscoverInfo extends IQ { * attributes. * */ - public static class Identity implements Comparable { + public static class Identity implements Comparable, Cloneable { - private String category; + private final String category; private String name; - private String type; + private final String type; private String lang; // 'xml:lang; - /** - * Creates a new identity for an XMPP entity. - * - * @param category the entity's category. - * @param name the entity's name. - * @deprecated As per the spec, the type field is mandatory and the 3 argument constructor should be used instead. - */ - public Identity(String category, String name) { - this.category = category; - this.name = name; + public Identity(Identity identity) { + this(identity.category, identity.name, identity.type); + lang = identity.lang; } - + /** * Creates a new identity for an XMPP entity. * 'category' and 'type' are required by @@ -327,17 +304,6 @@ public class DiscoverInfo extends IQ { return type; } - /** - * Sets the entity's type. To get the official registry of values for the - * 'type' attribute refer to Jabber::Registrar - * - * @param type the identity's type. - * @deprecated As per the spec, this field is mandatory and the 3 argument constructor should be used instead. - */ - public void setType(String type) { - this.type = type; - } - /** * Sets the natural language (xml:lang) for this identity (optional) * @@ -403,7 +369,7 @@ public class DiscoverInfo extends IQ { return true; } - + @Override public int hashCode() { int result = 1; @@ -447,6 +413,11 @@ public class DiscoverInfo extends IQ { return category.compareTo(other.category); } } + + @Override + public Identity clone() { + return new Identity(this); + } } /** @@ -455,9 +426,13 @@ public class DiscoverInfo extends IQ { * as well as specific feature types of interest, if any (e.g., for the purpose of feature * negotiation). */ - public static class Feature { + public static class Feature implements Cloneable { - private String variable; + private final String variable; + + public Feature(Feature feature) { + this.variable = feature.variable; + } /** * Creates a new feature offered by an XMPP entity or item. @@ -503,5 +478,10 @@ public class DiscoverInfo extends IQ { public int hashCode() { return 37 * variable.hashCode(); } + + @Override + public Feature clone() { + return new Feature(this); + } } } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverItems.java b/extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverItems.java index 48b5219bf..2edbc613b 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverItems.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverItems.java @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.jivesoftware.smackx.disco.packet; import org.jivesoftware.smack.packet.IQ; @@ -22,9 +21,8 @@ import org.jivesoftware.smack.util.XmlStringBuilder; import java.util.Collection; import java.util.Collections; -import java.util.Iterator; +import java.util.LinkedList; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; /** * A DiscoverItems IQ packet, which is used by XMPP clients to request and receive items @@ -39,7 +37,7 @@ public class DiscoverItems extends IQ { public static final String NAMESPACE = "http://jabber.org/protocol/disco#items"; - private final List items = new CopyOnWriteArrayList(); + private final List items = new LinkedList(); private String node; /** @@ -48,9 +46,7 @@ public class DiscoverItems extends IQ { * @param item the discovered entity's item */ public void addItem(Item item) { - synchronized (items) { - items.add(item); - } + items.add(item); } /** @@ -65,15 +61,14 @@ public class DiscoverItems extends IQ { } } + /** * Returns the discovered items of the queried XMPP entity. * - * @return an Iterator on the discovered entity's items + * @return an unmodifiable list of the discovered entity's items */ - public Iterator getItems() { - synchronized (items) { - return Collections.unmodifiableList(items).iterator(); - } + public List getItems() { + return Collections.unmodifiableList(items); } /** @@ -109,11 +104,10 @@ public class DiscoverItems extends IQ { xml.optAttribute("node", getNode()); xml.rightAngelBracket(); - synchronized (items) { - for (Item item : items) { - xml.append(item.toXML()); - } + for (Item item : items) { + xml.append(item.toXML()); } + xml.closeElement("query"); return xml; } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 363910961..83e3c2ad5 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -225,8 +225,8 @@ public class MultiUserChat { DiscoverItems result = ServiceDiscoveryManager.getInstanceFor(connection).discoverItems( user, discoNode); // Collect the entityID for each returned item - for (Iterator items = result.getItems(); items.hasNext();) { - answer.add(items.next().getEntityID()); + for (DiscoverItems.Item item : result.getItems()) { + answer.add(item.getEntityID()); } return answer.iterator(); } @@ -262,8 +262,7 @@ public class MultiUserChat { final List answer = new ArrayList(); ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection); DiscoverItems items = discoManager.discoverItems(connection.getServiceName()); - for (Iterator it = items.getItems(); it.hasNext();) { - DiscoverItems.Item item = it.next(); + for (DiscoverItems.Item item : items.getItems()) { DiscoverInfo info = discoManager.discoverInfo(item.getEntityID()); if (info.containsFeature(discoNamespace)) { answer.add(item.getEntityID()); @@ -289,8 +288,8 @@ public class MultiUserChat { List answer = new ArrayList(); ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(connection); DiscoverItems items = discoManager.discoverItems(serviceName); - for (Iterator it = items.getItems(); it.hasNext();) { - answer.add(new HostedRoom(it.next())); + for (DiscoverItems.Item item : items.getItems()) { + answer.add(new HostedRoom(item)); } return answer; } @@ -885,9 +884,7 @@ public class MultiUserChat { room, "x-roomuser-item"); // Look for an Identity that holds the reserved nickname and return its name - for (Iterator identities = result.getIdentities(); - identities.hasNext();) { - DiscoverInfo.Identity identity = identities.next(); + for (DiscoverInfo.Identity identity : result.getIdentities()) { return identity.getName(); } } diff --git a/extensions/src/main/java/org/jivesoftware/smackx/offline/OfflineMessageManager.java b/extensions/src/main/java/org/jivesoftware/smackx/offline/OfflineMessageManager.java index dd1fa93bc..c08676bdc 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/offline/OfflineMessageManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/offline/OfflineMessageManager.java @@ -121,8 +121,7 @@ public class OfflineMessageManager { List answer = new ArrayList(); DiscoverItems items = ServiceDiscoveryManager.getInstanceFor(connection).discoverItems( null, namespace); - for (Iterator it = items.getItems(); it.hasNext();) { - DiscoverItems.Item item = it.next(); + for (DiscoverItems.Item item : items.getItems()) { answer.add(new OfflineMessageHeader(item)); } return answer.iterator(); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java b/extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java index 6af3e7b8b..c528cce81 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java @@ -171,7 +171,7 @@ final public class PubSubManager DiscoverInfo infoReply = (DiscoverInfo) con.createPacketCollectorAndSend(info).nextResultOrThrow(); - if (infoReply.getIdentities().next().getType().equals(NodeType.leaf.toString())) + if (infoReply.getIdentities().get(0).getType().equals(NodeType.leaf.toString())) node = new LeafNode(con, id); else node = new CollectionNode(con, id); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/search/UserSearchManager.java b/extensions/src/main/java/org/jivesoftware/smackx/search/UserSearchManager.java index 9084c6299..5714b4fe3 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/search/UserSearchManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/search/UserSearchManager.java @@ -28,7 +28,6 @@ import org.jivesoftware.smackx.xdata.Form; import java.util.ArrayList; import java.util.Collection; -import java.util.Iterator; import java.util.List; /** @@ -105,9 +104,7 @@ public class UserSearchManager { final List searchServices = new ArrayList(); ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(con); DiscoverItems items = discoManager.discoverItems(con.getServiceName()); - Iterator iter = items.getItems(); - while (iter.hasNext()) { - DiscoverItems.Item item = iter.next(); + for (DiscoverItems.Item item : items.getItems()) { try { DiscoverInfo info; try { diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/RTPBridge.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/RTPBridge.java index 8dada09f2..f120d7c97 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/RTPBridge.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/RTPBridge.java @@ -21,7 +21,6 @@ import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Enumeration; -import java.util.Iterator; import java.util.logging.Logger; import org.jivesoftware.smack.SmackException.NoResponseException; @@ -435,9 +434,7 @@ public class RTPBridge extends IQ { // } DiscoverInfo discoInfo = disco.discoverInfo(connection.getServiceName()); - Iterator iter = discoInfo.getIdentities(); - while (iter.hasNext()) { - DiscoverInfo.Identity identity = iter.next(); + for (DiscoverInfo.Identity identity : discoInfo.getIdentities()) { if ((identity.getName() != null) && (identity.getName().startsWith("rtpbridge"))) { return true; } diff --git a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUN.java b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUN.java index 6fc6c6131..9768d2af8 100644 --- a/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUN.java +++ b/jingle/src/main/java/org/jivesoftware/smackx/jingle/nat/STUN.java @@ -17,7 +17,6 @@ package org.jivesoftware.smackx.jingle.nat; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; import java.util.logging.Logger; @@ -222,14 +221,10 @@ public class STUN extends IQ { ServiceDiscoveryManager disco = ServiceDiscoveryManager.getInstanceFor(connection); DiscoverItems items = disco.discoverItems(connection.getServiceName()); - Iterator iter = items.getItems(); - while (iter.hasNext()) { - DiscoverItems.Item item = iter.next(); + for (DiscoverItems.Item item : items.getItems()) { DiscoverInfo info = disco.discoverInfo(item.getEntityID()); - Iterator iter2 = info.getIdentities(); - while (iter2.hasNext()) { - DiscoverInfo.Identity identity = iter2.next(); + for (DiscoverInfo.Identity identity : info.getIdentities()) { if (identity.getCategory().equals("proxy") && identity.getType().equals("stun")) if (info.containsFeature(NAMESPACE)) return true;