1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-11-23 12:32:06 +01:00

Attempt implementing first IQs

This commit is contained in:
Paul Schaub 2020-04-05 12:12:00 +02:00
parent da7d2e7e08
commit c9efa5581d
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
9 changed files with 255 additions and 11 deletions

View file

@ -32,12 +32,12 @@ import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jivesoftware.smackx.disco.packet.DiscoverItems;
import org.jivesoftware.smackx.mam.MamManager;
import org.jivesoftware.smackx.mam.element.MamElements; import org.jivesoftware.smackx.mam.element.MamElements;
import org.jivesoftware.smackx.mix.core.element.iq.ClientJoinIQ;
import org.jivesoftware.smackx.mix.core.element.iq.ClientJoinIQBuilder;
import org.jivesoftware.smackx.mix.core.exception.NotAMixChannelOrNoPermissionToSubscribeException; import org.jivesoftware.smackx.mix.core.exception.NotAMixChannelOrNoPermissionToSubscribeException;
import org.jivesoftware.smackx.mix.core.exception.NotAMixServiceException; import org.jivesoftware.smackx.mix.core.exception.NotAMixServiceException;
import org.jivesoftware.smackx.pubsub.packet.PubSub; import org.jivesoftware.smackx.pubsub.packet.PubSub;
import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
import org.jxmpp.jid.DomainBareJid; import org.jxmpp.jid.DomainBareJid;
import org.jxmpp.jid.EntityBareJid; import org.jxmpp.jid.EntityBareJid;
@ -172,7 +172,12 @@ public final class MixManager extends Manager {
throws XMPPException.XMPPErrorException, NotAMixChannelOrNoPermissionToSubscribeException, throws XMPPException.XMPPErrorException, NotAMixChannelOrNoPermissionToSubscribeException,
SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException { SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException {
MixChannel channel = discoverMixChannelInformation(channelAddress); MixChannel channel = discoverMixChannelInformation(channelAddress);
ClientJoinIQ iq = new ClientJoinIQBuilder(connection())
.setNickname(nick)
.setChannelAddress(channelAddress)
.addMixNodeSubscription(MixNodes.NODE_MESSAGES)
.addMixNodeSubscription(MixNodes.NODE_PRESENCE)
.build();
return null; return null;
} }
} }

View file

@ -0,0 +1,33 @@
package org.jivesoftware.smackx.mix.core.element.iq;
import java.util.ArrayList;
import java.util.List;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smackx.mix.core.element.JoinElement;
import org.jivesoftware.smackx.mix.core.element.NickElement;
import org.jivesoftware.smackx.mix.core.element.SubscribeElement;
import org.jivesoftware.smackx.mix.pam.element.ClientJoinElement;
import org.jxmpp.jid.EntityBareJid;
public class ClientJoinIQ extends IQ {
private final EntityBareJid channelJid;
private final NickElement nickElement;
private final List<SubscribeElement> subscriptions;
public ClientJoinIQ(ClientJoinIQBuilder builder) {
super(builder, ClientJoinElement.V2.ELEMENT, null);
this.channelJid = builder.getChannelAddress();
this.nickElement = builder.getNickElement();
this.subscriptions = new ArrayList<>(builder.getSubscriptions());
}
@Override
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
JoinElement.V1 joinElement = new JoinElement.V1(subscriptions, nickElement);
xml.append(new ClientJoinElement.V2(channelJid, joinElement));
return xml;
}
}

View file

