Merge pull request #501 from Flowdalic/fix-redundant-namespaces

Fix redundant namespaces
This commit is contained in:
Florian Schmaus 2021-10-19 14:29:18 +02:00 committed by GitHub
commit ab92bc4b40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 144 additions and 47 deletions

View File

@ -202,7 +202,7 @@ public abstract class IQ extends Stanza implements IqView {
// Add the query section if there is one. // Add the query section if there is one.
IQChildElementXmlStringBuilder iqChildElement = getIQChildElementBuilder( IQChildElementXmlStringBuilder iqChildElement = getIQChildElementBuilder(
new IQChildElementXmlStringBuilder(this)); new IQChildElementXmlStringBuilder(getChildElementName(), getChildElementNamespace(), null, xml.getXmlEnvironment()));
// TOOD: Document the cases where iqChildElement is null but childElementName not. And if there are none, change // TOOD: Document the cases where iqChildElement is null but childElementName not. And if there are none, change
// the logic. // the logic.
if (iqChildElement == null) { if (iqChildElement == null) {
@ -399,17 +399,16 @@ public abstract class IQ extends Stanza implements IqView {
private boolean isEmptyElement; private boolean isEmptyElement;
private IQChildElementXmlStringBuilder(IQ iq) { public IQChildElementXmlStringBuilder(ExtensionElement extensionElement,
this(iq.getChildElementName(), iq.getChildElementNamespace()); XmlEnvironment enclosingXmlEnvironment) {
this(extensionElement.getElementName(), extensionElement.getNamespace(), extensionElement.getLanguage(),
enclosingXmlEnvironment);
} }
public IQChildElementXmlStringBuilder(ExtensionElement pe) { private IQChildElementXmlStringBuilder(String elementName, String xmlNs, String xmlLang,
this(pe.getElementName(), pe.getNamespace()); XmlEnvironment enclosingXmlEnvironment) {
} super(elementName, xmlNs, xmlLang, enclosingXmlEnvironment);
this.element = elementName;
private IQChildElementXmlStringBuilder(String element, String namespace) {
prelude(element, namespace);
this.element = element;
} }
public void setEmptyElement() { public void setEmptyElement() {

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2014-2020 Florian Schmaus * Copyright 2014-2021 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -53,11 +53,13 @@ public class XmlStringBuilder implements Appendable, CharSequence, Element {
} }
public XmlStringBuilder(FullyQualifiedElement element, XmlEnvironment enclosingXmlEnvironment) { public XmlStringBuilder(FullyQualifiedElement element, XmlEnvironment enclosingXmlEnvironment) {
sb = new LazyStringBuilder(); this(element.getElementName(), element.getNamespace(), element.getLanguage(), enclosingXmlEnvironment);
halfOpenElement(element); }
public XmlStringBuilder(String elementName, String xmlNs, String xmlLang, XmlEnvironment enclosingXmlEnvironment) {
sb = new LazyStringBuilder();
halfOpenElement(elementName);
String xmlNs = element.getNamespace();
String xmlLang = element.getLanguage();
if (enclosingXmlEnvironment == null) { if (enclosingXmlEnvironment == null) {
xmlnsAttribute(xmlNs); xmlnsAttribute(xmlNs);
xmllangAttribute(xmlLang); xmllangAttribute(xmlLang);

View File

@ -153,7 +153,7 @@ public class DataPacketExtension implements ExtensionElement {
@Override @Override
public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) { public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
XmlStringBuilder xml = getIQChildElementBuilder(new IQChildElementXmlStringBuilder(this)); XmlStringBuilder xml = getIQChildElementBuilder(new IQChildElementXmlStringBuilder(this, enclosingNamespace));
xml.closeElement(this); xml.closeElement(this);
return xml; return xml;
} }

View File

@ -51,7 +51,7 @@ public class JingleUtil {
JingleContentDescription description, JingleContentDescription description,
JingleContentTransport transport) { JingleContentTransport transport) {
Jingle.Builder jb = Jingle.getBuilder(); Jingle.Builder jb = Jingle.builder(connection);
jb.setAction(JingleAction.session_initiate) jb.setAction(JingleAction.session_initiate)
.setSessionId(sessionId) .setSessionId(sessionId)
.setInitiator(connection.getUser()); .setInitiator(connection.getUser());
@ -116,7 +116,7 @@ public class JingleUtil {
JingleContentDescription description, JingleContentDescription description,
JingleContentTransport transport) { JingleContentTransport transport) {
Jingle.Builder jb = Jingle.getBuilder(); Jingle.Builder jb = Jingle.builder(connection);
jb.setResponder(connection.getUser()) jb.setResponder(connection.getUser())
.setAction(JingleAction.session_accept) .setAction(JingleAction.session_accept)
.setSessionId(sessionId); .setSessionId(sessionId);
@ -151,7 +151,7 @@ public class JingleUtil {
} }
public Jingle createSessionTerminate(FullJid recipient, String sessionId, JingleReason reason) { public Jingle createSessionTerminate(FullJid recipient, String sessionId, JingleReason reason) {
Jingle.Builder jb = Jingle.getBuilder(); Jingle.Builder jb = Jingle.builder(connection);
jb.setAction(JingleAction.session_terminate) jb.setAction(JingleAction.session_terminate)
.setSessionId(sessionId) .setSessionId(sessionId)
.setReason(reason); .setReason(reason);
@ -230,7 +230,7 @@ public class JingleUtil {
public Jingle createSessionTerminateContentCancel(FullJid recipient, String sessionId, public Jingle createSessionTerminateContentCancel(FullJid recipient, String sessionId,
JingleContent.Creator contentCreator, String contentName) { JingleContent.Creator contentCreator, String contentName) {
Jingle.Builder jb = Jingle.getBuilder(); Jingle.Builder jb = Jingle.builder(connection);
jb.setAction(JingleAction.session_terminate) jb.setAction(JingleAction.session_terminate)
.setSessionId(sessionId); .setSessionId(sessionId);
@ -312,7 +312,7 @@ public class JingleUtil {
} }
public Jingle createSessionPing(FullJid recipient, String sessionId) { public Jingle createSessionPing(FullJid recipient, String sessionId) {
Jingle.Builder jb = Jingle.getBuilder(); Jingle.Builder jb = Jingle.builder(connection);
jb.setSessionId(sessionId) jb.setSessionId(sessionId)
.setAction(JingleAction.session_info); .setAction(JingleAction.session_info);
@ -341,7 +341,7 @@ public class JingleUtil {
public Jingle createTransportReplace(FullJid recipient, FullJid initiator, String sessionId, public Jingle createTransportReplace(FullJid recipient, FullJid initiator, String sessionId,
JingleContent.Creator contentCreator, String contentName, JingleContent.Creator contentCreator, String contentName,
JingleContentTransport transport) { JingleContentTransport transport) {
Jingle.Builder jb = Jingle.getBuilder(); Jingle.Builder jb = Jingle.builder(connection);
jb.setInitiator(initiator) jb.setInitiator(initiator)
.setSessionId(sessionId) .setSessionId(sessionId)
.setAction(JingleAction.transport_replace); .setAction(JingleAction.transport_replace);
@ -368,7 +368,7 @@ public class JingleUtil {
public Jingle createTransportAccept(FullJid recipient, FullJid initiator, String sessionId, public Jingle createTransportAccept(FullJid recipient, FullJid initiator, String sessionId,
JingleContent.Creator contentCreator, String contentName, JingleContent.Creator contentCreator, String contentName,
JingleContentTransport transport) { JingleContentTransport transport) {
Jingle.Builder jb = Jingle.getBuilder(); Jingle.Builder jb = Jingle.builder(connection);
jb.setAction(JingleAction.transport_accept) jb.setAction(JingleAction.transport_accept)
.setInitiator(initiator) .setInitiator(initiator)
.setSessionId(sessionId); .setSessionId(sessionId);
@ -395,7 +395,7 @@ public class JingleUtil {
public Jingle createTransportReject(FullJid recipient, FullJid initiator, String sessionId, public Jingle createTransportReject(FullJid recipient, FullJid initiator, String sessionId,
JingleContent.Creator contentCreator, String contentName, JingleContent.Creator contentCreator, String contentName,
JingleContentTransport transport) { JingleContentTransport transport) {
Jingle.Builder jb = Jingle.getBuilder(); Jingle.Builder jb = Jingle.builder(connection);
jb.setAction(JingleAction.transport_reject) jb.setAction(JingleAction.transport_reject)
.setInitiator(initiator) .setInitiator(initiator)
.setSessionId(sessionId); .setSessionId(sessionId);

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2003-2007 Jive Software, 2014-2017 Florian Schmaus * Copyright 2003-2007 Jive Software, 2014-2021 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,7 +21,11 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.IqBuilder;
import org.jivesoftware.smack.packet.IqData;
import org.jivesoftware.smack.packet.id.StandardStanzaIdSource;
import org.jivesoftware.smack.util.Objects; import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.StringUtils;
@ -65,9 +69,9 @@ public final class Jingle extends IQ {
private final List<JingleContent> contents; private final List<JingleContent> contents;
private Jingle(String sessionId, JingleAction action, FullJid initiator, FullJid responder, JingleReason reason, private Jingle(Builder builder, String sessionId, JingleAction action, FullJid initiator, FullJid responder, JingleReason reason,
List<JingleContent> contents) { List<JingleContent> contents) {
super(ELEMENT, NAMESPACE); super(builder, ELEMENT, NAMESPACE);
this.sessionId = StringUtils.requireNotNullNorEmpty(sessionId, "Jingle session ID must not be null"); this.sessionId = StringUtils.requireNotNullNorEmpty(sessionId, "Jingle session ID must not be null");
this.action = Objects.requireNonNull(action, "Jingle action must not be null"); this.action = Objects.requireNonNull(action, "Jingle action must not be null");
this.initiator = initiator; this.initiator = initiator;
@ -169,11 +173,31 @@ public final class Jingle extends IQ {
return xml; return xml;
} }
/**
* Deprecated, do not use.
*
* @return a builder.
* @deprecated use {@link #builder(XMPPConnection)} instead.
*/
@Deprecated
// TODO: Remove in Smack 4.6.
public static Builder getBuilder() { public static Builder getBuilder() {
return new Builder(); return builder(StandardStanzaIdSource.DEFAULT.getNewStanzaId());
} }
public static final class Builder { public static Builder builder(XMPPConnection connection) {
return new Builder(connection);
}
public static Builder builder(IqData iqData) {
return new Builder(iqData);
}
public static Builder builder(String stanzaId) {
return new Builder(stanzaId);
}
public static final class Builder extends IqBuilder<Builder, Jingle> {
private String sid; private String sid;
private JingleAction action; private JingleAction action;
@ -186,7 +210,16 @@ public final class Jingle extends IQ {
private List<JingleContent> contents; private List<JingleContent> contents;
private Builder() { Builder(IqData iqCommon) {
super(iqCommon);
}
Builder(XMPPConnection connection) {
super(connection);
}
Builder(String stanzaId) {
super(stanzaId);
} }
public Builder setSessionId(String sessionId) { public Builder setSessionId(String sessionId) {
@ -228,8 +261,14 @@ public final class Jingle extends IQ {
return this; return this;
} }
@Override
public Jingle build() { public Jingle build() {
return new Jingle(sid, action, initiator, responder, reason, contents); return new Jingle(this, sid, action, initiator, responder, reason, contents);
}
@Override
public Builder getThis() {
return this;
} }
} }
} }

View File

@ -145,6 +145,11 @@ public final class JingleContent implements FullyQualifiedElement {
xml.optAttribute(DISPOSITION_ATTRIBUTE_NAME, disposition); xml.optAttribute(DISPOSITION_ATTRIBUTE_NAME, disposition);
xml.attribute(NAME_ATTRIBUTE_NAME, name); xml.attribute(NAME_ATTRIBUTE_NAME, name);
xml.optAttribute(SENDERS_ATTRIBUTE_NAME, senders); xml.optAttribute(SENDERS_ATTRIBUTE_NAME, senders);
if (description == null && transport == null) {
return xml.closeEmptyElement();
}
xml.rightAngleBracket(); xml.rightAngleBracket();
xml.optAppend(description); xml.optAppend(description);

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2017-2019 Florian Schmaus * Copyright 2017-2021 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,11 +19,12 @@ package org.jivesoftware.smackx.jingle.provider;
import java.io.IOException; import java.io.IOException;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.jivesoftware.smack.packet.IqData;
import org.jivesoftware.smack.packet.StandardExtensionElement; import org.jivesoftware.smack.packet.StandardExtensionElement;
import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.parsing.SmackParsingException; import org.jivesoftware.smack.parsing.SmackParsingException;
import org.jivesoftware.smack.parsing.StandardExtensionElementProvider; import org.jivesoftware.smack.parsing.StandardExtensionElementProvider;
import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.provider.IqProvider;
import org.jivesoftware.smack.util.ParserUtils; import org.jivesoftware.smack.util.ParserUtils;
import org.jivesoftware.smack.xml.XmlPullParser; import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException; import org.jivesoftware.smack.xml.XmlPullParserException;
@ -40,13 +41,13 @@ import org.jivesoftware.smackx.jingle.element.UnknownJingleContentTransport;
import org.jxmpp.jid.FullJid; import org.jxmpp.jid.FullJid;
public class JingleProvider extends IQProvider<Jingle> { public class JingleProvider extends IqProvider<Jingle> {
private static final Logger LOGGER = Logger.getLogger(JingleProvider.class.getName()); private static final Logger LOGGER = Logger.getLogger(JingleProvider.class.getName());
@Override @Override
public Jingle parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { public Jingle parse(XmlPullParser parser, int initialDepth, IqData iqData, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException {
Jingle.Builder builder = Jingle.getBuilder(); Jingle.Builder builder = Jingle.builder(iqData);
String actionString = parser.getAttributeValue("", Jingle.ACTION_ATTRIBUTE_NAME); String actionString = parser.getAttributeValue("", Jingle.ACTION_ATTRIBUTE_NAME);
if (actionString != null) { if (actionString != null) {

View File

@ -36,6 +36,10 @@ public abstract class JingleTransportManager<D extends JingleContentTransport> i
} }
public XMPPConnection getConnection() { public XMPPConnection getConnection() {
return connection();
}
public XMPPConnection connection() {
return connection; return connection;
} }

View File

@ -148,7 +148,7 @@ public final class JingleS5BTransportManager extends JingleTransportManager<Jing
public Jingle createCandidateUsed(FullJid recipient, FullJid initiator, String sessionId, JingleContent.Senders contentSenders, public Jingle createCandidateUsed(FullJid recipient, FullJid initiator, String sessionId, JingleContent.Senders contentSenders,
JingleContent.Creator contentCreator, String contentName, String streamId, JingleContent.Creator contentCreator, String contentName, String streamId,
String candidateId) { String candidateId) {
Jingle.Builder jb = Jingle.getBuilder(); Jingle.Builder jb = Jingle.builder(connection());
jb.setSessionId(sessionId).setInitiator(initiator).setAction(JingleAction.transport_info); jb.setSessionId(sessionId).setInitiator(initiator).setAction(JingleAction.transport_info);
JingleContent.Builder cb = JingleContent.getBuilder(); JingleContent.Builder cb = JingleContent.getBuilder();
@ -165,7 +165,7 @@ public final class JingleS5BTransportManager extends JingleTransportManager<Jing
} }
public Jingle createCandidateError(FullJid remote, FullJid initiator, String sessionId, JingleContent.Senders senders, JingleContent.Creator creator, String name, String streamId) { public Jingle createCandidateError(FullJid remote, FullJid initiator, String sessionId, JingleContent.Senders senders, JingleContent.Creator creator, String name, String streamId) {
Jingle.Builder jb = Jingle.getBuilder(); Jingle.Builder jb = Jingle.builder(connection());
jb.setSessionId(sessionId).setInitiator(initiator).setAction(JingleAction.transport_info); jb.setSessionId(sessionId).setInitiator(initiator).setAction(JingleAction.transport_info);
JingleContent.Builder cb = JingleContent.getBuilder(); JingleContent.Builder cb = JingleContent.getBuilder();
@ -184,7 +184,7 @@ public final class JingleS5BTransportManager extends JingleTransportManager<Jing
public Jingle createProxyError(FullJid remote, FullJid initiator, String sessionId, public Jingle createProxyError(FullJid remote, FullJid initiator, String sessionId,
JingleContent.Senders senders, JingleContent.Creator creator, JingleContent.Senders senders, JingleContent.Creator creator,
String name, String streamId) { String name, String streamId) {
Jingle.Builder jb = Jingle.getBuilder(); Jingle.Builder jb = Jingle.builder(connection());
jb.setSessionId(sessionId).setAction(JingleAction.transport_info).setInitiator(initiator); jb.setSessionId(sessionId).setAction(JingleAction.transport_info).setInitiator(initiator);
JingleContent.Builder cb = JingleContent.getBuilder(); JingleContent.Builder cb = JingleContent.getBuilder();
@ -202,7 +202,7 @@ public final class JingleS5BTransportManager extends JingleTransportManager<Jing
public Jingle createCandidateActivated(FullJid remote, FullJid initiator, String sessionId, public Jingle createCandidateActivated(FullJid remote, FullJid initiator, String sessionId,
JingleContent.Senders senders, JingleContent.Creator creator, JingleContent.Senders senders, JingleContent.Creator creator,
String name, String streamId, String candidateId) { String name, String streamId, String candidateId) {
Jingle.Builder jb = Jingle.getBuilder(); Jingle.Builder jb = Jingle.builder(connection());
jb.setInitiator(initiator).setSessionId(sessionId).setAction(JingleAction.transport_info); jb.setInitiator(initiator).setSessionId(sessionId).setAction(JingleAction.transport_info);
JingleContent.Builder cb = JingleContent.getBuilder(); JingleContent.Builder cb = JingleContent.getBuilder();

View File

@ -75,8 +75,7 @@ public class JingleContentTest extends SmackTestSuite {
assertEquals(content1.toXML().toString(), builder.build().toXML().toString()); assertEquals(content1.toXML().toString(), builder.build().toXML().toString());
String xml = String xml =
"<content xmlns='urn:xmpp:jingle:1' creator='initiator' disposition='session' name='A name' senders='both'>" + "<content xmlns='urn:xmpp:jingle:1' creator='initiator' disposition='session' name='A name' senders='both'/>";
"</content>";
assertEquals(xml, content1.toXML().toString()); assertEquals(xml, content1.toXML().toString());
} }
} }

View File

@ -38,7 +38,7 @@ public class JingleTest extends SmackTestSuite {
@Test @Test
public void emptyBuilderTest() { public void emptyBuilderTest() {
Jingle.Builder builder = Jingle.getBuilder(); Jingle.Builder builder = Jingle.builder("id");
assertThrows(IllegalArgumentException.class, () -> { assertThrows(IllegalArgumentException.class, () -> {
builder.build(); builder.build();
}); });
@ -48,7 +48,7 @@ public class JingleTest extends SmackTestSuite {
public void onlySessionIdBuilderTest() { public void onlySessionIdBuilderTest() {
String sessionId = "testSessionId"; String sessionId = "testSessionId";
Jingle.Builder builder = Jingle.getBuilder(); Jingle.Builder builder = Jingle.builder("id");
builder.setSessionId(sessionId); builder.setSessionId(sessionId);
assertThrows(IllegalArgumentException.class, () -> { assertThrows(IllegalArgumentException.class, () -> {
builder.build(); builder.build();
@ -59,7 +59,7 @@ public class JingleTest extends SmackTestSuite {
public void parserTest() throws XmppStringprepException { public void parserTest() throws XmppStringprepException {
String sessionId = "testSessionId"; String sessionId = "testSessionId";
Jingle.Builder builder = Jingle.getBuilder(); Jingle.Builder builder = Jingle.builder("id");
builder.setSessionId(sessionId); builder.setSessionId(sessionId);
builder.setAction(JingleAction.session_initiate); builder.setAction(JingleAction.session_initiate);

View File

@ -0,0 +1,48 @@
/**
*
* Copyright 2021 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.jingle.element;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.jivesoftware.smack.packet.StreamOpen;
import org.junit.jupiter.api.Test;
public class JingleTest {
@Test
public void noRedundantNamespaceTest() {
Jingle.Builder jingleBuilder = Jingle.builder("test-id");
jingleBuilder.setSessionId("MySession");
jingleBuilder.setAction(JingleAction.content_accept);
JingleContent.Builder jingleContentBuilder = JingleContent.getBuilder();
jingleContentBuilder.setName("Hello world");
jingleContentBuilder.setCreator(JingleContent.Creator.initiator);
jingleBuilder.addJingleContent(jingleContentBuilder.build());
Jingle iq = jingleBuilder.build();
String actualXml = iq.toXML(StreamOpen.CLIENT_NAMESPACE).toString();
String expectedXml
= "<iq id='test-id' type='set'>"
+ "<jingle xmlns='urn:xmpp:jingle:1' action='content-accept' sid='MySession'>"
+ "<content creator='initiator' name='Hello world'/>"
+ "</jingle></iq>";
assertEquals(expectedXml, actualXml);
}
}

View File

@ -114,7 +114,7 @@ public class RoomInvitation implements ExtensionElement {
@Override @Override
public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) { public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
XmlStringBuilder xml = getIQChildElementBuilder(new IQChildElementXmlStringBuilder(this)); XmlStringBuilder xml = getIQChildElementBuilder(new IQChildElementXmlStringBuilder(this, enclosingNamespace));
xml.closeElement(this); xml.closeElement(this);
return xml; return xml;
} }

View File

@ -109,7 +109,7 @@ public class RoomTransfer implements ExtensionElement {
@Override @Override
public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) { public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
XmlStringBuilder xml = getIQChildElementBuilder(new IQChildElementXmlStringBuilder(this)); XmlStringBuilder xml = getIQChildElementBuilder(new IQChildElementXmlStringBuilder(this, enclosingNamespace));
xml.closeElement(this); xml.closeElement(this);
return xml; return xml;
} }