001/** 002 * 003 * Copyright 2009 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 */ 017package org.jivesoftware.smack; 018 019import java.net.InetAddress; 020import java.util.concurrent.TimeUnit; 021 022import javax.xml.namespace.QName; 023 024import org.jivesoftware.smack.SmackException.NoResponseException; 025import org.jivesoftware.smack.SmackException.NotConnectedException; 026import org.jivesoftware.smack.SmackException.OutgoingQueueFullException; 027import org.jivesoftware.smack.XMPPException.XMPPErrorException; 028import org.jivesoftware.smack.filter.IQReplyFilter; 029import org.jivesoftware.smack.filter.StanzaFilter; 030import org.jivesoftware.smack.iqrequest.IQRequestHandler; 031import org.jivesoftware.smack.packet.ExtensionElement; 032import org.jivesoftware.smack.packet.IQ; 033import org.jivesoftware.smack.packet.Message; 034import org.jivesoftware.smack.packet.MessageBuilder; 035import org.jivesoftware.smack.packet.Nonza; 036import org.jivesoftware.smack.packet.Presence; 037import org.jivesoftware.smack.packet.PresenceBuilder; 038import org.jivesoftware.smack.packet.Stanza; 039import org.jivesoftware.smack.packet.StanzaFactory; 040import org.jivesoftware.smack.packet.XmlElement; 041import org.jivesoftware.smack.util.Consumer; 042import org.jivesoftware.smack.util.Predicate; 043import org.jivesoftware.smack.util.XmppElementUtil; 044 045import org.jxmpp.jid.DomainBareJid; 046import org.jxmpp.jid.EntityFullJid; 047 048/** 049 * The XMPPConnection interface provides an interface for connections from a client to an XMPP server and 050 * implements shared methods which are used by the different types of connections (e.g. 051 * {@link org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection} or <code>XMPPTCPConnection</code>). To create a connection to an XMPP server 052 * a simple usage of this API might look like the following: 053 * 054 * <pre>{@code 055 * // Create the configuration for this new connection 056 * XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder(); 057 * configBuilder.setUsernameAndPassword("username", "password"); 058 * configBuilder.setXmppDomain("jabber.org"); 059 * 060 * AbstractXMPPConnection connection = new XMPPTCPConnection(configBuilder.build()); 061 * connection.connect(); 062 * connection.login(); 063 * 064 * Message message = connection.getStanzaFactory().buildMessageStanza() 065 * .to("mark@example.org) 066 * .setBody("Hi, how are you?") 067 * .build(); 068 * connection.sendStanza(message); 069 * 070 * connection.disconnect(); 071 * }</pre> 072 * <p> 073 * Note that the XMPPConnection interface does intentionally not declare any methods that manipulate 074 * the connection state, e.g. <code>connect()</code>, <code>disconnect()</code>. You should use the 075 * most-generic superclass connection type that is able to provide the methods you require. In most cases 076 * this should be {@link AbstractXMPPConnection}. And use or hand out instances of the 077 * XMPPConnection interface when you don't need to manipulate the connection state. 078 * </p> 079 * <p> 080 * XMPPConnections can be reused between connections. This means that an Connection may be connected, 081 * disconnected and then connected again. Listeners of the XMPPConnection will be retained across 082 * connections. 083 * </p> 084 * <h2>Processing Incoming Stanzas</h2> 085 * Smack provides a flexible framework for processing incoming stanzas using two constructs: 086 * <ul> 087 * <li>{@link StanzaCollector}: lets you synchronously wait for new stanzas</li> 088 * <li>{@link StanzaListener}: an interface for asynchronously notifying you of incoming stanzas</li> 089 * </ul> 090 * 091 * <h2>Incoming Stanza Listeners</h2> 092 * Most callbacks (listeners, handlers, …) than you can add to a connection come in three different variants: 093 * <ul> 094 * <li>standard</li> 095 * <li>async (asynchronous)</li> 096 * <li>sync (synchronous)</li> 097 * </ul> 098 * <p> 099 * Standard callbacks are invoked concurrently, but it is ensured that the same callback is never run concurrently. 100 * The callback's identity is used as key for that. The events delivered to the callback preserve the order of the 101 * causing events of the connection. 102 * </p> 103 * <p> 104 * Asynchronous callbacks are run decoupled from the connections main event loop. Hence a callback triggered by 105 * stanza B may (appear to) invoked before a callback triggered by stanza A, even though stanza A arrived before B. 106 * </p> 107 * <p> 108 * Synchronous callbacks are run synchronous to the main event loop of a connection. Hence they are invoked in the 109 * exact order of how events happen there, most importantly the arrival order of incoming stanzas. You should only 110 * use synchronous callbacks in rare situations. 111 * </p> 112 * <h2>Stanza Filters</h2> 113 * Stanza filters allow you to define the predicates for which listeners or collectors should be invoked. For more 114 * information about stanza filters, see {@link org.jivesoftware.smack.filter}. 115 * <h2>Provider Architecture</h2> 116 * XMPP is an extensible protocol. Smack allows for this extensible with its provider architecture that allows to 117 * plug-in providers that are able to parse the various XML extension elements used for XMPP's extensibility. For 118 * more information see {@link org.jivesoftware.smack.provider}. 119 * <h2>Debugging</h2> 120 * See {@link org.jivesoftware.smack.debugger} for Smack's API to debug XMPP connections. 121 * <h2>Modular Connection Architecture</h2> 122 * Smack's new modular connection architecture will one day replace the monolithic architecture. Its main entry 123 * point {@link org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection} has more information. 124 * 125 * @author Matt Tucker 126 * @author Guenther Niess 127 * @author Florian Schmaus 128 */ 129public interface XMPPConnection { 130 131 /** 132 * Returns the XMPP Domain of the service provided by the XMPP server and used for this connection. After 133 * authenticating with the server the returned value may be different. 134 * 135 * @return the XMPP domain of this XMPP session. 136 */ 137 DomainBareJid getXMPPServiceDomain(); 138 139 /** 140 * Returns the host name of the server where the XMPP server is running. This would be the 141 * IP address of the server or a name that may be resolved by a DNS server. 142 * 143 * @return the host name of the server where the XMPP server is running or null if not yet connected. 144 */ 145 String getHost(); 146 147 /** 148 * Returns the port number of the XMPP server for this connection. The default port 149 * for normal connections is 5222. 150 * 151 * @return the port number of the XMPP server or 0 if not yet connected. 152 */ 153 int getPort(); 154 155 /** 156 * Returns the full XMPP address of the user that is logged in to the connection or 157 * <code>null</code> if not logged in yet. An XMPP address is in the form 158 * username@server/resource. 159 * 160 * @return the full XMPP address of the user logged in. 161 */ 162 EntityFullJid getUser(); 163 164 /** 165 * Returns the local address currently in use for this connection, or <code>null</code> if 166 * this is invalid for the type of underlying connection. 167 * 168 * @return the local address currently in use for this connection 169 */ 170 InetAddress getLocalAddress(); 171 172 /** 173 * Returns the stream ID for this connection, which is the value set by the server 174 * when opening an XMPP stream. This value will be <code>null</code> if not connected to the server. 175 * 176 * @return the ID of this connection returned from the XMPP server or <code>null</code> if 177 * not connected to the server. 178 * @see <a href="http://xmpp.org/rfcs/rfc6120.html#streams-attr-id">RFC 6120 § 4.7.3. id</a> 179 */ 180 String getStreamId(); 181 182 /** 183 * Returns true if currently connected to the XMPP server. 184 * 185 * @return true if connected. 186 */ 187 boolean isConnected(); 188 189 /** 190 * Returns true if currently authenticated by successfully calling the login method. 191 * 192 * @return true if authenticated. 193 */ 194 boolean isAuthenticated(); 195 196 /** 197 * Returns true if currently authenticated anonymously. 198 * 199 * @return true if authenticated anonymously. 200 */ 201 boolean isAnonymous(); 202 203 /** 204 * Returns true if the connection to the server has successfully negotiated encryption. 205 * 206 * @return true if a secure connection to the server. 207 */ 208 boolean isSecureConnection(); 209 210 /** 211 * Returns true if network traffic is being compressed. When using stream compression network 212 * traffic can be reduced up to 90%. Therefore, stream compression is ideal when using a slow 213 * speed network connection. However, the server will need to use more CPU time in order to 214 * un/compress network data so under high load the server performance might be affected. 215 * 216 * @return true if network traffic is being compressed. 217 */ 218 boolean isUsingCompression(); 219 220 StanzaFactory getStanzaFactory(); 221 222 /** 223 * Sends the specified stanza to the server. 224 * 225 * @param stanza the stanza to send. 226 * @throws NotConnectedException if the connection is not connected. 227 * @throws InterruptedException if the calling thread was interrupted. 228 * */ 229 void sendStanza(Stanza stanza) throws NotConnectedException, InterruptedException; 230 231 void sendStanzaNonBlocking(Stanza stanza) throws NotConnectedException, OutgoingQueueFullException; 232 233 /** 234 * Try to send the given stanza. Returns {@code true} if the stanza was successfully put into the outgoing stanza 235 * queue, otherwise, if {@code false} is returned, the stanza could not be scheduled for sending (for example 236 * because the outgoing element queue is full). Note that this means that the stanza possibly was not put onto the 237 * wire, even if {@code true} is returned, it just has been successfully scheduled for sending. 238 * <p> 239 * <b>Note:</b> Implementations are not required to provide that functionality. In that case this method is mapped 240 * to {@link #sendStanza(Stanza)} and will possibly block until the stanza could be scheduled for sending. 241 * </p> 242 * 243 * @param stanza the stanza to send. 244 * @return {@code true} if the stanza was successfully scheduled to be send, {@code false} otherwise. 245 * @throws NotConnectedException if the connection is not connected. 246 * @since 4.4.0 247 * @deprecated use {@link #sendStanzaNonBlocking(Stanza)} instead. 248 */ 249 // TODO: Remove in Smack 4.7. 250 @Deprecated 251 boolean trySendStanza(Stanza stanza) throws NotConnectedException; 252 253 /** 254 * Try to send the given stanza. Returns {@code true} if the stanza was successfully put into the outgoing stanza 255 * queue within the given timeout period, otherwise, if {@code false} is returned, the stanza could not be scheduled 256 * for sending (for example because the outgoing element queue is full). Note that this means that the stanza 257 * possibly was not put onto the wire, even if {@code true} is returned, it just has been successfully scheduled for 258 * sending. 259 * <p> 260 * <b>Note:</b> Implementations are not required to provide that functionality. In that case this method is mapped 261 * to {@link #sendStanza(Stanza)} and will possibly block until the stanza could be scheduled for sending. 262 * </p> 263 * 264 * @param stanza the stanza to send. 265 * @param timeout how long to wait before giving up, in units of {@code unit}. 266 * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter. 267 * @return {@code true} if the stanza was successfully scheduled to be send, {@code false} otherwise. 268 * @throws NotConnectedException if the connection is not connected. 269 * @throws InterruptedException if the calling thread was interrupted. 270 * @since 4.4.0 271 * @deprecated use {@link #sendStanzaNonBlocking(Stanza)} instead. 272 */ 273 // TODO: Remove in Smack 4.7. 274 @Deprecated 275 boolean trySendStanza(Stanza stanza, long timeout, TimeUnit unit) throws NotConnectedException, InterruptedException; 276 277 /** 278 * Send a Nonza. 279 * <p> 280 * <b>This method is not meant for end-user usage!</b> It allows sending plain stream elements, which should not be 281 * done by a user manually. <b>Doing so may result in a unstable or unusable connection.</b> Certain Smack APIs use 282 * this method to send plain stream elements. 283 * </p> 284 * 285 * @param nonza the Nonza to send. 286 * @throws NotConnectedException if the XMPP connection is not connected. 287 * @throws InterruptedException if the calling thread was interrupted. 288 */ 289 void sendNonza(Nonza nonza) throws NotConnectedException, InterruptedException; 290 291 void sendNonzaNonBlocking(Nonza stanza) throws NotConnectedException, OutgoingQueueFullException; 292 293 /** 294 * Adds a connection listener to this connection that will be notified when 295 * the connection closes or fails. 296 * 297 * @param connectionListener a connection listener. 298 */ 299 void addConnectionListener(ConnectionListener connectionListener); 300 301 /** 302 * Removes a connection listener from this connection. 303 * 304 * @param connectionListener a connection listener. 305 */ 306 void removeConnectionListener(ConnectionListener connectionListener); 307 308 /** 309 * Send an IQ request and wait for the response. 310 * 311 * @param request the IQ request 312 * @param <I> the type of the expected result IQ. 313 * @return an IQ with type 'result' 314 * @throws NoResponseException if there was no response from the remote entity. 315 * @throws XMPPErrorException if there was an XMPP error returned. 316 * @throws NotConnectedException if the XMPP connection is not connected. 317 * @throws InterruptedException if the calling thread was interrupted. 318 * @since 4.3 319 */ 320 <I extends IQ> I sendIqRequestAndWaitForResponse(IQ request) 321 throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException; 322 323 /** 324 * Creates a new stanza collector collecting IQ responses that are replies to the IQ <code>request</code>. 325 * Does also send the <code>request</code> IQ. The stanza filter for the collector is an 326 * {@link IQReplyFilter}, guaranteeing that stanza id and JID in the 'from' address have 327 * expected values. 328 * 329 * @param request the IQ request to filter responses from 330 * @return a new stanza collector. 331 * @throws NotConnectedException if the XMPP connection is not connected. 332 * @throws InterruptedException if the calling thread was interrupted. 333 */ 334 StanzaCollector createStanzaCollectorAndSend(IQ request) throws NotConnectedException, InterruptedException; 335 336 /** 337 * Creates a new stanza collector for this connection. A stanza filter determines 338 * which stanzas will be accumulated by the collector. A StanzaCollector is 339 * more suitable to use than a {@link StanzaListener} when you need to wait for 340 * a specific result. 341 * 342 * @param stanzaFilter the stanza filter to use. 343 * @param stanza the stanza to send right after the collector got created 344 * @return a new stanza collector. 345 * @throws InterruptedException if the calling thread was interrupted. 346 * @throws NotConnectedException if the XMPP connection is not connected. 347 */ 348 StanzaCollector createStanzaCollectorAndSend(StanzaFilter stanzaFilter, Stanza stanza) 349 throws NotConnectedException, InterruptedException; 350 351 /** 352 * Creates a new stanza collector for this connection. A stanza filter 353 * determines which stanzas will be accumulated by the collector. A 354 * StanzaCollector is more suitable to use than a {@link StanzaListener} 355 * when you need to wait for a specific result. 356 * <p> 357 * <b>Note:</b> If you send a Stanza right after using this method, then 358 * consider using 359 * {@link #createStanzaCollectorAndSend(StanzaFilter, Stanza)} instead. 360 * Otherwise make sure cancel the StanzaCollector in every case, e.g. even 361 * if an exception is thrown, or otherwise you may leak the StanzaCollector. 362 * </p> 363 * 364 * @param stanzaFilter the stanza filter to use. 365 * @return a new stanza collector. 366 */ 367 StanzaCollector createStanzaCollector(StanzaFilter stanzaFilter); 368 369 /** 370 * Create a new stanza collector with the given stanza collector configuration. 371 * <p> 372 * Please make sure to cancel the collector when it is no longer required. See also 373 * {@link #createStanzaCollector(StanzaFilter)}. 374 * </p> 375 * 376 * @param configuration the stanza collector configuration. 377 * @return a new stanza collector. 378 * @since 4.1 379 */ 380 StanzaCollector createStanzaCollector(StanzaCollector.Configuration configuration); 381 382 /** 383 * Remove a stanza collector of this connection. 384 * 385 * @param collector a stanza collectors which was created for this connection. 386 */ 387 void removeStanzaCollector(StanzaCollector collector); 388 389 /** 390 * Registers a stanza listener with this connection. The listener will be invoked when a (matching) incoming stanza 391 * is received. The stanza filter determines which stanzas will be delivered to the listener. It is guaranteed that 392 * the same listener will not be invoked concurrently and the order of invocation will reflect the order in 393 * which the stanzas have been received. If the same stanza listener is added again with a different filter, only 394 * the new filter will be used. 395 * 396 * @param stanzaListener the stanza listener to notify of new received stanzas. 397 * @param stanzaFilter the stanza filter to use. 398 * @since 4.4.0 399 */ 400 void addStanzaListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter); 401 402 /** 403 * Removes a stanza listener for received stanzas from this connection. 404 * 405 * @param stanzaListener the stanza listener to remove. 406 * @return true if the stanza listener was removed. 407 * @since 4.4.0 408 */ 409 boolean removeStanzaListener(StanzaListener stanzaListener); 410 411 /** 412 * Registers a <b>synchronous</b> stanza listener with this connection. A stanza listener will be invoked only when 413 * an incoming stanza is received. A stanza filter determines which stanzas will be delivered to the listener. If 414 * the same stanza listener is added again with a different filter, only the new filter will be used. 415 * <p> 416 * <b>Important:</b> This stanza listeners will be called in the same <i>single</i> thread that processes all 417 * incoming stanzas. Only use this kind of stanza filter if it does not perform any XMPP activity that waits for a 418 * response. Consider using {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)} when possible, i.e. when 419 * the invocation order doesn't have to be the same as the order of the arriving stanzas. If the order of the 420 * arriving stanzas, consider using a {@link StanzaCollector} when possible. 421 * </p> 422 * 423 * @param stanzaListener the stanza listener to notify of new received stanzas. 424 * @param stanzaFilter the stanza filter to use. 425 * @see #addStanzaInterceptor(StanzaListener, StanzaFilter) 426 * @since 4.1 427 */ 428 void addSyncStanzaListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter); 429 430 /** 431 * Removes a stanza listener for received stanzas from this connection. 432 * 433 * @param stanzaListener the stanza listener to remove. 434 * @return true if the stanza listener was removed 435 * @since 4.1 436 */ 437 boolean removeSyncStanzaListener(StanzaListener stanzaListener); 438 439 /** 440 * Registers an <b>asynchronous</b> stanza listener with this connection. A stanza listener will be invoked only 441 * when an incoming stanza is received. A stanza filter determines which stanzas will be delivered to the listener. 442 * If the same stanza listener is added again with a different filter, only the new filter will be used. 443 * <p> 444 * Unlike {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)} stanza listeners added with this method will be 445 * invoked asynchronously in their own thread. Use this method if the order of the stanza listeners must not depend 446 * on the order how the stanzas where received. 447 * </p> 448 * 449 * @param stanzaListener the stanza listener to notify of new received stanzas. 450 * @param stanzaFilter the stanza filter to use. 451 * @see #addStanzaInterceptor(StanzaListener, StanzaFilter) 452 * @since 4.1 453 */ 454 void addAsyncStanzaListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter); 455 456 /** 457 * Removes an <b>asynchronous</b> stanza listener for received stanzas from this connection. 458 * 459 * @param stanzaListener the stanza listener to remove. 460 * @return true if the stanza listener was removed 461 * @since 4.1 462 */ 463 boolean removeAsyncStanzaListener(StanzaListener stanzaListener); 464 465 /** 466 * Registers a stanza listener with this connection. The listener will be 467 * notified of every stanza that this connection sends. A stanza filter determines 468 * which stanzas will be delivered to the listener. Note that the thread 469 * that writes stanzas will be used to invoke the listeners. Therefore, each 470 * stanza listener should complete all operations quickly or use a different 471 * thread for processing. 472 * 473 * @param stanzaListener the stanza listener to notify of sent stanzas. 474 * @param stanzaFilter the stanza filter to use. 475 */ 476 void addStanzaSendingListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter); 477 478 /** 479 * Removes a stanza listener for sending stanzas from this connection. 480 * 481 * @param stanzaListener the stanza listener to remove. 482 */ 483 void removeStanzaSendingListener(StanzaListener stanzaListener); 484 485 /** 486 * Registers a stanza interceptor with this connection. The interceptor will be 487 * invoked every time a stanza is about to be sent by this connection. Interceptors 488 * may modify the stanza to be sent. A stanza filter determines which stanzas 489 * will be delivered to the interceptor. 490 * 491 * <p> 492 * NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}. 493 * </p> 494 * 495 * @param stanzaInterceptor the stanza interceptor to notify of stanzas about to be sent. 496 * @param stanzaFilter the stanza filter to use. 497 * @deprecated use {@link #addMessageInterceptor(Consumer, Predicate)} or {@link #addPresenceInterceptor(Consumer, Predicate)} instead. 498 */ 499 @Deprecated 500 // TODO: Remove in Smack 4.5. 501 void addStanzaInterceptor(StanzaListener stanzaInterceptor, StanzaFilter stanzaFilter); 502 503 /** 504 * Removes a stanza interceptor. 505 * 506 * @param stanzaInterceptor the stanza interceptor to remove. 507 * @deprecated use {@link #removeMessageInterceptor(Consumer)} or {@link #removePresenceInterceptor(Consumer)} instead. 508 */ 509 @Deprecated 510 // TODO: Remove in Smack 4.5. 511 void removeStanzaInterceptor(StanzaListener stanzaInterceptor); 512 513 /** 514 * Registers a stanza interceptor with this connection. The interceptor will be 515 * invoked every time a stanza is about to be sent by this connection. Interceptors 516 * may modify the stanza to be sent. A stanza filter determines which stanzas 517 * will be delivered to the interceptor. 518 * 519 * <p> 520 * NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}. 521 * </p> 522 * 523 * @param messageInterceptor the stanza interceptor to notify of stanzas about to be sent. 524 * @param messageFilter the stanza filter to use. 525 */ 526 void addMessageInterceptor(Consumer<MessageBuilder> messageInterceptor, Predicate<Message> messageFilter); 527 528 /** 529 * Removes a message interceptor. 530 * 531 * @param messageInterceptor the message interceptor to remove. 532 */ 533 void removeMessageInterceptor(Consumer<MessageBuilder> messageInterceptor); 534 535 /** 536 * Registers a stanza interceptor with this connection. The interceptor will be 537 * invoked every time a stanza is about to be sent by this connection. Interceptors 538 * may modify the stanza to be sent. A stanza filter determines which stanzas 539 * will be delivered to the interceptor. 540 * 541 * <p> 542 * NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}. 543 * </p> 544 * 545 * @param presenceInterceptor the stanza interceptor to notify of stanzas about to be sent. 546 * @param presenceFilter the stanza filter to use. 547 */ 548 void addPresenceInterceptor(Consumer<PresenceBuilder> presenceInterceptor, Predicate<Presence> presenceFilter); 549 550 /** 551 * Removes a presence interceptor. 552 * 553 * @param presenceInterceptor the stanza interceptor to remove. 554 */ 555 void removePresenceInterceptor(Consumer<PresenceBuilder> presenceInterceptor); 556 /** 557 * Returns the current value of the reply timeout in milliseconds for request for this 558 * XMPPConnection instance. 559 * 560 * @return the reply timeout in milliseconds 561 */ 562 long getReplyTimeout(); 563 564 /** 565 * Set the stanza reply timeout in milliseconds. In most cases, Smack will throw a 566 * {@link NoResponseException} if no reply to a request was received within the timeout period. 567 * 568 * @param timeout for a reply in milliseconds 569 */ 570 void setReplyTimeout(long timeout); 571 572 /** 573 * Get the connection counter of this XMPPConnection instance. Those can be used as ID to 574 * identify the connection, but beware that the ID may not be unique if you create more then 575 * <code>2*Integer.MAX_VALUE</code> instances as the counter could wrap. 576 * 577 * @return the connection counter of this XMPPConnection 578 */ 579 int getConnectionCounter(); 580 581 enum FromMode { 582 /** 583 * Leave the 'from' attribute unchanged. This is the behavior of Smack < 4.0 584 */ 585 UNCHANGED, 586 /** 587 * Omit the 'from' attribute. According to RFC 6120 8.1.2.1 1. XMPP servers "MUST (...) 588 * override the 'from' attribute specified by the client". It is therefore safe to specify 589 * FromMode.OMITTED here. 590 */ 591 OMITTED, 592 /** 593 * Set the from to the clients full JID. This is usually not required. 594 */ 595 USER 596 } 597 598 /** 599 * Set the FromMode for this connection instance. Defines how the 'from' attribute of outgoing 600 * stanzas should be populated by Smack. 601 * 602 * @param fromMode TODO javadoc me please 603 */ 604 void setFromMode(FromMode fromMode); 605 606 /** 607 * Get the currently active FromMode. 608 * 609 * @return the currently active {@link FromMode} 610 */ 611 FromMode getFromMode(); 612 613 /** 614 * Get the feature stanza extensions for a given stream feature of the 615 * server, or <code>null</code> if the server doesn't support that feature. 616 * 617 * @param <F> {@link ExtensionElement} type of the feature. 618 * @param element TODO javadoc me please 619 * @param namespace TODO javadoc me please 620 * @return a stanza extensions of the feature or <code>null</code> 621 * @deprecated use {@link #getFeature(Class)} instead. 622 */ 623 // TODO: Remove in Smack 4.5. 624 @Deprecated 625 default <F extends XmlElement> F getFeature(String element, String namespace) { 626 QName qname = new QName(namespace, element); 627 return getFeature(qname); 628 } 629 630 /** 631 * Get the feature stanza extensions for a given stream feature of the 632 * server, or <code>null</code> if the server doesn't support that feature. 633 * 634 * @param <F> {@link ExtensionElement} type of the feature. 635 * @param qname the qualified name of the XML element of feature. 636 * @return a stanza extensions of the feature or <code>null</code> 637 * @since 4.4 638 */ 639 <F extends XmlElement> F getFeature(QName qname); 640 641 /** 642 * Get the feature stanza extensions for a given stream feature of the 643 * server, or <code>null</code> if the server doesn't support that feature. 644 * 645 * @param <F> {@link ExtensionElement} type of the feature. 646 * @param featureClass the class of the feature. 647 * @return a stanza extensions of the feature or <code>null</code> 648 * @since 4.4 649 */ 650 default <F extends XmlElement> F getFeature(Class<F> featureClass) { 651 QName qname = XmppElementUtil.getQNameFor(featureClass); 652 return getFeature(qname); 653 } 654 655 /** 656 * Return true if the server supports the given stream feature. 657 * 658 * @param element TODO javadoc me please 659 * @param namespace TODO javadoc me please 660 * @return true if the server supports the stream feature. 661 */ 662 default boolean hasFeature(String element, String namespace) { 663 QName qname = new QName(namespace, element); 664 return hasFeature(qname); 665 } 666 667 /** 668 * Return true if the server supports the given stream feature. 669 * 670 * @param qname the qualified name of the XML element of feature. 671 * @return true if the server supports the stream feature. 672 */ 673 boolean hasFeature(QName qname); 674 675 /** 676 * Send an IQ request asynchronously. The connection's default reply timeout will be used. 677 * 678 * @param request the IQ request to send. 679 * @return a SmackFuture for the response. 680 */ 681 SmackFuture<IQ, Exception> sendIqRequestAsync(IQ request); 682 683 /** 684 * Send an IQ request asynchronously. 685 * 686 * @param request the IQ request to send. 687 * @param timeout the reply timeout in milliseconds. 688 * @return a SmackFuture for the response. 689 */ 690 SmackFuture<IQ, Exception> sendIqRequestAsync(IQ request, long timeout); 691 692 /** 693 * Send a stanza asynchronously, waiting for exactly one response stanza using the given reply filter. The 694 * connection's default reply timeout will be used. 695 * 696 * @param stanza the stanza to send. 697 * @param replyFilter the filter used for the response stanza. 698 * @param <S> the type of the stanza to send. 699 * @return a SmackFuture for the response. 700 */ 701 <S extends Stanza> SmackFuture<S, Exception> sendAsync(S stanza, StanzaFilter replyFilter); 702 703 /** 704 * Send a stanza asynchronously, waiting for exactly one response stanza using the given reply filter. 705 * 706 * @param stanza the stanza to send. 707 * @param replyFilter the filter used for the response stanza. 708 * @param timeout the reply timeout in milliseconds. 709 * @param <S> the type of the stanza to send. 710 * @return a SmackFuture for the response. 711 */ 712 <S extends Stanza> SmackFuture<S, Exception> sendAsync(S stanza, StanzaFilter replyFilter, long timeout); 713 714 /** 715 * Add a callback that is called exactly once and synchronously with the incoming stanza that matches the given 716 * stanza filter. 717 * 718 * @param callback the callback invoked once the stanza filter matches a stanza. 719 * @param stanzaFilter the filter to match stanzas or null to match all. 720 */ 721 void addOneTimeSyncCallback(StanzaListener callback, StanzaFilter stanzaFilter); 722 723 /** 724 * Register an IQ request handler with this connection. 725 * <p> 726 * IQ request handler process incoming IQ requests, i.e. incoming IQ stanzas of type 'get' or 'set', and return a result. 727 * </p> 728 * @param iqRequestHandler the IQ request handler to register. 729 * @return the previously registered IQ request handler or null. 730 */ 731 IQRequestHandler registerIQRequestHandler(IQRequestHandler iqRequestHandler); 732 733 /** 734 * Convenience method for {@link #unregisterIQRequestHandler(String, String, org.jivesoftware.smack.packet.IQ.Type)}. 735 * 736 * @param iqRequestHandler TODO javadoc me please 737 * @return the previously registered IQ request handler or null. 738 */ 739 IQRequestHandler unregisterIQRequestHandler(IQRequestHandler iqRequestHandler); 740 741 /** 742 * Unregister an IQ request handler with this connection. 743 * 744 * @param element the IQ element the IQ request handler is responsible for. 745 * @param namespace the IQ namespace the IQ request handler is responsible for. 746 * @param type the IQ type the IQ request handler is responsible for. 747 * @return the previously registered IQ request handler or null. 748 */ 749 IQRequestHandler unregisterIQRequestHandler(String element, String namespace, IQ.Type type); 750 751 /** 752 * Returns the timestamp in milliseconds when the last stanza was received. 753 * 754 * @return the timestamp in milliseconds 755 */ 756 long getLastStanzaReceived(); 757}