From 6c4a02691eae725acba5167b88d097544116d69e Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 23 Apr 2018 22:00:12 +0200 Subject: [PATCH] Make PubSub's SimplePayload infer the XML Element name and namespace Fixes SMACK-816. --- .../jivesoftware/smack/util/ParserUtils.java | 15 +++++- .../smackx/pubsub/SimplePayload.java | 49 +++++++++++++++++-- .../smackx/pubsub/provider/ItemProvider.java | 2 +- .../smackx/pubsub/ItemValidationTest.java | 2 +- .../smackx/pubsub/SimplePayloadTest.java | 34 +++++++++++++ 5 files changed, 94 insertions(+), 8 deletions(-) create mode 100644 smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/SimplePayloadTest.java diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java index d42dc963a..e48ea0059 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2017 Florian Schmaus + * Copyright © 2014-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. @@ -23,6 +23,9 @@ import java.text.ParseException; import java.util.Date; import java.util.Locale; +import javax.xml.XMLConstants; +import javax.xml.namespace.QName; + import org.jivesoftware.smack.SmackException; import org.jxmpp.jid.EntityBareJid; @@ -250,4 +253,14 @@ public class ParserUtils { public static String getXmlLang(XmlPullParser parser) { return parser.getAttributeValue("http://www.w3.org/XML/1998/namespace", "lang"); } + + public static QName getQName(XmlPullParser parser) { + String elementName = parser.getName(); + String prefix = parser.getPrefix(); + if (prefix == null) { + prefix = XMLConstants.DEFAULT_NS_PREFIX; + } + String namespace = parser.getNamespace(); + return new QName(namespace, elementName, prefix); + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SimplePayload.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SimplePayload.java index 9fc523a37..28433eec0 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SimplePayload.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SimplePayload.java @@ -16,7 +16,17 @@ */ package org.jivesoftware.smackx.pubsub; +import java.io.IOException; + +import javax.xml.namespace.QName; + import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.util.PacketParserUtils; +import org.jivesoftware.smack.util.ParserUtils; +import org.jivesoftware.smack.util.StringUtils; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; /** * The default payload representation for {@link PayloadItem#getPayload()}. It simply @@ -27,7 +37,29 @@ import org.jivesoftware.smack.packet.ExtensionElement; public class SimplePayload implements ExtensionElement { private final String elemName; private final String ns; - private final CharSequence payload; + private final String payload; + + /** + * Construct a SimplePayload object with the specified element name, + * namespace and content. The content must be well formed XML. + * + * @param xmlPayload The payload data + */ + public SimplePayload(String xmlPayload) { + XmlPullParser parser; + try { + parser = PacketParserUtils.getParserFor(xmlPayload); + } + catch (XmlPullParserException | IOException e) { + throw new AssertionError(e); + } + QName qname = ParserUtils.getQName(parser); + + payload = xmlPayload; + + elemName = StringUtils.requireNotNullOrEmpty(qname.getLocalPart(), "Could not determine element name from XML payload"); + ns = StringUtils.requireNotNullOrEmpty(qname.getNamespaceURI(), "Could not determine namespace from XML payload"); + } /** * Construct a SimplePayload object with the specified element name, @@ -36,11 +68,18 @@ public class SimplePayload implements ExtensionElement { * @param elementName The root element name (of the payload) * @param namespace The namespace of the payload, null if there is none * @param xmlPayload The payload data + * @deprecated use {@link #SimplePayload(String)} insteas. */ + // TODO: Remove in Smack 4.5 + @Deprecated public SimplePayload(String elementName, String namespace, CharSequence xmlPayload) { - elemName = elementName; - payload = xmlPayload; - ns = namespace; + this(xmlPayload.toString()); + if (!elementName.equals(this.elemName)) { + throw new IllegalArgumentException(); + } + if (!namespace.equals(this.ns)) { + throw new IllegalArgumentException(); + } } @Override @@ -54,7 +93,7 @@ public class SimplePayload implements ExtensionElement { } @Override - public CharSequence toXML() { + public String toXML() { return payload; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java index 9f2587837..1850a302d 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java @@ -59,7 +59,7 @@ public class ItemProvider extends ExtensionElementProvider { if (extensionProvider == null) { // TODO: Should we use StandardExtensionElement in this case? And probably remove SimplePayload all together. CharSequence payloadText = PacketParserUtils.parseElement(parser, true); - return new PayloadItem<>(itemNamespace, id, node, new SimplePayload(payloadElemName, payloadNS, payloadText)); + return new PayloadItem<>(itemNamespace, id, node, new SimplePayload(payloadText.toString())); } else { return new PayloadItem<>(itemNamespace, id, node, extensionProvider.parse(parser)); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ItemValidationTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ItemValidationTest.java index 735baf8aa..0ada02f3d 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ItemValidationTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ItemValidationTest.java @@ -75,7 +75,7 @@ public class ItemValidationTest extends InitExtensions { @Test public void verifyPayloadItem() throws Exception { - SimplePayload payload = new SimplePayload(null, null, "This is the payload"); + SimplePayload payload = new SimplePayload("This is the payload"); PayloadItem simpleItem = new PayloadItem<>(payload); String simpleCtrl = "" + payload.toXML() + ""; diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/SimplePayloadTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/SimplePayloadTest.java new file mode 100644 index 000000000..2fd7d3c67 --- /dev/null +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/SimplePayloadTest.java @@ -0,0 +1,34 @@ +/** + * + * Copyright 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smackx.pubsub; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class SimplePayloadTest { + + @Test + public void simplePayloadTest() { + String xmlPayload = "Test"; + SimplePayload simplePayload = new SimplePayload(xmlPayload); + + assertEquals("element", simplePayload.getElementName()); + assertEquals("https://example.org", simplePayload.getNamespace()); + assertEquals(xmlPayload, simplePayload.toXML()); + } +}