diff --git a/source/org/jivesoftware/smack/packet/StreamError.java b/source/org/jivesoftware/smack/packet/StreamError.java index 8bb4c75bc..363e9fbb3 100644 --- a/source/org/jivesoftware/smack/packet/StreamError.java +++ b/source/org/jivesoftware/smack/packet/StreamError.java @@ -82,13 +82,21 @@ package org.jivesoftware.smack.packet; */ public class StreamError { + public static final String NAMESPACE = "urn:ietf:params:xml:ns:xmpp-streams"; + private String code; + private String text; public StreamError(String code) { super(); this.code = code; } + public StreamError(String code, String text) { + this(code); + this.text = text; + } + /** * Returns the error code. * @@ -98,9 +106,19 @@ public class StreamError { return code; } + /** + * Returns the error text, which may be null. + * + * @return the error text. + */ + public String getText() { + return text; + } + public String toString() { StringBuilder txt = new StringBuilder(); txt.append("stream:error (").append(code).append(")"); + if (text != null) txt.append(" text: ").append(text); return txt.toString(); } } diff --git a/source/org/jivesoftware/smack/util/PacketParserUtils.java b/source/org/jivesoftware/smack/util/PacketParserUtils.java index 57d539c59..7fba71f90 100644 --- a/source/org/jivesoftware/smack/util/PacketParserUtils.java +++ b/source/org/jivesoftware/smack/util/PacketParserUtils.java @@ -695,21 +695,33 @@ public class PacketParserUtils { */ public static StreamError parseStreamError(XmlPullParser parser) throws IOException, XmlPullParserException { - StreamError streamError = null; + final int depth = parser.getDepth(); boolean done = false; + String code = null; + String text = null; while (!done) { int eventType = parser.next(); if (eventType == XmlPullParser.START_TAG) { - streamError = new StreamError(parser.getName()); - } - else if (eventType == XmlPullParser.END_TAG) { - if (parser.getName().equals("error")) { - done = true; + String namespace = parser.getNamespace(); + if (StreamError.NAMESPACE.equals(namespace)) { + String name = parser.getName(); + if (name.equals("text") && !parser.isEmptyElementTag()) { + parser.next(); + text = parser.getText(); + } + else { + // If it's not a text element, that is qualified by the StreamError.NAMESPACE, + // then it has to be the stream error code + code = name; + } } } + else if (eventType == XmlPullParser.END_TAG && depth == parser.getDepth()) { + done = true; + } } - return streamError; + return new StreamError(code, text); } /** diff --git a/test-unit/org/jivesoftware/smack/packet/StreamErrorTest.java b/test-unit/org/jivesoftware/smack/packet/StreamErrorTest.java new file mode 100644 index 000000000..9c3e9dfc6 --- /dev/null +++ b/test-unit/org/jivesoftware/smack/packet/StreamErrorTest.java @@ -0,0 +1,89 @@ +package org.jivesoftware.smack.packet; + +import static org.junit.Assert.*; + +import org.jivesoftware.smack.TestUtils; +import org.jivesoftware.smack.packet.StreamError; +import org.jivesoftware.smack.util.PacketParserUtils; +import org.junit.Test; +import org.xmlpull.v1.XmlPullParser; + +public class StreamErrorTest { + + @Test + public void testParsingOfSimpleStreamError() { + StreamError error = null; + final String xml = + // Usually the stream:stream element has more attributes (to, version, ...) + // We omit those, since they are not relevant for testing + "" + + "" + + " +" + + "" + + ""; + try { + XmlPullParser parser = TestUtils.getParser(xml, "error"); + error = PacketParserUtils.parseStreamError(parser); + } catch (Exception e) { + fail(e.getMessage()); + } + assertNotNull(error); + assertEquals("conflict", error.getCode()); + } + + @Test + public void testParsingOfStreamErrorWithText() { + StreamError error = null; + final String xml = + // Usually the stream:stream element has more attributes (to, version, ...) + // We omit those, since they are not relevant for testing + "" + + "" + + "" + + "" + + "Replaced by new connection" + + "" + + "" + + ""; + try { + XmlPullParser parser = TestUtils.getParser(xml, "error"); + error = PacketParserUtils.parseStreamError(parser); + } catch (Exception e) { + fail(e.getMessage()); + } + assertNotNull(error); + assertEquals("conflict", error.getCode()); + assertEquals("Replaced by new connection", error.getText()); + } + + @Test + public void testParsingOfStreamErrorWithTextAndOptionalElement() { + StreamError error = null; + final String xml = + // Usually the stream:stream element has more attributes (to, version, ...) + // We omit those, since they are not relevant for testing + "" + + "" + + "" + + "" + + "Replaced by new connection" + + "" + + "" + + "Text contents of application-specific condition element: Foo Bar" + + "" + + "" + + ""; + try { + XmlPullParser parser = TestUtils.getParser(xml, "error"); + error = PacketParserUtils.parseStreamError(parser); + } catch (Exception e) { + fail(e.getMessage()); + } + assertNotNull(error); + assertEquals("conflict", error.getCode()); + assertEquals("Replaced by new connection", error.getText()); + // As of now, Smack ignores application-specific condition elements, so we don't + // test them. + } + +}