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;
023import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
024import org.jxmpp.jid.BareJid;
025
026/**
027 * Represents a affiliation between a user and a node, where the {@link Type} defines
028 * the type of affiliation.
029 * 
030 * Affiliations are retrieved from the {@link PubSubManager#getAffiliations()} method, which 
031 * gets affiliations for the calling user, based on the identity that is associated with 
032 * the {@link XMPPConnection}.
033 * 
034 * @author Robin Collier
035 */
036public class Affiliation implements ExtensionElement
037{
038    public static final String ELEMENT = "affiliation";
039
040    private final BareJid jid;
041    private final String node;
042    private final Type affiliation;
043    private final PubSubNamespace namespace;
044
045    public enum Type
046    {
047        member, none, outcast, owner, publisher
048    }
049
050    /**
051     * Constructs an affiliation.
052     * 
053     * @param node The node the user is affiliated with.
054     * @param affiliation the optional affiliation.
055     */
056    public Affiliation(String node, Type affiliation) {
057        this.node = StringUtils.requireNotNullOrEmpty(node, "node must not be null or empty");
058        this.affiliation = affiliation;
059        this.jid = null;
060        if (affiliation != null) {
061            namespace = PubSubNamespace.BASIC;
062        } else {
063            namespace = PubSubNamespace.OWNER;
064        }
065    }
066
067    /**
068     * Construct a affiliation modification request.
069     *
070     * @param jid
071     * @param affiliation
072     */
073    public Affiliation(BareJid jid, Type affiliation) {
074        this(jid, affiliation, PubSubNamespace.OWNER);
075    }
076
077    public Affiliation(BareJid jid, Type affiliation, PubSubNamespace namespace) {
078        this.jid = jid;
079        this.affiliation = affiliation;
080        this.node = null;
081        // This is usually the pubsub#owner namesapce, but see xep60 example 208 where just 'pubsub' is used
082        // ("notification of affilliation change")
083        this.namespace = namespace;
084    }
085
086    /**
087     * Get the node.
088     *
089     * @return the node.
090     * @deprecated use {@link #getNode} instead.
091     */
092    @Deprecated
093    public String getNodeId() {
094        return getNode();
095    }
096
097    public String getNode() {
098        return node;
099    }
100
101    /**
102     * Get the type.
103     *
104     * @return the type.
105     * @deprecated use {@link #getAffiliation()} instead.
106     */
107    @Deprecated
108    public Type getType() {
109        return getAffiliation();
110    }
111
112    public Type getAffiliation() {
113        return affiliation;
114    }
115
116    public BareJid getJid() {
117        return jid;
118    }
119
120    @Override
121    public String getElementName() {
122        return ELEMENT;
123    }
124
125    @Override
126    public String getNamespace() {
127        return namespace.getXmlns();
128    }
129
130    public PubSubNamespace getPubSubNamespace() {
131        return namespace;
132    }
133
134    /**
135     * Check if this is an affiliation element to modify affiliations on a node.
136     *
137     * @return <code>true</code> if this is an affiliation element to modify affiliations on a node, <code>false</code> otherwise.
138     * @since 4.2
139     */
140    public boolean isAffiliationModification() {
141        if (jid != null && affiliation != null) {
142            assert(node == null && namespace == PubSubNamespace.OWNER);
143            return true;
144        }
145        return false;
146    }
147
148    @Override
149    public XmlStringBuilder toXML() {
150        XmlStringBuilder xml = new XmlStringBuilder(this);
151        xml.optAttribute("node", node);
152        xml.optAttribute("jid", jid);
153        xml.optAttribute("affiliation", affiliation);
154        xml.closeEmptyElement();
155        return xml;
156    }
157}