From 6e32305987e64ad68a66bfd29372e10fcafc04a9 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 29 Oct 2019 11:14:55 +0100 Subject: [PATCH] Apply builder pattern to DiscoverInfo This is the first transformation of an IQ type to the builder type. --- .../smack/packet/AbstractIqBuilder.java | 69 ++++++++++ .../smack/packet/EmptyResultIQ.java | 2 +- .../org/jivesoftware/smack/packet/IQ.java | 21 ++- .../jivesoftware/smack/packet/IqBuilder.java | 20 +-- .../smack/packet/IqBuilderWithBuild.java | 45 +++++++ .../smack/packet/StanzaBuilder.java | 33 +++-- .../smack/packet/StanzaFactory.java | 4 + .../smack/provider/AbstractProvider.java | 45 +++++++ .../smack/provider/IQProvider.java | 40 +++++- .../smack/provider/IQProviderInfo.java | 2 +- .../smack/provider/IqProvider.java | 46 +++++++ .../jivesoftware/smack/provider/Provider.java | 24 +--- .../smack/provider/ProviderFileLoader.java | 4 +- .../smack/provider/ProviderManager.java | 14 +- .../smack/util/PacketParserUtils.java | 26 +++- .../iot/control/element/IoTSetResponse.java | 4 +- .../smackx/caps/EntityCapsManager.java | 19 ++- .../smackx/disco/ServiceDiscoveryManager.java | 42 +++--- .../smackx/disco/packet/DiscoverInfo.java | 118 ++++++++++++----- .../disco/packet/DiscoverInfoBuilder.java | 123 ++++++++++++++++++ .../smackx/disco/packet/DiscoverInfoView.java | 49 +++++++ .../disco/provider/DiscoverInfoProvider.java | 58 ++++----- .../org/jivesoftware/smackx/pubsub/Node.java | 11 +- .../smackx/pubsub/PubSubManager.java | 10 +- .../smackx/xdata/packet/DataForm.java | 15 ++- .../socks5/Socks5ByteStreamManagerTest.java | 74 ++++++----- .../bytestreams/socks5/Socks5PacketUtils.java | 12 +- .../smackx/caps/EntityCapsManagerTest.java | 24 ++-- .../jivesoftware/smackx/muc/RoomInfoTest.java | 10 +- .../smackx/pubsub/ConfigureFormTest.java | 18 ++- 30 files changed, 749 insertions(+), 233 deletions(-) create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractIqBuilder.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilderWithBuild.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/provider/AbstractProvider.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/provider/IqProvider.java create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoBuilder.java create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoView.java diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractIqBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractIqBuilder.java new file mode 100644 index 000000000..479bcb346 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractIqBuilder.java @@ -0,0 +1,69 @@ +/** + * + * Copyright 2019 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; + +import org.jivesoftware.smack.packet.id.StanzaIdSource; +import org.jivesoftware.smack.util.ToStringUtil; + +public abstract class AbstractIqBuilder> extends StanzaBuilder implements IqView { + + protected IQ.Type type = IQ.Type.get; + + AbstractIqBuilder(AbstractIqBuilder other) { + super(other); + type = other.type; + } + + AbstractIqBuilder(StanzaIdSource stanzaIdSource) { + super(stanzaIdSource); + } + + AbstractIqBuilder(String stanzaId) { + super(stanzaId); + } + + public static IqBuilder createResponse(IqView request) { + return createResponse(request, IQ.ResponseType.result); + } + + public static IqBuilder createErrorResponse(IqView request) { + return createResponse(request, IQ.ResponseType.error); + } + + protected static IqBuilder createResponse(IqView request, IQ.ResponseType responseType) { + if (!(request.getType() == IQ.Type.get || request.getType() == IQ.Type.set)) { + throw new IllegalArgumentException("IQ request must be of type 'set' or 'get'. Original IQ: " + request); + } + + IqBuilder commonResponseIqData = buildResponse(request, s -> { + return StanzaBuilder.buildIq(s); + }); + commonResponseIqData.ofType(responseType.getType()); + + return commonResponseIqData; + } + + @Override + protected final void addStanzaSpecificAttributes(ToStringUtil.Builder builder) { + builder.addValue("type", getType()); + } + + @Override + public final IQ.Type getType() { + return type; + } +} 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 index fd3b576c1..933bf089f 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java @@ -29,7 +29,7 @@ public class EmptyResultIQ extends IQ { } public EmptyResultIQ(IQ request) { - this(StanzaBuilder.buildIqResultFor(request)); + this(AbstractIqBuilder.createResponse(request)); } @Override 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 d202eb2cc..db76ecdaa 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 @@ -68,7 +68,7 @@ public abstract class IQ extends Stanza implements IqView { this(IqBuilder.EMPTY, childElementName, childElementNamespace); } - protected IQ(IqBuilder iqBuilder, String childElementName, String childElementNamespace) { + protected IQ(AbstractIqBuilder iqBuilder, String childElementName, String childElementNamespace) { super(iqBuilder); type = iqBuilder.type; @@ -376,6 +376,25 @@ public abstract class IQ extends Stanza implements IqView { } } + public enum ResponseType { + + result(Type.result), + + error(Type.error), + + ; + + final Type type; + + ResponseType(Type type) { + this.type = type; + } + + Type getType() { + return type; + } + } + public static class IQChildElementXmlStringBuilder extends XmlStringBuilder { private final String element; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java index a0994555f..e1bc905a2 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java @@ -16,16 +16,18 @@ */ package org.jivesoftware.smack.packet; -import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smack.packet.id.StandardStanzaIdSource; import org.jivesoftware.smack.packet.id.StanzaIdSource; import org.jivesoftware.smack.util.Objects; -import org.jivesoftware.smack.util.ToStringUtil; -public final class IqBuilder extends StanzaBuilder implements IqView { +// TODO: Rename to IqData. +public final class IqBuilder extends AbstractIqBuilder { + static final IqBuilder EMPTY = new IqBuilder(StandardStanzaIdSource.DEFAULT); - IQ.Type type = Type.get; + IqBuilder(IqBuilder other) { + super(other); + } IqBuilder(StanzaIdSource stanzaIdSource) { super(stanzaIdSource); @@ -35,11 +37,6 @@ public final class IqBuilder extends StanzaBuilder implements IqView super(stanzaId); } - @Override - protected void addStanzaSpecificAttributes(ToStringUtil.Builder builder) { - builder.addValue("type", type); - } - public IqBuilder ofType(IQ.Type type) { this.type = Objects.requireNonNull(type); return getThis(); @@ -49,9 +46,4 @@ public final class IqBuilder extends StanzaBuilder implements IqView public IqBuilder getThis() { return this; } - - @Override - public IQ.Type getType() { - return type; - } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilderWithBuild.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilderWithBuild.java new file mode 100644 index 000000000..5d8c993de --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilderWithBuild.java @@ -0,0 +1,45 @@ +/** + * + * Copyright 2019 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; + +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.util.Objects; + +// TODO: Rename to IqBuilder. +public abstract class IqBuilderWithBuild, I extends IQ> + extends AbstractIqBuilder { + + protected IqBuilderWithBuild(AbstractIqBuilder other) { + super(other); + } + + protected IqBuilderWithBuild(XMPPConnection connection) { + super(connection.getStanzaFactory().getStanzaIdSource()); + } + + protected IqBuilderWithBuild(String stanzaId) { + super(stanzaId); + } + + public IB ofType(IQ.Type type) { + this.type = Objects.requireNonNull(type); + return getThis(); + } + + public abstract I build(); + +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java index 4b2cba391..ec150e005 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java @@ -21,8 +21,8 @@ import java.util.List; import javax.xml.namespace.QName; -import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smack.packet.id.StanzaIdSource; +import org.jivesoftware.smack.util.Function; import org.jivesoftware.smack.util.MultiMap; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.ToStringUtil; @@ -46,6 +46,17 @@ public abstract class StanzaBuilder> implements Stanz MultiMap extensionElements = new MultiMap<>(); + protected StanzaBuilder(StanzaBuilder other) { + stanzaIdSource = other.stanzaIdSource; + stanzaId = other.stanzaId; + + to = other.to; + from = other.from; + stanzaError = other.stanzaError; + language = other.language; + extensionElements = other.extensionElements.clone(); + } + protected StanzaBuilder(StanzaIdSource stanzaIdSource) { this.stanzaIdSource = stanzaIdSource; this.stanzaId = null; @@ -282,20 +293,14 @@ public abstract class StanzaBuilder> implements Stanz return new IqBuilder(stanzaId); } - public static IqBuilder buildIqResultFor(IQ request) { - if (!(request.getType() == Type.get || request.getType() == Type.set)) { - throw new IllegalArgumentException( - "IQ request must be of type 'set' or 'get'. Original IQ: " + request.toXML()); - } + public static > SB buildResponse(StanzaView request, Function builderFromStanzaId) { + SB responseBuilder = builderFromStanzaId.apply(request.getStanzaId()); - return buildIq(request.getStanzaId()) - .to(request.getFrom()) - .from(request.getTo()) - .ofType(IQ.Type.result); + responseBuilder.to(request.getFrom()) + .from(request.getTo()) + ; + + return responseBuilder; } - public static EmptyResultIQ buildEmptyIqResultFor(IQ request) { - IqBuilder iqBuilder = buildIqResultFor(request); - return new EmptyResultIQ(iqBuilder); - } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java index 4a7a85ce8..738477cf7 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java @@ -22,6 +22,10 @@ public final class StanzaFactory { private final StanzaIdSource stanzaIdSource; + StanzaIdSource getStanzaIdSource() { + return stanzaIdSource; + } + public StanzaFactory(StanzaIdSource stanzaIdSource) { this.stanzaIdSource = stanzaIdSource; } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/AbstractProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/AbstractProvider.java new file mode 100644 index 000000000..5eda3b494 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/AbstractProvider.java @@ -0,0 +1,45 @@ +/** + * + * Copyright 2019 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.provider; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +import org.jivesoftware.smack.packet.Element; + +public class AbstractProvider { + + private final Class elementClass; + + @SuppressWarnings("unchecked") + protected AbstractProvider() { + Type currentType = getClass().getGenericSuperclass(); + while (!(currentType instanceof ParameterizedType)) { + Class currentClass = (Class) currentType; + currentType = currentClass.getGenericSuperclass(); + } + ParameterizedType parameterizedGenericSuperclass = (ParameterizedType) currentType; + Type[] actualTypeArguments = parameterizedGenericSuperclass.getActualTypeArguments(); + Type elementType = actualTypeArguments[0]; + + elementClass = (Class) elementType; + } + + public final Class getElementClass() { + return elementClass; + } +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProvider.java index 66e7aa0f1..514b3e875 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProvider.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProvider.java @@ -17,15 +17,53 @@ package org.jivesoftware.smack.provider; +import java.io.IOException; + import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.IqBuilder; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.parsing.SmackParsingException; +import org.jivesoftware.smack.util.ParserUtils; +import org.jivesoftware.smack.xml.XmlPullParser; +import org.jivesoftware.smack.xml.XmlPullParserException; /** + *

+ * Deprecation Notice: This class is deprecated, use {@link IQProvider} instead. + *

* An abstract class for parsing custom IQ packets. Each IQProvider must be registered with * the ProviderManager class for it to be used. Every implementation of this * abstract class must have a public, no-argument constructor. * * @author Matt Tucker */ -public abstract class IQProvider extends Provider { +public abstract class IQProvider extends IqProvider { + + public final I parse(XmlPullParser parser) throws IOException, XmlPullParserException, SmackParsingException { + return parse(parser, (XmlEnvironment) null); + } + + public final I parse(XmlPullParser parser, XmlEnvironment outerXmlEnvironment) throws IOException, XmlPullParserException, SmackParsingException { + // XPP3 calling convention assert: Parser should be at start tag + ParserUtils.assertAtStartTag(parser); + + final int initialDepth = parser.getDepth(); + final XmlEnvironment xmlEnvironment = XmlEnvironment.from(parser, outerXmlEnvironment); + + I e = parse(parser, initialDepth, xmlEnvironment); + + // XPP3 calling convention assert: Parser should be at end tag of the consumed/parsed element + ParserUtils.forwardToEndTagOfDepth(parser, initialDepth); + return e; + } + + @Override + public final I parse(XmlPullParser parser, int initialDepth, IqBuilder iqData, XmlEnvironment xmlEnvironment) + throws XmlPullParserException, IOException, SmackParsingException { + // Old-style IQ parsers do not need IqData. + return parse(parser, initialDepth, xmlEnvironment); + } + + public abstract I parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException; } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProviderInfo.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProviderInfo.java index abb14a62f..ec9baee99 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProviderInfo.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProviderInfo.java @@ -34,7 +34,7 @@ public final class IQProviderInfo extends AbstractProviderInfo { * @param namespace Namespace that provider parses. * @param iqProvider The provider implementation. */ - public IQProviderInfo(String elementName, String namespace, IQProvider iqProvider) { + public IQProviderInfo(String elementName, String namespace, IqProvider iqProvider) { super(elementName, namespace, iqProvider); } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/IqProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/IqProvider.java new file mode 100644 index 000000000..cab79ee72 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/IqProvider.java @@ -0,0 +1,46 @@ +/** + * + * Copyright 2019 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.provider; + +import java.io.IOException; + +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.IqBuilder; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.parsing.SmackParsingException; +import org.jivesoftware.smack.xml.XmlPullParser; +import org.jivesoftware.smack.xml.XmlPullParserException; + +public abstract class IqProvider extends AbstractProvider { + + public final I parse(XmlPullParser parser, IqBuilder iqCommon) + throws XmlPullParserException, IOException, SmackParsingException { + return parse(parser, iqCommon, null); + } + + public final I parse(XmlPullParser parser, IqBuilder iqData, XmlEnvironment outerXmlEnvironment) + throws XmlPullParserException, IOException, SmackParsingException { + final int initialDepth = parser.getDepth(); + final XmlEnvironment xmlEnvironment = XmlEnvironment.from(parser, outerXmlEnvironment); + + return parse(parser, initialDepth, iqData, xmlEnvironment); + } + + public abstract I parse(XmlPullParser parser, int initialDepth, IqBuilder iqData, XmlEnvironment xmlEnvironment) + throws XmlPullParserException, IOException, SmackParsingException; + +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java index ef1a225d9..4fdce0103 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java @@ -18,8 +18,6 @@ package org.jivesoftware.smack.provider; import java.io.IOException; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; import org.jivesoftware.smack.packet.Element; import org.jivesoftware.smack.packet.XmlEnvironment; @@ -40,27 +38,7 @@ import org.jivesoftware.smack.xml.XmlPullParserException; * @author Florian Schmaus * @param the type of the resulting element. */ -public abstract class Provider { - - private final Class elementClass; - - @SuppressWarnings("unchecked") - protected Provider() { - Type currentType = getClass().getGenericSuperclass(); - while (!(currentType instanceof ParameterizedType)) { - Class currentClass = (Class) currentType; - currentType = currentClass.getGenericSuperclass(); - } - ParameterizedType parameterizedGenericSuperclass = (ParameterizedType) currentType; - Type[] actualTypeArguments = parameterizedGenericSuperclass.getActualTypeArguments(); - Type elementType = actualTypeArguments[0]; - - elementClass = (Class) elementType; - } - - public final Class getElementClass() { - return elementClass; - } +public abstract class Provider extends AbstractProvider { public final E parse(XmlPullParser parser) throws IOException, XmlPullParserException, SmackParsingException { return parse(parser, null); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java index e39f81d26..6d3ea9f76 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java @@ -80,8 +80,8 @@ public class ProviderFileLoader implements ProviderLoader { // an IQ class, add the class object itself, then we'll use // reflection later to create instances of the class. // Add the provider to the map. - if (IQProvider.class.isAssignableFrom(provider)) { - IQProvider iqProvider = (IQProvider) provider.getConstructor().newInstance(); + if (IqProvider.class.isAssignableFrom(provider)) { + IqProvider iqProvider = (IqProvider) provider.getConstructor().newInstance(); iqProviders.add(new IQProviderInfo(elementName, namespace, iqProvider)); } else { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java index 377e6e47b..7527b330f 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java @@ -113,7 +113,7 @@ import org.jivesoftware.smack.util.XmppElementUtil; public final class ProviderManager { private static final Map> extensionProviders = new ConcurrentHashMap<>(); - private static final Map> iqProviders = new ConcurrentHashMap<>(); + private static final Map> iqProviders = new ConcurrentHashMap<>(); private static final Map> streamFeatureProviders = new ConcurrentHashMap<>(); private static final Map> nonzaProviders = new ConcurrentHashMap<>(); @@ -167,7 +167,7 @@ public final class ProviderManager { * @param namespace the XML namespace. * @return the IQ provider. */ - public static IQProvider getIQProvider(String elementName, String namespace) { + public static IqProvider getIQProvider(String elementName, String namespace) { QName key = getQName(elementName, namespace); return iqProviders.get(key); } @@ -179,8 +179,8 @@ public final class ProviderManager { * * @return all IQProvider instances. */ - public static List> getIQProviders() { - List> providers = new ArrayList<>(iqProviders.size()); + public static List> getIQProviders() { + List> providers = new ArrayList<>(iqProviders.size()); providers.addAll(iqProviders.values()); return providers; } @@ -200,10 +200,10 @@ public final class ProviderManager { validate(elementName, namespace); // First remove existing providers QName key = removeIQProvider(elementName, namespace); - if (provider instanceof IQProvider) { - iqProviders.put(key, (IQProvider) provider); + if (provider instanceof IqProvider) { + iqProviders.put(key, (IqProvider) provider); } else { - throw new IllegalArgumentException("Provider must be an IQProvider"); + throw new IllegalArgumentException("Provider must be an instance of IqProvider"); } } 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 57aaab932..eb7833f12 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 @@ -36,6 +36,7 @@ import org.jivesoftware.smack.packet.EmptyResultIQ; import org.jivesoftware.smack.packet.ErrorIQ; import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.IqBuilder; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smack.packet.Presence; @@ -51,7 +52,7 @@ import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.parsing.SmackParsingException; import org.jivesoftware.smack.parsing.StandardExtensionElementProvider; import org.jivesoftware.smack.provider.ExtensionElementProvider; -import org.jivesoftware.smack.provider.IQProvider; +import org.jivesoftware.smack.provider.IqProvider; import org.jivesoftware.smack.provider.ProviderManager; import org.jivesoftware.smack.xml.SmackXmlParser; import org.jivesoftware.smack.xml.XmlPullParser; @@ -542,9 +543,16 @@ public class PacketParserUtils { StanzaError error = null; final String id = parser.getAttributeValue("", "id"); + IqBuilder iqData = StanzaBuilder.buildIq(id); + final Jid to = ParserUtils.getJidAttribute(parser, "to"); + iqData.to(to); + final Jid from = ParserUtils.getJidAttribute(parser, "from"); + iqData.from(from); + final IQ.Type type = IQ.Type.fromString(parser.getAttributeValue("", "type")); + iqData.ofType(type); outerloop: while (true) { XmlPullParser.Event eventType = parser.next(); @@ -560,9 +568,9 @@ public class PacketParserUtils { // Otherwise, see if there is a registered provider for // this element name and namespace. default: - IQProvider provider = ProviderManager.getIQProvider(elementName, namespace); + IqProvider provider = ProviderManager.getIQProvider(elementName, namespace); if (provider != null) { - iqPacket = provider.parse(parser, outerXmlEnvironment); + iqPacket = provider.parse(parser, iqData, outerXmlEnvironment); } // 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_ELEMENT first. @@ -915,6 +923,18 @@ public class PacketParserUtils { return new Session.Feature(optional); } + public static void addExtensionElement(StanzaBuilder stanzaBuilder, XmlPullParser parser, XmlEnvironment outerXmlEnvironment) + throws XmlPullParserException, IOException, SmackParsingException { + ParserUtils.assertAtStartTag(parser); + addExtensionElement(stanzaBuilder, parser, parser.getName(), parser.getNamespace(), outerXmlEnvironment); + } + + public static void addExtensionElement(StanzaBuilder stanzaBuilder, XmlPullParser parser, String elementName, + String namespace, XmlEnvironment outerXmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { + ExtensionElement extensionElement = parseExtensionElement(elementName, namespace, parser, outerXmlEnvironment); + stanzaBuilder.addExtension(extensionElement); + } + public static void addExtensionElement(Stanza packet, XmlPullParser parser, XmlEnvironment outerXmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { ParserUtils.assertAtStartTag(parser); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java index 1f89efa0e..ef4513d1e 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java @@ -16,9 +16,9 @@ */ package org.jivesoftware.smackx.iot.control.element; +import org.jivesoftware.smack.packet.AbstractIqBuilder; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IqBuilder; -import org.jivesoftware.smack.packet.StanzaBuilder; public class IoTSetResponse extends IQ { @@ -35,7 +35,7 @@ public class IoTSetResponse extends IQ { } public IoTSetResponse(IoTSetRequest iotSetRequest) { - this(StanzaBuilder.buildIqResultFor(iotSetRequest)); + this(AbstractIqBuilder.createResponse(iotSetRequest)); } @Override diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java index c6b12c036..6591d7512 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java @@ -68,6 +68,8 @@ import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Feature; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoView; import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.packet.DataForm; @@ -521,16 +523,19 @@ public final class EntityCapsManager extends Manager { private void updateLocalEntityCaps() { XMPPConnection connection = connection(); - DiscoverInfo discoverInfo = new DiscoverInfo(); - discoverInfo.setType(IQ.Type.result); - sdm.addDiscoverInfoTo(discoverInfo); + DiscoverInfoBuilder discoverInfoBuilder = DiscoverInfo.builder("synthetized-disco-info-response") + .ofType(IQ.Type.result); + sdm.addDiscoverInfoTo(discoverInfoBuilder); // getLocalNodeVer() will return a result only after currentCapsVersion is set. Therefore // set it first and then call getLocalNodeVer() - currentCapsVersion = generateVerificationString(discoverInfo); + currentCapsVersion = generateVerificationString(discoverInfoBuilder); final String localNodeVer = getLocalNodeVer(); - discoverInfo.setNode(localNodeVer); + discoverInfoBuilder.setNode(localNodeVer); + + final DiscoverInfo discoverInfo = discoverInfoBuilder.build(); addDiscoverInfoByNode(localNodeVer, discoverInfo); + if (lastLocalCapsVersions.size() > 10) { CapsVersionAndHash oldCapsVersion = lastLocalCapsVersions.poll(); sdm.removeNodeInformationProvider(entityNode + '#' + oldCapsVersion.version); @@ -630,7 +635,7 @@ public final class EntityCapsManager extends Manager { return false; } - protected static CapsVersionAndHash generateVerificationString(DiscoverInfo discoverInfo) { + protected static CapsVersionAndHash generateVerificationString(DiscoverInfoView discoverInfo) { return generateVerificationString(discoverInfo, null); } @@ -646,7 +651,7 @@ public final class EntityCapsManager extends Manager { * @return The generated verification String or null if the hash is not * supported */ - protected static CapsVersionAndHash generateVerificationString(DiscoverInfo discoverInfo, String hash) { + protected static CapsVersionAndHash generateVerificationString(DiscoverInfoView discoverInfo, String hash) { if (hash == null) { hash = DEFAULT_HASH; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java index f6de2aca8..62fc38d1d 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java @@ -47,6 +47,7 @@ import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jivesoftware.smackx.xdata.packet.DataForm; @@ -159,34 +160,33 @@ public final class ServiceDiscoveryManager extends Manager { public IQ handleIQRequest(IQ iqRequest) { DiscoverInfo discoverInfo = (DiscoverInfo) iqRequest; // Answer the client's supported features if the request is of the GET type - DiscoverInfo response = new DiscoverInfo(); - response.setType(IQ.Type.result); - response.setTo(discoverInfo.getFrom()); - response.setStanzaId(discoverInfo.getStanzaId()); - response.setNode(discoverInfo.getNode()); + DiscoverInfoBuilder responseBuilder = DiscoverInfoBuilder.buildResponseFor(discoverInfo, IQ.ResponseType.result); + // Add the client's identity and features only if "node" is null // and if the request was not send to a node. If Entity Caps are // enabled the client's identity and features are may also added // if the right node is chosen if (discoverInfo.getNode() == null) { - addDiscoverInfoTo(response); + addDiscoverInfoTo(responseBuilder); } else { // Disco#info was sent to a node. Check if we have information of the // specified node NodeInformationProvider nodeInformationProvider = getNodeInformationProvider(discoverInfo.getNode()); if (nodeInformationProvider != null) { // Node was found. Add node features - response.addFeatures(nodeInformationProvider.getNodeFeatures()); + responseBuilder.addFeatures(nodeInformationProvider.getNodeFeatures()); // Add node identities - response.addIdentities(nodeInformationProvider.getNodeIdentities()); + responseBuilder.addIdentities(nodeInformationProvider.getNodeIdentities()); // Add packet extensions - response.addExtensions(nodeInformationProvider.getNodePacketExtensions()); + responseBuilder.addExtensions(nodeInformationProvider.getNodePacketExtensions()); } else { // Return error since specified node was not found - response.setType(IQ.Type.error); - response.setError(StanzaError.getBuilder(StanzaError.Condition.item_not_found).build()); + responseBuilder.ofType(IQ.Type.error); + responseBuilder.setError(StanzaError.getBuilder(StanzaError.Condition.item_not_found).build()); } } + + DiscoverInfo response = responseBuilder.build(); return response; } }); @@ -299,7 +299,7 @@ public final class ServiceDiscoveryManager extends Manager { * * @param response the discover info response packet */ - public synchronized void addDiscoverInfoTo(DiscoverInfo response) { + public synchronized void addDiscoverInfoTo(DiscoverInfoBuilder response) { // First add the identities of the connection response.addIdentities(getIdentities()); @@ -307,7 +307,9 @@ public final class ServiceDiscoveryManager extends Manager { for (String feature : getFeatures()) { response.addFeature(feature); } - response.addExtension(extendedInfo); + if (extendedInfo != null) { + response.addExtension(extendedInfo); + } } /** @@ -522,13 +524,15 @@ public final class ServiceDiscoveryManager extends Manager { * @throws InterruptedException if the calling thread was interrupted. */ public DiscoverInfo discoverInfo(Jid entityID, String node) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - // Discover the entity's info - DiscoverInfo disco = new DiscoverInfo(); - disco.setType(IQ.Type.get); - disco.setTo(entityID); - disco.setNode(node); + XMPPConnection connection = connection(); - Stanza result = connection().createStanzaCollectorAndSend(disco).nextResultOrThrow(); + // Discover the entity's info + DiscoverInfo discoInfoRequest = DiscoverInfo.builder(connection) + .to(entityID) + .setNode(node) + .build(); + + Stanza result = connection.createStanzaCollectorAndSend(discoInfoRequest).nextResultOrThrow(); return (DiscoverInfo) result; } 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 62e9cef67..6f47bb9d3 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 @@ -24,7 +24,9 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; +import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.IqBuilder; import org.jivesoftware.smack.util.EqualsUtil; import org.jivesoftware.smack.util.HashCode; import org.jivesoftware.smack.util.StringUtils; @@ -42,18 +44,53 @@ import org.jxmpp.util.XmppStringUtils; * * @author Gaston Dombiak */ -public class DiscoverInfo extends IQ implements TypedCloneable { +public class DiscoverInfo extends IQ implements DiscoverInfoView, TypedCloneable { public static final String ELEMENT = QUERY_ELEMENT; public static final String NAMESPACE = "http://jabber.org/protocol/disco#info"; - private final List features = new LinkedList<>(); + private final List features = new ArrayList<>(); private final Set featuresSet = new HashSet<>(); - private final List identities = new LinkedList<>(); + private final List identities = new ArrayList<>(); private final Set identitiesSet = new HashSet<>(); private String node; private boolean containsDuplicateFeatures; + DiscoverInfo(DiscoverInfoBuilder builder, boolean validate) { + super(builder, ELEMENT, NAMESPACE); + + features.addAll(builder.getFeatures()); + identities.addAll(builder.getIdentities()); + node = builder.getNode(); + + + for (Feature feature : features) { + boolean featureIsNew = featuresSet.add(feature); + if (!featureIsNew) { + containsDuplicateFeatures = true; + } + } + + for (Identity identity : identities) { + identitiesSet.add(identity.getKey()); + } + + if (!validate) { + return; + } + + if (containsDuplicateFeatures) { + throw new IllegalArgumentException("The disco#info request contains duplicate features."); + } + } + + /** + * Deprecated. + * + * @deprecated use {@link DiscoverInfoBuilder} instead. + */ + @Deprecated + // TODO: Remove in Smack 4.5. public DiscoverInfo() { super(ELEMENT, NAMESPACE); } @@ -67,17 +104,15 @@ public class DiscoverInfo extends IQ implements TypedCloneable { super(d); // Set node - setNode(d.getNode()); + node = d.getNode(); // Copy features - for (Feature f : d.features) { - addFeature(f.clone()); - } + features.addAll(d.features); + featuresSet.addAll(d.featuresSet); // Copy identities - for (Identity i : d.identities) { - addIdentity(i.clone()); - } + identities.addAll(d.identities); + identitiesSet.addAll(d.identitiesSet); } /** @@ -85,7 +120,10 @@ public class DiscoverInfo extends IQ implements TypedCloneable { * * @param feature the discovered feature * @return true if the feature did not already exist. + * @deprecated use {@link DiscoverInfoBuilder#addFeature(String)} instead. */ + @Deprecated + // TODO: Remove in Smack 4.5. public boolean addFeature(String feature) { return addFeature(new Feature(feature)); } @@ -94,7 +132,10 @@ public class DiscoverInfo extends IQ implements TypedCloneable { * Adds a collection of features to the packet. Does noting if featuresToAdd is null. * * @param featuresToAdd TODO javadoc me please + * @deprecated use {@link DiscoverInfoBuilder#addFeatures(Collection)} instead. */ + @Deprecated + // TODO: Remove in Smack 4.5. public void addFeatures(Collection featuresToAdd) { if (featuresToAdd == null) return; for (String feature : featuresToAdd) { @@ -102,6 +143,15 @@ public class DiscoverInfo extends IQ implements TypedCloneable { } } + /** + * Deprecated. + * + * @param feature the future. + * @return true if the feature is new. + * @deprecated use {@link DiscoverInfoBuilder#addFeature(Feature)} instead. + */ + @Deprecated + // TODO: Remove in Smack 4.5. public boolean addFeature(Feature feature) { features.add(feature); boolean featureIsNew = featuresSet.add(feature); @@ -111,11 +161,7 @@ public class DiscoverInfo extends IQ implements TypedCloneable { return featureIsNew; } - /** - * Returns the discovered features of an XMPP entity. - * - * @return an unmodifiable list of the discovered features of an XMPP entity - */ + @Override public List getFeatures() { return Collections.unmodifiableList(features); } @@ -124,7 +170,10 @@ public class DiscoverInfo extends IQ implements TypedCloneable { * Adds a new identity of the requested entity to the discovered information. * * @param identity the discovered entity's identity + * @deprecated use {@link DiscoverInfoBuilder#addIdentity(Identity)} instead. */ + @Deprecated + // TODO: Remove in Smack 4.5. public void addIdentity(Identity identity) { identities.add(identity); identitiesSet.add(identity.getKey()); @@ -134,7 +183,10 @@ public class DiscoverInfo extends IQ implements TypedCloneable { * Adds identities to the DiscoverInfo stanza. * * @param identitiesToAdd TODO javadoc me please + * @deprecated use {@link DiscoverInfoBuilder#addIdentities(Collection)} instead. */ + @Deprecated + // TODO: Remove in Smack 4.5. public void addIdentities(Collection identitiesToAdd) { if (identitiesToAdd == null) return; for (Identity identity : identitiesToAdd) { @@ -142,11 +194,7 @@ public class DiscoverInfo extends IQ implements TypedCloneable { } } - /** - * Returns the discovered identities of an XMPP entity. - * - * @return an unmodifiable list of the discovered identities - */ + @Override public List getIdentities() { return Collections.unmodifiableList(identities); } @@ -180,15 +228,7 @@ public class DiscoverInfo extends IQ implements TypedCloneable { return res; } - /** - * Returns the node attribute that supplements the 'jid' attribute. A node is merely - * something that is associated with a JID and for which the JID can provide information.

- * - * Node attributes SHOULD be used only when trying to provide or query information which - * is not directly addressable. - * - * @return the node attribute that supplements the 'jid' attribute - */ + @Override public String getNode() { return node; } @@ -201,7 +241,10 @@ public class DiscoverInfo extends IQ implements TypedCloneable { * is not directly addressable. * * @param node the node attribute that supplements the 'jid' attribute + * @deprecated use {@link DiscoverInfoBuilder#setNode(String)} instead. */ + @Deprecated + // TODO: Remove in Smack 4.5. public void setNode(String node) { this.node = StringUtils.requireNullOrNotEmpty(node, "The node can not be the empty string"); } @@ -256,11 +299,28 @@ public class DiscoverInfo extends IQ implements TypedCloneable { return containsDuplicateFeatures; } + public DiscoverInfoBuilder asBuilder() { + return new DiscoverInfoBuilder(this); + } + + // TODO: Deprecate in favor of asBuilder(). @Override public DiscoverInfo clone() { return new DiscoverInfo(this); } + public static DiscoverInfoBuilder builder(XMPPConnection connection) { + return new DiscoverInfoBuilder(connection); + } + + public static DiscoverInfoBuilder builder(IqBuilder iqData) { + return new DiscoverInfoBuilder(iqData); + } + + public static DiscoverInfoBuilder builder(String stanzaId) { + return new DiscoverInfoBuilder(stanzaId); + } + /** * Represents the identity of a given XMPP entity. An entity may have many identities but all * the identities SHOULD have the same name.

diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoBuilder.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoBuilder.java new file mode 100644 index 000000000..3f4f25578 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoBuilder.java @@ -0,0 +1,123 @@ +/** + * + * Copyright 2019 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.disco.packet; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.IqBuilder; +import org.jivesoftware.smack.packet.IqBuilderWithBuild; + +import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Feature; +import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; + +public class DiscoverInfoBuilder extends IqBuilderWithBuild + implements DiscoverInfoView { + + private final List features = new ArrayList<>(); + private final List identities = new ArrayList<>(); + + private String node; + + DiscoverInfoBuilder(IqBuilder iqCommon) { + super(iqCommon); + } + + DiscoverInfoBuilder(XMPPConnection connection) { + super(connection); + } + + DiscoverInfoBuilder(String stanzaId) { + super(stanzaId); + } + + public DiscoverInfoBuilder(DiscoverInfo discoverInfo) { + super(discoverInfo.getStanzaId()); + features.addAll(discoverInfo.getFeatures()); + identities.addAll(discoverInfo.getIdentities()); + node = discoverInfo.getNode(); + } + + @Override + public DiscoverInfoBuilder getThis() { + return this; + } + + public DiscoverInfoBuilder addFeatures(Collection features) { + for (String feature : features) { + addFeature(feature); + } + return getThis(); + } + + public DiscoverInfoBuilder addFeature(String feature) { + return addFeature(new Feature(feature)); + } + + public DiscoverInfoBuilder addFeature(Feature feature) { + features.add(feature); + return getThis(); + } + + public DiscoverInfoBuilder addIdentities(Collection identities) { + this.identities.addAll(identities); + return getThis(); + } + + public DiscoverInfoBuilder addIdentity(Identity identity) { + identities.add(identity); + return getThis(); + } + + public DiscoverInfoBuilder setNode(String node) { + this.node = node; + return getThis(); + } + + @Override + public DiscoverInfo build() { + return new DiscoverInfo(this, true); + } + + public DiscoverInfo buildWithoutValidiation() { + return new DiscoverInfo(this, false); + } + + @Override + public List getFeatures() { + return features; + } + + @Override + public List getIdentities() { + return identities; + } + + @Override + public String getNode() { + return node; + } + + public static DiscoverInfoBuilder buildResponseFor(DiscoverInfo request, IQ.ResponseType responseType) { + DiscoverInfoBuilder builder = new DiscoverInfoBuilder(createResponse(request, responseType)); + builder.setNode(request.getNode()); + return builder; + } +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoView.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoView.java new file mode 100644 index 000000000..8252f21f7 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoView.java @@ -0,0 +1,49 @@ +/** + * + * Copyright 2019 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.disco.packet; + +import java.util.List; + +import org.jivesoftware.smack.packet.IqView; + +public interface DiscoverInfoView extends IqView { + + /** + * Returns the discovered features of an XMPP entity. + * + * @return an unmodifiable list of the discovered features of an XMPP entity + */ + List getFeatures(); + + /** + * Returns the discovered identities of an XMPP entity. + * + * @return an unmodifiable list of the discovered identities + */ + List getIdentities(); + + /** + * Returns the node attribute that supplements the 'jid' attribute. A node is merely + * something that is associated with a JID and for which the JID can provide information.

+ * + * Node attributes SHOULD be used only when trying to provide or query information which + * is not directly addressable. + * + * @return the node attribute that supplements the 'jid' attribute + */ + String getNode(); +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/provider/DiscoverInfoProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/provider/DiscoverInfoProvider.java index 415c4eb15..7bc2f407f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/provider/DiscoverInfoProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/provider/DiscoverInfoProvider.java @@ -19,34 +19,34 @@ package org.jivesoftware.smackx.disco.provider; import java.io.IOException; +import org.jivesoftware.smack.packet.IqBuilder; import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.parsing.SmackParsingException; -import org.jivesoftware.smack.provider.IQProvider; +import org.jivesoftware.smack.provider.IqProvider; import org.jivesoftware.smack.util.PacketParserUtils; +import org.jivesoftware.smack.util.ParserUtils; import org.jivesoftware.smack.xml.XmlPullParser; import org.jivesoftware.smack.xml.XmlPullParserException; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; /** * The DiscoverInfoProvider parses Service Discovery information packets. * * @author Gaston Dombiak */ -public class DiscoverInfoProvider extends IQProvider { +public class DiscoverInfoProvider extends IqProvider { @Override - public DiscoverInfo parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { - DiscoverInfo discoverInfo = new DiscoverInfo(); - boolean done = false; - DiscoverInfo.Identity identity; - String category = ""; - String identityName = ""; - String type = ""; - String variable = ""; - String lang = ""; - discoverInfo.setNode(parser.getAttributeValue("", "node")); - while (!done) { + public DiscoverInfo parse(XmlPullParser parser, int initialDepth, IqBuilder iqData, XmlEnvironment xmlEnvironment) + throws XmlPullParserException, IOException, SmackParsingException { + DiscoverInfoBuilder discoverInfoBuilder = DiscoverInfo.builder(iqData); + + String node = parser.getAttributeValue("node"); + discoverInfoBuilder.setNode(node); + + outerloop: while (true) { XmlPullParser.Event eventType = parser.next(); if (eventType == XmlPullParser.Event.START_ELEMENT) { final String name = parser.getName(); @@ -54,39 +54,31 @@ public class DiscoverInfoProvider extends IQProvider { if (namespace.equals(DiscoverInfo.NAMESPACE)) { switch (name) { case "identity": - // Initialize the variables from the parsed XML - category = parser.getAttributeValue("", "category"); - identityName = parser.getAttributeValue("", "name"); - type = parser.getAttributeValue("", "type"); - lang = parser.getAttributeValue(parser.getNamespace("xml"), "lang"); + String category = parser.getAttributeValue("category"); + String identityName = parser.getAttributeValue("name"); + String type = parser.getAttributeValue("type"); + String lang = ParserUtils.getXmlLang(parser); + DiscoverInfo.Identity identity = new DiscoverInfo.Identity(category, type, identityName, lang); + discoverInfoBuilder.addIdentity(identity); break; case "feature": - // Initialize the variables from the parsed XML - variable = parser.getAttributeValue("", "var"); + String feature = parser.getAttributeValue("var"); + discoverInfoBuilder.addFeature(feature); break; } } // Otherwise, it must be a packet extension. else { - PacketParserUtils.addExtensionElement(discoverInfo, parser, xmlEnvironment); + PacketParserUtils.addExtensionElement(discoverInfoBuilder, parser, xmlEnvironment); } } else if (eventType == XmlPullParser.Event.END_ELEMENT) { - if (parser.getName().equals("identity")) { - // Create a new identity and add it to the discovered info. - identity = new DiscoverInfo.Identity(category, type, identityName, lang); - discoverInfo.addIdentity(identity); - } - if (parser.getName().equals("feature")) { - // Create a new feature and add it to the discovered info. - boolean notADuplicateFeature = discoverInfo.addFeature(variable); - assert notADuplicateFeature; - } - if (parser.getName().equals("query")) { - done = true; + if (parser.getDepth() == initialDepth) { + break outerloop; } } } + DiscoverInfo discoverInfo = discoverInfoBuilder.buildWithoutValidiation(); return discoverInfo; } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java index 2af5c3b19..815a05bd2 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java @@ -24,6 +24,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.StanzaListener; +import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.FlexibleStanzaTypeFilter; import org.jivesoftware.smack.filter.OrFilter; @@ -120,10 +121,12 @@ public abstract class Node { * @throws InterruptedException if the calling thread was interrupted. */ public DiscoverInfo discoverInfo() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - DiscoverInfo info = new DiscoverInfo(); - info.setTo(pubSubManager.getServiceJid()); - info.setNode(getId()); - return pubSubManager.getConnection().createStanzaCollectorAndSend(info).nextResultOrThrow(); + XMPPConnection connection = pubSubManager.getConnection(); + DiscoverInfo discoverInfoRequest = DiscoverInfo.builder(connection) + .to(pubSubManager.getServiceJid()) + .setNode(getId()) + .build(); + return connection.createStanzaCollectorAndSend(discoverInfoRequest).nextResultOrThrow(); } /** diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java index be92f373b..89dd1c761 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java @@ -289,11 +289,13 @@ public final class PubSubManager extends Manager { Node node = nodeMap.get(id); if (node == null) { - DiscoverInfo info = new DiscoverInfo(); - info.setTo(pubSubService); - info.setNode(id); + XMPPConnection connection = connection(); + DiscoverInfo info = DiscoverInfo.builder(connection) + .to(pubSubService) + .setNode(id) + .build(); - DiscoverInfo infoReply = connection().createStanzaCollectorAndSend(info).nextResultOrThrow(); + DiscoverInfo infoReply = connection.createStanzaCollectorAndSend(info).nextResultOrThrow(); if (infoReply.hasIdentity(PubSub.ELEMENT, "leaf")) { node = new LeafNode(this, id); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java index 79360a471..12d3bcab8 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java @@ -25,9 +25,11 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import javax.xml.namespace.QName; + import org.jivesoftware.smack.packet.Element; import org.jivesoftware.smack.packet.ExtensionElement; -import org.jivesoftware.smack.packet.Stanza; +import org.jivesoftware.smack.packet.StanzaView; import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.util.XmlStringBuilder; @@ -44,6 +46,8 @@ public class DataForm implements ExtensionElement { public static final String NAMESPACE = "jabber:x:data"; public static final String ELEMENT = "x"; + public static final QName QNAME = new QName(NAMESPACE, ELEMENT); + public enum Type { /** * This stanza contains a form to fill out. Display it to the user (if your program can). @@ -351,12 +355,13 @@ public class DataForm implements ExtensionElement { } /** - * Get data form from stanza. - * @param packet TODO javadoc me please + * Get data form from a stanza. + * + * @param stanzaView the stanza to get data form from. * @return the DataForm or null */ - public static DataForm from(Stanza packet) { - return (DataForm) packet.getExtension(ELEMENT, NAMESPACE); + public static DataForm from(StanzaView stanzaView) { + return (DataForm) stanzaView.getExtension(QNAME); } /** 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 39869435e..7c2e2b46e 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 @@ -49,6 +49,7 @@ import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jivesoftware.smackx.disco.packet.DiscoverItems.Item; @@ -145,7 +146,7 @@ public class Socks5ByteStreamManagerTest { FeatureNotSupportedException e = assertThrows(FeatureNotSupportedException.class, () -> { // build empty discover info as reply if targets features are queried - DiscoverInfo discoverInfo = new DiscoverInfo(); + DiscoverInfo discoverInfo = DiscoverInfo.builder("disco-1").build(); protocol.addResponse(discoverInfo); // start SOCKS5 Bytestream @@ -181,11 +182,11 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + DiscoverInfoBuilder discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); discoverInfo.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items with no proxy items @@ -233,11 +234,11 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + DiscoverInfoBuilder discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); discoverInfo.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items containing a proxy item @@ -252,12 +253,12 @@ public class Socks5ByteStreamManagerTest { // build discover info for proxy containing information about NOT being a Socks5 // proxy - DiscoverInfo proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); + DiscoverInfoBuilder proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); Identity identity = new Identity("noproxy", proxyJID.toString(), "bytestreams"); proxyInfo.addIdentity(identity); // return the proxy identity if proxy is queried - protocol.addResponse(proxyInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); SmackException e = assertThrows(SmackException.class, () -> { @@ -294,9 +295,10 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); - discoverInfo.addFeature(Bytestream.NAMESPACE); + DiscoverInfoBuilder discoverInfoBuilder = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + discoverInfoBuilder.addFeature(Bytestream.NAMESPACE); + DiscoverInfo discoverInfo = discoverInfoBuilder.build(); // return that SOCKS5 is supported if target is queried protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, Verification.requestTypeGET); @@ -313,12 +315,12 @@ public class Socks5ByteStreamManagerTest { // build discover info for proxy containing information about NOT being a Socks5 // proxy - DiscoverInfo proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); + DiscoverInfoBuilder proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); Identity identity = new Identity("noproxy", proxyJID.toString(), "bytestreams"); proxyInfo.addIdentity(identity); // return the proxy identity if proxy is queried - protocol.addResponse(proxyInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); SmackException e = assertThrows(SmackException.class, () -> { @@ -376,11 +378,11 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + DiscoverInfoBuilder discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); discoverInfo.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items containing a proxy item @@ -394,12 +396,12 @@ public class Socks5ByteStreamManagerTest { Verification.requestTypeGET); // build discover info for proxy containing information about being a SOCKS5 proxy - DiscoverInfo proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); + DiscoverInfoBuilder proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); Identity identity = new Identity("proxy", proxyJID.toString(), "bytestreams"); proxyInfo.addIdentity(identity); // return the socks5 bytestream proxy identity if proxy is queried - protocol.addResponse(proxyInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build a socks5 stream host info containing the address and the port of the @@ -458,11 +460,11 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + DiscoverInfoBuilder discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); discoverInfo.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items containing a proxy item @@ -476,12 +478,12 @@ public class Socks5ByteStreamManagerTest { Verification.requestTypeGET); // build discover info for proxy containing information about being a SOCKS5 proxy - DiscoverInfo proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); + DiscoverInfoBuilder proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); Identity identity = new Identity("proxy", proxyJID.toString(), "bytestreams"); proxyInfo.addIdentity(identity); // return the socks5 bytestream proxy identity if proxy is queried - protocol.addResponse(proxyInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build a socks5 stream host info containing the address and the port of the @@ -545,11 +547,11 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); - discoverInfo.addFeature(Bytestream.NAMESPACE); + DiscoverInfoBuilder discoverInfoBuilder = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + discoverInfoBuilder.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfoBuilder.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items containing a proxy item @@ -563,12 +565,12 @@ public class Socks5ByteStreamManagerTest { Verification.requestTypeGET); // build discover info for proxy containing information about being a SOCKS5 proxy - DiscoverInfo proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); + DiscoverInfoBuilder proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); Identity identity = new Identity("proxy", proxyJID.toString(), "bytestreams"); proxyInfo.addIdentity(identity); // return the socks5 bytestream proxy identity if proxy is queried - protocol.addResponse(proxyInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build a socks5 stream host info containing the address and the port of the @@ -639,11 +641,11 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + DiscoverInfoBuilder discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); discoverInfo.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items containing a proxy item @@ -657,12 +659,12 @@ public class Socks5ByteStreamManagerTest { Verification.requestTypeGET); // build discover info for proxy containing information about being a SOCKS5 proxy - DiscoverInfo proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); + DiscoverInfoBuilder proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); Identity identity = new Identity("proxy", proxyJID.toString(), "bytestreams"); proxyInfo.addIdentity(identity); // return the socks5 bytestream proxy identity if proxy is queried - protocol.addResponse(proxyInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build a socks5 stream host info containing the address and the port of the @@ -765,11 +767,11 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + DiscoverInfoBuilder discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); discoverInfo.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items containing no proxy item @@ -1009,11 +1011,11 @@ public class Socks5ByteStreamManagerTest { Verification streamHostUsedVerification, Socks5TestProxy socks5TestProxy) throws XmppStringprepException { // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + DiscoverInfoBuilder discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); discoverInfo.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items containing a proxy item @@ -1030,22 +1032,22 @@ public class Socks5ByteStreamManagerTest { * build discover info for proxy "proxy2.xmpp-server" containing information about being a * SOCKS5 proxy */ - DiscoverInfo proxyInfo1 = Socks5PacketUtils.createDiscoverInfo(JidCreate.from("proxy2.xmpp-server"), + DiscoverInfoBuilder proxyInfo1 = Socks5PacketUtils.createDiscoverInfo(JidCreate.from("proxy2.xmpp-server"), initiatorJID); Identity identity1 = new Identity("proxy", "proxy2.xmpp-server", "bytestreams"); proxyInfo1.addIdentity(identity1); // return the SOCKS5 bytestream proxy identity if proxy is queried - protocol.addResponse(proxyInfo1, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo1.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover info for proxy containing information about being a SOCKS5 proxy - DiscoverInfo proxyInfo2 = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); + DiscoverInfoBuilder proxyInfo2 = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); Identity identity2 = new Identity("proxy", proxyJID.toString(), "bytestreams"); proxyInfo2.addIdentity(identity2); // return the SOCKS5 bytestream proxy identity if proxy is queried - protocol.addResponse(proxyInfo2, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo2.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); /* 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 d6e9ca3b1..b5cee4cc7 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 @@ -21,6 +21,7 @@ import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jxmpp.jid.Jid; @@ -88,11 +89,12 @@ public class Socks5PacketUtils { * @param to the initiator * @return response to an info discovery request */ - public static DiscoverInfo createDiscoverInfo(Jid from, Jid to) { - DiscoverInfo discoverInfo = new DiscoverInfo(); - discoverInfo.setFrom(from); - discoverInfo.setTo(to); - discoverInfo.setType(IQ.Type.result); + public static DiscoverInfoBuilder createDiscoverInfo(Jid from, Jid to) { + DiscoverInfoBuilder discoverInfo = DiscoverInfo.builder("disco-1") + .from(from) + .to(to) + .ofType(IQ.Type.result) + ; return discoverInfo; } diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java index 518d0142e..739cae26e 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java @@ -34,6 +34,7 @@ import org.jivesoftware.smackx.InitExtensions; import org.jivesoftware.smackx.caps.cache.EntityCapsPersistentCache; import org.jivesoftware.smackx.caps.cache.SimpleDirectoryPersistentCache; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.packet.DataForm; @@ -97,11 +98,10 @@ public class EntityCapsManagerTest extends InitExtensions { } private static DiscoverInfo createComplexSamplePacket() throws XmppStringprepException { - DiscoverInfo di = new DiscoverInfo(); - di.setFrom(JidCreate.from("benvolio@capulet.lit/230193")); - di.setStanzaId("disco1"); - di.setTo(JidCreate.from("juliet@capulet.lit/chamber")); - di.setType(IQ.Type.result); + DiscoverInfoBuilder di = DiscoverInfo.builder("disco1"); + di.from(JidCreate.from("benvolio@capulet.lit/230193")); + di.to(JidCreate.from("juliet@capulet.lit/chamber")); + di.ofType(IQ.Type.result); Collection identities = new LinkedList(); DiscoverInfo.Identity i = new DiscoverInfo.Identity("client", "pc", "Psi 0.11", "en"); @@ -144,15 +144,14 @@ public class EntityCapsManagerTest extends InitExtensions { df.addField(ff.build()); di.addExtension(df); - return di; + return di.build(); } private static DiscoverInfo createMalformedDiscoverInfo() throws XmppStringprepException { - DiscoverInfo di = new DiscoverInfo(); - di.setFrom(JidCreate.from("benvolio@capulet.lit/230193")); - di.setStanzaId("disco1"); - di.setTo(JidCreate.from(")juliet@capulet.lit/chamber")); - di.setType(IQ.Type.result); + DiscoverInfoBuilder di = DiscoverInfo.builder("disco1"); + di.from("benvolio@capulet.lit/230193"); + di.to(")juliet@capulet.lit/chamber"); + di.ofType(IQ.Type.result); Collection identities = new LinkedList(); DiscoverInfo.Identity i = new DiscoverInfo.Identity("client", "pc", "Psi 0.11", "en"); @@ -217,7 +216,8 @@ public class EntityCapsManagerTest extends InitExtensions { di.addExtension(df); - return di; + DiscoverInfo discoverInfo = di.buildWithoutValidiation(); + return discoverInfo; } public static File createTempDirectory() throws IOException { diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/muc/RoomInfoTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/muc/RoomInfoTest.java index ddf453218..f809ca094 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/muc/RoomInfoTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/muc/RoomInfoTest.java @@ -30,8 +30,9 @@ public class RoomInfoTest { public void validateRoomWithEmptyForm() { DataForm dataForm = new DataForm(DataForm.Type.result); - DiscoverInfo discoInfo = new DiscoverInfo(); - discoInfo.addExtension(dataForm); + DiscoverInfo discoInfo = DiscoverInfo.builder("disco1") + .addExtension(dataForm) + .build(); RoomInfo roomInfo = new RoomInfo(discoInfo); assertTrue(roomInfo.getDescription().isEmpty()); assertTrue(roomInfo.getSubject().isEmpty()); @@ -54,8 +55,9 @@ public class RoomInfoTest { occupants.addValue("3"); dataForm.addField(occupants.build()); - DiscoverInfo discoInfo = new DiscoverInfo(); - discoInfo.addExtension(dataForm); + DiscoverInfo discoInfo = DiscoverInfo.builder("disco1") + .addExtension(dataForm) + .build(); RoomInfo roomInfo = new RoomInfo(discoInfo); assertEquals("The place for all good witches!", roomInfo.getDescription()); assertEquals("Spells", roomInfo.getSubject()); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java index a46a28bc4..d9fff1e03 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java @@ -26,6 +26,7 @@ import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.ThreadedDummyConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException.XMPPErrorException; +import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smack.packet.StanzaError; import org.jivesoftware.smack.packet.StanzaError.Condition; @@ -33,6 +34,7 @@ import org.jivesoftware.smack.packet.StanzaError.Condition; import org.jivesoftware.smackx.InitExtensions; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; import org.jivesoftware.smackx.pubsub.packet.PubSub; import org.jivesoftware.smackx.xdata.packet.DataForm; @@ -55,12 +57,14 @@ public class ConfigureFormTest extends InitExtensions { public void getConfigFormWithInsufficientPrivileges() throws XMPPException, SmackException, IOException, InterruptedException { ThreadedDummyConnection con = ThreadedDummyConnection.newInstance(); PubSubManager mgr = new PubSubManager(con, PubSubManagerTest.DUMMY_PUBSUB_SERVICE); - DiscoverInfo info = new DiscoverInfo(); - info.setType(Type.result); - info.setFrom(PubSubManagerTest.DUMMY_PUBSUB_SERVICE); + DiscoverInfoBuilder info = DiscoverInfo.builder("disco-result") + .ofType(IQ.Type.result) + .from(PubSubManagerTest.DUMMY_PUBSUB_SERVICE); Identity ident = new Identity("pubsub", null, "leaf"); info.addIdentity(ident); - con.addIQReply(info); + + DiscoverInfo discoverInfo = info.build(); + con.addIQReply(discoverInfo); Node node = mgr.getNode("princely_musings"); @@ -84,10 +88,12 @@ public class ConfigureFormTest extends InitExtensions { public void getConfigFormWithTimeout() throws XMPPException, SmackException, InterruptedException { ThreadedDummyConnection con = new ThreadedDummyConnection(); PubSubManager mgr = new PubSubManager(con, PubSubManagerTest.DUMMY_PUBSUB_SERVICE); - DiscoverInfo info = new DiscoverInfo(); + DiscoverInfoBuilder info = DiscoverInfo.builder("disco-result"); Identity ident = new Identity("pubsub", null, "leaf"); info.addIdentity(ident); - con.addIQReply(info); + + DiscoverInfo discoverInfo = info.build(); + con.addIQReply(discoverInfo); Node node = mgr.getNode("princely_musings");