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