@ -0,0 +1,78 @@
package org.jivesoftware.smackx.mix.core.element.iq;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.AbstractIqBuilder;
import org.jivesoftware.smack.packet.IqBuilder;
import org.jivesoftware.smackx.mix.core.element.NickElement;
import org.jivesoftware.smackx.mix.core.element.SubscribeElement;
import org.jxmpp.jid.EntityBareJid;
public class ClientJoinIQBuilder extends IqBuilder<ClientJoinIQBuilder, ClientJoinIQ> {
private EntityBareJid channelAddress;
private NickElement nickElement;
private final Set<SubscribeElement> subscriptions = new HashSet<>();
protected ClientJoinIQBuilder(AbstractIqBuilder<?> other) {
super(other);
}
public ClientJoinIQBuilder(XMPPConnection connection) {
super(connection);
}
protected ClientJoinIQBuilder(String stanzaId) {
super(stanzaId);
}
@Override
public ClientJoinIQBuilder getThis() {
return this;
}
@Override
public ClientJoinIQ build() {
return new ClientJoinIQ(this);
}
public ClientJoinIQBuilder setChannelAddress(EntityBareJid channelAddress) {
this.channelAddress = channelAddress;
return getThis();
}
public ClientJoinIQBuilder addMixNodeSubscription(String nodeName) {
return addMixNodeSubscription(new SubscribeElement(nodeName));
}
public ClientJoinIQBuilder addMixNodeSubscription(SubscribeElement subscription) {
return addMixNodeSubscriptions(Collections.singleton(subscription));
}
public ClientJoinIQBuilder addMixNodeSubscriptions(Collection<SubscribeElement> subscriptions) {
this.subscriptions.addAll(subscriptions);
return getThis();
}
public ClientJoinIQBuilder setNickname(String nick) {
this.nickElement = nick != null ? new NickElement(nick) : null;
return getThis();
}
public EntityBareJid getChannelAddress() {
return channelAddress;
}
public NickElement getNickElement() {
return nickElement;
}
public Set<SubscribeElement> getSubscriptions() {
return subscriptions;
}
}

View file

@ -1,5 +1,12 @@
package org.jivesoftware.smackx.mix.core.exception; package org.jivesoftware.smackx.mix.core.exception;
/**
* Exception that is thrown when the user tries to interact with an entity which is either not a MIX channel,
* or is one but the user doesn't have the permission to subscribe to it.
*
* @see <a href="https://xmpp.org/extensions/xep-0369.html#disco-channel-info">
* XEP-0369: §6.3 about discovering channel information</a>
*/
public class NotAMixChannelOrNoPermissionToSubscribeException extends Exception { public class NotAMixChannelOrNoPermissionToSubscribeException extends Exception {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;

View file

@ -4,18 +4,46 @@ import static org.jivesoftware.smackx.mix.misc.MixMiscConstants.NAMESPACE_MISC_0
import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.packet.XmlEnvironment;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smackx.mix.core.element.NickElement; import org.jivesoftware.smackx.mix.core.element.NickElement;
/**
* Element for registering a nick name with the MIX channel.
*
* see <a href="https://xmpp.org/extensions/xep-0407.html#usecase-user-register">
* XEP-0407: MIX Miscellaneous Capabilities - §3. Registering a Nick</a>
*/
public abstract class RegisterElement implements ExtensionElement { public abstract class RegisterElement implements ExtensionElement {
public static final String ELEMENT = "register"; public static final String ELEMENT = "register";
private final NickElement nick; private final NickElement nick;
/**
* Create an empty register element.
* A MIX service must assign a nick name if the request does not contain a nick child element.
*/
public RegisterElement() {
this(null);
}
/**
* Create a register element with a desired nick name.
*
* @param nickElement nick element containing the nick name.
*/
public RegisterElement(NickElement nickElement) { public RegisterElement(NickElement nickElement) {
this.nick = Objects.requireNonNull(nickElement, "Nick element MUST NOT be null."); this.nick = nickElement;
}
/**
* Return the nick child element.
* For a request, this is the requested nick name and for a response, this is the assigned nick name (might differ).
*
* @return nick element
*/
public NickElement getNick() {
return nick;
} }
@Override @Override
@ -27,12 +55,16 @@ public abstract class RegisterElement implements ExtensionElement {
public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) {
return new XmlStringBuilder(this) return new XmlStringBuilder(this)
.rightAngleBracket() .rightAngleBracket()
.append(nick) .optAppend(nick)
.closeElement(this); .closeElement(this);
} }
public static class V0 extends RegisterElement { public static class V0 extends RegisterElement {
public V0() {
super();
}
public V0(NickElement nickElement) { public V0(NickElement nickElement) {
super(nickElement); super(nickElement);
} }

View file

@ -27,7 +27,7 @@ public abstract class RegisterElementProvider<E extends RegisterElement> extends
nickElement = new NickElement(parser.nextText()); nickElement = new NickElement(parser.nextText());
} }
} else if (tagEvent == XmlPullParser.TagEvent.END_ELEMENT) { } else if (tagEvent == XmlPullParser.TagEvent.END_ELEMENT) {
if (SetNickElement.ELEMENT.equals(name)) { if (RegisterElement.ELEMENT.equals(name)) {
return new RegisterElement.V0(nickElement); return new RegisterElement.V0(nickElement);
} }
} }

View file

@ -0,0 +1,25 @@
package org.jivesoftware.smackx.mix.core.element.iq;
import org.jivesoftware.smack.DummyConnection;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.test.util.SmackTestSuite;
import org.jivesoftware.smackx.mix.core.MixNodes;
import org.junit.jupiter.api.Test;
import org.jxmpp.jid.impl.JidCreate;
public class ClientJoinIQTest extends SmackTestSuite {
@Test
public void serializationTest() {
ClientJoinIQ iq = new ClientJoinIQBuilder(DummyConnection.newConnectedDummyConnection())
.ofType(IQ.Type.set)
.setNickname("alice")
.setChannelAddress(JidCreate.entityBareFromOrThrowUnchecked("rabbithole@mix.wonderland.lit"))
.addMixNodeSubscription(MixNodes.NODE_MESSAGES)
.addMixNodeSubscription(MixNodes.NODE_PRESENCE)
.build();
System.out.println(iq.toXML());
}
}

View file

@ -9,12 +9,22 @@ import org.junit.jupiter.api.Test;
public class RegisterElementTest { public class RegisterElementTest {
@Test @Test
public void v0testSerialization() { public void testV0Serialization() {
RegisterElement register = new RegisterElement.V0(new NickElement("thirdwitch")); RegisterElement register = new RegisterElement.V0(new NickElement("thirdwitch"));
String expectedXml = "" + String expectedXml = "" +
"<register xmlns='urn:xmpp:mix:misc:0'>\n" + "<register xmlns='urn:xmpp:mix:misc:0'>" +
" <nick>thirdwitch</nick>\n" + " <nick>thirdwitch</nick>" +
"</register>\n"; "</register>";
assertXmlSimilar(expectedXml, register.toXML());
}
@Test
public void testV0NoNickSerialization() {
RegisterElement register = new RegisterElement.V0();
String expectedXml = "" +
"<register xmlns='urn:xmpp:mix:misc:0'>" +
"</register>";
assertXmlSimilar(expectedXml, register.toXML()); assertXmlSimilar(expectedXml, register.toXML());
} }

View file

@ -0,0 +1,54 @@
package org.jivesoftware.smackx.mix.misc.provider;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import java.io.IOException;
import org.jivesoftware.smack.parsing.SmackParsingException;
import org.jivesoftware.smack.test.util.TestUtils;
import org.jivesoftware.smack.xml.XmlPullParser;
import org.jivesoftware.smack.xml.XmlPullParserException;
import org.jivesoftware.smackx.mix.misc.element.RegisterElement;
import org.junit.jupiter.api.Test;
public class RegisterElementProviderTest {
private final RegisterElementProvider.V0 provider = new RegisterElementProvider.V0();
@Test
public void testV0Parsing() throws XmlPullParserException, IOException, SmackParsingException {
final String xml = "" +
"<register xmlns='urn:xmpp:mix:misc:0'>" +
" <nick>thirdwitch</nick>" +
"</register>";
final String nick = "thirdwitch";
XmlPullParser parser = TestUtils.getParser(xml);
RegisterElement parsed = provider.parse(parser);
assertEquals(nick, parsed.getNick().getValue());
}
@Test
public void testV0NoNickElementParsing() throws XmlPullParserException, IOException, SmackParsingException {
final String noChildElementXml = "<register xmlns='urn:xmpp:mix:misc:0'></register>";
XmlPullParser noChildElementParser = TestUtils.getParser(noChildElementXml);
RegisterElement noChildElementParsed = provider.parse(noChildElementParser);
assertNull(noChildElementParsed.getNick());
}
@Test
public void testV0EmptyParsing() throws XmlPullParserException, IOException, SmackParsingException {
final String emptyElementXml = "<register xmlns='urn:xmpp:mix:misc:0'/>";
XmlPullParser emptyElementParser = TestUtils.getParser(emptyElementXml);
RegisterElement emptyElementParsed = provider.parse(emptyElementParser);
assertNull(emptyElementParsed.getNick());
}
}