Use QName instead of XmppStringUtils.generateKey()

This commit is contained in:
Florian Schmaus 2019-06-11 00:10:38 +02:00
parent 7d59df9eed
commit 6e1193edaf
8 changed files with 80 additions and 61 deletions

View File

@ -239,7 +239,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
protected final Lock connectionLock = new ReentrantLock();
protected final Map<String, FullyQualifiedElement> streamFeatures = new HashMap<>();
protected final Map<QName, FullyQualifiedElement> streamFeatures = new HashMap<>();
/**
* The full JID of the authenticated user, as returned by the resource binding response of the server.
@ -389,8 +389,8 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
protected Exception currentConnectionException;
private final Map<String, IQRequestHandler> setIqRequestHandler = new HashMap<>();
private final Map<String, IQRequestHandler> getIqRequestHandler = new HashMap<>();
private final Map<QName, IQRequestHandler> setIqRequestHandler = new HashMap<>();
private final Map<QName, IQRequestHandler> getIqRequestHandler = new HashMap<>();
/**
* Create a new XMPPConnection to an XMPP server.
@ -1303,7 +1303,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
final IQ iq = (IQ) packet;
if (iq.isRequestIQ()) {
final IQ iqRequest = iq;
final String key = XmppStringUtils.generateKey(iq.getChildElementName(), iq.getChildElementNamespace());
final QName key = iqRequest.getChildElementQName();
IQRequestHandler iqRequestHandler;
final IQ.Type type = iq.getType();
switch (type) {
@ -1694,7 +1694,8 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
@SuppressWarnings("unchecked")
@Override
public <F extends FullyQualifiedElement> F getFeature(String element, String namespace) {
return (F) streamFeatures.get(XmppStringUtils.generateKey(element, namespace));
QName qname = new QName(namespace, element);
return (F) streamFeatures.get(qname);
}
@Override
@ -1703,7 +1704,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
}
protected void addStreamFeature(FullyQualifiedElement feature) {
String key = XmppStringUtils.generateKey(feature.getElementName(), feature.getNamespace());
QName key = feature.getQName();
streamFeatures.put(key, feature);
}
@ -1812,7 +1813,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
@Override
public IQRequestHandler registerIQRequestHandler(final IQRequestHandler iqRequestHandler) {
final String key = XmppStringUtils.generateKey(iqRequestHandler.getElement(), iqRequestHandler.getNamespace());
final QName key = iqRequestHandler.getQName();
switch (iqRequestHandler.getType()) {
case set:
synchronized (setIqRequestHandler) {
@ -1835,7 +1836,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
@Override
public IQRequestHandler unregisterIQRequestHandler(String element, String namespace, IQ.Type type) {
final String key = XmppStringUtils.generateKey(element, namespace);
final QName key = new QName(namespace, element);
switch (type) {
case set:
synchronized (setIqRequestHandler) {

View File

@ -1,6 +1,6 @@
/**
*
* Copyright 2015 Florian Schmaus
* Copyright 2015-2019 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,6 +16,8 @@
*/
package org.jivesoftware.smack.iqrequest;
import javax.xml.namespace.QName;
import org.jivesoftware.smack.packet.IQ;
/**
@ -50,4 +52,8 @@ public interface IQRequestHandler {
String getElement();
String getNamespace();
default QName getQName() {
return new QName(getNamespace(), getElement());
}
}

View File

@ -20,6 +20,8 @@ package org.jivesoftware.smack.packet;
import java.util.List;
import java.util.Locale;
import javax.xml.namespace.QName;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smack.util.XmlStringBuilder;
@ -46,6 +48,7 @@ public abstract class IQ extends Stanza {
public static final String IQ_ELEMENT = "iq";
public static final String QUERY_ELEMENT = "query";
private final QName childElementQName;
private final String childElementName;
private final String childElementNamespace;
@ -56,6 +59,7 @@ public abstract class IQ extends Stanza {
type = iq.getType();
this.childElementName = iq.childElementName;
this.childElementNamespace = iq.childElementNamespace;
this.childElementQName = iq.childElementQName;
}
protected IQ(String childElementName) {
@ -65,6 +69,11 @@ public abstract class IQ extends Stanza {
protected IQ(String childElementName, String childElementNamespace) {
this.childElementName = childElementName;
this.childElementNamespace = childElementNamespace;
if (childElementName == null) {
childElementQName = null;
} else {
childElementQName = new QName(childElementNamespace, childElementName);
}
}
/**
@ -115,6 +124,10 @@ public abstract class IQ extends Stanza {
return !isRequestIQ();
}
public final QName getChildElementQName() {
return childElementQName;
}
public final String getChildElementName() {
return childElementName;
}

View File

@ -1,6 +1,6 @@
/**
*
* Copyright 2015 Florian Schmaus.
* Copyright 2015-2019 Florian Schmaus.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,13 +21,13 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;
import org.jivesoftware.smack.util.MultiMap;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jxmpp.util.XmppStringUtils;
/**
* An {@link ExtensionElement} modeling the often required and used XML features when using XMPP. It
* is therefore suitable for most use cases. Use
@ -47,7 +47,7 @@ public final class StandardExtensionElement implements ExtensionElement {
private final String namespace;
private final Map<String, String> attributes;
private final String text;
private final MultiMap<String, StandardExtensionElement> elements;
private final MultiMap<QName, StandardExtensionElement> elements;
private XmlStringBuilder xmlCache;
@ -65,7 +65,7 @@ public final class StandardExtensionElement implements ExtensionElement {
}
private StandardExtensionElement(String name, String namespace, Map<String, String> attributes, String text,
MultiMap<String, StandardExtensionElement> elements) {
MultiMap<QName, StandardExtensionElement> elements) {
this.name = StringUtils.requireNotNullNorEmpty(name, "Name must not be null nor empty");
this.namespace = StringUtils.requireNotNullNorEmpty(namespace, "Namespace must not be null nor empty");
if (attributes == null) {
@ -100,7 +100,7 @@ public final class StandardExtensionElement implements ExtensionElement {
if (elements == null) {
return null;
}
String key = XmppStringUtils.generateKey(element, namespace);
QName key = new QName(namespace, element);
return elements.getFirst(key);
}
@ -112,7 +112,7 @@ public final class StandardExtensionElement implements ExtensionElement {
if (elements == null) {
return null;
}
String key = XmppStringUtils.generateKey(element, namespace);
QName key = new QName(namespace, element);
return elements.getAll(key);
}
@ -145,7 +145,7 @@ public final class StandardExtensionElement implements ExtensionElement {
xml.optEscape(text);
if (elements != null) {
for (Map.Entry<String, StandardExtensionElement> entry : elements.entrySet()) {
for (Map.Entry<QName, StandardExtensionElement> entry : elements.entrySet()) {
xml.append(entry.getValue().toXML(getNamespace()));
}
}
@ -165,7 +165,7 @@ public final class StandardExtensionElement implements ExtensionElement {
private Map<String, String> attributes;
private String text;
private MultiMap<String, StandardExtensionElement> elements;
private MultiMap<QName, StandardExtensionElement> elements;
private Builder(String name, String namespace) {
this.name = name;
@ -200,7 +200,8 @@ public final class StandardExtensionElement implements ExtensionElement {
if (elements == null) {
elements = new MultiMap<>();
}
String key = XmppStringUtils.generateKey(element.getElementName(), element.getNamespace());
QName key = element.getQName();
elements.put(key, element);
return this;
}

View File

@ -23,6 +23,8 @@ import java.util.Collection;
import java.util.List;
import java.util.Locale;
import javax.xml.namespace.QName;
import org.jivesoftware.smack.packet.id.StanzaIdUtil;
import org.jivesoftware.smack.util.MultiMap;
import org.jivesoftware.smack.util.PacketUtil;
@ -31,7 +33,6 @@ import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;
import org.jxmpp.util.XmppStringUtils;
/**
* Base class for XMPP Stanzas, which are called Stanza in older versions of Smack (i.e. &lt; 4.1).
@ -56,7 +57,7 @@ public abstract class Stanza implements TopLevelStreamElement {
protected static final String DEFAULT_LANGUAGE =
java.util.Locale.getDefault().getLanguage().toLowerCase(Locale.US);
private final MultiMap<String, ExtensionElement> packetExtensions = new MultiMap<>();
private final MultiMap<QName, ExtensionElement> extensionElements = new MultiMap<>();
private String id = null;
private Jid to;
@ -306,9 +307,9 @@ public abstract class Stanza implements TopLevelStreamElement {
* @return a list of all extension elements of this stanza.
*/
public List<ExtensionElement> getExtensions() {
synchronized (packetExtensions) {
synchronized (extensionElements) {
// No need to create a new list, values() will already create a new one for us
return packetExtensions.values();
return extensionElements.values();
}
}
@ -326,8 +327,8 @@ public abstract class Stanza implements TopLevelStreamElement {
public List<ExtensionElement> getExtensions(String elementName, String namespace) {
requireNotNullNorEmpty(elementName, "elementName must not be null nor empty");
requireNotNullNorEmpty(namespace, "namespace must not be null nor empty");
String key = XmppStringUtils.generateKey(elementName, namespace);
return packetExtensions.getAll(key);
QName key = new QName(namespace, elementName);
return extensionElements.getAll(key);
}
/**
@ -359,10 +360,10 @@ public abstract class Stanza implements TopLevelStreamElement {
if (namespace == null) {
return null;
}
String key = XmppStringUtils.generateKey(elementName, namespace);
QName key = new QName(namespace, elementName);
ExtensionElement packetExtension;
synchronized (packetExtensions) {
packetExtension = packetExtensions.getFirst(key);
synchronized (extensionElements) {
packetExtension = extensionElements.getFirst(key);
}
if (packetExtension == null) {
return null;
@ -377,9 +378,9 @@ public abstract class Stanza implements TopLevelStreamElement {
*/
public void addExtension(ExtensionElement extension) {
if (extension == null) return;
String key = XmppStringUtils.generateKey(extension.getElementName(), extension.getNamespace());
synchronized (packetExtensions) {
packetExtensions.put(key, extension);
QName key = extension.getQName();
synchronized (extensionElements) {
extensionElements.put(key, extension);
}
}
@ -393,7 +394,7 @@ public abstract class Stanza implements TopLevelStreamElement {
*/
public ExtensionElement overrideExtension(ExtensionElement extension) {
if (extension == null) return null;
synchronized (packetExtensions) {
synchronized (extensionElements) {
// Note that we need to use removeExtension(String, String) here. If would use
// removeExtension(ExtensionElement) then we would remove based on the equality of ExtensionElement, which
// is not what we want in this case.
@ -429,9 +430,9 @@ public abstract class Stanza implements TopLevelStreamElement {
if (elementName == null) {
return hasExtension(namespace);
}
String key = XmppStringUtils.generateKey(elementName, namespace);
synchronized (packetExtensions) {
return packetExtensions.containsKey(key);
QName key = new QName(namespace, elementName);
synchronized (extensionElements) {
return extensionElements.containsKey(key);
}
}
@ -442,8 +443,8 @@ public abstract class Stanza implements TopLevelStreamElement {
* @return true if a stanza extension exists, false otherwise.
*/
public boolean hasExtension(String namespace) {
synchronized (packetExtensions) {
for (ExtensionElement packetExtension : packetExtensions.values()) {
synchronized (extensionElements) {
for (ExtensionElement packetExtension : extensionElements.values()) {
if (packetExtension.getNamespace().equals(namespace)) {
return true;
}
@ -460,9 +461,9 @@ public abstract class Stanza implements TopLevelStreamElement {
* @return the removed stanza extension or null.
*/
public ExtensionElement removeExtension(String elementName, String namespace) {
String key = XmppStringUtils.generateKey(elementName, namespace);
synchronized (packetExtensions) {
return packetExtensions.remove(key);
QName key = new QName(namespace, elementName);
synchronized (extensionElements) {
return extensionElements.remove(key);
}
}
@ -473,9 +474,9 @@ public abstract class Stanza implements TopLevelStreamElement {
* @return the removed stanza extension or null.
*/
public ExtensionElement removeExtension(ExtensionElement extension) {
String key = XmppStringUtils.generateKey(extension.getElementName(), extension.getNamespace());
synchronized (packetExtensions) {
List<ExtensionElement> list = packetExtensions.getAll(key);
QName key = extension.getQName();
synchronized (extensionElements) {
List<ExtensionElement> list = extensionElements.getAll(key);
boolean removed = list.remove(extension);
if (removed) {
return extension;

View File

@ -1,6 +1,6 @@
/**
*
* Copyright © 2014 Florian Schmaus
* Copyright © 2014-2019 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,7 +19,7 @@ package org.jivesoftware.smack.packet;
public class TestIQ extends SimpleIQ {
public TestIQ() {
this(null, null);
this("https://igniterealtime.org/projects/smack", "test-iq");
}
public TestIQ(String element, String namespace) {

View File

@ -18,10 +18,12 @@
package org.jivesoftware.smackx.iqprivate;
import java.io.IOException;
import java.util.Hashtable;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
import javax.xml.namespace.QName;
import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
@ -39,8 +41,6 @@ import org.jivesoftware.smackx.iqprivate.packet.PrivateData;
import org.jivesoftware.smackx.iqprivate.packet.PrivateDataIQ;
import org.jivesoftware.smackx.iqprivate.provider.PrivateDataProvider;
import org.jxmpp.util.XmppStringUtils;
/**
* Manages private data, which is a mechanism to allow users to store arbitrary XML
* data on an XMPP server. Each private data chunk is defined by a element name and
@ -77,7 +77,7 @@ public final class PrivateDataManager extends Manager {
/**
* Map of provider instances.
*/
private static final Map<String, PrivateDataProvider> privateDataProviders = new Hashtable<>();
private static final Map<QName, PrivateDataProvider> privateDataProviders = new HashMap<>();
/**
* Returns the private data provider registered to the specified XML element name and namespace.
@ -102,7 +102,7 @@ public final class PrivateDataManager extends Manager {
* @return the PrivateData provider.
*/
public static PrivateDataProvider getPrivateDataProvider(String elementName, String namespace) {
String key = XmppStringUtils.generateKey(elementName, namespace);
QName key = new QName(namespace, elementName);
return privateDataProviders.get(key);
}
@ -116,7 +116,7 @@ public final class PrivateDataManager extends Manager {
*/
public static void addPrivateDataProvider(String elementName, String namespace,
PrivateDataProvider provider) {
String key = XmppStringUtils.generateKey(elementName, namespace);
QName key = new QName(namespace, elementName);
privateDataProviders.put(key, provider);
}
@ -127,7 +127,7 @@ public final class PrivateDataManager extends Manager {
* @param namespace The XML namespace.
*/
public static void removePrivateDataProvider(String elementName, String namespace) {
String key = XmppStringUtils.generateKey(elementName, namespace);
QName key = new QName(namespace, elementName);
privateDataProviders.remove(key);
}

View File

@ -16,8 +16,6 @@
*/
package org.jivesoftware.smackx.ox.element;
import static org.jivesoftware.smack.util.StringUtils.requireNotNullNorEmpty;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
@ -26,6 +24,8 @@ import java.util.Date;
import java.util.List;
import java.util.Set;
import javax.xml.namespace.QName;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.util.MultiMap;
import org.jivesoftware.smack.util.Objects;
@ -34,7 +34,6 @@ import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jxmpp.jid.Jid;
import org.jxmpp.util.XmppDateTime;
import org.jxmpp.util.XmppStringUtils;
/**
* This class describes an OpenPGP content element. It defines the elements and fields that OpenPGP content elements
@ -50,7 +49,7 @@ public abstract class OpenPgpContentElement implements ExtensionElement {
private final Set<? extends Jid> to;
private final Date timestamp;
private final MultiMap<String, ExtensionElement> payload;
private final MultiMap<QName, ExtensionElement> payload;
private String timestampString;
@ -59,7 +58,7 @@ public abstract class OpenPgpContentElement implements ExtensionElement {
this.timestamp = Objects.requireNonNull(timestamp);
this.payload = new MultiMap<>();
for (ExtensionElement e : payload) {
this.payload.put(XmppStringUtils.generateKey(e.getElementName(), e.getNamespace()), e);
this.payload.put(e.getQName(), e);
}
}
@ -104,9 +103,7 @@ public abstract class OpenPgpContentElement implements ExtensionElement {
* @return a set of all matching extensions.
*/
public List<ExtensionElement> getExtensions(String elementName, String namespace) {
requireNotNullNorEmpty(elementName, "elementName must not be null or empty");
requireNotNullNorEmpty(namespace, "namespace must not be null or empty");
String key = XmppStringUtils.generateKey(elementName, namespace);
QName key = new QName(namespace, elementName);
return payload.getAll(key);
}
@ -139,7 +136,7 @@ public abstract class OpenPgpContentElement implements ExtensionElement {
if (namespace == null) {
return null;
}
String key = XmppStringUtils.generateKey(elementName, namespace);
QName key = new QName(namespace, elementName);
ExtensionElement packetExtension;
synchronized (payload) {
packetExtension = payload.getFirst(key);