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