From 9e797c1b172870b1324f2d1ff2a911c9d99a3197 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 7 Nov 2014 21:12:01 +0100 Subject: [PATCH] Enable PacketExtensions for IQs This is actually only part one, i.e. with this commit if the user adds a PacketExtension to an IQ it will be included in IQ.toXml(). Which was previously only the case if the IQ subclass explicitly included packet extensions. The second part of the change is to change the IQ provider, so that packet extensions are automatically parsed. Cases where PacketExtensions are used for Message and IQ are slightly changed. The IQ sublcass now only has a field with this PacketExtension (see for example bytestreams.ibb.packet.DataPacketExtension). Also changed hoxt API: Removed unnecessary indirection and made the API more Smack idiomatic. --- documentation/extensions/hoxt.md | 63 ++-- .../org/jivesoftware/smack/packet/Bind.java | 9 +- .../smack/packet/EmptyResultIQ.java | 42 +++ .../jivesoftware/smack/packet/ErrorIQ.java | 38 +++ .../org/jivesoftware/smack/packet/IQ.java | 158 +++++++--- .../jivesoftware/smack/packet/Message.java | 5 +- .../org/jivesoftware/smack/packet/Packet.java | 14 +- .../jivesoftware/smack/packet/Presence.java | 6 +- .../smack/packet/RosterPacket.java | 10 +- .../jivesoftware/smack/packet/Session.java | 8 +- .../jivesoftware/smack/packet/SimpleIQ.java | 38 +++ .../smack/util/PacketParserUtils.java | 49 +-- .../smack/util/XmlStringBuilder.java | 25 +- .../org/jivesoftware/smack/RosterTest.java | 9 +- .../org/jivesoftware/smack/StanzaIdTest.java | 18 +- .../smack/packet/IQResponseTest.java | 36 +-- .../org/jivesoftware/smack/packet/TestIQ.java | 35 +++ .../smackx/carbons/packet/Carbon.java | 16 +- .../jivesoftware/smackx/hoxt/HOXTManager.java | 3 +- .../hoxt/packet/AbstractHttpOverXmpp.java | 285 +++++++++--------- .../smackx/hoxt/packet/HttpOverXmppReq.java | 258 +++++++--------- .../smackx/hoxt/packet/HttpOverXmppResp.java | 116 +++---- .../AbstractHttpOverXmppProvider.java | 5 +- .../provider/HttpOverXmppReqProvider.java | 16 +- .../provider/HttpOverXmppRespProvider.java | 13 +- .../AbstractHttpOverXmppProviderTest.java | 10 +- .../provider/HttpOverXmppReqProviderTest.java | 12 +- .../HttpOverXmppRespProviderTest.java | 6 +- .../ibb/InBandBytestreamSession.java | 22 +- .../smackx/bytestreams/ibb/packet/Close.java | 10 +- .../smackx/bytestreams/ibb/packet/Data.java | 14 +- .../ibb/packet/DataPacketExtension.java | 14 +- .../smackx/bytestreams/ibb/packet/Open.java | 11 +- .../bytestreams/socks5/packet/Bytestream.java | 27 +- .../commands/packet/AdHocCommandData.java | 7 +- .../smackx/disco/packet/DiscoverInfo.java | 12 +- .../smackx/disco/packet/DiscoverItems.java | 12 +- .../smackx/iqlast/packet/LastActivity.java | 10 +- .../smackx/iqprivate/PrivateDataManager.java | 57 +--- .../iqprivate/packet/PrivateDataIQ.java | 61 ++++ .../iqregister/packet/Registration.java | 11 +- .../smackx/iqversion/packet/Version.java | 10 +- .../smackx/muc/packet/MUCAdmin.java | 16 +- .../smackx/muc/packet/MUCOwner.java | 16 +- .../offline/packet/OfflineMessageRequest.java | 20 +- .../smackx/pep/packet/PEPPubSub.java | 44 +-- .../jivesoftware/smackx/ping/packet/Ping.java | 10 +- .../smackx/privacy/PrivacyListManager.java | 2 +- .../smackx/privacy/packet/Privacy.java | 21 +- .../smackx/pubsub/packet/PubSub.java | 13 +- .../smackx/search/SimpleUserSearch.java | 17 +- .../smackx/search/UserSearch.java | 17 +- .../sharedgroups/packet/SharedGroupsInfo.java | 18 +- .../smackx/si/packet/StreamInitiation.java | 50 ++- .../jivesoftware/smackx/time/packet/Time.java | 15 +- .../smackx/vcardtemp/packet/VCard.java | 258 ++++++---------- .../bytestreams/ibb/IBBPacketUtils.java | 19 +- .../bytestreams/ibb/packet/CloseTest.java | 2 +- .../bytestreams/ibb/packet/DataTest.java | 13 +- .../socks5/Socks5ByteStreamManagerTest.java | 11 +- .../socks5/Socks5ClientForInitiatorTest.java | 22 +- .../bytestreams/socks5/Socks5PacketUtils.java | 11 +- .../smackx/jingleold/nat/RTPBridge.java | 13 +- .../smackx/jingleold/nat/STUN.java | 16 +- .../smackx/jingleold/packet/Jingle.java | 19 +- .../smackx/workgroup/agent/AgentSession.java | 22 +- .../smackx/workgroup/agent/Offer.java | 18 +- .../workgroup/agent/OfferConfirmation.java | 22 +- .../workgroup/ext/forms/WorkgroupForm.java | 15 +- .../ext/history/AgentChatHistory.java | 72 +++-- .../workgroup/ext/history/ChatMetadata.java | 15 +- .../smackx/workgroup/ext/macros/Macros.java | 34 ++- .../smackx/workgroup/ext/notes/ChatNotes.java | 13 +- .../smackx/workgroup/packet/AgentInfo.java | 13 +- .../workgroup/packet/AgentStatusRequest.java | 10 +- .../workgroup/packet/AgentWorkgroups.java | 19 +- .../workgroup/packet/DepartQueuePacket.java | 17 +- .../workgroup/packet/MonitorPacket.java | 22 +- .../workgroup/packet/OccupantsInfo.java | 9 +- .../packet/OfferRequestProvider.java | 14 +- .../workgroup/packet/OfferRevokeProvider.java | 10 +- .../workgroup/packet/RoomInvitation.java | 31 +- .../smackx/workgroup/packet/RoomTransfer.java | 31 +- .../smackx/workgroup/packet/Transcript.java | 15 +- .../workgroup/packet/TranscriptSearch.java | 17 +- .../smackx/workgroup/packet/Transcripts.java | 15 +- .../workgroup/settings/ChatSettings.java | 37 +-- .../workgroup/settings/GenericSettings.java | 15 +- .../workgroup/settings/OfflineSettings.java | 16 +- .../workgroup/settings/SearchSettings.java | 16 +- .../workgroup/settings/SoundSettings.java | 16 +- .../settings/WorkgroupProperties.java | 15 +- .../smackx/workgroup/user/Workgroup.java | 12 +- 93 files changed, 1347 insertions(+), 1438 deletions(-) create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/ErrorIQ.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/SimpleIQ.java create mode 100644 smack-core/src/test/java/org/jivesoftware/smack/packet/TestIQ.java create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateDataIQ.java diff --git a/documentation/extensions/hoxt.md b/documentation/extensions/hoxt.md index 9a83a3834..b89f5a7d2 100644 --- a/documentation/extensions/hoxt.md +++ b/documentation/extensions/hoxt.md @@ -65,13 +65,11 @@ In this example we are HTTP client, so we send request (POST) and handle the response: ``` -// register listener for IQ packets -connection.addPacketListener(new IqPacketListener(), new PacketTypeFilter(IQ.class)); // create a request body String urlEncodedMessage = "I_love_you"; // create request -HttpOverXmppReq.Req req = new HttpOverXmppReq.Req(HttpMethod.POST, "/mailbox"); +HttpOverXmppReq req = new HttpOverXmppReq(HttpMethod.POST, "/mailbox"); req.setVersion("1.1"); // prepare headers @@ -86,52 +84,25 @@ AbstractHttpOverXmpp.Text child = new AbstractHttpOverXmpp.Text(urlEncodedMessag AbstractHttpOverXmpp.Data data = new AbstractHttpOverXmpp.Data(child); req.setData(data); -// create IQ packet -HttpOverXmppReq packet = new HttpOverXmppReq(); -packet.setReq(req); -packet.setTo("juliet@capulet.com/balcony"); -packet.setType(IQ.Type.SET); -packet.setPacketID("42"); +// add to +req.setTo("juliet@capulet.com/balcony"); // send it -connection.sendPacket(packet); - - -// then in your PacketListener -private class IqPacketListener implements PacketListener { - - @Override - public void processPacket(Packet packet) { - IQ iq = (IQ) packet; - - // verify from and packed ID - if (iq.getFrom().equals("juliet@capulet.com/balcony") && (iq.getPacketID().equals("42"))) { - - // ensure it's not ERROR - if (iq.getType().equals(IQ.Type.RESULT)) { - - // check if correct IQ implementation arrived - if (iq instanceof HttpOverXmppResp) { - HttpOverXmppResp resp = (HttpOverXmppResp) iq; - - // check HTTP response code - if (resp.getResp().getStatusCode() == 200) { - - // get content of the response - AbstractHttpOverXmpp.DataChild child = resp.getResp().getData().getChild(); - - // check which type of content of the response arrived - if (child instanceof AbstractHttpOverXmpp.Xml) { - - // print the message and anxiously read if from console ;) - System.out.println(((AbstractHttpOverXmpp.Xml) child).getText()); - } else { - // process other AbstractHttpOverXmpp.DataChild subtypes - } - } +connection.sendIqWithResponseCallback(req, new PacketListener() { + public void processPacket(Packet packet) { + HttpOverXmppResp resp = (HttpOverXmppResp) iq; + // check HTTP response code + if (resp.getStatusCode() == 200) { + // get content of the response + NamedElement child = resp.getData().getChild(); + // check which type of content of the response arrived + if (child instanceof AbstractHttpOverXmpp.Xml) { + // print the message and anxiously read if from console ;) + System.out.println(((AbstractHttpOverXmpp.Xml) child).getText()); + } else { + // process other AbstractHttpOverXmpp.DataChild subtypes } } } -} -} +}); ``` diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Bind.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Bind.java index ef5cc4232..df59cc5f6 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Bind.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Bind.java @@ -17,8 +17,6 @@ package org.jivesoftware.smack.packet; -import org.jivesoftware.smack.util.XmlStringBuilder; - /** * IQ packet used by Smack to bind a resource and to obtain the jid assigned by the server. * There are two ways to bind a resource. One is simply sending an empty Bind packet where the @@ -39,6 +37,7 @@ public class Bind extends IQ { private final String jid; public Bind(String resource, String jid) { + super(ELEMENT, NAMESPACE); this.resource = resource; this.jid = jid; } @@ -62,12 +61,10 @@ public class Bind extends IQ { } @Override - public XmlStringBuilder getChildElementXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement(ELEMENT).xmlnsAttribute(NAMESPACE).rightAngleBracket(); + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + xml.rightAngleBracket(); xml.optElement("resource", resource); xml.optElement("jid", jid); - xml.closeElement(ELEMENT); return xml; } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java new file mode 100644 index 000000000..0af904bc8 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java @@ -0,0 +1,42 @@ +/** + * + * Copyright © 2014 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.packet; + +public class EmptyResultIQ extends IQ { + + public EmptyResultIQ() { + super(null, null); + type = IQ.Type.result; + } + + public EmptyResultIQ(IQ request) { + this(); + if (!(request.getType() == Type.get || request.getType() == Type.set)) { + throw new IllegalArgumentException( + "IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML()); + } + setPacketID(request.getPacketID()); + setFrom(request.getTo()); + setTo(request.getFrom()); + } + + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + // Empty result IQs don't have an child elements + return null; + } +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/ErrorIQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/ErrorIQ.java new file mode 100644 index 000000000..18a3eca3a --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/ErrorIQ.java @@ -0,0 +1,38 @@ +/** + * + * Copyright © 2014 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.packet; + +public class ErrorIQ extends SimpleIQ { + + public static final String ELEMENT = XMPPError.ERROR; + + /** + * Constructs a new error IQ. + *

+ * According to RFC 6120 § 8.3.1 "4. An error stanza MUST contain an child element.", so the xmppError argument is mandatory. + *

+ * @param xmppError the XMPPError (required). + */ + public ErrorIQ(XMPPError xmppError) { + super(ELEMENT, null); + if (xmppError == null) { + throw new IllegalArgumentException("XMPPError must not be null"); + } + type = IQ.Type.error; + setError(xmppError); + } +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java index e2f941fc2..533b67b4b 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java @@ -43,16 +43,27 @@ public abstract class IQ extends Packet { public static final String ELEMENT = "iq"; public static final String QUERY_ELEMENT = "query"; - private Type type = Type.get; + private final String childElementName; + private final String childElementNamespace; - public IQ() { - super(); - } + protected Type type = Type.get; public IQ(IQ iq) { super(iq); type = iq.getType(); + this.childElementName = iq.childElementName; + this.childElementNamespace = iq.childElementNamespace; } + + protected IQ(String childElementName) { + this(childElementName, null); + } + + protected IQ(String childElementName, String childElementNamespace) { + this.childElementName = childElementName; + this.childElementNamespace = childElementNamespace; + } + /** * Returns the type of the IQ packet. * @@ -76,8 +87,16 @@ public abstract class IQ extends Packet { } } + public final String getChildElementName() { + return childElementName; + } + + public final String getChildElementNamespace() { + return childElementNamespace; + } + @Override - public CharSequence toXML() { + public final XmlStringBuilder toXML() { XmlStringBuilder buf = new XmlStringBuilder(); buf.halfOpenElement(ELEMENT); addCommonAttributes(buf); @@ -88,26 +107,84 @@ public abstract class IQ extends Packet { buf.attribute("type", type.toString()); } buf.rightAngleBracket(); - // Add the query section if there is one. - buf.optAppend(getChildElementXML()); - // Add the error sub-packet, if there is one. - XMPPError error = getError(); - if (error != null) { - buf.append(error.toXML()); - } + buf.append(getChildElementXML()); buf.closeElement(ELEMENT); return buf; } /** - * Returns the sub-element XML section of the IQ packet, or null if there - * isn't one. Packet extensions must be included, if any are defined.

- * - * Extensions of this class must override this method. + * Returns the sub-element XML section of the IQ packet, or the empty String if there + * isn't one. * * @return the child element section of the IQ XML. */ - public abstract CharSequence getChildElementXML(); + public final XmlStringBuilder getChildElementXML() { + XmlStringBuilder xml = new XmlStringBuilder(); + if (type == Type.error) { + // Add the error sub-packet, if there is one. + appendErrorIfExists(xml); + } + else if (childElementName != null) { + // Add the query section if there is one. + IQChildElementXmlStringBuilder iqChildElement = getIQChildElementBuilder(new IQChildElementXmlStringBuilder(this)); + if (iqChildElement != null) { + xml.append(iqChildElement); + XmlStringBuilder extensionsXml = getExtensionsXML(); + if (iqChildElement.isEmptyElement) { + if (extensionsXml.length() == 0) { + xml.closeEmptyElement(); + return xml; + } else { + xml.rightAngleBracket(); + } + } + xml.append(extensionsXml); + xml.closeElement(iqChildElement.element); + } + } + return xml; + } + + /** + * This method must be overwritten by IQ subclasses to create their child content. It is important that the builder + * does not include the final end element. This will be done automatically by IQChildelementXmlStringBuilder + * after eventual existing packet extensions have been added. + *

+ * For example to create an IQ with a extra attribute and an additional child element + *

+ *
+     * {@code
+     * 
+     *   
+     *      elementText
+     *   
+     * 
+     * }
+     * 
+ * the body of the {@code getIQChildElementBuilder} looks like + *
+     * {@code
+     * // The builder 'xml' will already have the child element and the 'xmlns' attribute added
+     * // So the current builder state is "
+     * If your IQ only contains attributes and no child elements, i.e. it can be represented as empty element, then you
+     * can mark it as such.
+     * 
+     * xml.attribute("myAttribute", "myAttributeValue");
+     * xml.setEmptyElement();
+     * 
+ * If your IQ does not contain any attributes or child elements (besides packet extensions), consider sub-classing + * {@link SimpleIQ} instead. + * + * @param xml a pre-created builder which already has the child element and the 'xmlns' attribute set. + * @return the build to create the IQ child content. + */ + protected abstract IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml); /** * Convenience method to create a new empty {@link Type#result IQ.Type.result} @@ -126,20 +203,7 @@ public abstract class IQ extends Packet { * @return a new {@link Type#result IQ.Type.result} IQ based on the originating IQ. */ public static IQ createResultIQ(final 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()); - } - final IQ result = new IQ() { - public String getChildElementXML() { - return null; - } - }; - result.setType(Type.result); - result.setPacketID(request.getPacketID()); - result.setFrom(request.getTo()); - result.setTo(request.getFrom()); - return result; + return new EmptyResultIQ(request); } /** @@ -165,17 +229,10 @@ public abstract class IQ extends Packet { throw new IllegalArgumentException( "IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML()); } - final IQ result = new IQ() { - @Override - public CharSequence getChildElementXML() { - return request.getChildElementXML(); - } - }; - result.setType(Type.error); + final IQ result = new ErrorIQ(error); result.setPacketID(request.getPacketID()); result.setFrom(request.getTo()); result.setTo(request.getFrom()); - result.setError(error); return result; } @@ -209,4 +266,27 @@ public abstract class IQ extends Packet { return Type.valueOf(string.toLowerCase(Locale.US)); } } + + public static class IQChildElementXmlStringBuilder extends XmlStringBuilder { + private final String element; + + private boolean isEmptyElement; + + private IQChildElementXmlStringBuilder(IQ iq) { + this(iq.getChildElementName(), iq.getChildElementNamespace()); + } + + public IQChildElementXmlStringBuilder(PacketExtension pe) { + this(pe.getElementName(), pe.getNamespace()); + } + + private IQChildElementXmlStringBuilder(String element, String namespace) { + prelude(element, namespace); + this.element = element; + } + + public void setEmptyElement() { + isEmptyElement = true; + } + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java index f5ac6030d..6a81e4e21 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java @@ -430,10 +430,7 @@ public final class Message extends Packet { buf.optElement("thread", thread); // Append the error subpacket if the message type is an error. if (type == Type.error) { - XMPPError error = getError(); - if (error != null) { - buf.append(error.toXML()); - } + appendErrorIfExists(buf); } // Add packet extensions, if any are defined. buf.append(getExtensionsXML()); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Packet.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Packet.java index 0fbd14a32..c33f9299e 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Packet.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Packet.java @@ -383,9 +383,21 @@ public abstract class Packet extends TopLevelStreamElement { * @param xml */ protected void addCommonAttributes(XmlStringBuilder xml) { - xml.optAttribute("id", getPacketID()); xml.optAttribute("to", getTo()); xml.optAttribute("from", getFrom()); + xml.optAttribute("id", getPacketID()); xml.xmllangAttribute(getLanguage()); } + + /** + * Append an XMPPError is this packet has one set. + * + * @param xml the XmlStringBuilder to append the error to. + */ + protected void appendErrorIfExists(XmlStringBuilder xml) { + XMPPError error = getError(); + if (error != null) { + xml.append(error.toXML()); + } + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java index 56d042eba..1f84755aa 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java @@ -223,10 +223,8 @@ public final class Presence extends Packet { buf.append(getExtensionsXML()); // Add the error sub-packet, if there is one. - XMPPError error = getError(); - if (error != null) { - buf.append(error.toXML()); - } + appendErrorIfExists(buf); + buf.closeElement(ELEMENT); return buf; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/RosterPacket.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/RosterPacket.java index d1b92ac1d..470b603e7 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/RosterPacket.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/RosterPacket.java @@ -40,6 +40,10 @@ public class RosterPacket extends IQ { private final List rosterItems = new ArrayList(); private String rosterVersion; + public RosterPacket() { + super(ELEMENT, NAMESPACE); + } + /** * Adds a roster item to the packet. * @@ -74,10 +78,7 @@ public class RosterPacket extends IQ { } @Override - public XmlStringBuilder getChildElementXML() { - XmlStringBuilder buf = new XmlStringBuilder(); - buf.halfOpenElement(ELEMENT); - buf.xmlnsAttribute(NAMESPACE); + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { buf.optAttribute("ver", rosterVersion); buf.rightAngleBracket(); @@ -86,7 +87,6 @@ public class RosterPacket extends IQ { buf.append(entry.toXML()); } } - buf.closeElement(ELEMENT); return buf; } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Session.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Session.java index 8f6ed5ea9..2b2ac49ed 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Session.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Session.java @@ -30,7 +30,7 @@ package org.jivesoftware.smack.packet; * * @author Gaston Dombiak */ -public class Session extends IQ { +public class Session extends SimpleIQ { public static final String ELEMENT = "session"; public static final String NAMESPACE = "urn:ietf:params:xml:ns:xmpp-session"; @@ -38,14 +38,10 @@ public class Session extends IQ { private static final String SESSION = '<' + ELEMENT + " xmlns='" + NAMESPACE + "'/>"; public Session() { + super(ELEMENT, NAMESPACE); setType(IQ.Type.set); } - @Override - public String getChildElementXML() { - return SESSION; - } - public static class Feature implements PacketExtension { public static final Session.Feature INSTANCE = new Feature(); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/SimpleIQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/SimpleIQ.java new file mode 100644 index 000000000..cd20108d8 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/SimpleIQ.java @@ -0,0 +1,38 @@ +/** + * + * Copyright © 2014 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.packet; + +/** + * A simple IQ. + *

+ * Simple IQs child elements do not contain further attributes besides 'xmlns'. They may contain additional packet + * extensions. + *

+ */ +public abstract class SimpleIQ extends IQ { + + protected SimpleIQ(String childElementName, String childElementNamespace) { + super(childElementName, childElementNamespace); + } + + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + xml.setEmptyElement(); + return xml; + } + +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java index 6a843bfc9..a56a81289 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java @@ -32,6 +32,8 @@ import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.compress.packet.Compress; import org.jivesoftware.smack.packet.DefaultPacketExtension; +import org.jivesoftware.smack.packet.EmptyResultIQ; +import org.jivesoftware.smack.packet.ErrorIQ; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Packet; @@ -634,10 +636,12 @@ public class PacketParserUtils { } // Only handle unknown IQs of type result. Types of 'get' and 'set' which are not understood // have to be answered with an IQ error response. See the code a few lines below + // Note that if we reach this code, it is guranteed that the result IQ contained a child element + // (RFC 6120 § 8.2.3 6) because otherwhise we would have reached the END_TAG first. else if (IQ.Type.result == type){ // No Provider found for the IQ stanza, parse it to an UnparsedIQ instance // so that the content of the IQ can be examined later on - iqPacket = new UnparsedResultIQ(parseElement(parser)); + iqPacket = new UnparsedResultIQ(elementName, namespace, parseElement(parser)); } } break; @@ -652,32 +656,28 @@ public class PacketParserUtils { } // Decide what to do when an IQ packet was not understood if (iqPacket == null) { - if (connection != null && (IQ.Type.get == type || IQ.Type.set == type)) { + switch (type) { + case get: + case set: + if (connection == null) { + return null; + } // If the IQ stanza is of type "get" or "set" containing a child element qualified // by a namespace with no registered Smack provider, then answer an IQ of type // "error" with code 501 ("feature-not-implemented") - iqPacket = new IQ() { - @Override - public String getChildElementXML() { - return null; - } - }; + iqPacket = new ErrorIQ(new XMPPError(XMPPError.Condition.feature_not_implemented)); iqPacket.setPacketID(id); iqPacket.setTo(from); iqPacket.setFrom(to); - iqPacket.setType(IQ.Type.error); - iqPacket.setError(new XMPPError(XMPPError.Condition.feature_not_implemented)); connection.sendPacket(iqPacket); return null; - } - else { - // If an IQ packet wasn't created above, create an empty IQ packet. - iqPacket = new IQ() { - @Override - public String getChildElementXML() { - return null; - } - }; + case error: + // If an IQ packet wasn't created above, create an empty error IQ packet. + iqPacket = new ErrorIQ(error); + break; + case result: + iqPacket = new EmptyResultIQ(); + break; } } @@ -1077,15 +1077,20 @@ public class PacketParserUtils { * */ public static class UnparsedResultIQ extends IQ { - public UnparsedResultIQ(CharSequence content) { + private UnparsedResultIQ(String element, String namespace, CharSequence content) { + super(element, namespace); this.content = content; } private final CharSequence content; + public CharSequence getContent() { + return content; + } + @Override - public CharSequence getChildElementXML() { - return this.content; + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + throw new UnsupportedOperationException(); } } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java index 0400b98cc..5d6e80fc9 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java @@ -39,8 +39,15 @@ public class XmlStringBuilder implements Appendable, CharSequence { halfOpenElement(e.getElementName()); } + public XmlStringBuilder escapedElement(String name, String escapedContent) { + assert escapedContent != null; + openElement(name); + append(escapedContent); + closeElement(name); + return this; + } + /** - * Does nothing if content is null. * * @param name * @param content @@ -94,6 +101,7 @@ public class XmlStringBuilder implements Appendable, CharSequence { } public XmlStringBuilder halfOpenElement(String name) { + assert(StringUtils.isNotEmpty(name)); sb.append('<').append(name); return this; } @@ -235,8 +243,12 @@ public class XmlStringBuilder implements Appendable, CharSequence { } public XmlStringBuilder prelude(PacketExtension pe) { - halfOpenElement(pe.getElementName()); - xmlnsAttribute(pe.getNamespace()); + return prelude(pe.getElementName(), pe.getNamespace()); + } + + public XmlStringBuilder prelude(String elementName, String namespace) { + halfOpenElement(elementName); + xmlnsAttribute(namespace); return this; } @@ -247,6 +259,13 @@ public class XmlStringBuilder implements Appendable, CharSequence { return this; } + public XmlStringBuilder optAppend(Element element) { + if (element != null) { + append(element.toXML()); + } + return this; + } + public XmlStringBuilder append(XmlStringBuilder xsb) { assert xsb != null; sb.append(xsb.sb); diff --git a/smack-core/src/test/java/org/jivesoftware/smack/RosterTest.java b/smack-core/src/test/java/org/jivesoftware/smack/RosterTest.java index a7a4a78a1..faebc25ab 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/RosterTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/RosterTest.java @@ -655,14 +655,7 @@ public class RosterTest { connection.processPacket(rosterPush); // Create and process the IQ response - final IQ response = new IQ() { - public String getChildElementXML() { - return null; - } - }; - response.setPacketID(rosterRequest.getPacketID()); - response.setType(Type.result); - response.setTo(connection.getUser()); + final IQ response = IQ.createResultIQ(rosterRequest); connection.processPacket(response); // Verify the roster update request diff --git a/smack-core/src/test/java/org/jivesoftware/smack/StanzaIdTest.java b/smack-core/src/test/java/org/jivesoftware/smack/StanzaIdTest.java index 49f06a503..083ec6908 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/StanzaIdTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/StanzaIdTest.java @@ -1,6 +1,6 @@ /** * - * Copyright © Florian Schmaus + * Copyright © 2014 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.TestIQ; import org.jivesoftware.smack.util.StringUtils; import org.junit.Test; @@ -27,26 +28,15 @@ public class StanzaIdTest { @Test public void testIqId() { - IQ iq1 = new TestIqId(); + IQ iq1 = new TestIQ(); String iq1Id = iq1.getPacketID(); assertTrue(StringUtils.isNotEmpty(iq1Id)); - IQ iq2 = new TestIqId(); + IQ iq2 = new TestIQ(); String iq2Id = iq2.getPacketID(); assertTrue(StringUtils.isNotEmpty(iq2Id)); assertFalse(iq1Id.equals(iq2Id)); } - private static class TestIqId extends IQ { - - public TestIqId() { - setType(Type.set); - } - - @Override - public CharSequence getChildElementXML() { - return ""; - } - } } diff --git a/smack-core/src/test/java/org/jivesoftware/smack/packet/IQResponseTest.java b/smack-core/src/test/java/org/jivesoftware/smack/packet/IQResponseTest.java index df3845b4e..9aea18595 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/packet/IQResponseTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/packet/IQResponseTest.java @@ -19,7 +19,6 @@ package org.jivesoftware.smack.packet; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import org.junit.Test; @@ -32,18 +31,15 @@ import org.junit.Test; */ public class IQResponseTest { - final static private String childElement = ""; + private static final String ELEMENT = "child"; + private static final String NAMESPACE = "http://igniterealtime.org/protocol/test"; /** * Test creating a simple and empty IQ response. */ @Test public void testGeneratingSimpleResponse() { - final IQ request = new IQ() { - public String getChildElementXML() { - return childElement; - } - }; + final IQ request = new TestIQ(ELEMENT, NAMESPACE); request.setFrom("sender@test/Smack"); request.setTo("receiver@test/Smack"); @@ -54,7 +50,7 @@ public class IQResponseTest { assertEquals(request.getPacketID(), result.getPacketID()); assertEquals(request.getFrom(), result.getTo()); assertEquals(request.getTo(), result.getFrom()); - assertNull(result.getChildElementXML()); + assertEquals("", result.getChildElementXML().toString()); } /** @@ -63,11 +59,8 @@ public class IQResponseTest { @Test public void testGeneratingValidErrorResponse() { final XMPPError error = new XMPPError(XMPPError.Condition.bad_request); - final IQ request = new IQ() { - public String getChildElementXML() { - return childElement; - } - }; + final IQ request = new TestIQ(ELEMENT, NAMESPACE); + request.setType(IQ.Type.set); request.setFrom("sender@test/Smack"); request.setTo("receiver@test/Smack"); @@ -79,7 +72,8 @@ public class IQResponseTest { assertEquals(request.getPacketID(), result.getPacketID()); assertEquals(request.getFrom(), result.getTo()); assertEquals(error, result.getError()); - assertEquals(childElement, result.getChildElementXML()); + // TODO this test was never valid + // assertEquals(CHILD_ELEMENT, result.getChildElementXML()); } /** @@ -88,11 +82,8 @@ public class IQResponseTest { */ @Test public void testGeneratingResponseBasedOnResult() { - final IQ request = new IQ() { - public String getChildElementXML() { - return childElement; - } - }; + final IQ request = new TestIQ(ELEMENT, NAMESPACE); + request.setType(IQ.Type.result); request.setFrom("sender@test/Smack"); request.setTo("receiver@test/Smack"); @@ -114,11 +105,8 @@ public class IQResponseTest { @Test public void testGeneratingErrorBasedOnError() { final XMPPError error = new XMPPError(XMPPError.Condition.bad_request); - final IQ request = new IQ() { - public String getChildElementXML() { - return childElement; - } - }; + final IQ request = new TestIQ(ELEMENT, NAMESPACE); + request.setType(IQ.Type.error); request.setFrom("sender@test/Smack"); request.setTo("receiver@test/Smack"); diff --git a/smack-core/src/test/java/org/jivesoftware/smack/packet/TestIQ.java b/smack-core/src/test/java/org/jivesoftware/smack/packet/TestIQ.java new file mode 100644 index 000000000..a9f203632 --- /dev/null +++ b/smack-core/src/test/java/org/jivesoftware/smack/packet/TestIQ.java @@ -0,0 +1,35 @@ +/** + * + * Copyright © 2014 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.packet; + +public class TestIQ extends SimpleIQ { + + public TestIQ() { + this(null, null); + } + + public TestIQ(String element, String namespace) { + super(element, namespace); + } + + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + if (getChildElementName() == null) + return null; + return super.getIQChildElementBuilder(xml); + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/carbons/packet/Carbon.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/carbons/packet/Carbon.java index 9dbd21990..ce521caa6 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/carbons/packet/Carbon.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/carbons/packet/Carbon.java @@ -16,7 +16,7 @@ */ package org.jivesoftware.smackx.carbons.packet; -import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.SimpleIQ; /** * Carbon IQs @@ -24,29 +24,23 @@ import org.jivesoftware.smack.packet.IQ; public class Carbon { public static final String NAMESPACE = "urn:xmpp:carbons:2"; - public static class Enable extends IQ { + public static class Enable extends SimpleIQ { public static final String ELEMENT = "enable"; public Enable() { + super(ELEMENT, NAMESPACE); setType(Type.set); } - @Override - public String getChildElementXML() { - return "<" + ELEMENT + " xmlns='" + NAMESPACE + "'/>"; - } } - public static class Disable extends IQ { + public static class Disable extends SimpleIQ { public static final String ELEMENT = "disable"; public Disable() { + super(ELEMENT, NAMESPACE); setType(Type.set); } - @Override - public String getChildElementXML() { - return "<" + ELEMENT + " xmlns='" + NAMESPACE + "'/>"; - } } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/HOXTManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/HOXTManager.java index fd24deeee..20b1b4aec 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/HOXTManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/HOXTManager.java @@ -23,6 +23,7 @@ import org.jivesoftware.smack.XMPPConnectionRegistry; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; +import org.jivesoftware.smackx.hoxt.packet.AbstractHttpOverXmpp; /** * Manager for HTTP ove XMPP transport (XEP-0332) extension. @@ -35,7 +36,7 @@ public class HOXTManager { /** * Namespace for this extension. */ - public static final String NAMESPACE = "urn:xmpp:http"; + public static final String NAMESPACE = AbstractHttpOverXmpp.NAMESPACE; static { XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() { diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/packet/AbstractHttpOverXmpp.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/packet/AbstractHttpOverXmpp.java index 9c326b1c6..ac4a5fc6d 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/packet/AbstractHttpOverXmpp.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/packet/AbstractHttpOverXmpp.java @@ -17,6 +17,8 @@ package org.jivesoftware.smackx.hoxt.packet; import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.NamedElement; +import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smackx.shim.packet.HeadersExtension; /** @@ -27,97 +29,84 @@ import org.jivesoftware.smackx.shim.packet.HeadersExtension; */ public abstract class AbstractHttpOverXmpp extends IQ { + public static final String NAMESPACE = "urn:xmpp:http"; + + protected AbstractHttpOverXmpp(String element) { + super(element, NAMESPACE); + } + + private HeadersExtension headers; + private Data data; + + protected String version; + + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + IQChildElementXmlStringBuilder builder = getIQHoxtChildElementBuilder(xml); + builder.append(headers.toXML()); + builder.append(data.toXML()); + + return builder; + } + /** - * Abstract representation of parent of Req and Resp elements. + * Returns start tag. + * + * @return start tag */ - public static abstract class AbstractBody { + protected abstract IQChildElementXmlStringBuilder getIQHoxtChildElementBuilder(IQChildElementXmlStringBuilder xml); - private HeadersExtension headers; - private Data data; + /** + * Returns version attribute. + * + * @return version attribute + */ + public String getVersion() { + return version; + } - protected String version; + /** + * Sets version attribute. + * + * @param version version attribute + */ + public void setVersion(String version) { + this.version = version; + } - /** - * Returns string containing xml representation of this object. - * - * @return xml representation of this object - */ - public String toXML() { - StringBuilder builder = new StringBuilder(); - builder.append(getStartTag()); - builder.append(headers.toXML()); - builder.append(data.toXML()); - builder.append(getEndTag()); - return builder.toString(); - } + /** + * Returns Headers element. + * + * @return Headers element + */ + public HeadersExtension getHeaders() { + return headers; + } - /** - * Returns start tag. - * - * @return start tag - */ - protected abstract String getStartTag(); + /** + * Sets Headers element. + * + * @param headers Headers element + */ + public void setHeaders(HeadersExtension headers) { + this.headers = headers; + } - /** - * Returns end tag. - * - * @return end tag - */ - protected abstract String getEndTag(); + /** + * Returns Data element. + * + * @return Data element + */ + public Data getData() { + return data; + } - /** - * Returns version attribute. - * - * @return version attribute - */ - public String getVersion() { - return version; - } - - /** - * Sets version attribute. - * - * @param version version attribute - */ - public void setVersion(String version) { - this.version = version; - } - - /** - * Returns Headers element. - * - * @return Headers element - */ - public HeadersExtension getHeaders() { - return headers; - } - - /** - * Sets Headers element. - * - * @param headers Headers element - */ - public void setHeaders(HeadersExtension headers) { - this.headers = headers; - } - - /** - * Returns Data element. - * - * @return Data element - */ - public Data getData() { - return data; - } - - /** - * Sets Data element. - * - * @param data Headers element - */ - public void setData(Data data) { - this.data = data; - } + /** + * Sets Data element. + * + * @param data Headers element + */ + public void setData(Data data) { + this.data = data; } /** @@ -126,14 +115,14 @@ public abstract class AbstractHttpOverXmpp extends IQ { */ public static class Data { - private final DataChild child; + private final NamedElement child; /** * Creates Data element. * * @param child element nested by Data */ - public Data(DataChild child) { + public Data(NamedElement child) { this.child = child; } @@ -155,29 +144,18 @@ public abstract class AbstractHttpOverXmpp extends IQ { * * @return element nested by Data */ - public DataChild getChild() { + public NamedElement getChild() { return child; } } - /** - * Interface for child elements of Data element. - */ - public static interface DataChild { - - /** - * Returns string containing xml representation of this object. - * - * @return xml representation of this object - */ - public String toXML(); - } - /** * Representation of Text element.

* This class is immutable. */ - public static class Text implements DataChild { + public static class Text implements NamedElement { + + public static final String ELEMENT = "text"; private final String text; @@ -191,14 +169,12 @@ public abstract class AbstractHttpOverXmpp extends IQ { } @Override - public String toXML() { - StringBuilder builder = new StringBuilder(); - builder.append(""); - if (text != null) { - builder.append(text); - } - builder.append(""); - return builder.toString(); + public XmlStringBuilder toXML() { + XmlStringBuilder xml = new XmlStringBuilder(this); + xml.rightAngleBracket(); + xml.optAppend(text); + xml.closeElement(this); + return xml; } /** @@ -209,13 +185,20 @@ public abstract class AbstractHttpOverXmpp extends IQ { public String getText() { return text; } + + @Override + public String getElementName() { + return ELEMENT; + } } /** * Representation of Base64 element.

* This class is immutable. */ - public static class Base64 implements DataChild { + public static class Base64 implements NamedElement { + + public static final String ELEMENT = "base64"; private final String text; @@ -229,14 +212,12 @@ public abstract class AbstractHttpOverXmpp extends IQ { } @Override - public String toXML() { - StringBuilder builder = new StringBuilder(); - builder.append(""); - if (text != null) { - builder.append(text); - } - builder.append(""); - return builder.toString(); + public XmlStringBuilder toXML() { + XmlStringBuilder xml = new XmlStringBuilder(this); + xml.rightAngleBracket(); + xml.optAppend(text); + xml.closeElement(this); + return xml; } /** @@ -247,18 +228,25 @@ public abstract class AbstractHttpOverXmpp extends IQ { public String getText() { return text; } + + @Override + public String getElementName() { + return ELEMENT; + } } /** * Representation of Xml element.

* This class is immutable. */ - public static class Xml implements DataChild { + public static class Xml implements NamedElement { + + public static final String ELEMENT = "xml"; private final String text; /** - * Creates this element. + * Creates this element.builder.toString(); * * @param text value of text */ @@ -267,14 +255,12 @@ public abstract class AbstractHttpOverXmpp extends IQ { } @Override - public String toXML() { - StringBuilder builder = new StringBuilder(); - builder.append(""); - if (text != null) { - builder.append(text); - } - builder.append(""); - return builder.toString(); + public XmlStringBuilder toXML() { + XmlStringBuilder xml = new XmlStringBuilder(this); + xml.rightAngleBracket(); + xml.optAppend(text); + xml.closeElement(this); + return xml; } /** @@ -285,13 +271,20 @@ public abstract class AbstractHttpOverXmpp extends IQ { public String getText() { return text; } + + @Override + public String getElementName() { + return ELEMENT; + } } /** * Representation of ChunkedBase64 element.

* This class is immutable. */ - public static class ChunkedBase64 implements DataChild { + public static class ChunkedBase64 implements NamedElement { + + public static final String ELEMENT = "chunkedBase64"; private final String streamId; @@ -305,12 +298,11 @@ public abstract class AbstractHttpOverXmpp extends IQ { } @Override - public String toXML() { - StringBuilder builder = new StringBuilder(); - builder.append(""); - return builder.toString(); + public XmlStringBuilder toXML() { + XmlStringBuilder xml = new XmlStringBuilder(this); + xml.attribute("streamId", streamId); + xml.closeEmptyElement(); + return xml; } /** @@ -321,13 +313,20 @@ public abstract class AbstractHttpOverXmpp extends IQ { public String getStreamId() { return streamId; } + + @Override + public String getElementName() { + return ELEMENT; + } } /** * Representation of Ibb element.

* This class is immutable. */ - public static class Ibb implements DataChild { + public static class Ibb implements NamedElement { + + public static final String ELEMENT = "ibb"; private final String sid; @@ -341,12 +340,11 @@ public abstract class AbstractHttpOverXmpp extends IQ { } @Override - public String toXML() { - StringBuilder builder = new StringBuilder(); - builder.append(""); - return builder.toString(); + public XmlStringBuilder toXML() { + XmlStringBuilder xml = new XmlStringBuilder(this); + xml.attribute("sid", sid); + xml.closeEmptyElement(); + return xml; } /** @@ -357,5 +355,10 @@ public abstract class AbstractHttpOverXmpp extends IQ { public String getSid() { return sid; } + + @Override + public String getElementName() { + return ELEMENT; + } } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/packet/HttpOverXmppReq.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/packet/HttpOverXmppReq.java index c0b6b4104..13bdd8f00 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/packet/HttpOverXmppReq.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/packet/HttpOverXmppReq.java @@ -17,7 +17,6 @@ package org.jivesoftware.smackx.hoxt.packet; import org.jivesoftware.smack.util.StringUtils; -import org.jivesoftware.smackx.hoxt.HOXTManager; /** * Represents Req IQ packet. @@ -27,177 +26,136 @@ import org.jivesoftware.smackx.hoxt.HOXTManager; */ public class HttpOverXmppReq extends AbstractHttpOverXmpp { - private Req req; + public static final String ELEMENT = "req"; + + + public HttpOverXmppReq(HttpMethod method, String resource) { + super(ELEMENT); + this.method = method; + this.resource = resource; + type = Type.set; + } + + private HttpMethod method; + private String resource; + + // TODO: validate: xs:minInclusive value='256' xs:maxInclusive value='65536' + private int maxChunkSize = 0; // 0 means not set + + private boolean sipub = true; + + private boolean ibb = true; + private boolean jingle = true; @Override - public String getChildElementXML() { - return req.toXML(); + protected IQChildElementXmlStringBuilder getIQHoxtChildElementBuilder(IQChildElementXmlStringBuilder builder) { + builder.append(" "); + builder.append("method='").append(method.toString()).append("'"); + builder.append(" "); + builder.append("resource='").append(StringUtils.escapeForXML(resource)).append("'"); + builder.append(" "); + builder.append("version='").append(StringUtils.escapeForXML(version)).append("'"); + if (maxChunkSize != 0) { + builder.append(" "); + builder.append("maxChunkSize='").append(Integer.toString(maxChunkSize)).append("'"); + } + builder.append(" "); + builder.append("sipub='").append(Boolean.toString(sipub)).append("'"); + builder.append(" "); + builder.append("ibb='").append(Boolean.toString(ibb)).append("'"); + builder.append(" "); + builder.append("jingle='").append(Boolean.toString(jingle)).append("'"); + builder.append(">"); + return builder; } /** - * Returns Req element. + * Returns method attribute. * - * @return Req element + * @return method attribute */ - public Req getReq() { - return req; + public HttpMethod getMethod() { + return method; } /** - * Sets Req element. + * Returns resource attribute. * - * @param req Req element + * @return resource attribute */ - public void setReq(Req req) { - this.req = req; + public String getResource() { + return resource; } /** - * Represents Req element. + * Returns maxChunkSize attribute. + * + * @return maxChunkSize attribute */ - public static class Req extends AbstractBody { + public int getMaxChunkSize() { + return maxChunkSize; + } - private HttpMethod method; - private String resource; + /** + * Sets maxChunkSize attribute. + * + * @param maxChunkSize maxChunkSize attribute + */ + public void setMaxChunkSize(int maxChunkSize) { + this.maxChunkSize = maxChunkSize; + } - // TODO: validate: xs:minInclusive value='256' xs:maxInclusive value='65536' - private int maxChunkSize = 0; // 0 means not set + /** + * Returns sipub attribute. + * + * @return sipub attribute + */ + public boolean isSipub() { + return sipub; + } - private boolean sipub = true; + /** + * Sets sipub attribute. + * + * @param sipub sipub attribute + */ + public void setSipub(boolean sipub) { + this.sipub = sipub; + } - private boolean ibb = true; - private boolean jingle = true; + /** + * Returns ibb attribute. + * + * @return ibb attribute + */ + public boolean isIbb() { + return ibb; + } - /** - * Creates this object. - * - * @param method method attribute - * @param resource resource attribute - */ - public Req(HttpMethod method, String resource) { - this.method = method; - this.resource = resource; - } + /** + * Sets ibb attribute. + * + * @param ibb ibb attribute + */ + public void setIbb(boolean ibb) { + this.ibb = ibb; + } - @Override - protected String getStartTag() { - StringBuilder builder = new StringBuilder(); - builder.append(""); - return builder.toString(); - } + /** + * Returns jingle attribute. + * + * @return jingle attribute + */ + public boolean isJingle() { + return jingle; + } - @Override - protected String getEndTag() { - return ""; - } - - /** - * Returns method attribute. - * - * @return method attribute - */ - public HttpMethod getMethod() { - return method; - } - - /** - * Returns resource attribute. - * - * @return resource attribute - */ - public String getResource() { - return resource; - } - - /** - * Returns maxChunkSize attribute. - * - * @return maxChunkSize attribute - */ - public int getMaxChunkSize() { - return maxChunkSize; - } - - /** - * Sets maxChunkSize attribute. - * - * @param maxChunkSize maxChunkSize attribute - */ - public void setMaxChunkSize(int maxChunkSize) { - this.maxChunkSize = maxChunkSize; - } - - /** - * Returns sipub attribute. - * - * @return sipub attribute - */ - public boolean isSipub() { - return sipub; - } - - /** - * Sets sipub attribute. - * - * @param sipub sipub attribute - */ - public void setSipub(boolean sipub) { - this.sipub = sipub; - } - - /** - * Returns ibb attribute. - * - * @return ibb attribute - */ - public boolean isIbb() { - return ibb; - } - - /** - * Sets ibb attribute. - * - * @param ibb ibb attribute - */ - public void setIbb(boolean ibb) { - this.ibb = ibb; - } - - /** - * Returns jingle attribute. - * - * @return jingle attribute - */ - public boolean isJingle() { - return jingle; - } - - /** - * Sets jingle attribute. - * - * @param jingle jingle attribute - */ - public void setJingle(boolean jingle) { - this.jingle = jingle; - } + /** + * Sets jingle attribute. + * + * @param jingle jingle attribute + */ + public void setJingle(boolean jingle) { + this.jingle = jingle; } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/packet/HttpOverXmppResp.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/packet/HttpOverXmppResp.java index 3979a224b..4e134f0d6 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/packet/HttpOverXmppResp.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/packet/HttpOverXmppResp.java @@ -17,7 +17,6 @@ package org.jivesoftware.smackx.hoxt.packet; import org.jivesoftware.smack.util.StringUtils; -import org.jivesoftware.smackx.hoxt.HOXTManager; /** * Represents Resp IQ packet. @@ -27,96 +26,63 @@ import org.jivesoftware.smackx.hoxt.HOXTManager; */ public class HttpOverXmppResp extends AbstractHttpOverXmpp { - private Resp resp; + public static final String ELEMENT = "resp"; + + + public HttpOverXmppResp() { + super(ELEMENT); + } + + private int statusCode; + private String statusMessage = null; @Override - public String getChildElementXML() { - return resp.toXML(); + protected IQChildElementXmlStringBuilder getIQHoxtChildElementBuilder(IQChildElementXmlStringBuilder builder) { + builder.append(" "); + builder.append("version='").append(StringUtils.escapeForXML(version)).append("'"); + builder.append(" "); + builder.append("statusCode='").append(Integer.toString(statusCode)).append("'"); + if (statusMessage != null) { + builder.append(" "); + builder.append("statusMessage='").append(StringUtils.escapeForXML(statusMessage)).append("'"); + } + builder.append(">"); + return builder; } /** - * Returns Resp element. + * Returns statusCode attribute. * - * @return Resp element + * @return statusCode attribute */ - public Resp getResp() { - return resp; + public int getStatusCode() { + return statusCode; } /** - * Sets Resp element. + * Sets statusCode attribute. * - * @param resp Resp element + * @param statusCode statusCode attribute */ - public void setResp(Resp resp) { - this.resp = resp; + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; } /** - * Represents Resp element. + * Returns statusMessage attribute. + * + * @return statusMessage attribute */ - public static class Resp extends AbstractBody { + public String getStatusMessage() { + return statusMessage; + } - private int statusCode; - private String statusMessage = null; - - @Override - protected String getStartTag() { - StringBuilder builder = new StringBuilder(); - builder.append(""); - return builder.toString(); - } - - @Override - protected String getEndTag() { - return ""; - } - - /** - * Returns statusCode attribute. - * - * @return statusCode attribute - */ - public int getStatusCode() { - return statusCode; - } - - /** - * Sets statusCode attribute. - * - * @param statusCode statusCode attribute - */ - public void setStatusCode(int statusCode) { - this.statusCode = statusCode; - } - - /** - * Returns statusMessage attribute. - * - * @return statusMessage attribute - */ - public String getStatusMessage() { - return statusMessage; - } - - /** - * Sets statusMessage attribute. - * - * @param statusMessage statusMessage attribute - */ - public void setStatusMessage(String statusMessage) { - this.statusMessage = statusMessage; - } + /** + * Sets statusMessage attribute. + * + * @param statusMessage statusMessage attribute + */ + public void setStatusMessage(String statusMessage) { + this.statusMessage = statusMessage; } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/AbstractHttpOverXmppProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/AbstractHttpOverXmppProvider.java index 01d188d7a..fcfcac495 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/AbstractHttpOverXmppProvider.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/AbstractHttpOverXmppProvider.java @@ -17,6 +17,7 @@ package org.jivesoftware.smackx.hoxt.provider; import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.packet.NamedElement; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.hoxt.packet.AbstractHttpOverXmpp; @@ -63,7 +64,7 @@ public abstract class AbstractHttpOverXmppProvider { - private static final String ELEMENT_REQ = "req"; - private static final String ATTRIBUTE_METHOD = "method"; private static final String ATTRIBUTE_RESOURCE = "resource"; private static final String ATTRIBUTE_MAX_CHUNK_SIZE = "maxChunkSize"; - /** - * Mandatory no argument constructor. - */ - public HttpOverXmppReqProvider() { - } - @Override public HttpOverXmppReq parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException, SmackException { @@ -53,7 +45,7 @@ public class HttpOverXmppReqProvider extends AbstractHttpOverXmppProvider { - private static final String ELEMENT_RESP = "resp"; - private static final String ATTRIBUTE_STATUS_MESSAGE = "statusMessage"; private static final String ATTRIBUTE_STATUS_CODE = "statusCode"; @@ -44,15 +42,12 @@ public class HttpOverXmppRespProvider extends AbstractHttpOverXmppProvider expectedHeaders) { diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/hoxt/provider/HttpOverXmppReqProviderTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/hoxt/provider/HttpOverXmppReqProviderTest.java index 48e666279..e317ea026 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/hoxt/provider/HttpOverXmppReqProviderTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/hoxt/provider/HttpOverXmppReqProviderTest.java @@ -31,7 +31,7 @@ public class HttpOverXmppReqProviderTest { @Test public void areAllReqAttributesCorrectlyParsed() throws Exception { String string = ""; - HttpOverXmppReq.Req req = parseReq(string); + HttpOverXmppReq req = parseReq(string); assertEquals(req.getVersion(), "1.1"); assertEquals(req.getMethod(), HttpMethod.OPTIONS); assertEquals(req.getResource(), "*"); @@ -40,7 +40,7 @@ public class HttpOverXmppReqProviderTest { @Test public void areGetRequestAttributesCorrectlyParsed() throws Exception { String string = ""; - HttpOverXmppReq.Req req = parseReq(string); + HttpOverXmppReq req = parseReq(string); assertEquals(req.getVersion(), "1.1"); assertEquals(req.getMethod(), HttpMethod.GET); assertEquals(req.getResource(), "/rdf/xep"); @@ -49,7 +49,7 @@ public class HttpOverXmppReqProviderTest { @Test public void getReqOptionAttributesCorrectlyParsed() throws Exception { String string = ""; - HttpOverXmppReq.Req req = parseReq(string); + HttpOverXmppReq req = parseReq(string); assertEquals(req.getMaxChunkSize(), 256); assertEquals(req.isSipub(), false); assertEquals(req.isIbb(), true); @@ -59,18 +59,18 @@ public class HttpOverXmppReqProviderTest { @Test public void getReqOptionalAttributesDefaultValues() throws Exception { String string = ""; - HttpOverXmppReq.Req req = parseReq(string); + HttpOverXmppReq req = parseReq(string); assertEquals(req.isSipub(), true); assertEquals(req.isIbb(), true); assertEquals(req.isJingle(), true); } - private HttpOverXmppReq.Req parseReq(String string) throws Exception { + private HttpOverXmppReq parseReq(String string) throws Exception { HttpOverXmppReqProvider provider = new HttpOverXmppReqProvider(); XmlPullParser parser = PacketParserUtils.getParserFor(string); IQ iq = provider.parse(parser); assertTrue(iq instanceof HttpOverXmppReq); HttpOverXmppReq castedIq = (HttpOverXmppReq) iq; - return castedIq.getReq(); + return castedIq; } } diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/hoxt/provider/HttpOverXmppRespProviderTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/hoxt/provider/HttpOverXmppRespProviderTest.java index 867b51a6c..6da0887a3 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/hoxt/provider/HttpOverXmppRespProviderTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/hoxt/provider/HttpOverXmppRespProviderTest.java @@ -39,8 +39,7 @@ public class HttpOverXmppRespProviderTest { IQ iq = provider.parse(parser); assertTrue(iq instanceof HttpOverXmppResp); - HttpOverXmppResp castedIq = (HttpOverXmppResp) iq; - HttpOverXmppResp.Resp resp = castedIq.getResp(); + HttpOverXmppResp resp = (HttpOverXmppResp) iq; assertEquals(resp.getVersion(), "1.1"); assertEquals(resp.getStatusCode(), 200); @@ -55,8 +54,7 @@ public class HttpOverXmppRespProviderTest { IQ iq = provider.parse(parser); assertTrue(iq instanceof HttpOverXmppResp); - HttpOverXmppResp castedIq = (HttpOverXmppResp) iq; - HttpOverXmppResp.Resp resp = castedIq.getResp(); + HttpOverXmppResp resp = (HttpOverXmppResp) iq; assertEquals(resp.getVersion(), "1.1"); assertEquals(resp.getStatusCode(), 200); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java index 0db995261..6771dda13 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java @@ -33,7 +33,6 @@ import org.jivesoftware.smack.filter.PacketTypeFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Packet; -import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.util.stringencoder.Base64; import org.jivesoftware.smackx.bytestreams.BytestreamSession; @@ -450,9 +449,7 @@ public class InBandBytestreamSession implements BytestreamSession { public void processPacket(Packet packet) throws NotConnectedException { // get data packet extension - DataPacketExtension data = (DataPacketExtension) packet.getExtension( - DataPacketExtension.ELEMENT, - DataPacketExtension.NAMESPACE); + DataPacketExtension data = ((Data) packet).getDataPacketExtension(); /* * check if sequence was not used already (see XEP-0047 Section 2.2) @@ -562,15 +559,20 @@ public class InBandBytestreamSession implements BytestreamSession { return false; } - // stanza contains data packet extension - PacketExtension packetExtension = packet.getExtension(DataPacketExtension.ELEMENT, - DataPacketExtension.NAMESPACE); - if (packetExtension == null || !(packetExtension instanceof DataPacketExtension)) { - return false; + DataPacketExtension data; + if (packet instanceof Data) { + data = ((Data) packet).getDataPacketExtension(); + } else { + // stanza contains data packet extension + data = packet.getExtension( + DataPacketExtension.ELEMENT, + DataPacketExtension.NAMESPACE); + if (data == null) { + return false; + } } // session ID equals this session ID - DataPacketExtension data = (DataPacketExtension) packetExtension; if (!data.getSessionID().equals(byteStreamRequest.getSessionID())) { return false; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Close.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Close.java index 9b6412eba..40d295169 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Close.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Close.java @@ -17,7 +17,6 @@ package org.jivesoftware.smackx.bytestreams.ibb.packet; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smack.util.XmlStringBuilder; /** * Represents a request to close an In-Band Bytestream. @@ -27,6 +26,7 @@ import org.jivesoftware.smack.util.XmlStringBuilder; public class Close extends IQ { public static final String ELEMENT = "close"; + public static final String NAMESPACE = DataPacketExtension.NAMESPACE; /* unique session ID identifying this In-Band Bytestream */ private final String sessionID; @@ -37,6 +37,7 @@ public class Close extends IQ { * @param sessionID unique session ID identifying this In-Band Bytestream */ public Close(String sessionID) { + super(ELEMENT, NAMESPACE); if (sessionID == null || "".equals(sessionID)) { throw new IllegalArgumentException("Session ID must not be null or empty"); } @@ -54,12 +55,9 @@ public class Close extends IQ { } @Override - public XmlStringBuilder getChildElementXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement(ELEMENT); - xml.xmlnsAttribute(DataPacketExtension.NAMESPACE); + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { xml.attribute("sid", sessionID); - xml.closeEmptyElement(); + xml.setEmptyElement(); return xml; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Data.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Data.java index 7c950771e..25000231a 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Data.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Data.java @@ -17,7 +17,6 @@ package org.jivesoftware.smackx.bytestreams.ibb.packet; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smack.util.XmlStringBuilder; /** * Represents a chunk of data sent over an In-Band Bytestream encapsulated in an @@ -36,24 +35,17 @@ public class Data extends IQ { * @param data data packet extension containing the encoded data */ public Data(DataPacketExtension data) { + super(DataPacketExtension.ELEMENT, DataPacketExtension.NAMESPACE); if (data == null) { throw new IllegalArgumentException("Data must not be null"); } this.dataPacketExtension = data; - /* - * also set as packet extension so that data packet extension can be - * retrieved from IQ stanza and message stanza in the same way - */ - addExtension(data); setType(IQ.Type.set); } /** * Returns the data packet extension. - *

- * Convenience method for packet.getExtension("data", - * "http://jabber.org/protocol/ibb"). * * @return the data packet extension */ @@ -62,8 +54,8 @@ public class Data extends IQ { } @Override - public XmlStringBuilder getChildElementXML() { - return dataPacketExtension.toXML(); + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + return dataPacketExtension.getIQChildElementBuilder(xml); } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/DataPacketExtension.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/DataPacketExtension.java index eea083def..71534f8c9 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/DataPacketExtension.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/DataPacketExtension.java @@ -17,6 +17,7 @@ package org.jivesoftware.smackx.bytestreams.ibb.packet; import org.jivesoftware.smack.packet.PacketExtension; +import org.jivesoftware.smack.packet.IQ.IQChildElementXmlStringBuilder; import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smack.util.stringencoder.Base64; @@ -135,13 +136,16 @@ public class DataPacketExtension implements PacketExtension { @Override public XmlStringBuilder toXML() { - XmlStringBuilder xml = new XmlStringBuilder(this); - xml.attribute("seq", Long.toString(seq)); - xml.attribute("sid", sessionID); - xml.rightAngleBracket(); - xml.append(data); + XmlStringBuilder xml = getIQChildElementBuilder(new IQChildElementXmlStringBuilder(this)); xml.closeElement(this); return xml; } + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + xml.attribute("seq", Long.toString(seq)); + xml.attribute("sid", sessionID); + xml.rightAngleBracket(); + xml.append(data); + return xml; + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Open.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Open.java index 3f1f915bc..7613c36d2 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Open.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/packet/Open.java @@ -19,7 +19,7 @@ package org.jivesoftware.smackx.bytestreams.ibb.packet; import java.util.Locale; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smack.packet.IQ.IQChildElementXmlStringBuilder; import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager.StanzaType; /** @@ -30,6 +30,7 @@ import org.jivesoftware.smackx.bytestreams.ibb.InBandBytestreamManager.StanzaTyp public class Open extends IQ { public static final String ELEMENT = "open"; + public static final String NAMESPACE = DataPacketExtension.NAMESPACE; /* unique session ID identifying this In-Band Bytestream */ private final String sessionID; @@ -54,6 +55,7 @@ public class Open extends IQ { * @param stanza stanza type used to encapsulate the data */ public Open(String sessionID, int blockSize, StanzaType stanza) { + super(ELEMENT, NAMESPACE); if (sessionID == null || "".equals(sessionID)) { throw new IllegalArgumentException("Session ID must not be null or empty"); } @@ -111,14 +113,11 @@ public class Open extends IQ { } @Override - public XmlStringBuilder getChildElementXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement(ELEMENT); - xml.xmlnsAttribute(DataPacketExtension.NAMESPACE); + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { xml.attribute("block-size", Integer.toString(blockSize)); xml.attribute("sid", sessionID); xml.attribute("stanza", stanza.toString().toLowerCase(Locale.US)); - xml.closeEmptyElement(); + xml.setEmptyElement(); return xml; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java index b6febddd4..2b29ef024 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/packet/Bytestream.java @@ -49,6 +49,7 @@ public class Bytestream extends IQ { * The default constructor */ public Bytestream() { + super(QUERY_ELEMENT, NAMESPACE); } /** @@ -58,6 +59,7 @@ public class Bytestream extends IQ { * @see #setSessionID(String) */ public Bytestream(final String SID) { + this(); setSessionID(SID); } @@ -215,11 +217,7 @@ public class Bytestream extends IQ { } @Override - public XmlStringBuilder getChildElementXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement(QUERY_ELEMENT); - xml.xmlnsAttribute(NAMESPACE); - + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { switch(getType()) { case set: xml.optAttribute("sid", getSessionID()); @@ -236,25 +234,20 @@ public class Bytestream extends IQ { break; case result: xml.rightAngleBracket(); - if (getUsedHost() != null) { - xml.append(getUsedHost().toXML()); - } + xml.optAppend(getUsedHost()); + // TODO Bytestream can include either used host *or* streamHosts. Never both. This should be ensured by the + // constructions mechanisms of Bytestream // A result from the server can also contain stream hosts - else if (countStreamHosts() > 0) { - for (StreamHost host : streamHosts) { - xml.append(host.toXML()); - } + for (StreamHost host : streamHosts) { + xml.append(host.toXML()); } break; case get: - xml.closeEmptyElement(); - // Return here so that we don't run into the - // closeElement(QUERY_ELEMNT) section - return xml; + xml.setEmptyElement(); + break; default: throw new IllegalStateException(); } - xml.closeElement(QUERY_ELEMENT); return xml; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/packet/AdHocCommandData.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/packet/AdHocCommandData.java index 332625f47..fc58c8088 100755 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/packet/AdHocCommandData.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/packet/AdHocCommandData.java @@ -19,7 +19,6 @@ package org.jivesoftware.smackx.commands.packet; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.PacketExtension; -import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smackx.commands.AdHocCommand; import org.jivesoftware.smackx.commands.AdHocCommand.Action; import org.jivesoftware.smackx.commands.AdHocCommand.SpecificErrorCondition; @@ -66,12 +65,11 @@ public class AdHocCommandData extends IQ { private AdHocCommand.Action executeAction; public AdHocCommandData() { + super(ELEMENT, NAMESPACE); } @Override - public XmlStringBuilder getChildElementXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement(ELEMENT).xmlnsAttribute(NAMESPACE); + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { xml.attribute("node", node); xml.optAttribute("sessionid", sessionID); xml.optAttribute("status", status); @@ -108,7 +106,6 @@ public class AdHocCommandData extends IQ { // buf.append(getError().toXML()); // } - xml.closeElement(ELEMENT); return xml; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java index 7e5d70f77..9b7e97159 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java @@ -40,6 +40,7 @@ import java.util.Set; */ public class DiscoverInfo extends IQ implements Cloneable { + public static final String ELEMENT = QUERY_ELEMENT; public static final String NAMESPACE = "http://jabber.org/protocol/disco#info"; private final List features = new LinkedList(); @@ -50,7 +51,7 @@ public class DiscoverInfo extends IQ implements Cloneable { private boolean containsDuplicateFeatures; public DiscoverInfo() { - super(); + super(ELEMENT, NAMESPACE); } /** @@ -212,10 +213,7 @@ public class DiscoverInfo extends IQ implements Cloneable { } @Override - public CharSequence getChildElementXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement("query"); - xml.xmlnsAttribute(NAMESPACE); + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { xml.optAttribute("node", getNode()); xml.rightAngleBracket(); for (Identity identity : identities) { @@ -224,9 +222,7 @@ public class DiscoverInfo extends IQ implements Cloneable { for (Feature feature : features) { xml.append(feature.toXML()); } - // Add packet extensions, if any are defined. - xml.append(getExtensionsXML()); - xml.closeElement("query"); + return xml; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverItems.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverItems.java index 7f295d88a..50636e616 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverItems.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverItems.java @@ -35,11 +35,16 @@ import java.util.List; */ public class DiscoverItems extends IQ { + public static final String ELEMENT = QUERY_ELEMENT; public static final String NAMESPACE = "http://jabber.org/protocol/disco#items"; private final List items = new LinkedList(); private String node; + public DiscoverItems() { + super(ELEMENT, NAMESPACE); + } + /** * Adds a new item to the discovered information. * @@ -97,10 +102,8 @@ public class DiscoverItems extends IQ { this.node = node; } - public XmlStringBuilder getChildElementXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement("query"); - xml.xmlnsAttribute(NAMESPACE); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { xml.optAttribute("node", getNode()); xml.rightAngleBracket(); @@ -108,7 +111,6 @@ public class DiscoverItems extends IQ { xml.append(item.toXML()); } - xml.closeElement("query"); return xml; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/packet/LastActivity.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/packet/LastActivity.java index d05eb8a8b..b4cd6fcd6 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/packet/LastActivity.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/packet/LastActivity.java @@ -22,7 +22,6 @@ import java.io.IOException; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.provider.IQProvider; -import org.jivesoftware.smack.util.XmlStringBuilder; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -37,12 +36,14 @@ import org.xmlpull.v1.XmlPullParserException; */ public class LastActivity extends IQ { + public static final String ELEMENT = QUERY_ELEMENT; public static final String NAMESPACE = "jabber:iq:last"; public long lastActivity = -1; public String message; public LastActivity() { + super(ELEMENT, NAMESPACE); setType(IQ.Type.get); } @@ -52,15 +53,12 @@ public class LastActivity extends IQ { } @Override - public XmlStringBuilder getChildElementXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement(IQ.QUERY_ELEMENT); - xml.xmlnsAttribute(NAMESPACE); + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { xml.optLongAttribute("seconds", lastActivity); // We don't support adding the optional message attribute, because it is usually only added // by XMPP servers and not by client entities. - xml.closeEmptyElement(); + xml.setEmptyElement(); return xml; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java index 54916e6ce..5c7b910b9 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java @@ -27,6 +27,7 @@ import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smackx.iqprivate.packet.DefaultPrivateData; import org.jivesoftware.smackx.iqprivate.packet.PrivateData; +import org.jivesoftware.smackx.iqprivate.packet.PrivateDataIQ; import org.jivesoftware.smackx.iqprivate.provider.PrivateDataProvider; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -156,18 +157,9 @@ public class PrivateDataManager extends Manager { public PrivateData getPrivateData(final String elementName, final String namespace) throws NoResponseException, XMPPErrorException, NotConnectedException { // Create an IQ packet to get the private data. - IQ privateDataGet = new IQ() { - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - buf.append(""); - buf.append("<").append(elementName).append(" xmlns=\"").append(namespace).append("\"/>"); - buf.append(""); - return buf.toString(); - } - }; - privateDataGet.setType(IQ.Type.get); + IQ privateDataGet = new PrivateDataIQ(elementName, namespace); - PrivateDataResult response = (PrivateDataResult) connection().createPacketCollectorAndSend( + PrivateDataIQ response = connection().createPacketCollectorAndSend( privateDataGet).nextResultOrThrow(); return response.getPrivateData(); } @@ -184,16 +176,7 @@ public class PrivateDataManager extends Manager { */ public void setPrivateData(final PrivateData privateData) throws NoResponseException, XMPPErrorException, NotConnectedException { // Create an IQ packet to set the private data. - IQ privateDataSet = new IQ() { - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - buf.append(""); - buf.append(privateData.toXML()); - buf.append(""); - return buf.toString(); - } - }; - privateDataSet.setType(IQ.Type.set); + IQ privateDataSet = new PrivateDataIQ(privateData); connection().createPacketCollectorAndSend(privateDataSet).nextResultOrThrow(); } @@ -214,10 +197,10 @@ public class PrivateDataManager extends Manager { /** * An IQ provider to parse IQ results containing private data. */ - public static class PrivateDataIQProvider extends IQProvider { + public static class PrivateDataIQProvider extends IQProvider { @Override - public PrivateDataResult parse(XmlPullParser parser, int initialDepth) + public PrivateDataIQ parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException, SmackException { PrivateData privateData = null; boolean done = false; @@ -268,33 +251,7 @@ public class PrivateDataManager extends Manager { } } } - return new PrivateDataResult(privateData); - } - } - - /** - * An IQ packet to hold PrivateData GET results. - */ - private static class PrivateDataResult extends IQ { - - private PrivateData privateData; - - PrivateDataResult(PrivateData privateData) { - this.privateData = privateData; - } - - public PrivateData getPrivateData() { - return privateData; - } - - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - buf.append(""); - if (privateData != null) { - buf.append(privateData.toXML()); - } - buf.append(""); - return buf.toString(); + return new PrivateDataIQ(privateData); } } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateDataIQ.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateDataIQ.java new file mode 100644 index 000000000..6063e040e --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/packet/PrivateDataIQ.java @@ -0,0 +1,61 @@ +/** + * + * Copyright © 2014 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smackx.iqprivate.packet; + +import org.jivesoftware.smack.packet.IQ; + +public class PrivateDataIQ extends IQ { + + public static final String ELEMENT = QUERY_ELEMENT; + public static final String NAMESPACE = "jabber:iq:private"; + + private final PrivateData privateData; + private final String getElement; + private final String getNamespace; + + public PrivateDataIQ(PrivateData privateData) { + this(privateData, null, null); + setType(Type.set); + } + + public PrivateDataIQ(String element, String namespace) { + this(null, element, namespace); + setType(Type.get); + } + + private PrivateDataIQ(PrivateData privateData, String getElement, String getNamespace) { + super(ELEMENT, NAMESPACE); + this.privateData = privateData; + this.getElement = getElement; + this.getNamespace = getNamespace; + } + + public PrivateData getPrivateData() { + return privateData; + } + + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + xml.rightAngleBracket(); + if (privateData != null) { + xml.append(privateData.toXML()); + } else { + xml.halfOpenElement(getElement).xmlnsAttribute(getNamespace).closeEmptyElement(); + } + return xml; + } +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/packet/Registration.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/packet/Registration.java index 4cd4a8b9c..fe78b61b8 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/packet/Registration.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/packet/Registration.java @@ -21,7 +21,6 @@ import java.util.Map; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.PacketExtension; -import org.jivesoftware.smack.util.XmlStringBuilder; /** * Represents registration packets. An empty GET query will cause the server to return information @@ -48,6 +47,7 @@ import org.jivesoftware.smack.util.XmlStringBuilder; */ public class Registration extends IQ { + public static final String ELEMENT = QUERY_ELEMENT; public static final String NAMESPACE = "jabber:iq:register"; private final String instructions; @@ -62,6 +62,7 @@ public class Registration extends IQ { } public Registration(String instructions, Map attributes) { + super(ELEMENT, NAMESPACE); this.instructions = instructions; this.attributes = attributes; } @@ -87,10 +88,7 @@ public class Registration extends IQ { } @Override - public XmlStringBuilder getChildElementXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement(QUERY_ELEMENT); - xml.xmlnsAttribute(NAMESPACE); + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { xml.rightAngleBracket(); xml.optElement("instructions", instructions); if (attributes != null && attributes.size() > 0) { @@ -99,9 +97,6 @@ public class Registration extends IQ { xml.element(name, value); } } - // Add packet extensions, if any are defined. - xml.append(getExtensionsXML()); - xml.closeElement(QUERY_ELEMENT); return xml; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/packet/Version.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/packet/Version.java index e87843be5..6ffbcd03b 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/packet/Version.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/packet/Version.java @@ -20,7 +20,6 @@ package org.jivesoftware.smackx.iqversion.packet; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Packet; -import org.jivesoftware.smack.util.XmlStringBuilder; /** * A Version IQ packet, which is used by XMPP clients to discover version information @@ -49,6 +48,7 @@ import org.jivesoftware.smack.util.XmlStringBuilder; * @author Gaston Dombiak */ public class Version extends IQ { + public static final String ELEMENT = QUERY_ELEMENT; public static final String NAMESPACE = "jabber:iq:version"; private final String name; @@ -56,6 +56,7 @@ public class Version extends IQ { private String os; public Version() { + super(ELEMENT, NAMESPACE); name = null; version = null; setType(Type.get); @@ -83,6 +84,7 @@ public class Version extends IQ { * @param os The operating system of the queried entity. This element is OPTIONAL. */ public Version(String name, String version, String os) { + super(ELEMENT, NAMESPACE); if (name == null) { throw new IllegalArgumentException("name must not be null"); @@ -141,15 +143,13 @@ public class Version extends IQ { } @Override - public XmlStringBuilder getChildElementXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement(IQ.QUERY_ELEMENT).xmlnsAttribute(NAMESPACE).rightAngleBracket(); + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + xml.rightAngleBracket(); // Although not really optional elements, 'name' and 'version' are not set when sending a // version request. So we must handle the case that those are 'null' here. xml.optElement("name", name); xml.optElement("version", version); xml.optElement("os", os); - xml.closeElement(IQ.QUERY_ELEMENT); return xml; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCAdmin.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCAdmin.java index ed264288e..33b970213 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCAdmin.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCAdmin.java @@ -21,7 +21,6 @@ import java.util.Collections; import java.util.List; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smack.util.XmlStringBuilder; /** * IQ packet that serves for kicking users, granting and revoking voice, banning users, @@ -33,10 +32,15 @@ import org.jivesoftware.smack.util.XmlStringBuilder; */ public class MUCAdmin extends IQ { + public static final String ELEMENT = QUERY_ELEMENT; public static final String NAMESPACE = MUCInitialPresence.NAMESPACE + "#admin"; private final List items = new ArrayList(); + public MUCAdmin() { + super(ELEMENT, NAMESPACE); + } + /** * Returns a List of item childs that holds information about roles, affiliation, * jids and nicks. @@ -62,19 +66,15 @@ public class MUCAdmin extends IQ { } @Override - public XmlStringBuilder getChildElementXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement(IQ.QUERY_ELEMENT); - xml.xmlnsAttribute(NAMESPACE); + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { xml.rightAngleBracket(); + synchronized (items) { for (MUCItem item : items) { xml.append(item.toXML()); } } - // Add packet extensions, if any are defined. - xml.append(getExtensionsXML()); - xml.closeElement(IQ.QUERY_ELEMENT); + return xml; } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCOwner.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCOwner.java index 8f9352a14..50f694d99 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCOwner.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/packet/MUCOwner.java @@ -17,7 +17,6 @@ package org.jivesoftware.smackx.muc.packet; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smack.util.XmlStringBuilder; import java.util.ArrayList; import java.util.Collections; @@ -32,11 +31,16 @@ import java.util.List; */ public class MUCOwner extends IQ { + public static final String ELEMENT = QUERY_ELEMENT; public static final String NAMESPACE = MUCInitialPresence.NAMESPACE + "#owner"; private final List items = new ArrayList(); private Destroy destroy; + public MUCOwner() { + super(ELEMENT, NAMESPACE); + } + /** * Returns a List of item childs that holds information about affiliation, * jids and nicks. @@ -84,20 +88,16 @@ public class MUCOwner extends IQ { } @Override - public XmlStringBuilder getChildElementXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement(IQ.QUERY_ELEMENT); - xml.xmlnsAttribute(NAMESPACE); + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { xml.rightAngleBracket(); + synchronized (items) { for (MUCItem item : items) { xml.append(item.toXML()); } } xml.optElement(getDestroy()); - // Add packet extensions, if any are defined. - xml.append(getExtensionsXML()); - xml.closeElement(IQ.QUERY_ELEMENT); + return xml; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/offline/packet/OfflineMessageRequest.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/offline/packet/OfflineMessageRequest.java index ee9bb9829..67f294740 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/offline/packet/OfflineMessageRequest.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/offline/packet/OfflineMessageRequest.java @@ -35,10 +35,17 @@ import java.util.List; */ public class OfflineMessageRequest extends IQ { + public static final String ELEMENT = "offline"; + public static final String NAMESPACE = "http://jabber.org/protocol/offline"; + private List items = new ArrayList(); private boolean purge = false; private boolean fetch = false; + public OfflineMessageRequest() { + super(ELEMENT, NAMESPACE); + } + /** * Returns a List of item childs that holds information about offline messages to * view or delete. @@ -99,9 +106,10 @@ public class OfflineMessageRequest extends IQ { this.fetch = fetch; } - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - buf.append(""); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.rightAngleBracket(); + synchronized (items) { for (int i = 0; i < items.size(); i++) { Item item = items.get(i); @@ -114,10 +122,8 @@ public class OfflineMessageRequest extends IQ { if (fetch) { buf.append(""); } - // Add packet extensions, if any are defined. - buf.append(getExtensionsXML()); - buf.append(""); - return buf.toString(); + + return buf; } /** diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/packet/PEPPubSub.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/packet/PEPPubSub.java index a2514426d..f3cc4d1bc 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/packet/PEPPubSub.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/packet/PEPPubSub.java @@ -29,39 +29,20 @@ import org.jivesoftware.smack.packet.IQ; */ public class PEPPubSub extends IQ { - PEPItem item; + public static final String ELEMENT = "pubsub"; + public static final String NAMESPACE = "http://jabber.org/protocol/pubsub"; + + private final PEPItem item; /** * Creates a new PubSub. * */ public PEPPubSub(PEPItem item) { - super(); - + super(ELEMENT, NAMESPACE); this.item = item; } - /** - * Returns the XML element name of the extension sub-packet root element. - * Always returns "x" - * - * @return the XML element name of the packet extension. - */ - public String getElementName() { - return "pubsub"; - } - - /** - * Returns the XML namespace of the extension sub-packet root element. - * According the specification the namespace is always "jabber:x:roster" - * (which is not to be confused with the 'jabber:iq:roster' namespace - * - * @return the XML namespace of the packet extension. - */ - public String getNamespace() { - return "http://jabber.org/protocol/pubsub"; - } - /** * Returns the XML representation of a Personal Event Publish according the specification. * @@ -79,14 +60,15 @@ public class PEPPubSub extends IQ { *

* */ - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append("\">"); - buf.append(""); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.rightAngleBracket(); + + buf.openElement("publish").attribute("node", item.getNode()).rightAngleBracket(); buf.append(item.toXML()); - buf.append(""); - buf.append(""); - return buf.toString(); + buf.closeElement("publish"); + + return buf; } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java index 596b4c278..0686753d1 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java @@ -17,25 +17,23 @@ package org.jivesoftware.smackx.ping.packet; import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.SimpleIQ; -public class Ping extends IQ { +public class Ping extends SimpleIQ { public static final String ELEMENT = "ping"; public static final String NAMESPACE = "urn:xmpp:ping"; public Ping() { + super(ELEMENT, NAMESPACE); } public Ping(String to) { + this(); setTo(to); setType(IQ.Type.get); } - @Override - public String getChildElementXML() { - return '<' + ELEMENT + " xmlns='" + NAMESPACE + "'/>"; - } - /** * Create a XMPP Pong for this Ping * diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java index 88c218017..946ee845f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java @@ -56,7 +56,7 @@ import org.jivesoftware.smackx.privacy.packet.PrivacyItem; * @see XEP-16: Privacy Lists */ public class PrivacyListManager extends Manager { - public static final String NAMESPACE = "jabber:iq:privacy"; + public static final String NAMESPACE = Privacy.NAMESPACE; private static final PacketFilter PACKET_FILTER = new AndFilter(IQTypeFilter.SET, new PacketExtensionFilter("query", NAMESPACE)); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/packet/Privacy.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/packet/Privacy.java index 94b6b2794..3de3faf29 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/packet/Privacy.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/packet/Privacy.java @@ -23,7 +23,6 @@ import java.util.Map; import java.util.Set; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smackx.privacy.PrivacyListManager; /** * A Privacy IQ Packet, is used by the {@link org.jivesoftware.smackx.privacy.PrivacyListManager} @@ -43,6 +42,9 @@ import org.jivesoftware.smackx.privacy.PrivacyListManager; * @author Francisco Vives */ public class Privacy extends IQ { + public static final String ELEMENT = QUERY_ELEMENT; + public static final String NAMESPACE = "jabber:iq:privacy"; + /** declineActiveList is true when the user declines the use of the active list **/ private boolean declineActiveList=false; /** activeName is the name associated with the active list set for the session **/ @@ -55,6 +57,10 @@ public class Privacy extends IQ { * key is the name of the list and the value a collection with privacy items. **/ private Map> itemLists = new HashMap>(); + public Privacy() { + super(ELEMENT, NAMESPACE); + } + /** * Set or update a privacy list with privacy items. * @@ -276,10 +282,10 @@ public class Privacy extends IQ { public Set getPrivacyListNames() { return this.itemLists.keySet(); } - - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - buf.append(""); + + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.rightAngleBracket(); // Add the active tag if (this.isDeclineActiveList()) { @@ -318,10 +324,7 @@ public class Privacy extends IQ { } } - // Add packet extensions, if any are defined. - buf.append(getExtensionsXML()); - buf.append(""); - return buf.toString(); + return buf; } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java index 9086495fc..e9713f8ef 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java @@ -18,7 +18,6 @@ package org.jivesoftware.smackx.pubsub.packet; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.PacketExtension; -import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smackx.pubsub.PubSubElementType; /** @@ -36,9 +35,11 @@ public class PubSub extends IQ private PubSubNamespace ns = PubSubNamespace.BASIC; public PubSub() { + super(ELEMENT, NAMESPACE); } public PubSub(String to, Type type) { + this(); setTo(to); setType(type); } @@ -119,11 +120,11 @@ public class PubSub extends IQ * */ @Override - public XmlStringBuilder getChildElementXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement(getElementName()).xmlnsAttribute(getNamespace()).rightAngleBracket(); - xml.append(getExtensionsXML()); - xml.closeElement(getElementName()); + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + // N.B. We could use SimpleIQ here, but PubSub IQs will nearly *always* have packet extensions, which means that + // SimpleIQs xml.setEmptyElement() is counter-productive in this case and we use xml.rightAngleBracket() + // instead, as there are likely sub-elements to follow. + xml.rightAngleBracket(); return xml; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/search/SimpleUserSearch.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/search/SimpleUserSearch.java index 08a056771..2eeee0361 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/search/SimpleUserSearch.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/search/SimpleUserSearch.java @@ -35,9 +35,16 @@ import java.util.List; */ class SimpleUserSearch extends IQ { + public static final String ELEMENT = UserSearch.ELEMENT; + public static final String NAMESPACE = UserSearch.NAMESPACE; + private Form form; private ReportedData data; + public SimpleUserSearch() { + super(ELEMENT, NAMESPACE); + } + public void setForm(Form form) { this.form = form; } @@ -46,13 +53,11 @@ class SimpleUserSearch extends IQ { return data; } - - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - buf.append(""); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.rightAngleBracket(); buf.append(getItemsToSearch()); - buf.append(""); - return buf.toString(); + return buf; } private String getItemsToSearch() { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/search/UserSearch.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/search/UserSearch.java index 9b77c8e64..2d9842a4f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/search/UserSearch.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/search/UserSearch.java @@ -24,9 +24,9 @@ import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.SimpleIQ; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.util.PacketParserUtils; -import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.packet.DataForm; @@ -43,25 +43,16 @@ import org.xmlpull.v1.XmlPullParserException; * * @author Derek DeMoro */ -public class UserSearch extends IQ { +public class UserSearch extends SimpleIQ { + public static final String ELEMENT = QUERY_ELEMENT; public static final String NAMESPACE = "jabber:iq:search"; /** * Creates a new instance of UserSearch. */ public UserSearch() { - } - - @Override - public XmlStringBuilder getChildElementXML() { - XmlStringBuilder xml = new XmlStringBuilder(); - xml.halfOpenElement(IQ.QUERY_ELEMENT); - xml.xmlnsAttribute(NAMESPACE); - xml.rightAngleBracket(); - xml.append(getExtensionsXML()); - xml.closeElement(IQ.QUERY_ELEMENT); - return xml; + super(ELEMENT, NAMESPACE); } /** diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/sharedgroups/packet/SharedGroupsInfo.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/sharedgroups/packet/SharedGroupsInfo.java index 806073df6..c50c93e0d 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/sharedgroups/packet/SharedGroupsInfo.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/sharedgroups/packet/SharedGroupsInfo.java @@ -36,8 +36,15 @@ import java.util.List; */ public class SharedGroupsInfo extends IQ { + public static final String ELEMENT = "sharedgroup"; + public static final String NAMESPACE = "http://www.jivesoftware.org/protocol/sharedgroup"; + private List groups = new ArrayList(); + public SharedGroupsInfo() { + super(ELEMENT, NAMESPACE); + } + /** * Returns a collection with the shared group names returned from the server. * @@ -47,14 +54,13 @@ public class SharedGroupsInfo extends IQ { return groups; } - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - buf.append(""); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.rightAngleBracket(); for (String group : groups) { - buf.append("").append(group).append(""); + buf.element("group", group); } - buf.append(""); - return buf.toString(); + return buf; } /** diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/si/packet/StreamInitiation.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/si/packet/StreamInitiation.java index d0b9f544c..bb405ee7b 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/si/packet/StreamInitiation.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/si/packet/StreamInitiation.java @@ -31,6 +31,9 @@ import org.jivesoftware.smackx.xdata.packet.DataForm; */ public class StreamInitiation extends IQ { + public static final String ELEMENT = "si"; + public static final String NAMESPACE = "http://jabber.org/protocol/si"; + private String id; private String mimeType; @@ -39,6 +42,10 @@ public class StreamInitiation extends IQ { private Feature featureNegotiation; + public StreamInitiation() { + super(ELEMENT, NAMESPACE); + } + /** * The "id" attribute is an opaque identifier. This attribute MUST be * present on type='set', and MUST be a valid string. This SHOULD NOT be @@ -127,41 +134,28 @@ public class StreamInitiation extends IQ { return featureNegotiation.getData(); } - /* - * (non-Javadoc) - * - * @see org.jivesoftware.smack.packet.IQ#getChildElementXML() - */ - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - if (this.getType().equals(IQ.Type.set)) { - buf.append(""); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + switch (getType()) { + case set: + buf.optAttribute("id", getSessionID()); + buf.optAttribute("mime-type", getMimeType()); + buf.attribute("profile", NAMESPACE + "/profile/file-transfer"); + buf.rightAngleBracket(); // Add the file section if there is one. - String fileXML = file.toXML(); - if (fileXML != null) { - buf.append(fileXML); - } - } - else if (this.getType().equals(IQ.Type.result)) { - buf.append(""); - } - else { + buf.optAppend(file.toXML()); + break; + case result: + buf.rightAngleBracket(); + break; + default: throw new IllegalArgumentException("IQ Type not understood"); } if (featureNegotiation != null) { buf.append(featureNegotiation.toXML()); } - buf.append(""); - return buf.toString(); + return buf; } /** diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/time/packet/Time.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/time/packet/Time.java index 60df002f6..d771381bd 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/time/packet/Time.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/time/packet/Time.java @@ -43,6 +43,7 @@ public class Time extends IQ { private String tzo; public Time() { + super(ELEMENT, NAMESPACE); setType(Type.get); } @@ -53,6 +54,7 @@ public class Time extends IQ { * @param cal the time value. */ public Time(Calendar cal) { + super(ELEMENT, NAMESPACE); tzo = XmppDateTime.asString(cal.getTimeZone()); // Convert local time to the UTC time. utc = XmppDateTime.formatXEP0082Date(cal.getTime()); @@ -128,14 +130,17 @@ public class Time extends IQ { return time; } - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - buf.append("<" + ELEMENT + " xmlns='" + NAMESPACE + "'>"); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.rightAngleBracket(); + if (utc != null) { buf.append("").append(utc).append(""); buf.append("").append(tzo).append(""); + } else { + buf.setEmptyElement(); } - buf.append(""); - return buf.toString(); + + return buf; } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java index fe5cbfd3d..e2dd78fad 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java @@ -39,7 +39,6 @@ import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.stringencoder.Base64; -import org.jivesoftware.smackx.vcardtemp.VCardManager; /** * A VCard class for use with the @@ -82,6 +81,9 @@ import org.jivesoftware.smackx.vcardtemp.VCardManager; * @author Kirill Maximov (kir@maxkir.com) */ public class VCard extends IQ { + public static final String ELEMENT = "vCard"; + public static final String NAMESPACE = "vcard-temp"; + private static final Logger LOGGER = Logger.getLogger(VCard.class.getName()); private static final String DEFAULT_MIME_TYPE = "image/jpeg"; @@ -123,6 +125,7 @@ public class VCard extends IQ { private Map otherUnescapableFields = new HashMap(); public VCard() { + super(ELEMENT, NAMESPACE); } /** @@ -562,10 +565,87 @@ public class VCard extends IQ { copyFieldsFrom(result); } - public String getChildElementXML() { - StringBuilder sb = new StringBuilder(); - new VCardWriter(sb).write(); - return sb.toString(); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + if (!hasContent()) { + xml.setEmptyElement(); + return xml; + } + xml.rightAngleBracket(); + if (hasNameField()) { + xml.openElement("N"); + xml.element("FAMILY", lastName); + xml.element("GIVEN", firstName); + xml.element("MIDDLE", middleName); + xml.closeElement("N"); + } + if (hasOrganizationFields()) { + xml.openElement("ORG"); + xml.element("ORGNAME", organization); + xml.element("ORGUNIT", organizationUnit); + xml.closeElement("ORG"); + } + for (Entry entry : otherSimpleFields.entrySet()) { + xml.element(entry.getKey(), entry.getValue()); + } + for (Entry entry : otherUnescapableFields.entrySet()) { + xml.openElement(entry.getKey()); + xml.append(entry.getValue()); + xml.closeElement(entry.getKey()); + } + if (photoBinval != null) { + xml.openElement("PHOTO"); + xml.escapedElement("BINVAL", photoBinval); + xml.element("TYPE", photoMimeType); + xml.closeElement("PHOTO"); + } + if (emailWork != null) { + xml.openElement("EMAIL"); + xml.emptyElement("WORK"); + xml.emptyElement("INTERNET"); + xml.emptyElement("PREF"); + xml.element("USERID", emailWork); + xml.closeElement("EMAIL"); + } + if (emailHome != null) { + xml.openElement("EMAIL"); + xml.emptyElement("HOME"); + xml.emptyElement("INTERNET"); + xml.emptyElement("PREF"); + xml.element("USERID", emailHome); + xml.closeElement("EMAIL"); + } + for (Entry phone : workPhones.entrySet()) { + xml.openElement("TEL"); + xml.emptyElement("WORK"); + xml.emptyElement(phone.getKey()); + xml.element("NUMBER", phone.getValue()); + xml.closeElement("TEL"); + } + for (Entry phone : homePhones.entrySet()) { + xml.openElement("TEL"); + xml.emptyElement("HOME"); + xml.emptyElement(phone.getKey()); + xml.element("NUMBER", phone.getValue()); + xml.closeElement("TEL"); + } + if (!workAddr.isEmpty()) { + xml.openElement("ADR"); + xml.emptyElement("WORK"); + for (Entry entry : workAddr.entrySet()) { + xml.element(entry.getKey(), entry.getValue()); + } + xml.closeElement("ADR"); + } + if (!homeAddr.isEmpty()) { + xml.openElement("ADR"); + xml.emptyElement("HOME"); + for (Entry entry : homeAddr.entrySet()) { + xml.element(entry.getKey(), entry.getValue()); + } + xml.closeElement("ADR"); + } + return xml; } private void copyFieldsFrom(VCard from) { @@ -688,173 +768,5 @@ public class VCard extends IQ { return result; } - public String toString() { - return getChildElementXML(); - } - - //============================================================== - - private class VCardWriter { - - private final StringBuilder sb; - - VCardWriter(StringBuilder sb) { - this.sb = sb; - } - - public void write() { - appendTag(VCardManager.ELEMENT, "xmlns", VCardManager.NAMESPACE, hasContent(), new ContentBuilder() { - public void addTagContent() { - buildActualContent(); - } - }); - } - - private void buildActualContent() { - if (hasNameField()) { - appendN(); - } - - appendOrganization(); - appendGenericFields(); - appendPhoto(); - - appendEmail(emailWork, "WORK"); - appendEmail(emailHome, "HOME"); - - appendPhones(workPhones, "WORK"); - appendPhones(homePhones, "HOME"); - - appendAddress(workAddr, "WORK"); - appendAddress(homeAddr, "HOME"); - } - - private void appendPhoto() { - if (photoBinval == null) - return; - - appendTag("PHOTO", true, new ContentBuilder() { - public void addTagContent() { - appendTag("BINVAL", photoBinval); // No need to escape photoBinval, as it's already Base64 encoded - appendTag("TYPE", StringUtils.escapeForXML(photoMimeType)); - } - }); - } - private void appendEmail(final String email, final String type) { - if (email != null) { - appendTag("EMAIL", true, new ContentBuilder() { - public void addTagContent() { - appendEmptyTag(type); - appendEmptyTag("INTERNET"); - appendEmptyTag("PREF"); - appendTag("USERID", StringUtils.escapeForXML(email)); - } - }); - } - } - - private void appendPhones(Map phones, final String code) { - for (final Map.Entry entry : phones.entrySet()) { - appendTag("TEL", true, new ContentBuilder() { - public void addTagContent() { - appendEmptyTag(entry.getKey()); - appendEmptyTag(code); - appendTag("NUMBER", StringUtils.escapeForXML(entry.getValue())); - } - }); - } - } - - private void appendAddress(final Map addr, final String code) { - if (addr.size() > 0) { - appendTag("ADR", true, new ContentBuilder() { - public void addTagContent() { - appendEmptyTag(code); - - for (final Entry entry : addr.entrySet()) { - appendTag(entry.getKey(), StringUtils.escapeForXML(entry.getValue())); - } - } - }); - } - } - - private void appendEmptyTag(Object tag) { - sb.append('<').append(tag).append("/>"); - } - - private void appendGenericFields() { - for (Map.Entry entry : otherSimpleFields.entrySet()) { - appendTag(entry.getKey().toString(), - StringUtils.escapeForXML(entry.getValue())); - } - - for (Map.Entry entry : otherUnescapableFields.entrySet()) { - appendTag(entry.getKey().toString(),entry.getValue()); - } - } - - private void appendOrganization() { - if (hasOrganizationFields()) { - appendTag("ORG", true, new ContentBuilder() { - public void addTagContent() { - appendTag("ORGNAME", StringUtils.escapeForXML(organization)); - appendTag("ORGUNIT", StringUtils.escapeForXML(organizationUnit)); - } - }); - } - } - - private void appendN() { - appendTag("N", true, new ContentBuilder() { - public void addTagContent() { - appendTag("FAMILY", StringUtils.escapeForXML(lastName)); - appendTag("GIVEN", StringUtils.escapeForXML(firstName)); - appendTag("MIDDLE", StringUtils.escapeForXML(middleName)); - } - }); - } - - private void appendTag(String tag, String attr, String attrValue, boolean hasContent, - ContentBuilder builder) { - sb.append('<').append(tag); - if (attr != null) { - sb.append(' ').append(attr).append('=').append('\'').append(attrValue).append('\''); - } - - if (hasContent) { - sb.append('>'); - builder.addTagContent(); - sb.append("\n"); - } - else { - sb.append("/>\n"); - } - } - - private void appendTag(String tag, boolean hasContent, ContentBuilder builder) { - appendTag(tag, null, null, hasContent, builder); - } - - private void appendTag(String tag, final CharSequence tagText) { - if (tagText == null) return; - final ContentBuilder contentBuilder = new ContentBuilder() { - public void addTagContent() { - sb.append(tagText.toString().trim()); - } - }; - appendTag(tag, true, contentBuilder); - } - - } - - //============================================================== - - private interface ContentBuilder { - - void addTagContent(); - } - - //============================================================== } diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/IBBPacketUtils.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/IBBPacketUtils.java index c577a4a9d..92dadc2d8 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/IBBPacketUtils.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/IBBPacketUtils.java @@ -16,6 +16,8 @@ */ package org.jivesoftware.smackx.bytestreams.ibb; +import org.jivesoftware.smack.packet.EmptyResultIQ; +import org.jivesoftware.smack.packet.ErrorIQ; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.XMPPError; @@ -35,17 +37,10 @@ public class IBBPacketUtils { * @return an error IQ */ public static IQ createErrorIQ(String from, String to, XMPPError xmppError) { - IQ errorIQ = new IQ() { - - public String getChildElementXML() { - return null; - } - - }; + IQ errorIQ = new ErrorIQ(xmppError); errorIQ.setType(IQ.Type.error); errorIQ.setFrom(from); errorIQ.setTo(to); - errorIQ.setError(xmppError); return errorIQ; } @@ -57,13 +52,7 @@ public class IBBPacketUtils { * @return a result IQ */ public static IQ createResultIQ(String from, String to) { - IQ result = new IQ() { - - public String getChildElementXML() { - return null; - } - - }; + IQ result = new EmptyResultIQ(); result.setType(IQ.Type.result); result.setFrom(from); result.setTo(to); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/packet/CloseTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/packet/CloseTest.java index a40448349..f9e6a569c 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/packet/CloseTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/packet/CloseTest.java @@ -64,8 +64,8 @@ public class CloseTest { @Test public void shouldReturnValidIQStanzaXML() throws Exception { String control = XMLBuilder.create("iq") - .a("from", "romeo@montague.lit/orchard") .a("to", "juliet@capulet.lit/balcony") + .a("from", "romeo@montague.lit/orchard") .a("id", "us71g45j") .a("type", "set") .e("close") diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/packet/DataTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/packet/DataTest.java index 4fbc43bf9..5618a669f 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/packet/DataTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/packet/DataTest.java @@ -19,12 +19,10 @@ package org.jivesoftware.smackx.bytestreams.ibb.packet; import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import java.util.Properties; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smack.util.stringencoder.Base64; import org.junit.Test; @@ -70,16 +68,7 @@ public class DataTest { .t(encodedData) .asString(outputProperties); - DataPacketExtension dpe = mock(DataPacketExtension.class); - XmlStringBuilder dataTag = new XmlStringBuilder(); - dataTag.halfOpenElement(DataPacketExtension.ELEMENT); - dataTag.xmlnsAttribute(DataPacketExtension.NAMESPACE); - dataTag.attribute("seq", "0"); - dataTag.attribute("sid", "i781hf64"); - dataTag.rightAngleBracket(); - dataTag.escape(encodedData); - dataTag.closeElement(DataPacketExtension.ELEMENT); - when(dpe.toXML()).thenReturn(dataTag); + DataPacketExtension dpe = new DataPacketExtension("i781hf64", 0, encodedData); Data data = new Data(dpe); data.setFrom("romeo@montague.lit/orchard"); data.setTo("juliet@capulet.lit/balcony"); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java index 4b5440a77..c88835e18 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java @@ -34,9 +34,9 @@ import org.jivesoftware.smack.SmackException.FeatureNotSupportedException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException.XMPPErrorException; +import org.jivesoftware.smack.packet.ErrorIQ; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.XMPPError; -import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; @@ -426,14 +426,7 @@ public class Socks5ByteStreamManagerTest { // build error packet to reject SOCKS5 Bytestream XMPPError xmppError = new XMPPError(XMPPError.Condition.not_acceptable); - IQ rejectPacket = new IQ() { - - public String getChildElementXML() { - return null; - } - - }; - rejectPacket.setType(Type.error); + IQ rejectPacket = new ErrorIQ(xmppError); rejectPacket.setFrom(targetJID); rejectPacket.setTo(initiatorJID); rejectPacket.setError(xmppError); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiatorTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiatorTest.java index 478b4c118..555398c51 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiatorTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiatorTest.java @@ -30,9 +30,10 @@ import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException.XMPPErrorException; +import org.jivesoftware.smack.packet.EmptyResultIQ; +import org.jivesoftware.smack.packet.ErrorIQ; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.XMPPError; -import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost; import org.jivesoftware.util.ConnectionUtils; @@ -197,17 +198,9 @@ public class Socks5ClientForInitiatorTest { // build error response as reply to the stream activation XMPPError xmppError = new XMPPError(XMPPError.Condition.internal_server_error); - IQ error = new IQ() { - - public String getChildElementXML() { - return null; - } - - }; - error.setType(Type.error); + IQ error = new ErrorIQ(xmppError); error.setFrom(proxyJID); error.setTo(initiatorJID); - error.setError(xmppError); protocol.addResponse(error, Verification.correspondingSenderReceiver, Verification.requestTypeSET); @@ -249,17 +242,10 @@ public class Socks5ClientForInitiatorTest { public void shouldSuccessfullyEstablishConnectionAndActivateSocks5Proxy() throws Exception { // build activation confirmation response - IQ activationResponse = new IQ() { + IQ activationResponse = new EmptyResultIQ(); - @Override - public String getChildElementXML() { - return null; - } - - }; activationResponse.setFrom(proxyJID); activationResponse.setTo(initiatorJID); - activationResponse.setType(IQ.Type.result); protocol.addResponse(activationResponse, Verification.correspondingSenderReceiver, Verification.requestTypeSET, new Verification() { diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5PacketUtils.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5PacketUtils.java index 98c1c77b5..fac8cab5d 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5PacketUtils.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5PacketUtils.java @@ -16,6 +16,7 @@ */ package org.jivesoftware.smackx.bytestreams.socks5; +import org.jivesoftware.smack.packet.EmptyResultIQ; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; @@ -100,17 +101,9 @@ public class Socks5PacketUtils { * @return response IQ for a activation request to the proxy */ public static IQ createActivationConfirmation(String from, String to) { - IQ response = new IQ() { - - @Override - public String getChildElementXML() { - return null; - } - - }; + IQ response = new EmptyResultIQ(); response.setFrom(from); response.setTo(to); - response.setType(IQ.Type.result); return response; } diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/RTPBridge.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/RTPBridge.java index 292bb765a..307e8c8cd 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/RTPBridge.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/RTPBridge.java @@ -93,6 +93,7 @@ public class RTPBridge extends IQ { * @param sid */ public RTPBridge(String sid) { + this(); this.sid = sid; } @@ -102,6 +103,7 @@ public class RTPBridge extends IQ { * @param action */ public RTPBridge(BridgeAction action) { + this(); this.bridgeAction = action; } @@ -112,6 +114,7 @@ public class RTPBridge extends IQ { * @param bridgeAction */ public RTPBridge(String sid, BridgeAction bridgeAction) { + this(); this.sid = sid; this.bridgeAction = bridgeAction; } @@ -120,6 +123,7 @@ public class RTPBridge extends IQ { * Creates a RTPBridge Packet without Session ID */ public RTPBridge() { + super(ELEMENT_NAME, NAMESPACE); } /** @@ -298,9 +302,9 @@ public class RTPBridge extends IQ { * * @return the Child Element XML of the Packet */ - public String getChildElementXML() { - StringBuilder str = new StringBuilder(); - str.append("<" + ELEMENT_NAME + " xmlns='" + NAMESPACE + "' sid='").append(sid).append("'>"); + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder str) { + str.attribute("sid", sid); + str.rightAngleBracket(); if (bridgeAction.equals(BridgeAction.create)) str.append(""); @@ -309,8 +313,7 @@ public class RTPBridge extends IQ { else str.append(""); - str.append(""); - return str.toString(); + return str; } /** diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/STUN.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/STUN.java index c5bd32149..c4416b4ea 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/STUN.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/nat/STUN.java @@ -26,7 +26,7 @@ import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.PacketCollector; import org.jivesoftware.smack.XMPPException; -import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.SimpleIQ; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.provider.ProviderManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; @@ -44,7 +44,7 @@ import org.xmlpull.v1.XmlPullParserException; * * @author Thiago Camargo */ -public class STUN extends IQ { +public class STUN extends SimpleIQ { private static final Logger LOGGER = Logger.getLogger(STUN.class.getName()); @@ -75,6 +75,7 @@ public class STUN extends IQ { * Creates a STUN IQ */ public STUN() { + super(ELEMENT_NAME, NAMESPACE); } /** @@ -104,17 +105,6 @@ public class STUN extends IQ { this.publicIp = publicIp; } - /** - * Get the Child Element XML of the Packet - * - * @return the child element XML - */ - public String getChildElementXML() { - StringBuilder str = new StringBuilder(); - str.append("<" + ELEMENT_NAME + " xmlns='" + NAMESPACE + "'/>"); - return str.toString(); - } - /** * IQProvider for RTP Bridge packets. * Parse receive RTPBridge packet to a RTPBridge instance diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/Jingle.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/Jingle.java index 6f3164109..4669d977b 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/Jingle.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/packet/Jingle.java @@ -66,7 +66,7 @@ public class Jingle extends IQ { */ public Jingle(final List contents, final JingleContentInfo mi, final String sid) { - super(); + this(); if (contents != null) { contents.addAll(contents); @@ -87,7 +87,7 @@ public class Jingle extends IQ { * @param content a content */ public Jingle(final JingleContent content) { - super(); + this(); addContent(content); @@ -106,7 +106,7 @@ public class Jingle extends IQ { * @param info The content info */ public Jingle(final JingleContentInfo info) { - super(); + this(); setContentInfo(info); @@ -146,7 +146,7 @@ public class Jingle extends IQ { * The default constructor */ public Jingle() { - super(); + super(NODENAME, NAMESPACE); } /** @@ -338,11 +338,7 @@ public class Jingle extends IQ { * * @return the XML string */ - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - - buf.append("<").append(getElementName()); - buf.append(" xmlns=\"").append(getNamespace()).append("\""); + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { if (getInitiator() != null) { buf.append(" initiator=\"").append(getInitiator()).append("\""); } @@ -350,7 +346,7 @@ public class Jingle extends IQ { buf.append(" responder=\"").append(getResponder()).append("\""); } if (getAction() != null) { - buf.append(" action=\"").append(getAction()).append("\""); + buf.append(" action=\"").append(getAction().name()).append("\""); } if (getSid() != null) { buf.append(" sid=\"").append(getSid()).append("\""); @@ -368,7 +364,6 @@ public class Jingle extends IQ { buf.append(contentInfo.toXML()); } - buf.append(""); - return buf.toString(); + return buf; } } diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java index 9fbcc9621..ac9b952a1 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java @@ -781,13 +781,7 @@ public class AgentSession { } else if (packet instanceof OfferRevokeProvider.OfferRevokePacket) { // Acknowledge the IQ set. - IQ reply = new IQ() { - public String getChildElementXML() { - return null; - } - }; - reply.setPacketID(packet.getPacketID()); - reply.setType(IQ.Type.result); + IQ reply = IQ.createResultIQ((OfferRevokeProvider.OfferRevokePacket) packet); connection.sendPacket(reply); fireOfferRevokeEvent((OfferRevokeProvider.OfferRevokePacket)packet); @@ -962,12 +956,7 @@ public class AgentSession { public void sendRoomInvitation(RoomInvitation.Type type, String invitee, String sessionID, String reason) throws NoResponseException, XMPPErrorException, NotConnectedException { final RoomInvitation invitation = new RoomInvitation(type, invitee, sessionID, reason); - IQ iq = new IQ() { - - public String getChildElementXML() { - return invitation.toXML(); - } - }; + IQ iq = new RoomInvitation.RoomInvitationIQ(invitation); iq.setType(IQ.Type.set); iq.setTo(workgroupJID); iq.setFrom(connection.getUser()); @@ -1004,12 +993,7 @@ public class AgentSession { public void sendRoomTransfer(RoomTransfer.Type type, String invitee, String sessionID, String reason) throws NoResponseException, XMPPErrorException, NotConnectedException { final RoomTransfer transfer = new RoomTransfer(type, invitee, sessionID, reason); - IQ iq = new IQ() { - - public String getChildElementXML() { - return transfer.toXML(); - } - }; + IQ iq = new RoomTransfer.RoomTransferIQ(transfer); iq.setType(IQ.Type.set); iq.setTo(workgroupJID); iq.setFrom(connection.getUser()); diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/Offer.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/Offer.java index 3b402b1fe..20559e74c 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/Offer.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/Offer.java @@ -194,13 +194,16 @@ public class Offer { private class RejectPacket extends IQ { RejectPacket(String workgroup) { + super("offer-reject", "http://jabber.org/protocol/workgroup"); this.setTo(workgroup); this.setType(IQ.Type.set); } - public String getChildElementXML() { - return ""; + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + xml.attribute("id", Offer.this.getSessionID()); + xml.setEmptyElement(); + return xml; } } @@ -210,13 +213,16 @@ public class Offer { private class AcceptPacket extends IQ { AcceptPacket(String workgroup) { + super("offer-accept", "http://jabber.org/protocol/workgroup"); this.setTo(workgroup); this.setType(IQ.Type.set); } - public String getChildElementXML() { - return ""; + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + xml.attribute("id", Offer.this.getSessionID()); + xml.setEmptyElement(); + return xml; } } diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/OfferConfirmation.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/OfferConfirmation.java index 2a1c2247b..7cb0d7198 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/OfferConfirmation.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/OfferConfirmation.java @@ -22,15 +22,20 @@ import java.io.IOException; import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.SimpleIQ; import org.jivesoftware.smack.provider.IQProvider; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -public class OfferConfirmation extends IQ { +public class OfferConfirmation extends SimpleIQ { private String userJID; private long sessionID; + public OfferConfirmation() { + super("offer-confirmation", "http://jabber.org/protocol/workgroup"); + } + public String getUserJID() { return userJID; } @@ -53,13 +58,6 @@ public class OfferConfirmation extends IQ { con.sendPacket(packet); } - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - buf.append(""); - buf.append(""); - return buf.toString(); - } - public static class Provider extends IQProvider { @Override @@ -103,14 +101,18 @@ public class OfferConfirmation extends IQ { String roomName; NotifyServicePacket(String workgroup, String roomName) { + super("offer-confirmation", "http://jabber.org/protocol/workgroup"); this.setTo(workgroup); this.setType(IQ.Type.result); this.roomName = roomName; } - public String getChildElementXML() { - return ""; + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + xml.attribute("roomname", roomName); + xml.setEmptyElement(); + return xml; } } diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/forms/WorkgroupForm.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/forms/WorkgroupForm.java index 169a6893b..31ca3dfc4 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/forms/WorkgroupForm.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/forms/WorkgroupForm.java @@ -20,13 +20,13 @@ package org.jivesoftware.smackx.workgroup.ext.forms; import java.io.IOException; import org.jivesoftware.smack.SmackException; -import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.SimpleIQ; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.util.PacketParserUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -public class WorkgroupForm extends IQ { +public class WorkgroupForm extends SimpleIQ { /** * Element name of the packet extension. @@ -38,15 +38,8 @@ public class WorkgroupForm extends IQ { */ public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup"; - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - - buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">"); - // Add packet extensions, if any are defined. - buf.append(getExtensionsXML()); - buf.append(" "); - - return buf.toString(); + public WorkgroupForm() { + super(ELEMENT_NAME, NAMESPACE); } /** diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/history/AgentChatHistory.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/history/AgentChatHistory.java index f20f055e2..5b96a9870 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/history/AgentChatHistory.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/history/AgentChatHistory.java @@ -33,34 +33,6 @@ import java.util.List; * to one or more jids and therefore retrievable. */ public class AgentChatHistory extends IQ { - private String agentJID; - private int maxSessions; - private long startDate; - - private List agentChatSessions = new ArrayList(); - - public AgentChatHistory(String agentJID, int maxSessions, Date startDate) { - this.agentJID = agentJID; - this.maxSessions = maxSessions; - this.startDate = startDate.getTime(); - } - - public AgentChatHistory(String agentJID, int maxSessions) { - this.agentJID = agentJID; - this.maxSessions = maxSessions; - this.startDate = 0; - } - - public AgentChatHistory() { - } - - public void addChatSession(AgentChatSession chatSession) { - agentChatSessions.add(chatSession); - } - - public Collection getAgentChatSessions() { - return agentChatSessions; - } /** * Element name of the packet extension. @@ -72,19 +44,45 @@ public class AgentChatHistory extends IQ { */ public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup"; - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); + private String agentJID; + private int maxSessions; + private long startDate; - buf.append("<").append(ELEMENT_NAME).append(" xmlns="); - buf.append('"'); - buf.append(NAMESPACE); - buf.append('"'); + private List agentChatSessions = new ArrayList(); + + public AgentChatHistory(String agentJID, int maxSessions, Date startDate) { + this(); + this.agentJID = agentJID; + this.maxSessions = maxSessions; + this.startDate = startDate.getTime(); + } + + public AgentChatHistory(String agentJID, int maxSessions) { + this(); + this.agentJID = agentJID; + this.maxSessions = maxSessions; + this.startDate = 0; + } + + public AgentChatHistory() { + super(ELEMENT_NAME, NAMESPACE); + } + + public void addChatSession(AgentChatSession chatSession) { + agentChatSessions.add(chatSession); + } + + public Collection getAgentChatSessions() { + return agentChatSessions; + } + + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { buf.append(" agentJID=\"" + agentJID + "\""); buf.append(" maxSessions=\"" + maxSessions + "\""); buf.append(" startDate=\"" + startDate + "\""); - - buf.append("> "); - return buf.toString(); + buf.setEmptyElement(); + return buf; } /** diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/history/ChatMetadata.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/history/ChatMetadata.java index 1acc1d83a..0a53f4f83 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/history/ChatMetadata.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/history/ChatMetadata.java @@ -43,6 +43,10 @@ public class ChatMetadata extends IQ { private String sessionID; + public ChatMetadata() { + super(ELEMENT_NAME, NAMESPACE); + } + public String getSessionID() { return sessionID; } @@ -62,15 +66,12 @@ public class ChatMetadata extends IQ { return map; } - - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - - buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">"); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.rightAngleBracket(); buf.append("").append(getSessionID()).append(""); - buf.append(" "); - return buf.toString(); + return buf; } /** diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/macros/Macros.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/macros/Macros.java index bf8d4eb46..c98afc9fd 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/macros/Macros.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/macros/Macros.java @@ -33,10 +33,24 @@ import org.xmlpull.v1.XmlPullParser; */ public class Macros extends IQ { + /** + * Element name of the packet extension. + */ + public static final String ELEMENT_NAME = "macros"; + + /** + * Namespace of the packet extension. + */ + public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup"; + private MacroGroup rootGroup; private boolean personal; private MacroGroup personalMacroGroup; + public Macros() { + super(ELEMENT_NAME, NAMESPACE); + } + public MacroGroup getRootGroup() { return rootGroup; } @@ -61,21 +75,10 @@ public class Macros extends IQ { this.personalMacroGroup = personalMacroGroup; } + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.rightAngleBracket(); - /** - * Element name of the packet extension. - */ - public static final String ELEMENT_NAME = "macros"; - - /** - * Namespace of the packet extension. - */ - public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup"; - - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - - buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">"); if (isPersonal()) { buf.append("true"); } @@ -84,9 +87,8 @@ public class Macros extends IQ { buf.append(StringUtils.escapeForXML(getPersonalMacroGroup().toXML())); buf.append(""); } - buf.append(" "); - return buf.toString(); + return buf; } /** diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/notes/ChatNotes.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/notes/ChatNotes.java index 842d79e39..2c6e9d588 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/notes/ChatNotes.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/ext/notes/ChatNotes.java @@ -21,7 +21,6 @@ import java.io.IOException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.provider.IQProvider; -import org.jivesoftware.smack.util.XmlStringBuilder; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -40,6 +39,9 @@ public class ChatNotes extends IQ { */ public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup"; + public ChatNotes() { + super(ELEMENT_NAME, NAMESPACE); + } private String sessionID; private String notes; @@ -60,18 +62,17 @@ public class ChatNotes extends IQ { this.notes = notes; } - public String getChildElementXML() { - XmlStringBuilder buf = new XmlStringBuilder(); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.rightAngleBracket(); - buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">"); buf.append("").append(getSessionID()).append(""); if (getNotes() != null) { buf.element("notes", getNotes()); } - buf.append(" "); - return buf.toString(); + return buf; } /** diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/AgentInfo.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/AgentInfo.java index 1826bf591..1187c5f9b 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/AgentInfo.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/AgentInfo.java @@ -42,6 +42,10 @@ public class AgentInfo extends IQ { private String jid; private String name; + public AgentInfo() { + super(ELEMENT_NAME, NAMESPACE); + } + /** * Returns the Agent's jid. * @@ -80,19 +84,18 @@ public class AgentInfo extends IQ { this.name = name; } - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.rightAngleBracket(); - buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">"); if (jid != null) { buf.append("").append(getJid()).append(""); } if (name != null) { buf.append("").append(getName()).append(""); } - buf.append(" "); - return buf.toString(); + return buf; } /** diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/AgentStatusRequest.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/AgentStatusRequest.java index eab3501bd..cc1e51dbd 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/AgentStatusRequest.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/AgentStatusRequest.java @@ -50,6 +50,7 @@ public class AgentStatusRequest extends IQ { private Set agents; public AgentStatusRequest() { + super(ELEMENT_NAME, NAMESPACE); agents = new HashSet(); } @@ -69,9 +70,9 @@ public class AgentStatusRequest extends IQ { return NAMESPACE; } - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">"); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.rightAngleBracket(); synchronized (agents) { for (Iterator i=agents.iterator(); i.hasNext(); ) { Item item = (Item) i.next(); @@ -84,8 +85,7 @@ public class AgentStatusRequest extends IQ { buf.append(""); } } - buf.append(" "); - return buf.toString(); + return buf; } public static class Item { diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/AgentWorkgroups.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/AgentWorkgroups.java index b2aabc9e5..1b6b6029e 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/AgentWorkgroups.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/AgentWorkgroups.java @@ -40,6 +40,10 @@ public class AgentWorkgroups extends IQ { private String agentJID; private List workgroups; + private AgentWorkgroups() { + super("workgroups", "http://jabber.org/protocol/workgroup"); + } + /** * Creates an AgentWorkgroups request for the given agent. This IQ will be sent and an answer * will be received with the jid of the workgroups where the agent can work. @@ -47,6 +51,7 @@ public class AgentWorkgroups extends IQ { * @param agentJID the id of the agent to get his workgroups. */ public AgentWorkgroups(String agentJID) { + this(); this.agentJID = agentJID; this.workgroups = new ArrayList(); } @@ -59,6 +64,7 @@ public class AgentWorkgroups extends IQ { * @param workgroups the list of workgroup JIDs where the agent can work. */ public AgentWorkgroups(String agentJID, List workgroups) { + this(); this.agentJID = agentJID; this.workgroups = workgroups; } @@ -76,21 +82,16 @@ public class AgentWorkgroups extends IQ { return Collections.unmodifiableList(workgroups); } - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - - buf.append(""); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.attribute("jid", agentJID).rightAngleBracket(); for (Iterator it=workgroups.iterator(); it.hasNext();) { String workgroupJID = it.next(); buf.append(""); } - buf.append(""); - - return buf.toString(); + return buf; } /** diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/DepartQueuePacket.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/DepartQueuePacket.java index cb72bc54a..40885d648 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/DepartQueuePacket.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/DepartQueuePacket.java @@ -34,6 +34,10 @@ public class DepartQueuePacket extends IQ { private String user; + private DepartQueuePacket() { + super("depart-queue", "http://jabber.org/protocol/workgroup"); + } + /** * Creates a depart queue request packet to the specified workgroup. * @@ -51,6 +55,7 @@ public class DepartQueuePacket extends IQ { * @param user the user to make depart from the queue. */ public DepartQueuePacket(String workgroup, String user) { + this(); this.user = user; setTo(workgroup); @@ -58,16 +63,14 @@ public class DepartQueuePacket extends IQ { setFrom(user); } - public String getChildElementXML() { - StringBuilder buf = new StringBuilder("").append(this.user).append(""); - } - else { - buf.append("/>"); + buf.append("").append(this.user).append(""); } - return buf.toString(); + return buf; } } diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/MonitorPacket.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/MonitorPacket.java index 44e4a5d9f..9da53db75 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/MonitorPacket.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/MonitorPacket.java @@ -55,27 +55,19 @@ public class MonitorPacket extends IQ { */ public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup"; - public String getElementName() { - return ELEMENT_NAME; + public MonitorPacket() { + super(ELEMENT_NAME, NAMESPACE); } - public String getNamespace() { - return NAMESPACE; - } + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.rightAngleBracket(); - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - - buf.append("<").append(ELEMENT_NAME).append(" xmlns="); - buf.append('"'); - buf.append(NAMESPACE); - buf.append('"'); - buf.append(">"); if (sessionID != null) { buf.append(""); } - buf.append(" "); - return buf.toString(); + + return buf; } diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/OccupantsInfo.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/OccupantsInfo.java index ee0d088f1..3abe85ac6 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/OccupantsInfo.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/OccupantsInfo.java @@ -60,6 +60,7 @@ public class OccupantsInfo extends IQ { private final Set occupants; public OccupantsInfo(String roomID) { + super(ELEMENT_NAME, NAMESPACE); this.roomID = roomID; this.occupants = new HashSet(); } @@ -76,9 +77,8 @@ public class OccupantsInfo extends IQ { return Collections.unmodifiableSet(occupants); } - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { buf.append("\" roomID=\"").append(roomID).append("\">"); synchronized (occupants) { for (OccupantInfo occupant : occupants) { @@ -98,8 +98,7 @@ public class OccupantsInfo extends IQ { buf.append(""); } } - buf.append(" "); - return buf.toString(); + return buf; } public static class OccupantInfo { diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/OfferRequestProvider.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/OfferRequestProvider.java index 8a382db75..f3c166fca 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/OfferRequestProvider.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/OfferRequestProvider.java @@ -122,6 +122,7 @@ public class OfferRequestProvider extends IQProvider { public OfferRequestPacket(String userJID, String userID, int timeout, Map> metaData, String sessionID, OfferContent content) { + super("offer", "http://jabber.org/protocol/workgroup"); this.userJID = userJID; this.userID = userID; this.timeout = timeout; @@ -182,11 +183,10 @@ public class OfferRequestProvider extends IQProvider { return this.metaData; } - public String getChildElementXML () { - StringBuilder buf = new StringBuilder(); - - buf.append(""); - buf.append("").append(timeout).append(""); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.append(" jid=\"").append(userJID).append("\">"); + buf.append("").append(Integer.toString(timeout)).append(""); if (sessionID != null) { buf.append('<').append(SessionID.ELEMENT_NAME); @@ -206,9 +206,7 @@ public class OfferRequestProvider extends IQProvider { buf.append(UserID.NAMESPACE).append("\"/>"); } - buf.append(""); - - return buf.toString(); + return buf; } } } diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/OfferRevokeProvider.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/OfferRevokeProvider.java index 01b065f41..d384347fb 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/OfferRevokeProvider.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/OfferRevokeProvider.java @@ -73,6 +73,7 @@ public class OfferRevokeProvider extends IQProvider { private String reason; public OfferRevokePacket (String userJID, String userID, String cause, String sessionID) { + super("offer-revoke", "http://jabber.org/protocol/workgroup"); this.userJID = userJID; this.userID = userID; this.reason = cause; @@ -95,9 +96,9 @@ public class OfferRevokeProvider extends IQProvider { return this.sessionID; } - public String getChildElementXML () { - StringBuilder buf = new StringBuilder(); - buf.append(""); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.append(" jid=\"").append(userID).append("\">"); if (reason != null) { buf.append("").append(reason).append(""); } @@ -107,8 +108,7 @@ public class OfferRevokeProvider extends IQProvider { if (userID != null) { buf.append(new UserID(userID).toXML()); } - buf.append(""); - return buf.toString(); + return buf; } } } diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/RoomInvitation.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/RoomInvitation.java index 463a7cc22..8f4c587d8 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/RoomInvitation.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/RoomInvitation.java @@ -19,8 +19,11 @@ package org.jivesoftware.smackx.workgroup.packet; import java.io.IOException; +import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.PacketExtension; +import org.jivesoftware.smack.packet.IQ.IQChildElementXmlStringBuilder; import org.jivesoftware.smack.provider.PacketExtensionProvider; +import org.jivesoftware.smack.util.XmlStringBuilder; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -101,11 +104,15 @@ public class RoomInvitation implements PacketExtension { return sessionID; } - public String toXML() { - StringBuilder buf = new StringBuilder(); + @Override + public XmlStringBuilder toXML() { + XmlStringBuilder xml = getIQChildElementBuilder(new IQChildElementXmlStringBuilder(this)); + xml.closeElement(this); + return xml; + } - buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE); - buf.append("\" type=\"").append(type).append("\">"); + public IQ.IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.append("\" type=\"").append(type.name()).append("\">"); buf.append(""); if (invitee != null) { buf.append("").append(invitee).append(""); @@ -116,10 +123,8 @@ public class RoomInvitation implements PacketExtension { if (reason != null) { buf.append("").append(reason).append(""); } - // Add packet extensions, if any are defined. - buf.append(" "); - return buf.toString(); + return buf; } /** @@ -141,6 +146,18 @@ public class RoomInvitation implements PacketExtension { workgroup } + public static class RoomInvitationIQ extends IQ { + private final RoomInvitation roomInvitation; + public RoomInvitationIQ(RoomInvitation roomInvitation) { + super(ELEMENT_NAME, NAMESPACE); + this.roomInvitation = roomInvitation; + } + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + return roomInvitation.getIQChildElementBuilder(xml); + } + } + public static class Provider extends PacketExtensionProvider { @Override diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/RoomTransfer.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/RoomTransfer.java index a23e8bf92..6144f7a25 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/RoomTransfer.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/RoomTransfer.java @@ -19,8 +19,11 @@ package org.jivesoftware.smackx.workgroup.packet; import java.io.IOException; +import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.PacketExtension; +import org.jivesoftware.smack.packet.IQ.IQChildElementXmlStringBuilder; import org.jivesoftware.smack.provider.PacketExtensionProvider; +import org.jivesoftware.smack.util.XmlStringBuilder; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -101,11 +104,15 @@ public class RoomTransfer implements PacketExtension { return sessionID; } - public String toXML() { - StringBuilder buf = new StringBuilder(); + @Override + public XmlStringBuilder toXML() { + XmlStringBuilder xml = getIQChildElementBuilder(new IQChildElementXmlStringBuilder(this)); + xml.closeElement(this); + return xml; + } - buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE); - buf.append("\" type=\"").append(type).append("\">"); + public IQ.IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.append("\" type=\"").append(type.name()).append("\">"); buf.append(""); if (invitee != null) { buf.append("").append(invitee).append(""); @@ -116,10 +123,8 @@ public class RoomTransfer implements PacketExtension { if (reason != null) { buf.append("").append(reason).append(""); } - // Add packet extensions, if any are defined. - buf.append(" "); - return buf.toString(); + return buf; } /** @@ -141,6 +146,18 @@ public class RoomTransfer implements PacketExtension { workgroup } + public static class RoomTransferIQ extends IQ { + private final RoomTransfer roomTransfer; + public RoomTransferIQ(RoomTransfer roomTransfer) { + super(ELEMENT_NAME, NAMESPACE); + this.roomTransfer = roomTransfer; + } + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { + return roomTransfer.getIQChildElementBuilder(xml); + } + } + public static class Provider extends PacketExtensionProvider { @Override diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/Transcript.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/Transcript.java index 745afef66..4af3e4bf2 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/Transcript.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/Transcript.java @@ -42,8 +42,7 @@ public class Transcript extends IQ { * @param sessionID the id of the session to get the conversation transcript. */ public Transcript(String sessionID) { - this.sessionID = sessionID; - this.packets = new ArrayList(); + this(sessionID, new ArrayList()); } /** @@ -54,6 +53,7 @@ public class Transcript extends IQ { * @param packets the list of messages and presences send to the room. */ public Transcript(String sessionID, List packets) { + super("transcript", "http://jabber.org/protocol/workgroup"); this.sessionID = sessionID; this.packets = packets; } @@ -77,10 +77,9 @@ public class Transcript extends IQ { return Collections.unmodifiableList(packets); } - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - - buf.append(""); @@ -89,8 +88,6 @@ public class Transcript extends IQ { buf.append(packet.toXML()); } - buf.append(""); - - return buf.toString(); + return buf; } } diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/TranscriptSearch.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/TranscriptSearch.java index 7940e3556..d3485fdd8 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/TranscriptSearch.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/TranscriptSearch.java @@ -20,7 +20,7 @@ package org.jivesoftware.smackx.workgroup.packet; import java.io.IOException; import org.jivesoftware.smack.SmackException; -import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.SimpleIQ; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.util.PacketParserUtils; import org.xmlpull.v1.XmlPullParser; @@ -32,7 +32,7 @@ import org.xmlpull.v1.XmlPullParserException; * * @author Gaston Dombiak */ -public class TranscriptSearch extends IQ { +public class TranscriptSearch extends SimpleIQ { /** * Element name of the packet extension. @@ -44,16 +44,9 @@ public class TranscriptSearch extends IQ { */ public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup"; - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - - buf.append("<").append(ELEMENT_NAME).append(" xmlns=\"").append(NAMESPACE).append("\">"); - // Add packet extensions, if any are defined. - buf.append(getExtensionsXML()); - buf.append(" "); - - return buf.toString(); - } + public TranscriptSearch() { + super(ELEMENT_NAME, NAMESPACE); + } /** * An IQProvider for TranscriptSearch packets. diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/Transcripts.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/Transcripts.java index 8f9145772..3cd6f74e2 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/Transcripts.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/Transcripts.java @@ -50,8 +50,7 @@ public class Transcripts extends IQ { * @param userID the id of the user to get his conversations transcripts. */ public Transcripts(String userID) { - this.userID = userID; - this.summaries = new ArrayList(); + this(userID, new ArrayList()); } /** @@ -62,6 +61,7 @@ public class Transcripts extends IQ { * @param summaries the list of TranscriptSummaries. */ public Transcripts(String userID, List summaries) { + super("transcripts", "http://jabber.org/protocol/workgroup"); this.userID = userID; this.summaries = summaries; } @@ -90,10 +90,9 @@ public class Transcripts extends IQ { return Collections.unmodifiableList(summaries); } - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - - buf.append(""); @@ -101,9 +100,7 @@ public class Transcripts extends IQ { buf.append(transcriptSummary.toXML()); } - buf.append(""); - - return buf.toString(); + return buf; } /** diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/ChatSettings.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/ChatSettings.java index 1cf1ffccb..ca5596ab8 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/ChatSettings.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/ChatSettings.java @@ -49,11 +49,23 @@ public class ChatSettings extends IQ { private String key; private int type = -1; + /** + * Element name of the packet extension. + */ + public static final String ELEMENT_NAME = "chat-settings"; + + /** + * Namespace of the packet extension. + */ + public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup"; + public ChatSettings() { + super(ELEMENT_NAME, NAMESPACE); settings = new ArrayList(); } public ChatSettings(String key) { + this(); setKey(key); } @@ -94,24 +106,8 @@ public class ChatSettings extends IQ { return null; } - - /** - * Element name of the packet extension. - */ - public static final String ELEMENT_NAME = "chat-settings"; - - /** - * Namespace of the packet extension. - */ - public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup"; - - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - - buf.append("<").append(ELEMENT_NAME).append(" xmlns="); - buf.append('"'); - buf.append(NAMESPACE); - buf.append('"'); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { if (key != null) { buf.append(" key=\"" + key + "\""); } @@ -119,9 +115,8 @@ public class ChatSettings extends IQ { if (type != -1) { buf.append(" type=\"" + type + "\""); } - - buf.append("> "); - return buf.toString(); + buf.setEmptyElement(); + return buf; } /** diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/GenericSettings.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/GenericSettings.java index 4b898ad5a..05f5d3321 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/GenericSettings.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/GenericSettings.java @@ -60,22 +60,19 @@ public class GenericSettings extends IQ { */ public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup"; - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); + public GenericSettings() { + super(ELEMENT_NAME, NAMESPACE); + } - buf.append("<").append(ELEMENT_NAME).append(" xmlns="); - buf.append('"'); - buf.append(NAMESPACE); - buf.append('"'); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { buf.append(">"); if (ModelUtil.hasLength(getQuery())) { buf.append("" + getQuery() + ""); } - buf.append(" "); - return buf.toString(); + return buf; } - /** * Packet extension provider for SoundSetting Packets. */ diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/OfflineSettings.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/OfflineSettings.java index fbb2c4f38..0483de5cc 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/OfflineSettings.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/OfflineSettings.java @@ -20,12 +20,12 @@ package org.jivesoftware.smackx.workgroup.settings; import java.io.IOException; import org.jivesoftware.smackx.workgroup.util.ModelUtil; -import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.SimpleIQ; import org.jivesoftware.smack.provider.IQProvider; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -public class OfflineSettings extends IQ { +public class OfflineSettings extends SimpleIQ { private String redirectURL; private String offlineText; @@ -96,18 +96,10 @@ public class OfflineSettings extends IQ { */ public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup"; - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - - buf.append("<").append(ELEMENT_NAME).append(" xmlns="); - buf.append('"'); - buf.append(NAMESPACE); - buf.append('"'); - buf.append("> "); - return buf.toString(); + public OfflineSettings() { + super(ELEMENT_NAME, NAMESPACE); } - /** * Packet extension provider for AgentStatusRequest packets. */ diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/SearchSettings.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/SearchSettings.java index 3d823a942..918417545 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/SearchSettings.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/SearchSettings.java @@ -19,12 +19,12 @@ package org.jivesoftware.smackx.workgroup.settings; import java.io.IOException; import org.jivesoftware.smackx.workgroup.util.ModelUtil; -import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.SimpleIQ; import org.jivesoftware.smack.provider.IQProvider; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -public class SearchSettings extends IQ { +public class SearchSettings extends SimpleIQ { private String forumsLocation; private String kbLocation; @@ -67,18 +67,10 @@ public class SearchSettings extends IQ { */ public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup"; - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - - buf.append("<").append(ELEMENT_NAME).append(" xmlns="); - buf.append('"'); - buf.append(NAMESPACE); - buf.append('"'); - buf.append("> "); - return buf.toString(); + public SearchSettings() { + super(ELEMENT_NAME, NAMESPACE); } - /** * Packet extension provider for AgentStatusRequest packets. */ diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/SoundSettings.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/SoundSettings.java index e9562563a..67317ee39 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/SoundSettings.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/SoundSettings.java @@ -19,13 +19,13 @@ package org.jivesoftware.smackx.workgroup.settings; import java.io.IOException; -import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.SimpleIQ; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.util.stringencoder.Base64; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -public class SoundSettings extends IQ { +public class SoundSettings extends SimpleIQ { private String outgoingSound; private String incomingSound; @@ -57,18 +57,10 @@ public class SoundSettings extends IQ { */ public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup"; - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - - buf.append("<").append(ELEMENT_NAME).append(" xmlns="); - buf.append('"'); - buf.append(NAMESPACE); - buf.append('"'); - buf.append("> "); - return buf.toString(); + public SoundSettings() { + super(ELEMENT_NAME, NAMESPACE); } - /** * Packet extension provider for SoundSetting Packets. */ diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/WorkgroupProperties.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/WorkgroupProperties.java index 758e31af3..8166c69d4 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/WorkgroupProperties.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/settings/WorkgroupProperties.java @@ -75,18 +75,17 @@ public class WorkgroupProperties extends IQ { */ public static final String NAMESPACE = "http://jivesoftware.com/protocol/workgroup"; - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); + public WorkgroupProperties() { + super(ELEMENT_NAME, NAMESPACE); + } - buf.append("<").append(ELEMENT_NAME).append(" xmlns="); - buf.append('"'); - buf.append(NAMESPACE); - buf.append('"'); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { if (ModelUtil.hasLength(getJid())) { buf.append("jid=\"" + getJid() + "\" "); } - buf.append("> "); - return buf.toString(); + buf.setEmptyElement(); + return buf; } /** diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java index 418065432..3780e3dda 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java @@ -577,6 +577,7 @@ public class Workgroup { private DataForm form; public JoinQueuePacket(String workgroup, Form answerForm, String userID) { + super("join-queue", "http://jabber.org/protocol/workgroup"); this.userID = userID; setTo(workgroup); @@ -586,10 +587,9 @@ public class Workgroup { addExtension(form); } - public String getChildElementXML() { - StringBuilder buf = new StringBuilder(); - - buf.append(""); + @Override + protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder buf) { + buf.rightAngleBracket(); buf.append(""); // Add the user unique identification if the session is anonymous if (connection.isAnonymous()) { @@ -599,9 +599,7 @@ public class Workgroup { // Append data form text buf.append(form.toXML()); - buf.append(""); - - return buf.toString(); + return buf; } }