001/**
002 *
003 * Copyright 2015-2016 Florian Schmaus
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;
018
019import java.util.Date;
020
021import org.jivesoftware.smack.packet.Presence;
022import org.jivesoftware.smack.util.Objects;
023
024import org.jivesoftware.smackx.muc.packet.MUCInitialPresence;
025
026import org.jxmpp.jid.EntityFullJid;
027import org.jxmpp.jid.impl.JidCreate;
028import org.jxmpp.jid.parts.Resourcepart;
029
030/**
031 * The configuration used to enter a MUC room. This configuration is usually used when joining an
032 * existing room. When creating a new room, only the Nickname setting is relevant.
033 * <p>
034 * A builder for this can be obtained by calling {@link MultiUserChat#getEnterConfigurationBuilder(Resourcepart)}.
035 * </p>
036 * 
037 * @author Florian Schmaus
038 * @since 4.2
039 */
040public final class MucEnterConfiguration {
041
042    private final Resourcepart nickname;
043    private final String password;
044    private final int maxChars;
045    private final int maxStanzas;
046    private final int seconds;
047    private final Date since;
048    private final long timeout;
049    private final Presence joinPresence;
050
051    MucEnterConfiguration(Builder builder) {
052        nickname = builder.nickname;
053        password = builder.password;
054        maxChars = builder.maxChars;
055        maxStanzas = builder.maxStanzas;
056        seconds = builder.seconds;
057        since = builder.since;
058        timeout = builder.timeout;
059
060        if (builder.joinPresence == null) {
061            joinPresence = new Presence(Presence.Type.available);
062        }
063        else {
064            joinPresence = builder.joinPresence.clone();
065        }
066        // Indicate the the client supports MUC
067        joinPresence.addExtension(new MUCInitialPresence(password, maxChars, maxStanzas, seconds,
068                        since));
069    }
070
071    Presence getJoinPresence(MultiUserChat multiUserChat) {
072        final EntityFullJid jid = JidCreate.fullFrom(multiUserChat.getRoom(), nickname);
073        joinPresence.setTo(jid);
074        return joinPresence;
075    }
076
077    long getTimeout() {
078        return timeout;
079    }
080
081    public static final class Builder {
082        private final Resourcepart nickname;
083
084        private String password;
085        private int maxChars = -1;
086        private int maxStanzas = -1;
087        private int seconds = -1;
088        private Date since;
089        private long timeout;
090        private Presence joinPresence;
091
092        Builder(Resourcepart nickname, long timeout) {
093            this.nickname = Objects.requireNonNull(nickname, "Nickname must not be null");
094            timeoutAfter(timeout);
095        }
096
097        /**
098         * Set the presence used to join the MUC room.
099         * <p>
100         * The 'to' value of the given presence will be overridden and the given presence must be of type
101         * 'available', otherwise an {@link IllegalArgumentException} will be thrown.
102         * <p>
103         *
104         * @param presence
105         * @return a reference to this builder.
106         */
107        public Builder withPresence(Presence presence) {
108            if (presence.getType() != Presence.Type.available) {
109                throw new IllegalArgumentException("Presence must be of type 'available'");
110            }
111
112            joinPresence = presence;
113            return this;
114        }
115
116        /**
117         * Use the given password to join the MUC room.
118         *
119         * @param password the password used to join.
120         * @return a reference to this builder.
121         */
122        public Builder withPassword(String password) {
123            this.password = password;
124            return this;
125        }
126
127        /**
128         * Set the timeout used when joining the MUC room.
129         *
130         * @param timeout the timeout to use when joining.
131         * @return a reference to this builder.
132         */
133        public Builder timeoutAfter(long timeout) {
134            if (timeout <= 0) {
135                throw new IllegalArgumentException("timeout must be positive");
136            }
137            this.timeout = timeout;
138            return this;
139        }
140
141        /**
142         * Request that that MUC is going to sent us no history when joining.
143         * 
144         * @return a reference to this builder.
145         */
146        public Builder requestNoHistory() {
147            maxChars = 0;
148            maxStanzas = -1;
149            seconds = -1;
150            since = null;
151            return this;
152        }
153
154        /**
155         * Sets the total number of characters to receive in the history.
156         * 
157         * @param maxChars the total number of characters to receive in the history.
158         * @return a reference to this builder.
159         */
160        public Builder requestMaxCharsHistory(int maxChars) {
161            this.maxChars = maxChars;
162            return this;
163        }
164
165        /**
166         * Sets the total number of messages to receive in the history.
167         * 
168         * @param maxStanzas the total number of messages to receive in the history.
169         * @return a reference to this builder.
170         */
171        public Builder requestMaxStanzasHistory(int maxStanzas) {
172            this.maxStanzas = maxStanzas;
173            return this;
174        }
175
176        /**
177         * Sets the number of seconds to use to filter the messages received during that time. 
178         * In other words, only the messages received in the last "X" seconds will be included in 
179         * the history.
180         * 
181         * @param seconds the number of seconds to use to filter the messages received during 
182         * that time.
183         * @return a reference to this builder.
184         */
185        public Builder requestHistorySince(int seconds) {
186            this.seconds = seconds;
187            return this;
188        }
189
190        /**
191         * Sets the since date to use to filter the messages received during that time. 
192         * In other words, only the messages received since the datetime specified will be 
193         * included in the history.
194         * 
195         * @param since the since date to use to filter the messages received during that time.
196         * @return a reference to this builder.
197         */
198        public Builder requestHistorySince(Date since) {
199            this.since = since;
200            return this;
201        }
202
203        /**
204         * Build a new {@link MucEnterConfiguration} with the current builder.
205         *
206         * @return a new {@code MucEnterConfiguration}.
207         */
208        public MucEnterConfiguration build() {
209            return new MucEnterConfiguration(this);
210        }
211
212    }
213}