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 &lt; 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}