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