diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java index 55c07e07a..0f7ebe138 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java @@ -16,6 +16,8 @@ */ package org.jivesoftware.smack.util; +import java.util.Collection; + import org.jivesoftware.smack.packet.Element; import org.jivesoftware.smack.packet.NamedElement; import org.jivesoftware.smack.packet.PacketExtension; @@ -272,6 +274,13 @@ public class XmlStringBuilder implements Appendable, CharSequence { return this; } + public XmlStringBuilder append(Collection elements) { + for (Element element : elements) { + append(element.toXML()); + } + return this; + } + public XmlStringBuilder emptyElement(Enum element) { return emptyElement(element.name()); } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/AbstractHttpOverXmppProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/AbstractHttpOverXmppProvider.java index fcfcac495..6079256c1 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/AbstractHttpOverXmppProvider.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/AbstractHttpOverXmppProvider.java @@ -21,15 +21,12 @@ import org.jivesoftware.smack.packet.NamedElement; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.hoxt.packet.AbstractHttpOverXmpp; -import org.jivesoftware.smackx.shim.packet.Header; import org.jivesoftware.smackx.shim.packet.HeadersExtension; -import org.jivesoftware.smackx.shim.provider.HeaderProvider; +import org.jivesoftware.smackx.shim.provider.HeadersProvider; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; -import java.util.HashSet; -import java.util.Set; /** * Abstract parent for Req and Resp packet providers. @@ -39,8 +36,6 @@ import java.util.Set; */ public abstract class AbstractHttpOverXmppProvider extends IQProvider { - private static final String ELEMENT_HEADERS = "headers"; - private static final String ELEMENT_HEADER = "header"; private static final String ELEMENT_DATA = "data"; private static final String ELEMENT_TEXT = "text"; private static final String ELEMENT_BASE_64 = "base64"; @@ -71,8 +66,8 @@ public abstract class AbstractHttpOverXmppProvider set = new HashSet
(); - boolean done = false; - - while (!done) { - int eventType = parser.next(); - - if (eventType == XmlPullParser.START_TAG) { - if (parser.getName().equals(ELEMENT_HEADER)) { - Header header = provider.parse(parser); - set.add(header); - } - } else if (eventType == XmlPullParser.END_TAG) { - if (parser.getName().equals(ELEMENT_HEADERS)) { - done = true; - } - } - } - return new HeadersExtension(set); - } - private AbstractHttpOverXmpp.Data parseData(XmlPullParser parser) throws XmlPullParserException, IOException { NamedElement child = null; boolean done = false; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/packet/Header.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/packet/Header.java index cf343bfca..41840ef26 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/packet/Header.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/packet/Header.java @@ -16,47 +16,50 @@ */ package org.jivesoftware.smackx.shim.packet; +import org.jivesoftware.smack.packet.NamedElement; import org.jivesoftware.smack.packet.PacketExtension; +import org.jivesoftware.smack.util.XmlStringBuilder; /** * Represents a Header entry as specified by the Stanza Headers and Internet Metadata (SHIM) * @author Robin Collier */ -public class Header implements PacketExtension -{ - private String name; - private String value; - - public Header(String name, String value) - { - this.name = name; - this.value = value; - } - - public String getName() - { - return name; - } +public class Header implements PacketExtension { + public static final String ELEMENT = "header"; - public String getValue() - { - return value; - } + private final String name; + private final String value; - public String getElementName() - { - return "header"; - } + public Header(String name, String value) { + this.name = name; + this.value = value; + } - public String getNamespace() - { - return HeadersExtension.NAMESPACE; - } + public String getName() { + return name; + } - public String toXML() - { - return "
" + value + "
"; - } + public String getValue() { + return value; + } + public String getElementName() { + return ELEMENT; + } + + public String getNamespace() { + return HeadersExtension.NAMESPACE; + } + + @Override + public XmlStringBuilder toXML() { + // Upcast to NamedElement since we don't want a xmlns attribute + XmlStringBuilder xml = new XmlStringBuilder((NamedElement) this); + xml.attribute("name", name); + xml.rightAngleBracket(); + xml.escape(value); + xml.closeElement(this); + return xml; + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/packet/HeadersExtension.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/packet/HeadersExtension.java index a7d2d53ad..66e900b77 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/packet/HeadersExtension.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/packet/HeadersExtension.java @@ -16,10 +16,12 @@ */ package org.jivesoftware.smackx.shim.packet; -import java.util.Collection; import java.util.Collections; +import java.util.List; +import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.PacketExtension; +import org.jivesoftware.smack.util.XmlStringBuilder; /** * Extension representing a list of headers as specified in Stanza Headers and Internet Metadata (SHIM) @@ -28,44 +30,48 @@ import org.jivesoftware.smack.packet.PacketExtension; * * @author Robin Collier */ -public class HeadersExtension implements PacketExtension -{ - public static final String NAMESPACE = "http://jabber.org/protocol/shim"; - - private Collection
headers = Collections.emptyList(); - - public HeadersExtension(Collection
headerList) - { - if (headerList != null) - headers = headerList; - } - - public Collection
getHeaders() - { - return headers; - } +public class HeadersExtension implements PacketExtension { + public static final String ELEMENT = "headers"; + public static final String NAMESPACE = "http://jabber.org/protocol/shim"; - public String getElementName() - { - return "headers"; - } + private final List
headers; - public String getNamespace() - { - return NAMESPACE; - } + public HeadersExtension(List
headerList) { + if (headerList != null) { + headers = Collections.unmodifiableList(headerList); + } else { + headers = Collections.emptyList(); + } + } - public String toXML() - { - StringBuilder builder = new StringBuilder("<" + getElementName() + " xmlns='" + getNamespace() + "'>"); - - for (Header header : headers) - { - builder.append(header.toXML()); - } - builder.append("'); + public List
getHeaders() { + return headers; + } - return builder.toString(); - } + public String getElementName() { + return ELEMENT; + } + public String getNamespace() { + return NAMESPACE; + } + + @Override + public XmlStringBuilder toXML() { + XmlStringBuilder xml = new XmlStringBuilder(this); + xml.rightAngleBracket(); + xml.append(headers); + xml.closeElement(this); + return xml; + } + + /** + * Return the SHIM headers extension of this stanza or null if there is none. + * + * @param packet + * @return the headers extension or null. + */ + public static HeadersExtension from(Packet packet) { + return packet.getExtension(ELEMENT, NAMESPACE); + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/provider/HeaderProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/provider/HeaderProvider.java index d039f2b9b..f43b8f846 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/provider/HeaderProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/provider/HeaderProvider.java @@ -28,23 +28,23 @@ import org.xmlpull.v1.XmlPullParserException; * * @author Robin Collier */ -public class HeaderProvider extends PacketExtensionProvider
-{ +public class HeaderProvider extends PacketExtensionProvider
{ @Override - public Header parse(XmlPullParser parser, int initialDepth) - throws XmlPullParserException, IOException { - String name = parser.getAttributeValue(null, "name"); - String value = null; - - parser.next(); - - if (parser.getEventType() == XmlPullParser.TEXT) - value = parser.getText(); - - while(parser.getEventType() != XmlPullParser.END_TAG) - parser.next(); - - return new Header(name, value); - } + public Header parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException { + String name = parser.getAttributeValue(null, "name"); + String value = null; + + parser.next(); + + if (parser.getEventType() == XmlPullParser.TEXT) { + value = parser.getText(); + } + + while (parser.getEventType() != XmlPullParser.END_TAG) { + parser.next(); + } + + return new Header(name, value); + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/provider/HeadersProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/provider/HeadersProvider.java index 494648750..a1ca25a78 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/provider/HeadersProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/shim/provider/HeadersProvider.java @@ -16,7 +16,6 @@ */ package org.jivesoftware.smackx.shim.provider; -import java.util.Collection; import java.util.List; import java.util.Map; @@ -30,13 +29,14 @@ import org.jivesoftware.smackx.shim.packet.HeadersExtension; * * @author Robin Collier */ -public class HeadersProvider extends EmbeddedExtensionProvider -{ - @SuppressWarnings("unchecked") - @Override - protected HeadersExtension createReturnExtension(String currentElement, String currentNamespace, Map attributeMap, List content) - { - return new HeadersExtension((Collection
)content); - } +public class HeadersProvider extends EmbeddedExtensionProvider { + public static final HeadersProvider INSTANCE = new HeadersProvider(); + + @SuppressWarnings("unchecked") + @Override + protected HeadersExtension createReturnExtension(String currentElement, String currentNamespace, + Map attributeMap, List content) { + return new HeadersExtension((List
) content); + } } diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/shim/provider/HeadersProviderTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/shim/provider/HeadersProviderTest.java new file mode 100644 index 000000000..1e2669b04 --- /dev/null +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/shim/provider/HeadersProviderTest.java @@ -0,0 +1,50 @@ +/** + * + * Copyright 2014 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.shim.provider; + +import static org.junit.Assert.assertEquals; + + +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.test.util.TestUtils; +import org.jivesoftware.smack.util.PacketParserUtils; +import org.jivesoftware.smackx.shim.packet.Header; +import org.jivesoftware.smackx.shim.packet.HeadersExtension; +import org.junit.Test; +import org.xmlpull.v1.XmlPullParser; + +public class HeadersProviderTest { + + @Test + public void headersInMessageTest() throws Exception { + // @formatter:off + final String messageStanza = + "" + + "Wherefore are thou?!?" + + "" + + "
high
" + + "
" + + "
"; + // @formatter:on + XmlPullParser parser = TestUtils.getMessageParser(messageStanza); + Message message = PacketParserUtils.parseMessage(parser); + HeadersExtension headers = HeadersExtension.from(message); + Header header = headers.getHeaders().get(0); + assertEquals("Urgency", header.getName()); + assertEquals("high", header.getValue()); + } +}