1
0
Fork 0
mirror of https://codeberg.org/Mercury-IM/Smack synced 2025-12-08 14:11:07 +01:00

Change Element.toXml() to toXml(String enclosingNamespace)

This commit is contained in:
Florian Schmaus 2018-04-25 14:20:18 +02:00
parent 380f9a2b72
commit 5ab2903c32
229 changed files with 634 additions and 536 deletions

View file

@ -45,7 +45,7 @@ public class Compress implements Nonza {
}
@Override
public XmlStringBuilder toXML() {
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this);
xml.rightAngleBracket();
xml.element("method", method);
@ -77,7 +77,7 @@ public class Compress implements Nonza {
}
@Override
public XmlStringBuilder toXML() {
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this);
xml.rightAngleBracket();
for (String method : methods) {

View file

@ -39,7 +39,7 @@ public final class Compressed implements Nonza {
}
@Override
public String toXML() {
public String toXML(String enclosingNamespace) {
return '<' + ELEMENT + " xmlns='" + NAMESPACE + "'/>";
}
}

View file

@ -171,7 +171,7 @@ public abstract class AbstractDebugger extends SmackDebugger {
@Override
public void onIncomingStreamElement(TopLevelStreamElement streamElement) {
if (printInterpreted) {
log("RCV PKT (" + connection.getConnectionCounter() + "): " + streamElement.toXML());
log("RCV PKT (" + connection.getConnectionCounter() + "): " + streamElement.toXML(null));
}
}

View file

@ -114,7 +114,7 @@ public class AbstractError {
xml.closeElement("text");
}
for (ExtensionElement packetExtension : extensions) {
xml.append(packetExtension.toXML());
xml.append(packetExtension.toXML(null));
}
}

View file

@ -37,7 +37,7 @@ public abstract class AbstractTextElement implements ExtensionElement {
}
@Override
public XmlStringBuilder toXML() {
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this);
xml.optXmlLangAttribute(lang);
xml.rightAngleBracket();

View file

@ -89,7 +89,7 @@ public final class Bind extends IQ {
}
@Override
public String toXML() {
public String toXML(String enclosingNamespace) {
return '<' + ELEMENT + " xmlns='" + NAMESPACE + "'/>";
}

View file

@ -86,7 +86,7 @@ public class DefaultExtensionElement implements ExtensionElement {
}
@Override
public CharSequence toXML() {
public CharSequence toXML(String enclosingNamespace) {
XmlStringBuilder buf = new XmlStringBuilder();
buf.halfOpenElement(elementName).xmlnsAttribute(namespace).rightAngleBracket();
for (String name : getNames()) {

View file

@ -1,6 +1,6 @@
/**
*
* Copyright © 2014 Florian Schmaus
* Copyright © 2014-2018 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -23,10 +23,14 @@ package org.jivesoftware.smack.packet;
*/
public interface Element {
// TODO: Add a toXML() non-parameter default method once Smack supports Java 8.
/**
* Returns the XML representation of this Element.
* Returns the XML representation of this Element. This method takes an optional argument for the enclosing
* namespace which may be null or the empty String if the value is not known.
*
* @param enclosingNamespace the enclosing namespace or {@code null}.
* @return the stanza extension as XML.
*/
CharSequence toXML();
CharSequence toXML(String enclosingNamespace);
}

View file

@ -125,8 +125,8 @@ public abstract class IQ extends Stanza {
}
@Override
public final XmlStringBuilder toXML() {
XmlStringBuilder buf = new XmlStringBuilder();
public final XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder buf = new XmlStringBuilder(enclosingNamespace);
buf.halfOpenElement(IQ_ELEMENT);
addCommonAttributes(buf);
if (type == null) {
@ -226,7 +226,7 @@ public abstract class IQ extends Stanza {
protected final void initializeAsResultFor(IQ request) {
if (!(request.getType() == Type.get || request.getType() == Type.set)) {
throw new IllegalArgumentException(
"IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML());
"IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML(null));
}
setStanzaId(request.getStanzaId());
setFrom(request.getTo());
@ -275,7 +275,7 @@ public abstract class IQ extends Stanza {
public static ErrorIQ createErrorResponse(final IQ request, final StanzaError.Builder error) {
if (!(request.getType() == Type.get || request.getType() == Type.set)) {
throw new IllegalArgumentException(
"IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML());
"IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML(null));
}
final ErrorIQ result = new ErrorIQ(error);
result.setStanzaId(request.getStanzaId());
@ -367,6 +367,7 @@ public abstract class IQ extends Stanza {
}
private IQChildElementXmlStringBuilder(String element, String namespace) {
super("");
prelude(element, namespace);
this.element = element;
}

View file

@ -53,7 +53,7 @@ public class Mechanisms implements ExtensionElement {
}
@Override
public XmlStringBuilder toXML() {
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this);
xml.rightAngleBracket();
for (String mechanism : mechanisms) {

View file

@ -24,6 +24,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smack.util.TypedCloneable;
import org.jivesoftware.smack.util.XmlStringBuilder;
@ -474,7 +475,7 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
}
@Override
public XmlStringBuilder toXML() {
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder buf = new XmlStringBuilder();
buf.halfOpenElement(ELEMENT);
addCommonAttributes(buf);
@ -491,7 +492,7 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
// Skip the default language
if (subject.equals(defaultSubject))
continue;
buf.append(subject.toXML());
buf.append(subject.toXML(null));
}
// Add the body in the default language
Body defaultBody = getMessageBody(null);
@ -503,7 +504,7 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
// Skip the default language
if (body.equals(defaultBody))
continue;
buf.append(body.toXML());
buf.append(body.toXML(enclosingNamespace));
}
buf.optElement("thread", thread);
// Append the error subpacket if the message type is an error.
@ -606,7 +607,7 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
}
@Override
public XmlStringBuilder toXML() {
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(getElementName()).xmllangAttribute(getLanguage()).rightAngleBracket();
xml.escape(subject);
@ -624,10 +625,31 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
public static final String ELEMENT = "body";
public static final String NAMESPACE = StreamOpen.CLIENT_NAMESPACE;
enum BodyElementNamespace {
client(StreamOpen.CLIENT_NAMESPACE),
server(StreamOpen.SERVER_NAMESPACE),
;
private final String xmlNamespace;
BodyElementNamespace(String xmlNamespace) {
this.xmlNamespace = xmlNamespace;
}
public String getNamespace() {
return xmlNamespace;
}
}
private final String message;
private final String language;
private final BodyElementNamespace namespace;
private Body(String language, String message) {
public Body(String language, String message) {
this(language, message, BodyElementNamespace.client);
}
public Body(String language, String message, BodyElementNamespace namespace) {
if (language == null) {
throw new NullPointerException("Language cannot be null.");
}
@ -636,6 +658,7 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
}
this.language = language;
this.message = message;
this.namespace = Objects.requireNonNull(namespace);
}
/**
@ -688,13 +711,13 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
@Override
public String getNamespace() {
return NAMESPACE;
return namespace.xmlNamespace;
}
@Override
public XmlStringBuilder toXML() {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(getElementName()).xmllangAttribute(getLanguage()).rightAngleBracket();
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this, enclosingNamespace);
xml.xmllangAttribute(getLanguage()).rightAngleBracket();
xml.escape(message);
xml.closeElement(getElementName());
return xml;

View file

@ -272,7 +272,7 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
}
@Override
public XmlStringBuilder toXML() {
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder buf = new XmlStringBuilder();
buf.halfOpenElement(ELEMENT);
addCommonAttributes(buf);

View file

@ -67,7 +67,7 @@ public class Session extends SimpleIQ {
}
@Override
public XmlStringBuilder toXML() {
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this);
if (optional) {
xml.rightAngleBracket();

View file

@ -132,10 +132,6 @@ public final class StandardExtensionElement implements ExtensionElement {
}
@Override
public XmlStringBuilder toXML() {
return toXML(null);
}
public XmlStringBuilder toXML(String enclosingNamespace) {
if (xmlCache != null) {
return xmlCache;

View file

@ -490,7 +490,7 @@ public abstract class Stanza implements TopLevelStreamElement {
XmlStringBuilder xml = new XmlStringBuilder();
// Add in all standard extension sub-packets.
for (ExtensionElement extension : getExtensions()) {
xml.append(extension.toXML());
xml.append(extension.toXML(null));
}
return xml;
}

View file

@ -48,7 +48,7 @@ public class StartTls implements Nonza {
}
@Override
public XmlStringBuilder toXML() {
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder(this);
xml.rightAngleBracket();
xml.condEmptyElement(required, "required");

View file

@ -136,11 +136,11 @@ public class StreamError extends AbstractError implements Nonza {
@Override
public String toString() {
return toXML().toString();
return toXML(null).toString();
}
@Override
public XmlStringBuilder toXML() {
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder();
xml.openElement(ELEMENT);
xml.halfOpenElement(condition.toString()).xmlnsAttribute(NAMESPACE).closeEmptyElement();

View file

@ -96,8 +96,12 @@ public class StreamOpen implements Nonza {
}
@Override
public XmlStringBuilder toXML() {
XmlStringBuilder xml = new XmlStringBuilder(this);
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(getElementName());
// We always want to state 'xmlns' for stream open tags.
xml.attribute("xmlns", enclosingNamespace);
xml.attribute("to", to);
xml.attribute("xmlns:stream", "http://etherx.jabber.org/streams");
xml.attribute("version", VERSION);

View file

@ -44,7 +44,7 @@ public class SaslStreamElements {
}
@Override
public XmlStringBuilder toXML() {
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(ELEMENT).xmlnsAttribute(NAMESPACE).attribute("mechanism", mechanism).rightAngleBracket();
xml.optAppend(authenticationText);
@ -84,7 +84,7 @@ public class SaslStreamElements {
}
@Override
public XmlStringBuilder toXML() {
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder().halfOpenElement(ELEMENT).xmlnsAttribute(
NAMESPACE).rightAngleBracket();
xml.optAppend(data);
@ -120,7 +120,7 @@ public class SaslStreamElements {
}
@Override
public XmlStringBuilder toXML() {
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(ELEMENT).xmlnsAttribute(NAMESPACE).rightAngleBracket();
xml.optAppend(authenticationText);
@ -171,7 +171,7 @@ public class SaslStreamElements {
}
@Override
public XmlStringBuilder toXML() {
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(ELEMENT).xmlnsAttribute(NAMESPACE).rightAngleBracket();
xml.optAppend(data);
@ -236,7 +236,7 @@ public class SaslStreamElements {
}
@Override
public XmlStringBuilder toXML() {
public XmlStringBuilder toXML(String enclosingNamespace) {
XmlStringBuilder xml = new XmlStringBuilder();
xml.halfOpenElement(ELEMENT).xmlnsAttribute(NAMESPACE).rightAngleBracket();
xml.emptyElement(saslErrorString);
@ -247,7 +247,7 @@ public class SaslStreamElements {
@Override
public String toString() {
return toXML().toString();
return toXML(null).toString();
}
@Override

View file

@ -1,6 +1,6 @@
/**
*
* Copyright 2014-2017 Florian Schmaus
* Copyright 2014-2018 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,13 +27,20 @@ import org.jivesoftware.smack.packet.NamedElement;
import org.jxmpp.util.XmppDateTime;
public class XmlStringBuilder implements Appendable, CharSequence {
public class XmlStringBuilder implements Appendable, CharSequence, Element {
public static final String RIGHT_ANGLE_BRACKET = Character.toString('>');
private final LazyStringBuilder sb;
private final String enclosingNamespace;
public XmlStringBuilder() {
this("");
}
public XmlStringBuilder(String enclosingNamespace) {
sb = new LazyStringBuilder();
this.enclosingNamespace = enclosingNamespace != null ? enclosingNamespace : "";
}
public XmlStringBuilder(ExtensionElement pe) {
@ -47,13 +54,9 @@ public class XmlStringBuilder implements Appendable, CharSequence {
}
public XmlStringBuilder(ExtensionElement ee, String enclosingNamespace) {
this();
this(enclosingNamespace);
String namespace = ee.getNamespace();
if (namespace.equals(enclosingNamespace)) {
halfOpenElement(ee.getElementName());
} else {
prelude(ee);
}
prelude(ee);
}
public XmlStringBuilder escapedElement(String name, String escapedContent) {
@ -111,7 +114,7 @@ public class XmlStringBuilder implements Appendable, CharSequence {
public XmlStringBuilder element(Element element) {
assert element != null;
return append(element.toXML());
return append(element.toXML(null));
}
public XmlStringBuilder optElement(String name, String content) {
@ -146,7 +149,7 @@ public class XmlStringBuilder implements Appendable, CharSequence {
public XmlStringBuilder optElement(Element element) {
if (element != null) {
append(element.toXML());
append(element.toXML(null));
}
return this;
}
@ -350,8 +353,41 @@ public class XmlStringBuilder implements Appendable, CharSequence {
return this;
}
private static final class XmlNsAttribute implements CharSequence {
private final String value;
private final String xmlFragment;
private XmlNsAttribute(String value) {
this.value = StringUtils.requireNotNullOrEmpty(value, "Value must not be null");
this.xmlFragment = " xmlns='" + value + '\'';
}
@Override
public String toString() {
return xmlFragment;
}
@Override
public int length() {
return xmlFragment.length();
}
@Override
public char charAt(int index) {
return xmlFragment.charAt(index);
}
@Override
public CharSequence subSequence(int start, int end) {
return xmlFragment.subSequence(start, end);
}
}
public XmlStringBuilder xmlnsAttribute(String value) {
optAttribute("xmlns", value);
if (value != null && !enclosingNamespace.equals(value)) {
XmlNsAttribute xmlNsAttribute = new XmlNsAttribute(value);
append(xmlNsAttribute);
}
return this;
}
@ -409,7 +445,7 @@ public class XmlStringBuilder implements Appendable, CharSequence {
public XmlStringBuilder optAppend(Element element) {
if (element != null) {
append(element.toXML());
append(element.toXML(enclosingNamespace));
}
return this;
}
@ -422,7 +458,7 @@ public class XmlStringBuilder implements Appendable, CharSequence {
public XmlStringBuilder append(Collection<? extends Element> elements) {
for (Element element : elements) {
append(element.toXML());
append(element.toXML(null));
}
return this;
}
@ -512,14 +548,46 @@ public class XmlStringBuilder implements Appendable, CharSequence {
* @param writer
* @throws IOException
*/
public void write(Writer writer) throws IOException {
public void write(Writer writer, String enclosingNamespace) throws IOException {
for (CharSequence csq : sb.getAsList()) {
if (csq instanceof XmlStringBuilder) {
((XmlStringBuilder) csq).write(writer);
((XmlStringBuilder) csq).write(writer, enclosingNamespace);
}
else if (csq instanceof XmlNsAttribute) {
XmlNsAttribute xmlNsAttribute = (XmlNsAttribute) csq;
if (!xmlNsAttribute.value.equals(enclosingNamespace)) {
writer.write(xmlNsAttribute.toString());
enclosingNamespace = xmlNsAttribute.value;
}
}
else {
writer.write(csq.toString());
}
}
}
@Override
public CharSequence toXML(String enclosingNamespace) {
StringBuilder res = new StringBuilder();
appendXmlTo(res, enclosingNamespace);
return res;
}
private void appendXmlTo(StringBuilder res, String enclosingNamespace) {
for (CharSequence csq : sb.getAsList()) {
if (csq instanceof XmlStringBuilder) {
((XmlStringBuilder) csq).appendXmlTo(res, enclosingNamespace);
}
else if (csq instanceof XmlNsAttribute) {
XmlNsAttribute xmlNsAttribute = (XmlNsAttribute) csq;
if (!xmlNsAttribute.value.equals(enclosingNamespace)) {
sb.append(xmlNsAttribute);
enclosingNamespace = xmlNsAttribute.value;
}
}
else {
res.append(csq);
}
}
}
}