001/**
002 *
003 * Copyright the original author or authors
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jivesoftware.smackx.pubsub;
018
019import org.jivesoftware.smack.XMPPConnection;
020import org.jivesoftware.smack.packet.ExtensionElement;
021import org.jivesoftware.smack.util.StringUtils;
022import org.jivesoftware.smack.util.XmlStringBuilder;
023
024import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
025
026import org.jxmpp.jid.BareJid;
027
028/**
029 * Represents a affiliation between a user and a node, where the {@link Type} defines
030 * the type of affiliation.
031 * 
032 * Affiliations are retrieved from the {@link PubSubManager#getAffiliations()} method, which 
033 * gets affiliations for the calling user, based on the identity that is associated with 
034 * the {@link XMPPConnection}.
035 * 
036 * @author Robin Collier
037 */
038public class Affiliation implements ExtensionElement
039{
040    public static final String ELEMENT = "affiliation";
041
042    private final BareJid jid;
043    private final String node;
044    private final Type affiliation;
045    private final PubSubNamespace namespace;
046
047    public enum Type
048    {
049        member, none, outcast, owner, publisher
050    }
051
052    /**
053     * Constructs an affiliation.
054     * 
055     * @param node The node the user is affiliated with.
056     * @param affiliation the optional affiliation.
057     */
058    public Affiliation(String node, Type affiliation) {
059        this.node = StringUtils.requireNotNullOrEmpty(node, "node must not be null or empty");
060        this.affiliation = affiliation;
061        this.jid = null;
062        if (affiliation != null) {
063            namespace = PubSubNamespace.BASIC;
064        } else {
065            namespace = PubSubNamespace.OWNER;
066        }
067    }
068
069    /**
070     * Construct a affiliation modification request.
071     *
072     * @param jid
073     * @param affiliation
074     */
075    public Affiliation(BareJid jid, Type affiliation) {
076        this(jid, affiliation, PubSubNamespace.OWNER);
077    }
078
079    public Affiliation(BareJid jid, Type affiliation, PubSubNamespace namespace) {
080        this.jid = jid;
081        this.affiliation = affiliation;
082        this.node = null;
083        // This is usually the pubsub#owner namespace, but see xep60 example 208 where just 'pubsub' is used
084        // ("notification of affiliation change")
085        this.namespace = namespace;
086    }
087
088    /**
089     * Get the node.
090     *
091     * @return the node.
092     * @deprecated use {@link #getNode} instead.
093     */
094    @Deprecated
095    public String getNodeId() {
096        return getNode();
097    }
098
099    public String getNode() {
100        return node;
101    }
102
103    /**
104     * Get the type.
105     *
106     * @return the type.
107     * @deprecated use {@link #getAffiliation()} instead.
108     */
109    @Deprecated
110    public Type getType() {
111        return getAffiliation();
112    }
113
114    public Type getAffiliation() {
115        return affiliation;
116    }
117
118    public BareJid getJid() {
119        return jid;
120    }
121
122    @Override
123    public String getElementName() {
124        return ELEMENT;
125    }
126
127    @Override
128    public String getNamespace() {
129        return namespace.getXmlns();
130    }
131
132    public PubSubNamespace getPubSubNamespace() {
133        return namespace;
134    }
135
136    /**
137     * Check if this is an affiliation element to modify affiliations on a node.
138     *
139     * @return <code>true</code> if this is an affiliation element to modify affiliations on a node, <code>false</code> otherwise.
140     * @since 4.2
141     */
142    public boolean isAffiliationModification() {
143        if (jid != null && affiliation != null) {
144            assert (node == null && namespace == PubSubNamespace.OWNER);
145            return true;
146        }
147        return false;
148    }
149
150    @Override
151    public XmlStringBuilder toXML() {
152        XmlStringBuilder xml = new XmlStringBuilder(this);
153        xml.optAttribute("node", node);
154        xml.optAttribute("jid", jid);
155        xml.optAttribute("affiliation", affiliation);
156        xml.closeEmptyElement();
157        return xml;
158    }
159}