001/**
002 *
003 * Copyright 2003-2007 Jive Software, 2020 Paul Schaub.
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.muc.packet;
018
019import javax.xml.namespace.QName;
020
021import org.jivesoftware.smack.packet.ExtensionElement;
022import org.jivesoftware.smack.packet.Stanza;
023import org.jivesoftware.smack.util.EqualsUtil;
024import org.jivesoftware.smack.util.HashCode;
025import org.jivesoftware.smack.util.Objects;
026import org.jivesoftware.smack.util.XmlStringBuilder;
027
028import org.jxmpp.jid.EntityBareJid;
029
030/**
031 * A group chat invitation stanza extension, which is used to invite other
032 * users to a group chat room.
033 *
034 * This implementation now conforms to XEP-0249: Direct MUC Invitations,
035 * while staying backwards compatible to legacy MUC invitations.
036 *
037 * @author Matt Tucker
038 * @author Paul Schaub
039 */
040public class GroupChatInvitation implements ExtensionElement {
041
042    /**
043     * Element name of the stanza extension.
044     */
045    public static final String ELEMENT = "x";
046
047    /**
048     * Namespace of the stanza extension.
049     */
050    public static final String NAMESPACE = "jabber:x:conference";
051
052    public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
053
054    public static final String ATTR_CONTINUE = "continue";
055    public static final String ATTR_JID = "jid";
056    public static final String ATTR_PASSWORD = "password";
057    public static final String ATTR_REASON = "reason";
058    public static final String ATTR_THREAD = "thread";
059
060    private final EntityBareJid roomAddress;
061    private final String reason;
062    private final String password;
063    private final String thread;
064    private final boolean continueAsOneToOneChat;
065
066    /**
067     * Creates a new group chat invitation to the specified room address.
068     * GroupChat room addresses are in the form <code>room@service</code>,
069     * where <code>service</code> is the name of group chat server, such as
070     * <code>chat.example.com</code>.
071     *
072     * @param roomAddress the address of the group chat room.
073     */
074    public GroupChatInvitation(EntityBareJid roomAddress) {
075        this(roomAddress, null, null, false, null);
076    }
077
078    /**
079     * Creates a new group chat invitation to the specified room address.
080     * GroupChat room addresses are in the form <code>room@service</code>,
081     * where <code>service</code> is the name of group chat server, such as
082     * <code>chat.example.com</code>.
083     *
084     * @param roomAddress the address of the group chat room.
085     * @param reason the purpose for the invitation
086     * @param password specifies a password needed for entry
087     * @param continueAsOneToOneChat specifies if the groupchat room continues a one-to-one chat having the designated thread
088     * @param thread the thread to continue
089     */
090    public GroupChatInvitation(EntityBareJid roomAddress,
091                               String reason,
092                               String password,
093                               boolean continueAsOneToOneChat,
094                               String thread) {
095        this.roomAddress = Objects.requireNonNull(roomAddress);
096        this.reason = reason;
097        this.password = password;
098        this.continueAsOneToOneChat = continueAsOneToOneChat;
099        this.thread = thread;
100    }
101
102    /**
103     * Returns the purpose for the invitation.
104     *
105     * @return the address of the group chat room.
106     */
107    public String getReason() {
108        return reason;
109    }
110
111    /**
112     * Returns the password needed for entry.
113     *
114     * @return the password needed for entry
115     */
116    public String getPassword() {
117        return password;
118    }
119
120    /**
121     * Returns the thread to continue.
122     *
123     * @return the thread to continue.
124     */
125    public String getThread() {
126        return thread;
127    }
128
129    /**
130     * Returns whether the groupchat room continues a one-to-one chat.
131     *
132     * @return whether the groupchat room continues a one-to-one chat.
133     */
134    public boolean continueAsOneToOneChat() {
135        return continueAsOneToOneChat;
136    }
137
138    /**
139     * Returns the address of the group chat room. GroupChat room addresses
140     * are in the form <code>room@service</code>, where <code>service</code> is
141     * the name of group chat server, such as <code>chat.example.com</code>.
142     *
143     * @return the address of the group chat room.
144     */
145    public EntityBareJid getRoomAddress() {
146        return roomAddress;
147    }
148
149    @Override
150    public String getElementName() {
151        return ELEMENT;
152    }
153
154    @Override
155    public String getNamespace() {
156        return NAMESPACE;
157    }
158
159    @Override
160    public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
161        XmlStringBuilder xml = new XmlStringBuilder(this);
162        xml.jidAttribute(getRoomAddress());
163        xml.optAttribute(ATTR_REASON, getReason());
164        xml.optAttribute(ATTR_PASSWORD, getPassword());
165        xml.optAttribute(ATTR_THREAD, getThread());
166        xml.optBooleanAttribute(ATTR_CONTINUE, continueAsOneToOneChat());
167
168        xml.closeEmptyElement();
169        return xml;
170    }
171
172    @Override
173    public boolean equals(Object obj) {
174        return EqualsUtil.equals(this, obj, (equalsBuilder, other) -> equalsBuilder
175                        .append(getRoomAddress(), other.getRoomAddress())
176                        .append(getPassword(), other.getPassword())
177                        .append(getReason(), other.getReason())
178        .append(continueAsOneToOneChat(), other.continueAsOneToOneChat())
179        .append(getThread(), other.getThread()));
180    }
181
182    @Override
183    public int hashCode() {
184        return HashCode.builder()
185                .append(getRoomAddress())
186                .append(getPassword())
187                .append(getReason())
188                .append(continueAsOneToOneChat())
189                .append(getThread())
190                .build();
191    }
192
193    /**
194     * Get the group chat invitation from the given stanza.
195     * @param packet TODO javadoc me please
196     * @return the GroupChatInvitation or null
197     */
198    public static GroupChatInvitation from(Stanza packet) {
199        return packet.getExtension(GroupChatInvitation.class);
200    }
201
202}