mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-26 08:12:05 +01:00
Process all XML namespaces in PubSub ItemProvider
Fixes SMACK-601
This commit is contained in:
parent
1e5f0eb749
commit
b5b134f569
4 changed files with 46 additions and 9 deletions
|
@ -217,8 +217,14 @@ public class PacketParserUtils {
|
|||
* @throws IOException
|
||||
*/
|
||||
public static String parseElement(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
return parseElement(parser, false);
|
||||
}
|
||||
|
||||
public static String parseElement(XmlPullParser parser,
|
||||
boolean fullNamespaces) throws XmlPullParserException,
|
||||
IOException {
|
||||
assert (parser.getEventType() == XmlPullParser.START_TAG);
|
||||
return parseContentDepth(parser, parser.getDepth());
|
||||
return parseContentDepth(parser, parser.getDepth(), fullNamespaces);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -245,28 +251,36 @@ public class PacketParserUtils {
|
|||
}
|
||||
// Advance the parser, since we want to parse the content of the current element
|
||||
parser.next();
|
||||
return parseContentDepth(parser, parser.getDepth());
|
||||
return parseContentDepth(parser, parser.getDepth(), false);
|
||||
}
|
||||
|
||||
public static String parseContentDepth(XmlPullParser parser, int depth)
|
||||
throws XmlPullParserException, IOException {
|
||||
return parseContentDepth(parser, depth, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content from the current position of the parser up to the closing tag of the
|
||||
* given depth. Note that only the outermost namespace attributes ("xmlns") will be returned,
|
||||
* not nested ones.
|
||||
* not nested ones, if <code>fullNamespaces</code> is false. If it is true, then namespaces of
|
||||
* parent elements will be added to child elements that don't define a different namespace.
|
||||
* <p>
|
||||
* This method is able to parse the content with MX- and KXmlParser. In order to achieve
|
||||
* this some trade-off has to be make, because KXmlParser does not support xml-roundtrip (ie.
|
||||
* return a String on getText() on START_TAG and END_TAG). We are therefore required to work
|
||||
* around this limitation, which results in only partial support for XML namespaces ("xmlns"):
|
||||
* Only the outermost namespace of elements will be included in the resulting String.
|
||||
* Only the outermost namespace of elements will be included in the resulting String, if
|
||||
* <code>fullNamespaces</code> is set to false.
|
||||
* </p>
|
||||
*
|
||||
* @param parser
|
||||
* @param depth
|
||||
* @param fullNamespaces
|
||||
* @return the content of the current depth
|
||||
* @throws XmlPullParserException
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String parseContentDepth(XmlPullParser parser, int depth) throws XmlPullParserException, IOException {
|
||||
public static String parseContentDepth(XmlPullParser parser, int depth, boolean fullNamespaces) throws XmlPullParserException, IOException {
|
||||
XmlStringBuilder xml = new XmlStringBuilder();
|
||||
int event = parser.getEventType();
|
||||
boolean isEmptyElement = false;
|
||||
|
@ -277,7 +291,7 @@ public class PacketParserUtils {
|
|||
while (true) {
|
||||
if (event == XmlPullParser.START_TAG) {
|
||||
xml.halfOpenElement(parser.getName());
|
||||
if (namespaceElement == null) {
|
||||
if (namespaceElement == null || fullNamespaces) {
|
||||
String namespace = parser.getNamespace();
|
||||
if (StringUtils.isNotEmpty(namespace)) {
|
||||
xml.attribute("xmlns", namespace);
|
||||
|
|
|
@ -67,7 +67,7 @@ public class ParsingExceptionTest {
|
|||
try {
|
||||
PacketParserUtils.parseMessage(parser);
|
||||
} catch (Exception e) {
|
||||
content = PacketParserUtils.parseContentDepth(parser, parserDepth);
|
||||
content = PacketParserUtils.parseContentDepth(parser, parserDepth, false);
|
||||
}
|
||||
assertNotNull(content);
|
||||
assertEquals(MESSAGE_EXCEPTION_ELEMENT + EXTENSION2 + "</message>", content);
|
||||
|
|
|
@ -24,9 +24,14 @@ import static org.junit.Assert.assertNull;
|
|||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.xml.parsers.FactoryConfigurationError;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
|
||||
import org.custommonkey.xmlunit.Diff;
|
||||
import org.custommonkey.xmlunit.examples.RecursiveElementNameAndTextQualifier;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
|
@ -34,6 +39,7 @@ import org.jivesoftware.smack.packet.Packet;
|
|||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.junit.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
|
@ -790,6 +796,23 @@ public class PacketParserUtilsTest {
|
|||
assertEquals("", content);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseElementMultipleNamespace()
|
||||
throws ParserConfigurationException,
|
||||
FactoryConfigurationError, XmlPullParserException,
|
||||
IOException, TransformerException, SAXException {
|
||||
// @formatter:off
|
||||
final String stanza = XMLBuilder.create("outer", "outerNamespace").a("outerAttribute", "outerValue")
|
||||
.element("inner", "innerNamespace").a("innverAttribute", "innerValue")
|
||||
.element("innermost")
|
||||
.t("some text")
|
||||
.asString();
|
||||
// @formatter:on
|
||||
XmlPullParser parser = TestUtils.getParser(stanza, "outer");
|
||||
String result = PacketParserUtils.parseElement(parser, true);
|
||||
assertXMLEqual(stanza, result);
|
||||
}
|
||||
|
||||
private String determineNonDefaultLanguage() {
|
||||
String otherLanguage = "jp";
|
||||
Locale[] availableLocales = Locale.getAvailableLocales();
|
||||
|
|
|
@ -54,7 +54,7 @@ public class ItemProvider implements PacketExtensionProvider
|
|||
|
||||
if (ProviderManager.getExtensionProvider(payloadElemName, payloadNS) == null)
|
||||
{
|
||||
String payloadText = PacketParserUtils.parseElement(parser);
|
||||
String payloadText = PacketParserUtils.parseElement(parser, true);
|
||||
return new PayloadItem<SimplePayload>(id, node, new SimplePayload(payloadElemName, payloadNS, payloadText));
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue