mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-26 08:12:05 +01:00
Make XHMTMLExtensionProvider use parseElement()
which makes the whole provider much simpler. Also use CharSequence as Base for XHTML-IM bodies.
This commit is contained in:
parent
94a16ba41e
commit
54b18e3575
5 changed files with 25 additions and 109 deletions
|
@ -63,8 +63,7 @@ public class PacketParserUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static XmlPullParser getParserFor(Reader reader) throws XmlPullParserException, IOException {
|
public static XmlPullParser getParserFor(Reader reader) throws XmlPullParserException, IOException {
|
||||||
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
|
XmlPullParser parser = newXmppParser();
|
||||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
|
||||||
parser.setInput(reader);
|
parser.setInput(reader);
|
||||||
|
|
||||||
// Wind the parser forward to the first start tag
|
// Wind the parser forward to the first start tag
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class XHTMLManager {
|
||||||
* @param message an XHTML message
|
* @param message an XHTML message
|
||||||
* @return an Iterator for the bodies in the message or null if none.
|
* @return an Iterator for the bodies in the message or null if none.
|
||||||
*/
|
*/
|
||||||
public static List<String> getBodies(Message message) {
|
public static List<CharSequence> getBodies(Message message) {
|
||||||
XHTMLExtension xhtmlExtension = (XHTMLExtension) message.getExtension(XHTMLExtension.ELEMENT, XHTMLExtension.NAMESPACE);
|
XHTMLExtension xhtmlExtension = (XHTMLExtension) message.getExtension(XHTMLExtension.ELEMENT, XHTMLExtension.NAMESPACE);
|
||||||
if (xhtmlExtension != null)
|
if (xhtmlExtension != null)
|
||||||
return xhtmlExtension.getBodies();
|
return xhtmlExtension.getBodies();
|
||||||
|
|
|
@ -26,14 +26,11 @@ import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An XHTML sub-packet, which is used by XMPP clients to exchange formatted text. The XHTML
|
* An XHTML sub-packet, which is used by XMPP clients to exchange formatted text. The XHTML
|
||||||
* extension is only a subset of XHTML 1.0.<p>
|
* extension is only a subset of XHTML 1.0.
|
||||||
*
|
* <p>
|
||||||
* The following link summarizes the requirements of XHTML IM:
|
* The following link summarizes the requirements of XHTML IM:
|
||||||
* <a href="http://www.xmpp.org/extensions/jep-0071.html#sect-id2598018">Valid tags</a>.<p>
|
* <a href="http://www.xmpp.org/extensions/xep-0071.html">XEP-0071: XHTML-IM</a>.
|
||||||
*
|
* </p>
|
||||||
* Warning: this is an non-standard protocol documented by
|
|
||||||
* <a href="http://www.xmpp.org/extensions/jep-0071.html">XEP-71</a>. Because this is a
|
|
||||||
* non-standard protocol, it is subject to change.
|
|
||||||
*
|
*
|
||||||
* @author Gaston Dombiak
|
* @author Gaston Dombiak
|
||||||
*/
|
*/
|
||||||
|
@ -42,7 +39,7 @@ public class XHTMLExtension implements PacketExtension {
|
||||||
public static final String ELEMENT = "html";
|
public static final String ELEMENT = "html";
|
||||||
public static final String NAMESPACE = "http://jabber.org/protocol/xhtml-im";
|
public static final String NAMESPACE = "http://jabber.org/protocol/xhtml-im";
|
||||||
|
|
||||||
private List<String> bodies = new ArrayList<String>();
|
private List<CharSequence> bodies = new ArrayList<CharSequence>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the XML element name of the extension sub-packet root element.
|
* Returns the XML element name of the extension sub-packet root element.
|
||||||
|
@ -85,7 +82,7 @@ public class XHTMLExtension implements PacketExtension {
|
||||||
XmlStringBuilder xml = new XmlStringBuilder(this);
|
XmlStringBuilder xml = new XmlStringBuilder(this);
|
||||||
xml.rightAngelBracket();
|
xml.rightAngelBracket();
|
||||||
// Loop through all the bodies and append them to the string buffer
|
// Loop through all the bodies and append them to the string buffer
|
||||||
for (String body : getBodies()) {
|
for (CharSequence body : getBodies()) {
|
||||||
xml.append(body);
|
xml.append(body);
|
||||||
}
|
}
|
||||||
xml.closeElement(this);
|
xml.closeElement(this);
|
||||||
|
@ -97,9 +94,9 @@ public class XHTMLExtension implements PacketExtension {
|
||||||
*
|
*
|
||||||
* @return a List of the bodies in the packet.
|
* @return a List of the bodies in the packet.
|
||||||
*/
|
*/
|
||||||
public List<String> getBodies() {
|
public List<CharSequence> getBodies() {
|
||||||
synchronized (bodies) {
|
synchronized (bodies) {
|
||||||
return Collections.unmodifiableList(new ArrayList<String>(bodies));
|
return Collections.unmodifiableList(new ArrayList<CharSequence>(bodies));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +105,7 @@ public class XHTMLExtension implements PacketExtension {
|
||||||
*
|
*
|
||||||
* @param body the body to add.
|
* @param body the body to add.
|
||||||
*/
|
*/
|
||||||
public void addBody(String body) {
|
public void addBody(CharSequence body) {
|
||||||
synchronized (bodies) {
|
synchronized (bodies) {
|
||||||
bodies.add(body);
|
bodies.add(body);
|
||||||
}
|
}
|
||||||
|
@ -120,7 +117,9 @@ public class XHTMLExtension implements PacketExtension {
|
||||||
* @return the number of bodies in the XHTML packet.
|
* @return the number of bodies in the XHTML packet.
|
||||||
*/
|
*/
|
||||||
public int getBodiesCount() {
|
public int getBodiesCount() {
|
||||||
return bodies.size();
|
synchronized (bodies) {
|
||||||
|
return bodies.size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright 2003-2007 Jive Software, 2014 Vyacheslav Blinov
|
* Copyright 2003-2007 Jive Software, 2014 Florian Schmaus
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -19,7 +19,7 @@ package org.jivesoftware.smackx.xhtmlim.provider;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
import org.jivesoftware.smack.packet.PacketExtension;
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
import org.jivesoftware.smack.provider.PacketExtensionProvider;
|
||||||
import org.jivesoftware.smack.util.StringUtils;
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
import org.jivesoftware.smackx.xhtmlim.packet.XHTMLExtension;
|
import org.jivesoftware.smackx.xhtmlim.packet.XHTMLExtension;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
@ -29,108 +29,27 @@ import java.io.IOException;
|
||||||
/**
|
/**
|
||||||
* The XHTMLExtensionProvider parses XHTML packets.
|
* The XHTMLExtensionProvider parses XHTML packets.
|
||||||
*
|
*
|
||||||
* @author Vyacheslav Blinov
|
* @author Florian Schmaus
|
||||||
*/
|
*/
|
||||||
public class XHTMLExtensionProvider implements PacketExtensionProvider {
|
public class XHTMLExtensionProvider implements PacketExtensionProvider {
|
||||||
@Override
|
@Override
|
||||||
public PacketExtension parseExtension(XmlPullParser parser) throws IOException, XmlPullParserException {
|
public PacketExtension parseExtension(XmlPullParser parser) throws IOException, XmlPullParserException {
|
||||||
XHTMLExtension xhtmlExtension = new XHTMLExtension();
|
XHTMLExtension xhtmlExtension = new XHTMLExtension();
|
||||||
final String XHTML_EXTENSION_ELEMENT_NAME = xhtmlExtension.getElementName();
|
|
||||||
|
|
||||||
int startDepth = parser.getDepth();
|
int startDepth = parser.getDepth();
|
||||||
int tagDepth = parser.getDepth();
|
|
||||||
boolean tagStarted = false;
|
|
||||||
StringBuilder buffer = new StringBuilder();
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
int eventType = parser.next();
|
int eventType = parser.getEventType();
|
||||||
|
String name = parser.getName();
|
||||||
if (eventType == XmlPullParser.START_TAG) {
|
if (eventType == XmlPullParser.START_TAG) {
|
||||||
boolean appendNamespace = false;
|
if (name.equals(Message.BODY)) {
|
||||||
if (Message.BODY.equals(parser.getName())) {
|
xhtmlExtension.addBody(PacketParserUtils.parseElement(parser));
|
||||||
buffer = new StringBuilder();
|
|
||||||
tagDepth = parser.getDepth();
|
|
||||||
appendNamespace = true;
|
|
||||||
}
|
}
|
||||||
maybeCloseTag(tagStarted, buffer);
|
|
||||||
appendStartTagPartial(buffer, parser, appendNamespace);
|
|
||||||
tagStarted = true;
|
|
||||||
} else if (eventType == XmlPullParser.TEXT) {
|
|
||||||
tagStarted = maybeCloseTag(tagStarted, buffer);
|
|
||||||
appendText(buffer, parser);
|
|
||||||
} else if (eventType == XmlPullParser.END_TAG) {
|
} else if (eventType == XmlPullParser.END_TAG) {
|
||||||
String name = parser.getName();
|
if (name.equals(XHTMLExtension.ELEMENT) && parser.getDepth() <= startDepth) {
|
||||||
if (XHTML_EXTENSION_ELEMENT_NAME.equals(name) && parser.getDepth() <= startDepth) {
|
|
||||||
return xhtmlExtension;
|
return xhtmlExtension;
|
||||||
} else {
|
|
||||||
// xpp does not allows us to detect if tag is self-closing, so we have to
|
|
||||||
// handle self-closing tags by our own means
|
|
||||||
appendEndTag(buffer, parser, tagStarted);
|
|
||||||
tagStarted = false;
|
|
||||||
if (Message.BODY.equals(name) && parser.getDepth() <= tagDepth) {
|
|
||||||
xhtmlExtension.addBody(buffer.toString());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
parser.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void appendStartTagPartial(StringBuilder builder, XmlPullParser parser, boolean withNamespace) {
|
|
||||||
builder.append('<');
|
|
||||||
|
|
||||||
String prefix = parser.getPrefix();
|
|
||||||
if (StringUtils.isNotEmpty(prefix)) {
|
|
||||||
builder.append(prefix).append(':');
|
|
||||||
}
|
|
||||||
builder.append(parser.getName());
|
|
||||||
|
|
||||||
int attributesCount = parser.getAttributeCount();
|
|
||||||
// handle namespace
|
|
||||||
if (withNamespace) {
|
|
||||||
String namespace = parser.getNamespace();
|
|
||||||
if (StringUtils.isNotEmpty(namespace)) {
|
|
||||||
builder.append(" xmlns='").append(namespace).append('\'');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// handle attributes
|
|
||||||
for (int i = 0; i < attributesCount; ++i) {
|
|
||||||
builder.append(' ');
|
|
||||||
String attributeNamespace = parser.getAttributeNamespace(i);
|
|
||||||
if (StringUtils.isNotEmpty(attributeNamespace)) {
|
|
||||||
builder.append(attributeNamespace).append(':');
|
|
||||||
}
|
|
||||||
builder.append(parser.getAttributeName(i));
|
|
||||||
String value = parser.getAttributeValue(i);
|
|
||||||
if (value != null) {
|
|
||||||
// We need to return valid XML so any inner text needs to be re-escaped
|
|
||||||
builder.append("='").append(StringUtils.escapeForXML(value)).append('\'');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static void appendEndTag(StringBuilder builder, XmlPullParser parser, boolean tagStarted) {
|
|
||||||
if (tagStarted) {
|
|
||||||
builder.append("/>");
|
|
||||||
} else {
|
|
||||||
builder.append("</").append(parser.getName()).append('>');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean appendText(StringBuilder builder, XmlPullParser parser) {
|
|
||||||
String text = parser.getText();
|
|
||||||
if (text == null) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
// We need to return valid XML so any inner text needs to be re-escaped
|
|
||||||
builder.append(StringUtils.escapeForXML(parser.getText()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean maybeCloseTag(boolean tagStarted, StringBuilder builder) {
|
|
||||||
if (tagStarted) {
|
|
||||||
builder.append('>');
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
package org.jivesoftware.smackx.xhtmlim.provider;
|
package org.jivesoftware.smackx.xhtmlim.provider;
|
||||||
|
|
||||||
import org.jivesoftware.smack.packet.PacketExtension;
|
import org.jivesoftware.smack.packet.PacketExtension;
|
||||||
|
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||||
import org.jivesoftware.smackx.xhtmlim.packet.XHTMLExtension;
|
import org.jivesoftware.smackx.xhtmlim.packet.XHTMLExtension;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
import org.xmlpull.v1.XmlPullParserFactory;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -36,8 +36,7 @@ public class XHTMLExtensionProviderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parsesWell() throws IOException, XmlPullParserException {
|
public void parsesWell() throws IOException, XmlPullParserException {
|
||||||
XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
|
XmlPullParser parser = PacketParserUtils.newXmppParser();
|
||||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
|
||||||
parser.setInput(getClass().getResourceAsStream(XHTML_EXTENSION_SAMPLE_RESOURCE_NAME), "UTF-8");
|
parser.setInput(getClass().getResourceAsStream(XHTML_EXTENSION_SAMPLE_RESOURCE_NAME), "UTF-8");
|
||||||
parser.next();
|
parser.next();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue