diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/MixCoreConstants.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/MixCoreConstants.java new file mode 100644 index 000000000..0df94fc17 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/MixCoreConstants.java @@ -0,0 +1,41 @@ +package org.jivesoftware.smackx.mix.core; + +public class MixCoreConstants { + + public static final String URN_XMPP_MIX = "urn:xmpp:mix"; + public static final String MIX_NODES = URN_XMPP_MIX + ":nodes"; + + public static final String NAMESPACE_CORE_BARE = "urn:xmpp:mix:core"; + public static final String NAMESPACE_CORE_1 = NAMESPACE_CORE_BARE + ":1"; + + /** + * This indicates support of MIX, and is returned by all MIX services. + */ + public static final String NAMESPACE_CORE = NAMESPACE_CORE_1; + + public static final String FEATURE_CORE_1 = NAMESPACE_CORE_1; + + public static final String FEATURE_SEARCHABLE_1 = FEATURE_CORE_1 + "#searchable"; + + public static final String FEATURE_CREATE_CHANNEL_1 = FEATURE_CORE_1 + "#create-channel"; + + /** + * For distributing messages to the channel. Each item of this node + * will contain a message sent to the channel. + */ + public static final String NODE_MESSAGES = MIX_NODES + ":messages"; + + /** + * For storing the list of participants and the associated nick. + * Channel participants are added when they join the channel and + * removed when they leave. + */ + public static final String NODE_PARTICIPANTS = MIX_NODES + ":participants"; + + public static final String NODE_PRESENCE = MIX_NODES + ":presence"; + + /** + * For storing general channel information, such as description. + */ + public static final String NODE_INFO = MIX_NODES + ":info"; +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/MixManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/MixManager.java new file mode 100644 index 000000000..b55750a27 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/MixManager.java @@ -0,0 +1,38 @@ +package org.jivesoftware.smackx.mix.core; + +import java.util.Map; +import java.util.WeakHashMap; + +import org.jivesoftware.smack.ConnectionCreationListener; +import org.jivesoftware.smack.Manager; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPConnectionRegistry; +import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; + +public final class MixManager extends Manager { + + private static final Map INSTANCES = new WeakHashMap<>(); + + static { + XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() { + @Override + public void connectionCreated(XMPPConnection connection) { + MixManager.getInstanceFor(connection); + } + }); + } + + public static MixManager getInstanceFor(XMPPConnection connection) { + MixManager manager = INSTANCES.get(connection); + if (manager == null) { + manager = new MixManager(connection); + INSTANCES.put(connection, manager); + } + return manager; + } + + private MixManager(XMPPConnection connection) { + super(connection); + ServiceDiscoveryManager.getInstanceFor(connection).addFeature(MixCoreConstants.FEATURE_CORE_1); + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/MixNodes.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/MixNodes.java new file mode 100644 index 000000000..628b5846a --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/MixNodes.java @@ -0,0 +1,10 @@ +package org.jivesoftware.smackx.mix.core; + +import org.jivesoftware.smackx.mix.core.element.SubscribeElement; + +public class MixNodes { + public static final SubscribeElement NODE_MESSAGES = new SubscribeElement(MixCoreConstants.NODE_MESSAGES); + public static final SubscribeElement NODE_PRESENCE = new SubscribeElement(MixCoreConstants.NODE_PRESENCE); + public static final SubscribeElement NODE_PARTICIPANTS = new SubscribeElement(MixCoreConstants.NODE_PARTICIPANTS); + public static final SubscribeElement NODE_INFO = new SubscribeElement(MixCoreConstants.NODE_INFO); +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/AbstractSubscriptionsModifyingElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/AbstractSubscriptionsModifyingElement.java new file mode 100644 index 000000000..b4b8c6664 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/AbstractSubscriptionsModifyingElement.java @@ -0,0 +1,25 @@ +package org.jivesoftware.smackx.mix.core.element; + +import java.util.Collections; +import java.util.List; + +import org.jivesoftware.smack.util.XmlStringBuilder; + +public abstract class AbstractSubscriptionsModifyingElement { + + private final List nodeSubscriptions; + + public AbstractSubscriptionsModifyingElement(List nodeSubscriptions) { + this.nodeSubscriptions = Collections.unmodifiableList(nodeSubscriptions); + } + + public List getNodeSubscriptions() { + return nodeSubscriptions; + } + + protected void appendSubscribeElementsToXml(XmlStringBuilder xml) { + for (SubscribeElement subscribe : getNodeSubscriptions()) { + xml.append(subscribe); + } + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/CreateChannelElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/CreateChannelElement.java new file mode 100644 index 000000000..6ba6ff4f2 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/CreateChannelElement.java @@ -0,0 +1,58 @@ +package org.jivesoftware.smackx.mix.core.element; + +import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.StringUtils; +import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.mix.core.MixCoreConstants; + +public abstract class CreateChannelElement implements ExtensionElement { + + public static final String ELEMENT = "create"; + public static final String ATTR_CHANNEL = "channel"; + + protected final String channel; + + public CreateChannelElement() { + this(null); + } + + public CreateChannelElement(String channel) { + channel = channel != null ? channel.trim() : null; + this.channel = StringUtils.requireNullOrNotEmpty(channel, "Channel name MUST either be null or NOT empty."); + } + + public String getChannel() { + return channel; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + return new XmlStringBuilder(this) + .optAttribute(ATTR_CHANNEL, getChannel()) + .closeEmptyElement(); + } + + public static class V1 extends CreateChannelElement { + + public static final String NAMESPACE = MixCoreConstants.NAMESPACE_CORE_1; + + public V1() { + super(); + } + + public V1(String channel) { + super(channel); + } + + @Override + public String getNamespace() { + return NAMESPACE; + } + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/DestroyChannelElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/DestroyChannelElement.java new file mode 100644 index 000000000..7cb603443 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/DestroyChannelElement.java @@ -0,0 +1,48 @@ +package org.jivesoftware.smackx.mix.core.element; + +import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.StringUtils; +import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.mix.core.MixCoreConstants; + +public abstract class DestroyChannelElement implements ExtensionElement { + + public static final String ELEMENT = "destroy"; + public static final String ATTR_CHANNEL = "channel"; + + private final String channel; + + public DestroyChannelElement(String channel) { + channel = channel != null ? channel.trim() : null; + this.channel = StringUtils.requireNotNullNorEmpty(channel, "Channel name MUST NOT be null NOR empty."); + } + + public String getChannel() { + return channel; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + return new XmlStringBuilder(this).attribute(ATTR_CHANNEL, getChannel()).closeEmptyElement(); + } + + public static class V1 extends DestroyChannelElement { + + public static final String NAMESPACE = MixCoreConstants.NAMESPACE_CORE_1; + + public V1(String channel) { + super(channel); + } + + @Override + public String getNamespace() { + return NAMESPACE; + } + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/JidElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/JidElement.java new file mode 100644 index 000000000..fa9a01ee0 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/JidElement.java @@ -0,0 +1,35 @@ +package org.jivesoftware.smackx.mix.core.element; + +import org.jivesoftware.smack.packet.NamedElement; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.Objects; +import org.jivesoftware.smack.util.XmlStringBuilder; + +import org.jxmpp.jid.EntityBareJid; + +public class JidElement implements NamedElement { + + public static final String ELEMENT = "jid"; + + private final EntityBareJid value; + + public JidElement(EntityBareJid value) { + this.value = Objects.requireNonNull(value); + } + + public EntityBareJid getValue() { + return value; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + return new XmlStringBuilder(this).rightAngleBracket() + .escapeAttributeValue(getValue().asEntityBareJidString()) + .closeElement(this); + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/JoinElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/JoinElement.java new file mode 100644 index 000000000..51532ee10 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/JoinElement.java @@ -0,0 +1,83 @@ +package org.jivesoftware.smackx.mix.core.element; + +import java.util.List; + +import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.mix.core.MixCoreConstants; + +public abstract class JoinElement + extends AbstractSubscriptionsModifyingElement + implements ExtensionElement { + + public static final String ELEMENT = "join"; + public static final String ATTR_ID = "id"; + + private final NickElement nick; + private final String id; + + public JoinElement(List nodeSubscriptions) { + this(nodeSubscriptions, null); + } + + public JoinElement(List nodeSubscriptions, NickElement nick) { + this(null, nodeSubscriptions, nick); + } + + public JoinElement(String id, List nodeSubscriptions, NickElement nick) { + super(nodeSubscriptions); + this.id = id; + this.nick = nick; + } + + /** + * Users Stable Participant ID. May be null. + * @return id + */ + public String getId() { + return id; + } + + public NickElement getNick() { + return nick; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + public static class V1 extends JoinElement { + + public static final String NAMESPACE = MixCoreConstants.NAMESPACE_CORE_1; + + public V1(List nodeSubscriptions) { + super(nodeSubscriptions); + } + + public V1(List nodeSubscriptions, NickElement nick) { + super(nodeSubscriptions, nick); + } + + public V1(String id, List nodeSubscriptions, NickElement nick) { + super(id, nodeSubscriptions, nick); + } + + @Override + public String getNamespace() { + return NAMESPACE; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + XmlStringBuilder xml = new XmlStringBuilder(this) + .optAttribute(ATTR_ID, getId()) + .rightAngleBracket(); + appendSubscribeElementsToXml(xml); + xml.optAppend(getNick()); + return xml.closeElement(this); + } + } + +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/LeaveElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/LeaveElement.java new file mode 100644 index 000000000..e70cb897e --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/LeaveElement.java @@ -0,0 +1,31 @@ +package org.jivesoftware.smackx.mix.core.element; + +import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.mix.core.MixCoreConstants; + +public abstract class LeaveElement implements ExtensionElement { + + public static final String ELEMENT = "leave"; + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + return new XmlStringBuilder(this).closeEmptyElement(); + } + + public static class V1 extends LeaveElement { + + public static final String NAMESPACE = MixCoreConstants.NAMESPACE_CORE_1; + + @Override + public String getNamespace() { + return NAMESPACE; + } + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/MixElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/MixElement.java new file mode 100644 index 000000000..e81d043f0 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/MixElement.java @@ -0,0 +1,54 @@ +package org.jivesoftware.smackx.mix.core.element; + +import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.mix.core.MixCoreConstants; + +public abstract class MixElement implements ExtensionElement { + + public static final String ELEMENT = "mix"; + + protected final NickElement nick; + protected final JidElement jid; + + public MixElement(NickElement nick) { + this(nick, null); + } + + public MixElement(NickElement nick, JidElement jid) { + this.nick = nick; + this.jid = jid; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + return new XmlStringBuilder(this).rightAngleBracket() + .append(nick) + .optAppend(jid) + .closeElement(this); + } + + public static class V1 extends MixElement { + + public static final String NAMESPACE = MixCoreConstants.NAMESPACE_CORE_1; + + public V1(NickElement nick) { + super(nick); + } + + public V1(NickElement nick, JidElement jid) { + super(nick, jid); + } + + @Override + public String getNamespace() { + return NAMESPACE; + } + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/NickElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/NickElement.java new file mode 100644 index 000000000..28c2e7b38 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/NickElement.java @@ -0,0 +1,35 @@ +package org.jivesoftware.smackx.mix.core.element; + +import org.jivesoftware.smack.packet.NamedElement; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.Objects; +import org.jivesoftware.smack.util.StringUtils; +import org.jivesoftware.smack.util.XmlStringBuilder; + +public class NickElement implements NamedElement { + + public static final String ELEMENT = "nick"; + + private final String value; + + public NickElement(String value) { + value = value != null ? value.trim() : null; + this.value = StringUtils.requireNotNullNorEmpty(value, "Nickname MUST NOT be null NOR empty."); + } + + public String getValue() { + return value; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + return new XmlStringBuilder(this).rightAngleBracket() + .escapeAttributeValue(getValue()) + .closeElement(this); + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/ParticipantElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/ParticipantElement.java new file mode 100644 index 000000000..235f4d198 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/ParticipantElement.java @@ -0,0 +1,61 @@ +package org.jivesoftware.smackx.mix.core.element; + +import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.Objects; +import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.mix.core.MixCoreConstants; + +import org.jxmpp.jid.EntityBareJid; + +public abstract class ParticipantElement implements ExtensionElement { + + public static final String ELEMENT = "participant"; + + protected final NickElement nick; + protected final JidElement jid; + + public ParticipantElement(NickElement nick, JidElement jid) { + this.nick = Objects.requireNonNull(nick); + this.jid = Objects.requireNonNull(jid); + } + + public NickElement getNick() { + return nick; + } + + public JidElement getJid() { + return jid; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + public static class V1 extends ParticipantElement { + + public static final String NAMESPACE = MixCoreConstants.NAMESPACE_CORE_1; + + public V1(NickElement nick, JidElement jid) { + super(nick, jid); + } + + public V1(String nick, EntityBareJid jid) { + super(new NickElement(nick), new JidElement(jid)); + } + + @Override + public String getNamespace() { + return NAMESPACE; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + return new XmlStringBuilder(this).rightAngleBracket() + .append(getNick()) + .append(getJid()) + .closeElement(this); + } + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/SetNickElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/SetNickElement.java new file mode 100644 index 000000000..5a49eac3e --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/SetNickElement.java @@ -0,0 +1,56 @@ +package org.jivesoftware.smackx.mix.core.element; + +import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.Objects; +import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.mix.core.MixCoreConstants; + +public abstract class SetNickElement implements ExtensionElement { + + public static final String ELEMENT = "setnick"; + + private final NickElement nick; + + public SetNickElement(String nick) { + this(new NickElement(nick)); + } + + public SetNickElement(NickElement nick) { + this.nick = Objects.requireNonNull(nick); + } + + public NickElement getNick() { + return nick; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + return new XmlStringBuilder(this).rightAngleBracket() + .append(getNick()) + .closeElement(this); + } + + public static class V1 extends SetNickElement { + + public static final String NAMESPACE = MixCoreConstants.NAMESPACE_CORE_1; + + public V1(String nick) { + super(nick); + } + + public V1(NickElement nick) { + super(nick); + } + + @Override + public String getNamespace() { + return NAMESPACE; + } + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/SubscribeElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/SubscribeElement.java new file mode 100644 index 000000000..a61d48440 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/SubscribeElement.java @@ -0,0 +1,35 @@ +package org.jivesoftware.smackx.mix.core.element; + +import org.jivesoftware.smack.packet.NamedElement; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.mix.core.MixCoreConstants; + +public class SubscribeElement implements NamedElement { + + public static final String ELEMENT = "subscribe"; + public static final String ATTR_NODE = "node"; + + private final String node; + + public SubscribeElement(String node) { + this.node = node; + } + + public String getValue() { + return node; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + return new XmlStringBuilder(this) + .attribute(ATTR_NODE, getValue()) + .closeEmptyElement(); + } + +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/UpdateSubscriptionElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/UpdateSubscriptionElement.java new file mode 100644 index 000000000..5f3862e06 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/core/element/UpdateSubscriptionElement.java @@ -0,0 +1,65 @@ +package org.jivesoftware.smackx.mix.core.element; + +import java.util.List; + +import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.mix.core.MixCoreConstants; + +import org.jxmpp.jid.EntityBareJid; + +public abstract class UpdateSubscriptionElement + extends AbstractSubscriptionsModifyingElement + implements ExtensionElement { + + public static final String ELEMENT = "update-subscription"; + public static final String ATTR_JID = "jid"; + + private final EntityBareJid jid; + + public UpdateSubscriptionElement(List nodeSubscriptions, EntityBareJid jid) { + super(nodeSubscriptions); + this.jid = jid; + } + + /** + * Possibly null! + * @return jid or null + */ + public EntityBareJid getJid() { + return jid; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + public static class V1 extends UpdateSubscriptionElement { + + public static final String NAMESPACE = MixCoreConstants.NAMESPACE_CORE_1; + + public V1(List nodeSubscriptions) { + super(nodeSubscriptions, null); + } + + public V1(List nodeSubscriptions, EntityBareJid jid) { + super(nodeSubscriptions, jid); + } + + @Override + public String getNamespace() { + return NAMESPACE; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + XmlStringBuilder xml = new XmlStringBuilder(this) + .optAttribute(ATTR_JID, getJid()) + .rightAngleBracket(); + appendSubscribeElementsToXml(xml); + return xml.closeElement(this); + } + } +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/pam/MixPamConstants.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/pam/MixPamConstants.java new file mode 100644 index 000000000..ada6852d4 --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/pam/MixPamConstants.java @@ -0,0 +1,14 @@ +package org.jivesoftware.smackx.mix.pam; + +import static org.jivesoftware.smackx.mix.core.MixCoreConstants.URN_XMPP_MIX; + +public class MixPamConstants { + + private static final String NAMESPACE_PAM_BARE = URN_XMPP_MIX + ":pam"; + + public static final String NAMESPACE_PAM_2 = NAMESPACE_PAM_BARE + ":2"; + + public static final String FEATURE_PAM_2 = NAMESPACE_PAM_2; + + public static final String FEATURE_PAM_ARCHIVE_2 = FEATURE_PAM_2 + "#archive"; +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/pam/element/ClientJoinElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/pam/element/ClientJoinElement.java new file mode 100644 index 000000000..64047b85a --- /dev/null +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mix/pam/element/ClientJoinElement.java @@ -0,0 +1,60 @@ +package org.jivesoftware.smackx.mix.pam.element; + +import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.util.Objects; +import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.mix.core.element.JoinElement; +import org.jivesoftware.smackx.mix.pam.MixPamConstants; + +import org.jxmpp.jid.EntityBareJid; + +public abstract class ClientJoinElement implements ExtensionElement { + + public static final String ELEMENT = "client-join"; + public static final String ATTR_CHANNEL = "channel"; + + private final EntityBareJid channel; + private final JoinElement join; + + public ClientJoinElement(EntityBareJid channel, JoinElement join) { + this.channel = Objects.requireNonNull(channel); + this.join = Objects.requireNonNull(join); + } + + public EntityBareJid getChannel() { + return channel; + } + + public JoinElement getJoin() { + return join; + } + + @Override + public String getElementName() { + return ELEMENT; + } + + @Override + public XmlStringBuilder toXML(XmlEnvironment xmlEnvironment) { + return new XmlStringBuilder(this) + .attribute(ATTR_CHANNEL, getChannel()) + .rightAngleBracket() + .append(getJoin()) + .closeElement(this); + } + + public static class V2 extends ClientJoinElement { + + public static final String NAMESPACE = MixPamConstants.NAMESPACE_PAM_2; + + public V2(EntityBareJid channel, JoinElement.V1 join) { + super(channel, join); + } + + @Override + public String getNamespace() { + return NAMESPACE; + } + } +} diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/CreateChannelElementTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/CreateChannelElementTest.java new file mode 100644 index 000000000..5548bc635 --- /dev/null +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/CreateChannelElementTest.java @@ -0,0 +1,30 @@ +package org.jivesoftware.smackx.mix.core.element; + +import static org.jivesoftware.smack.test.util.XmlUnitUtils.assertXmlSimilar; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class CreateChannelElementTest { + + @Test + public void v1Test() { + String expectedXml = ""; + + CreateChannelElement element = new CreateChannelElement.V1("coven"); + + assertXmlSimilar(expectedXml, element.toXML()); + } + + @Test + public void v1DisallowEmptyChannelNameTest() { + assertThrows(IllegalArgumentException.class, () -> new CreateChannelElement.V1(" ")); + } + + @Test + public void v1AllowNullChannelNameTest() { + assertDoesNotThrow(() -> new CreateChannelElement.V1()); + assertDoesNotThrow(() -> new CreateChannelElement.V1(null)); + } +} diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/DestroyChannelElementTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/DestroyChannelElementTest.java new file mode 100644 index 000000000..ee53ce134 --- /dev/null +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/DestroyChannelElementTest.java @@ -0,0 +1,28 @@ +package org.jivesoftware.smackx.mix.core.element; + +import static org.jivesoftware.smack.test.util.XmlUnitUtils.assertXmlSimilar; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class DestroyChannelElementTest { + + @Test + public void v1Test() { + String expectedXml = ""; + + DestroyChannelElement element = new DestroyChannelElement.V1("coven"); + + assertXmlSimilar(expectedXml, element.toXML()); + } + + @Test + public void v1DisallowNullChannel() { + assertThrows(IllegalArgumentException.class, () -> new DestroyChannelElement.V1(null)); + } + + @Test + public void v1DisallowEmptyChannel() { + assertThrows(IllegalArgumentException.class, () -> new DestroyChannelElement.V1(" ")); + } +} diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/JidElementTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/JidElementTest.java new file mode 100644 index 000000000..6ee5e65d3 --- /dev/null +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/JidElementTest.java @@ -0,0 +1,26 @@ +package org.jivesoftware.smackx.mix.core.element; + +import static org.jivesoftware.smack.test.util.XmlUnitUtils.assertXmlSimilar; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; +import org.jxmpp.jid.EntityBareJid; +import org.jxmpp.jid.impl.JidCreate; + +public class JidElementTest { + + @Test + public void v1Test() { + String expectedXml = "hag66@shakespeare.example"; + + EntityBareJid jid = JidCreate.entityBareFromOrThrowUnchecked("hag66@shakespeare.example"); + JidElement element = new JidElement(jid); + + assertXmlSimilar(expectedXml, element.toXML()); + } + + @Test + public void v1DisallowNullArg() { + assertThrows(IllegalArgumentException.class, () -> new JidElement(null)); + } +} diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/JoinElementTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/JoinElementTest.java new file mode 100644 index 000000000..3138c6d78 --- /dev/null +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/JoinElementTest.java @@ -0,0 +1,42 @@ +package org.jivesoftware.smackx.mix.core.element; + +import static org.jivesoftware.smack.test.util.XmlUnitUtils.assertXmlSimilar; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.List; + +import org.jivesoftware.smackx.mix.core.MixNodes; + +import org.junit.jupiter.api.Test; + +public class JoinElementTest { + + @Test + public void v1ElementTest() { + final String expectedXml = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " third witch\n" + + ""; + final String id = "123456"; + final List nodeSubscriptions = Arrays.asList( + MixNodes.NODE_MESSAGES, + MixNodes.NODE_PRESENCE, + MixNodes.NODE_PARTICIPANTS, + MixNodes.NODE_INFO); + final String nick = "third witch"; + + NickElement nickElement = new NickElement(nick); + JoinElement joinElement = new JoinElement.V1(id, nodeSubscriptions, nickElement); + + assertXmlSimilar(expectedXml, joinElement.toXML()); + assertEquals(id, joinElement.getId()); + assertEquals(nick, joinElement.getNick().getValue()); + assertEquals(nodeSubscriptions, joinElement.getNodeSubscriptions()); + } +} diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/LeaveElementTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/LeaveElementTest.java new file mode 100644 index 000000000..6c6a997e3 --- /dev/null +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/LeaveElementTest.java @@ -0,0 +1,17 @@ +package org.jivesoftware.smackx.mix.core.element; + +import static org.jivesoftware.smack.test.util.XmlUnitUtils.assertXmlSimilar; + +import org.junit.jupiter.api.Test; + +public class LeaveElementTest { + + @Test + public void v1Test() { + String expectedXml = ""; + + LeaveElement element = new LeaveElement.V1(); + + assertXmlSimilar(expectedXml, element.toXML()); + } +} diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/MixElementTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/MixElementTest.java new file mode 100644 index 000000000..f5505abca --- /dev/null +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/MixElementTest.java @@ -0,0 +1,24 @@ +package org.jivesoftware.smackx.mix.core.element; + +import static org.jivesoftware.smack.test.util.XmlUnitUtils.assertXmlSimilar; + +import org.junit.jupiter.api.Test; +import org.jxmpp.jid.impl.JidCreate; + +public class MixElementTest { + + @Test + public void v1Test() { + String expectedXml = "" + + "\n" + + " thirdwitch\n" + + " hag66@shakespeare.example\n" + + ""; + + NickElement nick = new NickElement("thirdwitch"); + JidElement jid = new JidElement(JidCreate.entityBareFromOrThrowUnchecked("hag66@shakespeare.example")); + MixElement element = new MixElement.V1(nick, jid); + + assertXmlSimilar(expectedXml, element.toXML()); + } +} diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/NickElementTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/NickElementTest.java new file mode 100644 index 000000000..7d07d3475 --- /dev/null +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/NickElementTest.java @@ -0,0 +1,28 @@ +package org.jivesoftware.smackx.mix.core.element; + +import static org.jivesoftware.smack.test.util.XmlUnitUtils.assertXmlSimilar; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class NickElementTest { + + @Test + public void test() { + final String expectedXml = "vanitasvitae"; + + NickElement element = new NickElement("vanitasvitae"); + + assertXmlSimilar(expectedXml, element.toXML()); + } + + @Test + public void testDisallowNullArg() { + assertThrows(IllegalArgumentException.class, () -> new NickElement(null)); + } + + @Test + public void testDisallowEmptyArg() { + assertThrows(IllegalArgumentException.class, () -> new NickElement(" ")); + } +} diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/ParticipantElementTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/ParticipantElementTest.java new file mode 100644 index 000000000..aaa115f7a --- /dev/null +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/ParticipantElementTest.java @@ -0,0 +1,28 @@ +package org.jivesoftware.smackx.mix.core.element; + +import static org.jivesoftware.smack.test.util.XmlUnitUtils.assertXmlSimilar; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; +import org.jxmpp.jid.EntityBareJid; +import org.jxmpp.jid.impl.JidCreate; + +public class ParticipantElementTest { + + @Test + public void testParticipantElement() { + final String nick = "thirdwitch"; + final EntityBareJid jid = JidCreate.entityBareFromOrThrowUnchecked("hag66@shakespeare.example"); + final String expectedXml = "" + + "\n" + + " thirdwitch\n" + + " hag66@shakespeare.example\n" + + ""; + + ParticipantElement participantElement = new ParticipantElement.V1(nick, jid); + + assertXmlSimilar(expectedXml, participantElement.toXML()); + assertEquals(nick, participantElement.getNick().getValue()); + assertEquals(jid, participantElement.getJid().getValue()); + } +} diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/SetNickElementTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/SetNickElementTest.java new file mode 100644 index 000000000..62a5c72c2 --- /dev/null +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/SetNickElementTest.java @@ -0,0 +1,26 @@ +package org.jivesoftware.smackx.mix.core.element; + +import static org.jivesoftware.smack.test.util.XmlUnitUtils.assertXmlSimilar; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class SetNickElementTest { + + @Test + public void v1Test() { + String expectedXml = "" + + "\n" + + " thirdwitch\n" + + ""; + + SetNickElement element = new SetNickElement.V1("thirdwitch"); + + assertXmlSimilar(expectedXml, element.toXML()); + } + + @Test + public void disallowNullNickTest() { + assertThrows(IllegalArgumentException.class, () -> new SetNickElement.V1((NickElement) null)); + } +} diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/UpdateSubscriptionElementTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/UpdateSubscriptionElementTest.java new file mode 100644 index 000000000..02b186556 --- /dev/null +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/core/element/UpdateSubscriptionElementTest.java @@ -0,0 +1,41 @@ +package org.jivesoftware.smackx.mix.core.element; + +import static org.jivesoftware.smack.test.util.XmlUnitUtils.assertXmlSimilar; + +import java.util.Collections; + +import org.jivesoftware.smackx.mix.core.MixNodes; + +import org.junit.jupiter.api.Test; +import org.jxmpp.jid.impl.JidCreate; + +public class UpdateSubscriptionElementTest { + + @Test + public void v1Test() { + String expectedXml = "" + + "\n" + + " \n" + + ""; + + UpdateSubscriptionElement element = new UpdateSubscriptionElement.V1( + Collections.singletonList(MixNodes.NODE_MESSAGES)); + + assertXmlSimilar(expectedXml, element.toXML()); + } + + @Test + public void v1TestWithJid() { + String expectedXml = "" + + "\n" + + " \n" + + ""; + + UpdateSubscriptionElement element = new UpdateSubscriptionElement.V1( + Collections.singletonList(MixNodes.NODE_MESSAGES), + JidCreate.entityBareFromOrThrowUnchecked("hag66@shakespeare.example")); + + assertXmlSimilar(expectedXml, element.toXML()); + } +} diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/pam/element/ClientJoinElementTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/pam/element/ClientJoinElementTest.java new file mode 100644 index 000000000..65290d85e --- /dev/null +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/mix/pam/element/ClientJoinElementTest.java @@ -0,0 +1,34 @@ +package org.jivesoftware.smackx.mix.pam.element; + +import static org.jivesoftware.smack.test.util.XmlUnitUtils.assertXmlSimilar; + +import java.util.Arrays; + +import org.jivesoftware.smackx.mix.core.MixNodes; +import org.jivesoftware.smackx.mix.core.element.JoinElement; + +import org.junit.jupiter.api.Test; +import org.jxmpp.jid.EntityBareJid; +import org.jxmpp.jid.impl.JidCreate; + +public class ClientJoinElementTest { + + @Test + public void v2Test() { + String expectedXml = "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + + EntityBareJid channel = JidCreate.entityBareFromOrThrowUnchecked("coven@mix.shakespeare.example"); + JoinElement.V1 join = new JoinElement.V1(Arrays.asList(MixNodes.NODE_MESSAGES, MixNodes.NODE_PRESENCE, MixNodes.NODE_PARTICIPANTS, MixNodes.NODE_INFO)); + ClientJoinElement element = new ClientJoinElement.V2(channel, join); + + assertXmlSimilar(expectedXml, element.toXML()); + } +}