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