diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleReason.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleReason.java
index 91c909aba..116c8375d 100644
--- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleReason.java
+++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/element/JingleReason.java
@@ -1,6 +1,6 @@
/**
*
- * Copyright 2017-2019 Florian Schmaus
+ * Copyright 2017-2022 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,6 +19,7 @@ package org.jivesoftware.smackx.jingle.element;
import java.util.HashMap;
import java.util.Map;
+import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.FullyQualifiedElement;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.util.StringUtils;
@@ -105,9 +106,17 @@ public class JingleReason implements FullyQualifiedElement {
}
protected final Reason reason;
+ private final String text;
+ private final ExtensionElement element;
public JingleReason(Reason reason) {
+ this(reason, null, null);
+ }
+
+ public JingleReason(Reason reason, String text, ExtensionElement element) {
this.reason = reason;
+ this.text = text;
+ this.element = element;
}
@Override
@@ -120,6 +129,26 @@ public class JingleReason implements FullyQualifiedElement {
return NAMESPACE;
}
+ /**
+ * An optional text that provides human-readable information about the reason for the action.
+ *
+ * @return a human-readable text with information regarding this reason or null
.
+ * @since 4.4.5
+ */
+ public String getText() {
+ return text;
+ }
+
+ /**
+ * An optional element that provides more detailed machine-readable information about the reason for the action.
+ *
+ * @return an elemnet with machine-readable information about this reason or null
.
+ * @since 4.4.5
+ */
+ public ExtensionElement getElement() {
+ return element;
+ }
+
@Override
public XmlStringBuilder toXML(XmlEnvironment enclosingXmlEnvironment) {
XmlStringBuilder xml = new XmlStringBuilder(this, enclosingXmlEnvironment);
@@ -142,7 +171,11 @@ public class JingleReason implements FullyQualifiedElement {
private final String sessionId;
public AlternativeSession(String sessionId) {
- super(Reason.alternative_session);
+ this(sessionId, null, null);
+ }
+
+ public AlternativeSession(String sessionId, String text, ExtensionElement element) {
+ super(Reason.alternative_session, text, element);
if (StringUtils.isNullOrEmpty(sessionId)) {
throw new NullPointerException("SessionID must not be null or empty.");
}
diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleProvider.java
index f6c352a75..861375995 100644
--- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleProvider.java
+++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/provider/JingleProvider.java
@@ -1,6 +1,6 @@
/**
*
- * Copyright 2017-2021 Florian Schmaus
+ * Copyright 2017-2022 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,12 +19,14 @@ package org.jivesoftware.smackx.jingle.provider;
import java.io.IOException;
import java.util.logging.Logger;
+import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.IqData;
import org.jivesoftware.smack.packet.StandardExtensionElement;
import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.parsing.SmackParsingException;
import org.jivesoftware.smack.parsing.StandardExtensionElementProvider;
import org.jivesoftware.smack.provider.IqProvider;
+import org.jivesoftware.smack.util.PacketParserUtils;
import org.jivesoftware.smack.util.ParserUtils;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
@@ -76,16 +78,7 @@ public class JingleProvider extends IqProvider {
builder.addJingleContent(content);
break;
case JingleReason.ELEMENT:
- parser.next();
- String reasonString = parser.getName();
- JingleReason reason;
- if (reasonString.equals("alternative-session")) {
- parser.next();
- String sid = parser.nextText();
- reason = new JingleReason.AlternativeSession(sid);
- } else {
- reason = new JingleReason(Reason.fromString(reasonString));
- }
+ JingleReason reason = parseJingleReason(parser);
builder.setReason(reason);
break;
default:
@@ -178,4 +171,57 @@ public class JingleProvider extends IqProvider {
return builder.build();
}
+
+ public static JingleReason parseJingleReason(XmlPullParser parser)
+ throws XmlPullParserException, IOException, SmackParsingException {
+ ParserUtils.assertAtStartTag(parser);
+ final int initialDepth = parser.getDepth();
+ final String jingleNamespace = parser.getNamespace();
+
+ JingleReason.Reason reason = null;
+ ExtensionElement element = null;
+ String text = null;
+
+ // 'sid' is only set if the reason is 'alternative-session'.
+ String sid = null;
+
+ outerloop: while (true) {
+ XmlPullParser.TagEvent event = parser.nextTag();
+ switch (event) {
+ case START_ELEMENT:
+ String elementName = parser.getName();
+ String namespace = parser.getNamespace();
+ if (namespace.equals(jingleNamespace)) {
+ switch (elementName) {
+ case "text":
+ text = parser.nextText();
+ break;
+ case "alternative-session":
+ parser.next();
+ sid = parser.nextText();
+ break;
+ default:
+ reason = Reason.fromString(elementName);
+ break;
+ }
+ } else {
+ element = PacketParserUtils.parseExtensionElement(elementName, namespace, parser, null);
+ }
+ break;
+ case END_ELEMENT:
+ if (parser.getDepth() == initialDepth) {
+ break outerloop;
+ }
+ break;
+ }
+ }
+
+ JingleReason res;
+ if (sid != null) {
+ res = new JingleReason.AlternativeSession(sid, text, element);
+ } else {
+ res = new JingleReason(reason, text, element);
+ }
+ return res;
+ }
}
diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/jingle/provider/JingleProviderTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/jingle/provider/JingleProviderTest.java
index c17543148..1ca0fa71a 100644
--- a/smack-extensions/src/test/java/org/jivesoftware/smackx/jingle/provider/JingleProviderTest.java
+++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/jingle/provider/JingleProviderTest.java
@@ -1,6 +1,6 @@
/**
*
- * Copyright 2017 Florian Schmaus
+ * Copyright 2017-2022 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,23 +17,30 @@
package org.jivesoftware.smackx.jingle.provider;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
-import org.jivesoftware.smack.util.PacketParserUtils;
-import org.jivesoftware.smack.xml.XmlPullParser;
+import org.jivesoftware.smack.packet.ExtensionElement;
+import org.jivesoftware.smack.packet.StandardExtensionElement;
+import org.jivesoftware.smack.parsing.SmackParsingException;
+import org.jivesoftware.smack.test.util.SmackTestUtil;
import org.jivesoftware.smack.xml.XmlPullParserException;
import org.jivesoftware.smackx.jingle.element.Jingle;
import org.jivesoftware.smackx.jingle.element.JingleContentDescription;
import org.jivesoftware.smackx.jingle.element.JingleContentTransport;
+import org.jivesoftware.smackx.jingle.element.JingleReason;
-import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
public class JingleProviderTest {
- @Test
- public void testParseUnknownJingleContentDescrption() throws Exception {
+ @ParameterizedTest
+ @EnumSource(SmackTestUtil.XmlPullParserKind.class)
+ public void testParseUnknownJingleContentDescrption(SmackTestUtil.XmlPullParserKind parserKind)
+ throws XmlPullParserException, IOException, SmackParsingException {
final String unknownJingleContentDescriptionNamespace = "urn:xmpp:jingle:unknown-description:5";
final String unknownJingleContentDescription =
// @formatter:off
@@ -50,8 +57,8 @@ public class JingleProviderTest {
"" +
"";
// @formatter:on
- XmlPullParser parser = createTestJingle(unknownJingleContentDescription);
- Jingle jingle = (Jingle) PacketParserUtils.parseIQ(parser);
+ CharSequence xml = createTestJingle(unknownJingleContentDescription);
+ Jingle jingle = SmackTestUtil.parse(xml, JingleProvider.class, parserKind);
JingleContentDescription jingleContentDescription = jingle.getSoleContentOrThrow().getDescription();
@@ -59,8 +66,10 @@ public class JingleProviderTest {
assertEquals(unknownJingleContentDescriptionNamespace, parsedUnknownJingleContentDescriptionNamespace);
}
- @Test
- public void testParseUnknownJingleContentTransport() throws Exception {
+ @ParameterizedTest
+ @EnumSource(SmackTestUtil.XmlPullParserKind.class)
+ public void testParseUnknownJingleContentTransport(SmackTestUtil.XmlPullParserKind parserKind)
+ throws XmlPullParserException, IOException, SmackParsingException {
final String unknownJingleContentTransportNamespace = "urn:xmpp:jingle:unknown-transport:foo:1";
final String unknownJingleContentTransport =
// @formatter:off
@@ -81,8 +90,8 @@ public class JingleProviderTest {
" type='direct'/>" +
"";
// @formatter:on
- XmlPullParser parser = createTestJingle(unknownJingleContentTransport);
- Jingle jingle = (Jingle) PacketParserUtils.parseIQ(parser);
+ CharSequence xml = createTestJingle(unknownJingleContentTransport);
+ Jingle jingle = SmackTestUtil.parse(xml, JingleProvider.class, parserKind);
JingleContentTransport jingleContentTransport = jingle.getSoleContentOrThrow().getTransport();
@@ -90,7 +99,38 @@ public class JingleProviderTest {
assertEquals(unknownJingleContentTransportNamespace, parsedUnknownJingleContentTransportNamespace);
}
- private static XmlPullParser createTestJingle(String... childs) throws XmlPullParserException, IOException {
+ @ParameterizedTest
+ @EnumSource(SmackTestUtil.XmlPullParserKind.class)
+ public void testReasonElementWithExtraElement(SmackTestUtil.XmlPullParserKind parserKind)
+ throws XmlPullParserException, IOException, SmackParsingException {
+ String xml = ""
+ + ""
+ + ""
+ + ""
+ + ""
+ + ""
+ + ""
+ + "";
+ Jingle jingle = SmackTestUtil.parse(xml, JingleProvider.class, parserKind);
+ JingleReason jingleReason = jingle.getReason();
+
+ assertEquals(JingleReason.Reason.success, jingleReason.asEnum());
+
+ ExtensionElement element = jingleReason.getElement();
+ // TODO: Use JUnit 5.8's assertInstanceOf when possible
+ // assertInstanceOf(StandardExtesionElement.class, extraElement);
+ assertTrue(element instanceof StandardExtensionElement);
+ StandardExtensionElement extraElement = (StandardExtensionElement) element;
+ assertEquals("https://example.org", extraElement.getNamespace());
+ assertEquals("bar", extraElement.getAttributes().get("foo"));
+ }
+
+ private static CharSequence createTestJingle(String... childs) throws XmlPullParserException, IOException {
StringBuilder sb = new StringBuilder();
sb.append(// @formatter:off
"" +
"" +
+ "action='session-initiate' " +
+ "initiator='romeo@montague.example/dr4hcr0st3lup4c' " +
+ "sid='851ba2'>" +
""
// @formatter:on
);
@@ -114,9 +154,6 @@ public class JingleProviderTest {
// @formatter:on
);
- String jingleStanza = sb.toString();
-
- XmlPullParser parser = PacketParserUtils.getParserFor(jingleStanza);
- return parser;
+ return sb;
}
}