XMPPConnection.java

  1. /**
  2.  *
  3.  * Copyright 2009 Jive Software.
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.jivesoftware.smack;

  18. import java.net.InetAddress;
  19. import java.util.concurrent.TimeUnit;

  20. import javax.xml.namespace.QName;

  21. import org.jivesoftware.smack.SmackException.NoResponseException;
  22. import org.jivesoftware.smack.SmackException.NotConnectedException;
  23. import org.jivesoftware.smack.SmackException.OutgoingQueueFullException;
  24. import org.jivesoftware.smack.XMPPException.XMPPErrorException;
  25. import org.jivesoftware.smack.filter.IQReplyFilter;
  26. import org.jivesoftware.smack.filter.StanzaFilter;
  27. import org.jivesoftware.smack.iqrequest.IQRequestHandler;
  28. import org.jivesoftware.smack.packet.ExtensionElement;
  29. import org.jivesoftware.smack.packet.IQ;
  30. import org.jivesoftware.smack.packet.Message;
  31. import org.jivesoftware.smack.packet.MessageBuilder;
  32. import org.jivesoftware.smack.packet.Nonza;
  33. import org.jivesoftware.smack.packet.Presence;
  34. import org.jivesoftware.smack.packet.PresenceBuilder;
  35. import org.jivesoftware.smack.packet.Stanza;
  36. import org.jivesoftware.smack.packet.StanzaFactory;
  37. import org.jivesoftware.smack.packet.XmlElement;
  38. import org.jivesoftware.smack.util.Consumer;
  39. import org.jivesoftware.smack.util.Predicate;
  40. import org.jivesoftware.smack.util.XmppElementUtil;

  41. import org.jxmpp.jid.DomainBareJid;
  42. import org.jxmpp.jid.EntityFullJid;

  43. /**
  44.  * The XMPPConnection interface provides an interface for connections from a client to an XMPP server and
  45.  * implements shared methods which are used by the different types of connections (e.g.
  46.  * {@link org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection} or <code>XMPPTCPConnection</code>). To create a connection to an XMPP server
  47.  * a simple usage of this API might look like the following:
  48.  *
  49.  * <pre>{@code
  50.  * // Create the configuration for this new connection
  51.  * XMPPTCPConnectionConfiguration.Builder configBuilder = XMPPTCPConnectionConfiguration.builder();
  52.  * configBuilder.setUsernameAndPassword("username", "password");
  53.  * configBuilder.setXmppDomain("jabber.org");
  54.  *
  55.  * AbstractXMPPConnection connection = new XMPPTCPConnection(configBuilder.build());
  56.  * connection.connect();
  57.  * connection.login();
  58.  *
  59.  * Message message = connection.getStanzaFactory().buildMessageStanza()
  60.  *     .to("mark@example.org)
  61.  *     .setBody("Hi, how are you?")
  62.  *     .build();
  63.  * connection.sendStanza(message);
  64.  *
  65.  * connection.disconnect();
  66.  * }</pre>
  67.  * <p>
  68.  * Note that the XMPPConnection interface does intentionally not declare any methods that manipulate
  69.  * the connection state, e.g. <code>connect()</code>, <code>disconnect()</code>. You should use the
  70.  * most-generic superclass connection type that is able to provide the methods you require. In most cases
  71.  * this should be {@link AbstractXMPPConnection}. And use or hand out instances of the
  72.  * XMPPConnection interface when you don't need to manipulate the connection state.
  73.  * </p>
  74.  * <p>
  75.  * XMPPConnections can be reused between connections. This means that an Connection may be connected,
  76.  * disconnected and then connected again. Listeners of the XMPPConnection will be retained across
  77.  * connections.
  78.  * </p>
  79.  * <h2>Processing Incoming Stanzas</h2>
  80.  * Smack provides a flexible framework for processing incoming stanzas using two constructs:
  81.  * <ul>
  82.  *  <li>{@link StanzaCollector}: lets you synchronously wait for new stanzas</li>
  83.  *  <li>{@link StanzaListener}: an interface for asynchronously notifying you of incoming stanzas</li>
  84.  * </ul>
  85.  *
  86.  * <h2>Incoming Stanza Listeners</h2>
  87.  * Most callbacks (listeners, handlers, …) than you can add to a connection come in three different variants:
  88.  * <ul>
  89.  * <li>asynchronous - e.g., {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}</li>
  90.  * <li>synchronous  - e.g., {@link #addSyncStanzaListener(StanzaListener, StanzaFilter)}</li>
  91.  * <li>other        - e.g., {@link #addStanzaListener(StanzaListener, StanzaFilter)}</li>
  92.  * </ul>
  93.  * <p>
  94.  * Asynchronous callbacks are run decoupled from the connections main event loop. Hence, a callback triggered by
  95.  * stanza B may (appear to) invoked before a callback triggered by stanza A, even though stanza A arrived before B.
  96.  * </p>
  97.  * <p>
  98.  * Synchronous callbacks are invoked concurrently, but it is ensured that the same callback is never run concurrently
  99.  * and that they are executed in order. That is, if both stanza A and B trigger the same callback, and A arrives before
  100.  * B, then the callback will be invoked with A first, and then B. Furthermore, those callbacks are not executed within
  101.  * the main loop. However it is still advisable that those callbacks do not block or only block briefly.
  102.  * </p>
  103.  * <p>
  104.  * Other callbacks are run synchronous to the main event loop of a connection and are executed within the main loop.
  105.  * <b>This means that if such a callback blocks, the main event loop also blocks, which can easily cause deadlocks.
  106.  * Therefore, you should avoid using those callbacks unless you know what you are doing.</b>
  107.  * </p>
  108.  * <h2>Stanza Filters</h2>
  109.  * Stanza filters allow you to define the predicates for which listeners or collectors should be invoked. For more
  110.  * information about stanza filters, see {@link org.jivesoftware.smack.filter}.
  111.  * <h2>Provider Architecture</h2>
  112.  * XMPP is an extensible protocol. Smack allows for this extensible with its provider architecture that allows to
  113.  * plug-in providers that are able to parse the various XML extension elements used for XMPP's extensibility. For
  114.  * more information see {@link org.jivesoftware.smack.provider}.
  115.  * <h2>Debugging</h2>
  116.  * See {@link org.jivesoftware.smack.debugger} for Smack's API to debug XMPP connections.
  117.  * <h2>Modular Connection Architecture</h2>
  118.  * Smack's new modular connection architecture will one day replace the monolithic architecture. Its main entry
  119.  * point {@link org.jivesoftware.smack.c2s.ModularXmppClientToServerConnection} has more information.
  120.  *
  121.  * @author Matt Tucker
  122.  * @author Guenther Niess
  123.  * @author Florian Schmaus
  124.  */
  125. public interface XMPPConnection {

  126.     /**
  127.      * Returns the XMPP Domain of the service provided by the XMPP server and used for this connection. After
  128.      * authenticating with the server the returned value may be different.
  129.      *
  130.      * @return the XMPP domain of this XMPP session.
  131.      */
  132.     DomainBareJid getXMPPServiceDomain();

  133.     /**
  134.      * Returns the host name of the server where the XMPP server is running. This would be the
  135.      * IP address of the server or a name that may be resolved by a DNS server.
  136.      *
  137.      * @return the host name of the server where the XMPP server is running or null if not yet connected.
  138.      */
  139.     String getHost();

  140.     /**
  141.      * Returns the port number of the XMPP server for this connection. The default port
  142.      * for normal connections is 5222.
  143.      *
  144.      * @return the port number of the XMPP server or 0 if not yet connected.
  145.      */
  146.     int getPort();

  147.     /**
  148.      * Returns the full XMPP address of the user that is logged in to the connection or
  149.      * <code>null</code> if not logged in yet. An XMPP address is in the form
  150.      * username@server/resource.
  151.      *
  152.      * @return the full XMPP address of the user logged in.
  153.      */
  154.     EntityFullJid getUser();

  155.     /**
  156.      * Returns the local address currently in use for this connection, or <code>null</code> if
  157.      * this is invalid for the type of underlying connection.
  158.      *
  159.      * @return the local address currently in use for this connection
  160.      */
  161.     InetAddress getLocalAddress();

  162.     /**
  163.      * Returns the stream ID for this connection, which is the value set by the server
  164.      * when opening an XMPP stream. This value will be <code>null</code> if not connected to the server.
  165.      *
  166.      * @return the ID of this connection returned from the XMPP server or <code>null</code> if
  167.      *      not connected to the server.
  168.      * @see <a href="http://xmpp.org/rfcs/rfc6120.html#streams-attr-id">RFC 6120 § 4.7.3. id</a>
  169.      */
  170.     String getStreamId();

  171.     /**
  172.      * Returns true if currently connected to the XMPP server.
  173.      *
  174.      * @return true if connected.
  175.      */
  176.     boolean isConnected();

  177.     /**
  178.      * Returns true if currently authenticated by successfully calling the login method.
  179.      *
  180.      * @return true if authenticated.
  181.      */
  182.     boolean isAuthenticated();

  183.     /**
  184.      * Returns true if currently authenticated anonymously.
  185.      *
  186.      * @return true if authenticated anonymously.
  187.      */
  188.     boolean isAnonymous();

  189.     /**
  190.      * Returns true if the connection to the server has successfully negotiated encryption.
  191.      *
  192.      * @return true if a secure connection to the server.
  193.      */
  194.     boolean isSecureConnection();

  195.     /**
  196.      * Returns true if network traffic is being compressed. When using stream compression network
  197.      * traffic can be reduced up to 90%. Therefore, stream compression is ideal when using a slow
  198.      * speed network connection. However, the server will need to use more CPU time in order to
  199.      * un/compress network data so under high load the server performance might be affected.
  200.      *
  201.      * @return true if network traffic is being compressed.
  202.      */
  203.     boolean isUsingCompression();

  204.     StanzaFactory getStanzaFactory();

  205.     /**
  206.      * Sends the specified stanza to the server.
  207.      *
  208.      * @param stanza the stanza to send.
  209.      * @throws NotConnectedException if the connection is not connected.
  210.      * @throws InterruptedException if the calling thread was interrupted.
  211.      * */
  212.     void sendStanza(Stanza stanza) throws NotConnectedException, InterruptedException;

  213.     void sendStanzaNonBlocking(Stanza stanza) throws NotConnectedException, OutgoingQueueFullException;

  214.     /**
  215.      * Try to send the given stanza. Returns {@code true} if the stanza was successfully put into the outgoing stanza
  216.      * queue, otherwise, if {@code false} is returned, the stanza could not be scheduled for sending (for example
  217.      * because the outgoing element queue is full). Note that this means that the stanza possibly was not put onto the
  218.      * wire, even if {@code true} is returned, it just has been successfully scheduled for sending.
  219.      * <p>
  220.      * <b>Note:</b> Implementations are not required to provide that functionality. In that case this method is mapped
  221.      * to {@link #sendStanza(Stanza)} and will possibly block until the stanza could be scheduled for sending.
  222.      * </p>
  223.      *
  224.      * @param stanza the stanza to send.
  225.      * @return {@code true} if the stanza was successfully scheduled to be sent, {@code false} otherwise.
  226.      * @throws NotConnectedException if the connection is not connected.
  227.      * @since 4.4.0
  228.      * @deprecated use {@link #sendStanzaNonBlocking(Stanza)} instead.
  229.      */
  230.     // TODO: Remove in Smack 4.7.
  231.     @Deprecated
  232.     boolean trySendStanza(Stanza stanza) throws NotConnectedException;

  233.     /**
  234.      * Try to send the given stanza. Returns {@code true} if the stanza was successfully put into the outgoing stanza
  235.      * queue within the given timeout period, otherwise, if {@code false} is returned, the stanza could not be scheduled
  236.      * for sending (for example because the outgoing element queue is full). Note that this means that the stanza
  237.      * possibly was not put onto the wire, even if {@code true} is returned, it just has been successfully scheduled for
  238.      * 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.      * @param timeout how long to wait before giving up, in units of {@code unit}.
  246.      * @param unit a {@code TimeUnit} determining how to interpret the {@code timeout} parameter.
  247.      * @return {@code true} if the stanza was successfully scheduled to be sent, {@code false} otherwise.
  248.      * @throws NotConnectedException if the connection is not connected.
  249.      * @throws InterruptedException if the calling thread was interrupted.
  250.      * @since 4.4.0
  251.      * @deprecated use {@link #sendStanzaNonBlocking(Stanza)} instead.
  252.      */
  253.     // TODO: Remove in Smack 4.7.
  254.     @Deprecated
  255.     boolean trySendStanza(Stanza stanza, long timeout, TimeUnit unit)  throws NotConnectedException, InterruptedException;

  256.     /**
  257.      * Send a Nonza.
  258.      * <p>
  259.      * <b>This method is not meant for end-user usage!</b> It allows sending plain stream elements, which should not be
  260.      * done by a user manually. <b>Doing so may result in a unstable or unusable connection.</b> Certain Smack APIs use
  261.      * this method to send plain stream elements.
  262.      * </p>
  263.      *
  264.      * @param nonza the Nonza to send.
  265.      * @throws NotConnectedException if the XMPP connection is not connected.
  266.      * @throws InterruptedException if the calling thread was interrupted.
  267.      */
  268.     void sendNonza(Nonza nonza) throws NotConnectedException, InterruptedException;

  269.     void sendNonzaNonBlocking(Nonza stanza) throws NotConnectedException, OutgoingQueueFullException;

  270.     /**
  271.      * Adds a connection listener to this connection that will be notified when
  272.      * the connection closes or fails.
  273.      *
  274.      * @param connectionListener a connection listener.
  275.      */
  276.     void addConnectionListener(ConnectionListener connectionListener);

  277.     /**
  278.      * Removes a connection listener from this connection.
  279.      *
  280.      * @param connectionListener a connection listener.
  281.      */
  282.     void removeConnectionListener(ConnectionListener connectionListener);

  283.     /**
  284.      * Send an IQ request and wait for the response.
  285.      *
  286.      * @param request the IQ request
  287.      * @param <I> the type of the expected result IQ.
  288.      * @return an IQ with type 'result'
  289.      * @throws NoResponseException if there was no response from the remote entity.
  290.      * @throws XMPPErrorException if there was an XMPP error returned.
  291.      * @throws NotConnectedException if the XMPP connection is not connected.
  292.      * @throws InterruptedException if the calling thread was interrupted.
  293.      * @since 4.3
  294.      */
  295.     <I extends IQ> I sendIqRequestAndWaitForResponse(IQ request)
  296.             throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException;

  297.     /**
  298.      * Creates a new stanza collector collecting IQ responses that are replies to the IQ <code>request</code>.
  299.      * Does also send the <code>request</code> IQ. The stanza filter for the collector is an
  300.      * {@link IQReplyFilter}, guaranteeing that stanza id and JID in the 'from' address have
  301.      * expected values.
  302.      *
  303.      * @param request the IQ request to filter responses from
  304.      * @return a new stanza collector.
  305.      * @throws NotConnectedException if the XMPP connection is not connected.
  306.      * @throws InterruptedException if the calling thread was interrupted.
  307.      */
  308.     StanzaCollector createStanzaCollectorAndSend(IQ request) throws NotConnectedException, InterruptedException;

  309.     /**
  310.      * Creates a new stanza collector for this connection. A stanza filter determines
  311.      * which stanzas will be accumulated by the collector. A StanzaCollector is
  312.      * more suitable to use than a {@link StanzaListener} when you need to wait for
  313.      * a specific result.
  314.      *
  315.      * @param stanzaFilter the stanza filter to use.
  316.      * @param stanza the stanza to send right after the collector got created
  317.      * @return a new stanza collector.
  318.      * @throws InterruptedException if the calling thread was interrupted.
  319.      * @throws NotConnectedException if the XMPP connection is not connected.
  320.      */
  321.     StanzaCollector createStanzaCollectorAndSend(StanzaFilter stanzaFilter, Stanza stanza)
  322.                     throws NotConnectedException, InterruptedException;

  323.     /**
  324.      * Creates a new stanza collector for this connection. A stanza filter
  325.      * determines which stanzas will be accumulated by the collector. A
  326.      * StanzaCollector is more suitable to use than a {@link StanzaListener}
  327.      * when you need to wait for a specific result.
  328.      * <p>
  329.      * <b>Note:</b> If you send a Stanza right after using this method, then
  330.      * consider using
  331.      * {@link #createStanzaCollectorAndSend(StanzaFilter, Stanza)} instead.
  332.      * Otherwise make sure cancel the StanzaCollector in every case, e.g. even
  333.      * if an exception is thrown, or otherwise you may leak the StanzaCollector.
  334.      * </p>
  335.      *
  336.      * @param stanzaFilter the stanza filter to use.
  337.      * @return a new stanza collector.
  338.      */
  339.     StanzaCollector createStanzaCollector(StanzaFilter stanzaFilter);

  340.     /**
  341.      * Create a new stanza collector with the given stanza collector configuration.
  342.      * <p>
  343.      * Please make sure to cancel the collector when it is no longer required. See also
  344.      * {@link #createStanzaCollector(StanzaFilter)}.
  345.      * </p>
  346.      *
  347.      * @param configuration the stanza collector configuration.
  348.      * @return a new stanza collector.
  349.      * @since 4.1
  350.      */
  351.     StanzaCollector createStanzaCollector(StanzaCollector.Configuration configuration);

  352.     /**
  353.      * Remove a stanza collector of this connection.
  354.      *
  355.      * @param collector a stanza collectors which was created for this connection.
  356.      */
  357.     void removeStanzaCollector(StanzaCollector collector);

  358.     /**
  359.      * Registers a stanza listener with this connection. The listener will be invoked when a (matching) incoming stanza
  360.      * is received. The stanza filter determines which stanzas will be delivered to the listener. It is guaranteed that
  361.      * the same listener will not be invoked concurrently and the order of invocation will reflect the order in
  362.      * which the stanzas have been received. If the same stanza listener is added again with a different filter, only
  363.      * the new filter will be used.
  364.      *
  365.      * @param stanzaListener the stanza listener to notify of new received stanzas.
  366.      * @param stanzaFilter the stanza filter to use.
  367.      * @since 4.4.0
  368.      */
  369.     void addStanzaListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter);

  370.     /**
  371.      * Removes a stanza listener for received stanzas from this connection.
  372.      *
  373.      * @param stanzaListener the stanza listener to remove.
  374.      * @return true if the stanza listener was removed.
  375.      * @since 4.4.0
  376.      */
  377.     boolean removeStanzaListener(StanzaListener stanzaListener);

  378.     /**
  379.      * Registers a <b>synchronous</b> stanza listener with this connection. A stanza listener will be invoked only when
  380.      * an incoming stanza is received. A stanza filter determines which stanzas will be delivered to the listener. If
  381.      * the same stanza listener is added again with a different filter, only the new filter will be used.
  382.      * <p>
  383.      * <b>Important:</b> This stanza listeners will be called in the same <i>single</i> thread that processes all
  384.      * incoming stanzas. Only use this kind of stanza filter if it does not perform any XMPP activity that waits for a
  385.      * response. Consider using {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)} when possible, i.e. when
  386.      * the invocation order doesn't have to be the same as the order of the arriving stanzas. If the order of the
  387.      * arriving stanzas, consider using a {@link StanzaCollector} when possible.
  388.      * </p>
  389.      *
  390.      * @param stanzaListener the stanza listener to notify of new received stanzas.
  391.      * @param stanzaFilter the stanza filter to use.
  392.      * @since 4.1
  393.      */
  394.     void addSyncStanzaListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter);

  395.     /**
  396.      * Removes a stanza listener for received stanzas from this connection.
  397.      *
  398.      * @param stanzaListener the stanza listener to remove.
  399.      * @return true if the stanza listener was removed
  400.      * @since 4.1
  401.      */
  402.     boolean removeSyncStanzaListener(StanzaListener stanzaListener);

  403.     /**
  404.      * Registers an <b>asynchronous</b> stanza listener with this connection. A stanza listener will be invoked only
  405.      * when an incoming stanza is received. A stanza filter determines which stanzas will be delivered to the listener.
  406.      * If the same stanza listener is added again with a different filter, only the new filter will be used.
  407.      * <p>
  408.      * Unlike {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)} stanza listeners added with this method will be
  409.      * invoked asynchronously in their own thread. Use this method if the order of the stanza listeners must not depend
  410.      * on the order how the stanzas where received.
  411.      * </p>
  412.      *
  413.      * @param stanzaListener the stanza listener to notify of new received stanzas.
  414.      * @param stanzaFilter the stanza filter to use.
  415.      * @since 4.1
  416.     */
  417.     void addAsyncStanzaListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter);

  418.     /**
  419.      * Removes an <b>asynchronous</b> stanza listener for received stanzas from this connection.
  420.      *
  421.      * @param stanzaListener the stanza listener to remove.
  422.      * @return true if the stanza listener was removed
  423.      * @since 4.1
  424.      */
  425.     boolean removeAsyncStanzaListener(StanzaListener stanzaListener);

  426.     /**
  427.      * Registers a stanza listener with this connection. The listener will be
  428.      * notified of every stanza that this connection sends. A stanza filter determines
  429.      * which stanzas will be delivered to the listener. Note that the thread
  430.      * that writes stanzas will be used to invoke the listeners. Therefore, each
  431.      * stanza listener should complete all operations quickly or use a different
  432.      * thread for processing.
  433.      *
  434.      * @param stanzaListener the stanza listener to notify of sent stanzas.
  435.      * @param stanzaFilter   the stanza filter to use.
  436.      */
  437.     void addStanzaSendingListener(StanzaListener stanzaListener, StanzaFilter stanzaFilter);

  438.     /**
  439.      * Removes a stanza listener for sending stanzas from this connection.
  440.      *
  441.      * @param stanzaListener the stanza listener to remove.
  442.      */
  443.     void removeStanzaSendingListener(StanzaListener stanzaListener);

  444.     /**
  445.      * Registers a stanza interceptor with this connection. The interceptor will be
  446.      * invoked every time a stanza is about to be sent by this connection. Interceptors
  447.      * may modify the stanza to be sent. A stanza filter determines which stanzas
  448.      * will be delivered to the interceptor.
  449.      *
  450.      * <p>
  451.      * NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}.
  452.      * </p>
  453.      *
  454.      * @param messageInterceptor the stanza interceptor to notify of stanzas about to be sent.
  455.      * @param messageFilter      the stanza filter to use.
  456.      */
  457.     void addMessageInterceptor(Consumer<MessageBuilder> messageInterceptor, Predicate<Message> messageFilter);

  458.     /**
  459.      * Removes a message interceptor.
  460.      *
  461.      * @param messageInterceptor the message interceptor to remove.
  462.      */
  463.     void removeMessageInterceptor(Consumer<MessageBuilder> messageInterceptor);

  464.     /**
  465.      * Registers a stanza interceptor with this connection. The interceptor will be
  466.      * invoked every time a stanza is about to be sent by this connection. Interceptors
  467.      * may modify the stanza to be sent. A stanza filter determines which stanzas
  468.      * will be delivered to the interceptor.
  469.      *
  470.      * <p>
  471.      * NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}.
  472.      * </p>
  473.      *
  474.      * @param presenceInterceptor the stanza interceptor to notify of stanzas about to be sent.
  475.      * @param presenceFilter      the stanza filter to use.
  476.      */
  477.     void addPresenceInterceptor(Consumer<PresenceBuilder> presenceInterceptor, Predicate<Presence> presenceFilter);

  478.     /**
  479.      * Removes a presence interceptor.
  480.      *
  481.      * @param presenceInterceptor the stanza interceptor to remove.
  482.      */
  483.     void removePresenceInterceptor(Consumer<PresenceBuilder> presenceInterceptor);
  484.     /**
  485.      * Returns the current value of the reply timeout in milliseconds for request for this
  486.      * XMPPConnection instance.
  487.      *
  488.      * @return the reply timeout in milliseconds
  489.      */
  490.     long getReplyTimeout();

  491.     /**
  492.      * Set the stanza reply timeout in milliseconds. In most cases, Smack will throw a
  493.      * {@link NoResponseException} if no reply to a request was received within the timeout period.
  494.      *
  495.      * @param timeout for a reply in milliseconds
  496.      */
  497.     void setReplyTimeout(long timeout);

  498.     /**
  499.      * Get the connection counter of this XMPPConnection instance. Those can be used as ID to
  500.      * identify the connection, but beware that the ID may not be unique if you create more then
  501.      * <code>2*Integer.MAX_VALUE</code> instances as the counter could wrap.
  502.      *
  503.      * @return the connection counter of this XMPPConnection
  504.      */
  505.     int getConnectionCounter();

  506.     enum FromMode {
  507.         /**
  508.          * Leave the 'from' attribute unchanged. This is the behavior of Smack &lt; 4.0
  509.          */
  510.         UNCHANGED,
  511.         /**
  512.          * Omit the 'from' attribute. According to RFC 6120 8.1.2.1 1. XMPP servers "MUST (...)
  513.          * override the 'from' attribute specified by the client". It is therefore safe to specify
  514.          * FromMode.OMITTED here.
  515.          */
  516.         OMITTED,
  517.         /**
  518.          * Set the from to the clients full JID. This is usually not required.
  519.          */
  520.         USER
  521.     }

  522.     /**
  523.      * Set the FromMode for this connection instance. Defines how the 'from' attribute of outgoing
  524.      * stanzas should be populated by Smack.
  525.      *
  526.      * @param fromMode TODO javadoc me please
  527.      */
  528.     void setFromMode(FromMode fromMode);

  529.     /**
  530.      * Get the currently active FromMode.
  531.      *
  532.      * @return the currently active {@link FromMode}
  533.      */
  534.     FromMode getFromMode();

  535.     /**
  536.      * Get the feature stanza extensions for a given stream feature of the
  537.      * server, or <code>null</code> if the server doesn't support that feature.
  538.      *
  539.      * @param <F> {@link ExtensionElement} type of the feature.
  540.      * @param qname the qualified name of the XML element of feature.
  541.      * @return a stanza extensions of the feature or <code>null</code>
  542.      * @since 4.4
  543.      */
  544.     <F extends XmlElement> F getFeature(QName qname);

  545.     /**
  546.      * Get the feature stanza extensions for a given stream feature of the
  547.      * server, or <code>null</code> if the server doesn't support that feature.
  548.      *
  549.      * @param <F> {@link ExtensionElement} type of the feature.
  550.      * @param featureClass the class of the feature.
  551.      * @return a stanza extensions of the feature or <code>null</code>
  552.      * @since 4.4
  553.      */
  554.     default <F extends XmlElement> F getFeature(Class<F> featureClass) {
  555.         QName qname = XmppElementUtil.getQNameFor(featureClass);
  556.         return getFeature(qname);
  557.     }

  558.     /**
  559.      * Return true if the server supports the given stream feature.
  560.      *
  561.      * @param element TODO javadoc me please
  562.      * @param namespace TODO javadoc me please
  563.      * @return true if the server supports the stream feature.
  564.      */
  565.     default boolean hasFeature(String element, String namespace) {
  566.         QName qname = new QName(namespace, element);
  567.         return hasFeature(qname);
  568.     }

  569.     /**
  570.      * Return true if the server supports the given stream feature.
  571.      *
  572.      * @param qname the qualified name of the XML element of feature.
  573.      * @return true if the server supports the stream feature.
  574.      */
  575.     boolean hasFeature(QName qname);

  576.     /**
  577.      * Send an IQ request asynchronously. The connection's default reply timeout will be used.
  578.      *
  579.      * @param request the IQ request to send.
  580.      * @return a SmackFuture for the response.
  581.      */
  582.     SmackFuture<IQ, Exception> sendIqRequestAsync(IQ request);

  583.     /**
  584.      * Send an IQ request asynchronously.
  585.      *
  586.      * @param request the IQ request to send.
  587.      * @param timeout the reply timeout in milliseconds.
  588.      * @return a SmackFuture for the response.
  589.      */
  590.     SmackFuture<IQ, Exception> sendIqRequestAsync(IQ request, long timeout);

  591.     /**
  592.      * Send a stanza asynchronously, waiting for exactly one response stanza using the given reply filter. The
  593.      * connection's default reply timeout will be used.
  594.      *
  595.      * @param stanza the stanza to send.
  596.      * @param replyFilter the filter used for the response stanza.
  597.      * @param <S> the type of the stanza to send.
  598.      * @return a SmackFuture for the response.
  599.      */
  600.     <S extends Stanza> SmackFuture<S, Exception> sendAsync(S stanza, StanzaFilter replyFilter);

  601.     /**
  602.      * Send a stanza asynchronously, waiting for exactly one response stanza using the given reply filter.
  603.      *
  604.      * @param stanza the stanza to send.
  605.      * @param replyFilter the filter used for the response stanza.
  606.      * @param timeout the reply timeout in milliseconds.
  607.      * @param <S> the type of the stanza to send.
  608.      * @return a SmackFuture for the response.
  609.      */
  610.     <S extends Stanza> SmackFuture<S, Exception> sendAsync(S stanza, StanzaFilter replyFilter, long timeout);

  611.     /**
  612.      * Add a callback that is called exactly once and synchronously with the incoming stanza that matches the given
  613.      * stanza filter.
  614.      *
  615.      * @param callback the callback invoked once the stanza filter matches a stanza.
  616.      * @param stanzaFilter the filter to match stanzas or null to match all.
  617.      */
  618.     void addOneTimeSyncCallback(StanzaListener callback, StanzaFilter stanzaFilter);

  619.     /**
  620.      * Register an IQ request handler with this connection.
  621.      * <p>
  622.      * IQ request handler process incoming IQ requests, i.e. incoming IQ stanzas of type 'get' or 'set', and return a result.
  623.      * </p>
  624.      * @param iqRequestHandler the IQ request handler to register.
  625.      * @return the previously registered IQ request handler or null.
  626.      */
  627.     IQRequestHandler registerIQRequestHandler(IQRequestHandler iqRequestHandler);

  628.     /**
  629.      * Convenience method for {@link #unregisterIQRequestHandler(String, String, org.jivesoftware.smack.packet.IQ.Type)}.
  630.      *
  631.      * @param iqRequestHandler TODO javadoc me please
  632.      * @return the previously registered IQ request handler or null.
  633.      */
  634.     IQRequestHandler unregisterIQRequestHandler(IQRequestHandler iqRequestHandler);

  635.     /**
  636.      * Unregister an IQ request handler with this connection.
  637.      *
  638.      * @param element the IQ element the IQ request handler is responsible for.
  639.      * @param namespace the IQ namespace the IQ request handler is responsible for.
  640.      * @param type the IQ type the IQ request handler is responsible for.
  641.      * @return the previously registered IQ request handler or null.
  642.      */
  643.     IQRequestHandler unregisterIQRequestHandler(String element, String namespace, IQ.Type type);

  644.     /**
  645.      * Returns the timestamp in milliseconds when the last stanza was received.
  646.      *
  647.      * @return the timestamp in milliseconds
  648.      */
  649.     long getLastStanzaReceived();
  650. }