001/**
002 *
003 * Copyright 2003-2007 Jive Software.
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 */
017
018package org.jivesoftware.smackx.muc.packet;
019
020import java.util.Date;
021
022import org.jivesoftware.smack.packet.ExtensionElement;
023import org.jivesoftware.smack.packet.NamedElement;
024import org.jivesoftware.smack.packet.Stanza;
025import org.jivesoftware.smack.util.XmlStringBuilder;
026
027import org.jxmpp.util.XmppDateTime;
028
029/**
030 * Represents extended presence information whose sole purpose is to signal the ability of
031 * the occupant to speak the MUC protocol when joining a room. If the room requires a password
032 * then the MUCInitialPresence should include one.
033 * <p>
034 * The amount of discussion history provided on entering a room (perhaps because the
035 * user is on a low-bandwidth connection or is using a small-footprint client) could be managed by
036 * setting a configured History instance to the MUCInitialPresence instance.
037 *
038 * @author Gaston Dombiak
039 * @see MUCInitialPresence#setHistory(MUCInitialPresence.History)
040 */
041public class MUCInitialPresence implements ExtensionElement {
042
043    public static final String ELEMENT = "x";
044    public static final String NAMESPACE = "http://jabber.org/protocol/muc";
045
046    // TODO make those fields final once deprecated setter methods have been removed.
047    private String password;
048    private History history;
049
050    /**
051     * Deprecated constructor.
052     * @deprecated use {@link #MUCInitialPresence(String, int, int, int, Date)} instead.
053     */
054    @Deprecated
055    public MUCInitialPresence() {
056    }
057
058    /**
059     * Construct a new MUC initial presence extension.
060     *
061     * @param password the optional password used to enter the room.
062     * @param maxChars the maximal count of characters of history to request.
063     * @param maxStanzas the maximal count of stanzas of history to request.
064     * @param seconds the last seconds since when to request history.
065     * @param since the date since when to request history.
066     */
067    public MUCInitialPresence(String password, int maxChars, int maxStanzas, int seconds, Date since) {
068        this.password = password;
069        if (maxChars > -1 || maxStanzas > -1 || seconds > -1 || since != null) {
070            this.history = new History(maxChars, maxStanzas, seconds, since);
071        } else {
072            this.history = null;
073        }
074    }
075
076    @Override
077    public String getElementName() {
078        return ELEMENT;
079    }
080
081    @Override
082    public String getNamespace() {
083        return NAMESPACE;
084    }
085
086    @Override
087    public XmlStringBuilder toXML(String enclosingNamespace) {
088        XmlStringBuilder xml = new XmlStringBuilder(this);
089        xml.rightAngleBracket();
090        xml.optElement("password", getPassword());
091        xml.optElement(getHistory());
092        xml.closeElement(this);
093        return xml;
094    }
095
096    /**
097     * Returns the history that manages the amount of discussion history provided on
098     * entering a room.
099     *
100     * @return the history that manages the amount of discussion history provided on
101     * entering a room.
102     */
103    public History getHistory() {
104        return history;
105    }
106
107    /**
108     * Returns the password to use when the room requires a password.
109     *
110     * @return the password to use when the room requires a password.
111     */
112    public String getPassword() {
113        return password;
114    }
115
116    /**
117     * Sets the History that manages the amount of discussion history provided on
118     * entering a room.
119     *
120     * @param history that manages the amount of discussion history provided on
121     * entering a room.
122     * @deprecated use {@link #MUCInitialPresence(String, int, int, int, Date)} instead.
123     */
124    @Deprecated
125    public void setHistory(History history) {
126        this.history = history;
127    }
128
129    /**
130     * Sets the password to use when the room requires a password.
131     *
132     * @param password the password to use when the room requires a password.
133     * @deprecated use {@link #MUCInitialPresence(String, int, int, int, Date)} instead.
134     */
135    @Deprecated
136    public void setPassword(String password) {
137        this.password = password;
138    }
139
140    /**
141     * Retrieve the MUCInitialPresence PacketExtension from packet, if any.
142     *
143     * @param packet
144     * @return the MUCInitialPresence PacketExtension or {@code null}
145     * @deprecated use {@link #from(Stanza)} instead
146     */
147    @Deprecated
148    public static MUCInitialPresence getFrom(Stanza packet) {
149        return from(packet);
150    }
151
152    /**
153     * Retrieve the MUCInitialPresence PacketExtension from packet, if any.
154     *
155     * @param packet
156     * @return the MUCInitialPresence PacketExtension or {@code null}
157     */
158    public static MUCInitialPresence from(Stanza packet) {
159        return packet.getExtension(ELEMENT, NAMESPACE);
160    }
161
162    /**
163     * The History class controls the number of characters or messages to receive
164     * when entering a room.
165     *
166     * @author Gaston Dombiak
167     */
168    public static class History implements NamedElement {
169
170        public static final String ELEMENT = "history";
171
172        // TODO make those fields final once the deprecated setter methods have been removed.
173        private int maxChars;
174        private int maxStanzas;
175        private int seconds;
176        private Date since;
177
178        /**
179         * Deprecated constructor.
180         * @deprecated use {@link #History(int, int, int, Date)} instead.
181         */
182        @Deprecated
183        public History() {
184            this.maxChars = -1;
185            this.maxStanzas = -1;
186            this.seconds = -1;
187        }
188
189        public History(int maxChars, int maxStanzas, int seconds, Date since) {
190            if (maxChars < 0 && maxStanzas < 0 && seconds < 0 && since == null) {
191                throw new IllegalArgumentException();
192            }
193            this.maxChars = maxChars;
194            this.maxStanzas = maxStanzas;
195            this.seconds = seconds;
196            this.since = since;
197        }
198
199        /**
200         * Returns the total number of characters to receive in the history.
201         *
202         * @return total number of characters to receive in the history.
203         */
204        public int getMaxChars() {
205            return maxChars;
206        }
207
208        /**
209         * Returns the total number of messages to receive in the history.
210         *
211         * @return the total number of messages to receive in the history.
212         */
213        public int getMaxStanzas() {
214            return maxStanzas;
215        }
216
217        /**
218         * Returns the number of seconds to use to filter the messages received during that time.
219         * In other words, only the messages received in the last "X" seconds will be included in
220         * the history.
221         *
222         * @return the number of seconds to use to filter the messages received during that time.
223         */
224        public int getSeconds() {
225            return seconds;
226        }
227
228        /**
229         * Returns the since date to use to filter the messages received during that time.
230         * In other words, only the messages received since the datetime specified will be
231         * included in the history.
232         *
233         * @return the since date to use to filter the messages received during that time.
234         */
235        public Date getSince() {
236            return since;
237        }
238
239        /**
240         * Sets the total number of characters to receive in the history.
241         *
242         * @param maxChars the total number of characters to receive in the history.
243         * @deprecated use {@link #History(int, int, int, Date)} instead.
244         */
245        @Deprecated
246        public void setMaxChars(int maxChars) {
247            this.maxChars = maxChars;
248        }
249
250        /**
251         * Sets the total number of messages to receive in the history.
252         *
253         * @param maxStanzas the total number of messages to receive in the history.
254         * @deprecated use {@link #History(int, int, int, Date)} instead.
255         */
256        @Deprecated
257        public void setMaxStanzas(int maxStanzas) {
258            this.maxStanzas = maxStanzas;
259        }
260
261        /**
262         * Sets the number of seconds to use to filter the messages received during that time.
263         * In other words, only the messages received in the last "X" seconds will be included in
264         * the history.
265         *
266         * @param seconds the number of seconds to use to filter the messages received during
267         * that time.
268         * @deprecated use {@link #History(int, int, int, Date)} instead.
269         */
270        @Deprecated
271        public void setSeconds(int seconds) {
272            this.seconds = seconds;
273        }
274
275        /**
276         * Sets the since date to use to filter the messages received during that time.
277         * In other words, only the messages received since the datetime specified will be
278         * included in the history.
279         *
280         * @param since the since date to use to filter the messages received during that time.
281         * @deprecated use {@link #History(int, int, int, Date)} instead.
282         */
283        @Deprecated
284        public void setSince(Date since) {
285            this.since = since;
286        }
287
288        @Override
289        public XmlStringBuilder toXML(String enclosingNamespace) {
290            XmlStringBuilder xml = new XmlStringBuilder(this);
291            xml.optIntAttribute("maxchars", getMaxChars());
292            xml.optIntAttribute("maxstanzas", getMaxStanzas());
293            xml.optIntAttribute("seconds", getSeconds());
294            if (getSince() != null) {
295                xml.attribute("since", XmppDateTime.formatXEP0082Date(getSince()));
296            }
297            xml.closeEmptyElement();
298            return xml;
299        }
300
301        @Override
302        public String getElementName() {
303            return ELEMENT;
304        }
305    }
306}