1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $RCSfile$ 3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Revision$ 4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Date$ 5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Copyright 2009 Jive Software. 7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * you may not use this file except in compliance with the License. 10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * You may obtain a copy of the License at 11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * http://www.apache.org/licenses/LICENSE-2.0 13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Unless required by applicable law or agreed to in writing, software 15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * distributed under the License is distributed on an "AS IS" BASIS, 16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * See the License for the specific language governing permissions and 18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * limitations under the License. 19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.jivesoftware.smack; 22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.Reader; 24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.Writer; 25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.lang.reflect.Constructor; 26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.ArrayList; 27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Collection; 28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Collections; 29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.List; 30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Map; 31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Set; 32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.concurrent.ConcurrentHashMap; 33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.concurrent.ConcurrentLinkedQueue; 34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.concurrent.CopyOnWriteArrayList; 35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.concurrent.CopyOnWriteArraySet; 36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.concurrent.atomic.AtomicInteger; 37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.compression.JzlibInputOutputStream; 39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.compression.XMPPInputOutputStream; 40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.compression.Java7ZlibInputOutputStream; 41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.debugger.SmackDebugger; 42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.filter.PacketFilter; 43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.Packet; 44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.Presence; 45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The abstract Connection class provides an interface for connections to a 48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * XMPP server and implements shared methods which are used by the 49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * different types of connections (e.g. XMPPConnection or BoshConnection). 50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * To create a connection to a XMPP server a simple usage of this API might 52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * look like the following: 53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <pre> 54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * // Create a connection to the igniterealtime.org XMPP server. 55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Connection con = new XMPPConnection("igniterealtime.org"); 56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * // Connect to the server 57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * con.connect(); 58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * // Most servers require you to login before performing other tasks. 59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * con.login("jsmith", "mypass"); 60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * // Start a new conversation with John Doe and send him a message. 61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Chat chat = connection.getChatManager().createChat("jdoe@igniterealtime.org"</font>, new MessageListener() { 62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <p/> 63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * public void processMessage(Chat chat, Message message) { 64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * // Print out any messages we get back to standard out. 65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * System.out.println(<font color="green">"Received message: "</font> + message); 66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * } 67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * }); 68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * chat.sendMessage(<font color="green">"Howdy!"</font>); 69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * // Disconnect from the server 70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * con.disconnect(); 71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * </pre> 72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <p/> 73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Connections can be reused between connections. This means that an Connection 74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * may be connected, disconnected and then connected again. Listeners of the Connection 75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * will be retained accross connections.<p> 76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <p/> 77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * If a connected Connection gets disconnected abruptly then it will try to reconnect 78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * again. To stop the reconnection process, use {@link #disconnect()}. Once stopped 79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * you can use {@link #connect()} to manually connect to the server. 80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see XMPPConnection 82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Matt Tucker 83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Guenther Niess 84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic abstract class Connection { 86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Counter to uniquely identify connections that are created. 89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private final static AtomicInteger connectionCounter = new AtomicInteger(0); 91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * A set of listeners which will be invoked if a new connection is created. 94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private final static Set<ConnectionCreationListener> connectionEstablishedListeners = 96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen new CopyOnWriteArraySet<ConnectionCreationListener>(); 97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected final static List<XMPPInputOutputStream> compressionHandlers = new ArrayList<XMPPInputOutputStream>(2); 99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Value that indicates whether debugging is enabled. When enabled, a debug 102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * window will apear for each new connection that will contain the following 103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * information:<ul> 104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li> Client Traffic -- raw XML traffic generated by Smack and sent to the server. 105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li> Server Traffic -- raw XML traffic sent by the server to the client. 106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <li> Interpreted Packets -- shows XML packets from the server as parsed by Smack. 107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * </ul> 108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <p/> 109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Debugging can be enabled by setting this field to true, or by setting the Java system 110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * property <tt>smack.debugEnabled</tt> to true. The system property can be set on the 111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * command line such as "java SomeApp -Dsmack.debugEnabled=true". 112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static boolean DEBUG_ENABLED = false; 114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen static { 116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Use try block since we may not have permission to get a system 117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // property (for example, when an applet). 118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DEBUG_ENABLED = Boolean.getBoolean("smack.debugEnabled"); 120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (Exception e) { 122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Ignore. 123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Ensure the SmackConfiguration class is loaded by calling a method in it. 125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen SmackConfiguration.getVersion(); 126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add the Java7 compression handler first, since it's preferred 127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen compressionHandlers.add(new Java7ZlibInputOutputStream()); 128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // If we don't have access to the Java7 API use the JZlib compression handler 129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen compressionHandlers.add(new JzlibInputOutputStream()); 130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * A collection of ConnectionListeners which listen for connection closing 134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * and reconnection events. 135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected final Collection<ConnectionListener> connectionListeners = 137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen new CopyOnWriteArrayList<ConnectionListener>(); 138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * A collection of PacketCollectors which collects packets for a specified filter 141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * and perform blocking and polling operations on the result queue. 142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected final Collection<PacketCollector> collectors = new ConcurrentLinkedQueue<PacketCollector>(); 144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * List of PacketListeners that will be notified when a new packet was received. 147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected final Map<PacketListener, ListenerWrapper> recvListeners = 149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen new ConcurrentHashMap<PacketListener, ListenerWrapper>(); 150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * List of PacketListeners that will be notified when a new packet was sent. 153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected final Map<PacketListener, ListenerWrapper> sendListeners = 155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen new ConcurrentHashMap<PacketListener, ListenerWrapper>(); 156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * List of PacketInterceptors that will be notified when a new packet is about to be 159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * sent to the server. These interceptors may modify the packet before it is being 160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * actually sent to the server. 161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected final Map<PacketInterceptor, InterceptorWrapper> interceptors = 163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen new ConcurrentHashMap<PacketInterceptor, InterceptorWrapper>(); 164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The AccountManager allows creation and management of accounts on an XMPP server. 167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private AccountManager accountManager = null; 169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The ChatManager keeps track of references to all current chats. 172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected ChatManager chatManager = null; 174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The SmackDebugger allows to log and debug XML traffic. 177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected SmackDebugger debugger = null; 179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The Reader which is used for the {@see debugger}. 182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected Reader reader; 184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The Writer which is used for the {@see debugger}. 187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected Writer writer; 189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The permanent storage for the roster 192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected RosterStorage rosterStorage; 194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The SASLAuthentication manager that is responsible for authenticating with the server. 198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected SASLAuthentication saslAuthentication = new SASLAuthentication(this); 200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * A number to uniquely identify connections that are created. This is distinct from the 203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * connection ID, which is a value sent by the server once a connection is made. 204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected final int connectionCounterValue = connectionCounter.getAndIncrement(); 206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Holds the initial configuration used while creating the connection. 209d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected final ConnectionConfiguration config; 211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Holds the Caps Node information for the used XMPP service (i.e. the XMPP server) 214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 215d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private String serviceCapsNode; 216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected XMPPInputOutputStream compressionHandler; 218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 219d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Create a new Connection to a XMPP server. 221d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param configuration The configuration which is used to establish the connection. 223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected Connection(ConnectionConfiguration configuration) { 225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen config = configuration; 226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 227d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the configuration used to connect to the server. 230d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the configuration used to connect to the server. 232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 233d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected ConnectionConfiguration getConfiguration() { 234d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return config; 235d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the name of the service provided by the XMPP server for this connection. 239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * This is also called XMPP domain of the connected server. After 240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * authenticating with the server the returned value may be different. 241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the name of the service provided by the XMPP server. 243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getServiceName() { 245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return config.getServiceName(); 246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 247d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 248d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the host name of the server where the XMPP server is running. This would be the 250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * IP address of the server or a name that may be resolved by a DNS server. 251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 252d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the host name of the server where the XMPP server is running. 253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 254d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getHost() { 255d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return config.getHost(); 256d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 257d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 258d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 259d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the port number of the XMPP server for this connection. The default port 260d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * for normal connections is 5222. The default port for SSL connections is 5223. 261d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 262d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the port number of the XMPP server. 263d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 264d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public int getPort() { 265d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return config.getPort(); 266d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 267d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 268d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 269d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the full XMPP address of the user that is logged in to the connection or 270d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <tt>null</tt> if not logged in yet. An XMPP address is in the form 271d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * username@server/resource. 272d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 273d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the full XMPP address of the user logged in. 274d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 275d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public abstract String getUser(); 276d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 277d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 278d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the connection ID for this connection, which is the value set by the server 279d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * when opening a XMPP stream. If the server does not set a connection ID, this value 280d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * will be null. This value will be <tt>null</tt> if not connected to the server. 281d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 282d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the ID of this connection returned from the XMPP server or <tt>null</tt> if 283d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * not connected to the server. 284d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 285d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public abstract String getConnectionID(); 286d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 287d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 288d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns true if currently connected to the XMPP server. 289d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 290d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return true if connected. 291d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 292d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public abstract boolean isConnected(); 293d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 294d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 295d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns true if currently authenticated by successfully calling the login method. 296d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 297d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return true if authenticated. 298d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 299d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public abstract boolean isAuthenticated(); 300d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 301d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 302d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns true if currently authenticated anonymously. 303d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 304d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return true if authenticated anonymously. 305d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 306d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public abstract boolean isAnonymous(); 307d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 308d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 309d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns true if the connection to the server has successfully negotiated encryption. 310d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 311d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return true if a secure connection to the server. 312d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 313d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public abstract boolean isSecureConnection(); 314d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 315d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 316d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns if the reconnection mechanism is allowed to be used. By default 317d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * reconnection is allowed. 318d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 319d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return true if the reconnection mechanism is allowed to be used. 320d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 321d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected boolean isReconnectionAllowed() { 322d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return config.isReconnectionAllowed(); 323d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 324d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 325d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 326d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns true if network traffic is being compressed. When using stream compression network 327d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * traffic can be reduced up to 90%. Therefore, stream compression is ideal when using a slow 328d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * speed network connection. However, the server will need to use more CPU time in order to 329d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * un/compress network data so under high load the server performance might be affected. 330d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 331d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return true if network traffic is being compressed. 332d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 333d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public abstract boolean isUsingCompression(); 334d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 335d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 336d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Establishes a connection to the XMPP server and performs an automatic login 337d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * only if the previous connection state was logged (authenticated). It basically 338d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * creates and maintains a connection to the server.<p> 339d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <p/> 340d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Listeners will be preserved from a previous connection if the reconnection 341d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * occurs after an abrupt termination. 342d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 343d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException if an error occurs while trying to establish the connection. 344d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 345d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public abstract void connect() throws XMPPException; 346d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 347d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 348d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Logs in to the server using the strongest authentication mode supported by 349d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the server, then sets presence to available. If the server supports SASL authentication 350d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * then the user will be authenticated using SASL if not Non-SASL authentication will 351d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * be tried. If more than five seconds (default timeout) elapses in each step of the 352d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * authentication process without a response from the server, or if an error occurs, a 353d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * XMPPException will be thrown.<p> 354d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 355d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Before logging in (i.e. authenticate) to the server the connection must be connected. 356d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 357d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * It is possible to log in without sending an initial available presence by using 358d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link ConnectionConfiguration#setSendPresence(boolean)}. If this connection is 359d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * not interested in loading its roster upon login then use 360d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link ConnectionConfiguration#setRosterLoadedAtLogin(boolean)}. 361d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Finally, if you want to not pass a password and instead use a more advanced mechanism 362d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * while using SASL then you may be interested in using 363d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link ConnectionConfiguration#setCallbackHandler(javax.security.auth.callback.CallbackHandler)}. 364d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * For more advanced login settings see {@link ConnectionConfiguration}. 365d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 366d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param username the username. 367d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param password the password or <tt>null</tt> if using a CallbackHandler. 368d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException if an error occurs. 369d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 370d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void login(String username, String password) throws XMPPException { 371d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen login(username, password, "Smack"); 372d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 373d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 374d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 375d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Logs in to the server using the strongest authentication mode supported by 376d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the server, then sets presence to available. If the server supports SASL authentication 377d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * then the user will be authenticated using SASL if not Non-SASL authentication will 378d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * be tried. If more than five seconds (default timeout) elapses in each step of the 379d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * authentication process without a response from the server, or if an error occurs, a 380d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * XMPPException will be thrown.<p> 381d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 382d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Before logging in (i.e. authenticate) to the server the connection must be connected. 383d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 384d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * It is possible to log in without sending an initial available presence by using 385d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link ConnectionConfiguration#setSendPresence(boolean)}. If this connection is 386d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * not interested in loading its roster upon login then use 387d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link ConnectionConfiguration#setRosterLoadedAtLogin(boolean)}. 388d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Finally, if you want to not pass a password and instead use a more advanced mechanism 389d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * while using SASL then you may be interested in using 390d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link ConnectionConfiguration#setCallbackHandler(javax.security.auth.callback.CallbackHandler)}. 391d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * For more advanced login settings see {@link ConnectionConfiguration}. 392d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 393d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param username the username. 394d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param password the password or <tt>null</tt> if using a CallbackHandler. 395d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param resource the resource. 396d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException if an error occurs. 397d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IllegalStateException if not connected to the server, or already logged in 398d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * to the serrver. 399d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 400d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public abstract void login(String username, String password, String resource) throws XMPPException; 401d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 402d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 403d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Logs in to the server anonymously. Very few servers are configured to support anonymous 404d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * authentication, so it's fairly likely logging in anonymously will fail. If anonymous login 405d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * does succeed, your XMPP address will likely be in the form "123ABC@server/789XYZ" or 406d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * "server/123ABC" (where "123ABC" and "789XYZ" is a random value generated by the server). 407d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 408d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException if an error occurs or anonymous logins are not supported by the server. 409d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IllegalStateException if not connected to the server, or already logged in 410d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * to the serrver. 411d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 412d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public abstract void loginAnonymously() throws XMPPException; 413d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 414d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 415d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sends the specified packet to the server. 416d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 417d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packet the packet to send. 418d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 419d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public abstract void sendPacket(Packet packet); 420d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 421d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 422d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns an account manager instance for this connection. 423d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 424d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return an account manager for this connection. 425d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 426d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public AccountManager getAccountManager() { 427d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (accountManager == null) { 428d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen accountManager = new AccountManager(this); 429d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 430d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return accountManager; 431d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 432d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 433d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 434d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns a chat manager instance for this connection. The ChatManager manages all incoming and 435d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * outgoing chats on the current connection. 436d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 437d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return a chat manager instance for this connection. 438d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 439d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public synchronized ChatManager getChatManager() { 440d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (this.chatManager == null) { 441d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.chatManager = new ChatManager(this); 442d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 443d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return this.chatManager; 444d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 445d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 446d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 447d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the roster for the user. 448d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <p> 449d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * This method will never return <code>null</code>, instead if the user has not yet logged into 450d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the server or is logged in anonymously all modifying methods of the returned roster object 451d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * like {@link Roster#createEntry(String, String, String[])}, 452d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link Roster#removeEntry(RosterEntry)} , etc. except adding or removing 453d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * {@link RosterListener}s will throw an IllegalStateException. 454d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 455d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the user's roster. 456d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 457d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public abstract Roster getRoster(); 458d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 459d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 460d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Set the store for the roster of this connection. If you set the roster storage 461d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * of a connection you enable support for XEP-0237 (RosterVersioning) 462d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param store the store used for roster versioning 463d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IllegalStateException if you add a roster store when roster is initializied 464d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 465d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public abstract void setRosterStorage(RosterStorage storage) throws IllegalStateException; 466d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 467d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 468d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the SASLAuthentication manager that is responsible for authenticating with 469d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the server. 470d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 471d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the SASLAuthentication manager that is responsible for authenticating with 472d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the server. 473d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 474d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public SASLAuthentication getSASLAuthentication() { 475d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return saslAuthentication; 476d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 477d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 478d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 479d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Closes the connection by setting presence to unavailable then closing the connection to 480d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the XMPP server. The Connection can still be used for connecting to the server 481d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * again.<p> 482d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <p/> 483d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * This method cleans up all resources used by the connection. Therefore, the roster, 484d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * listeners and other stateful objects cannot be re-used by simply calling connect() 485d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * on this connection again. This is unlike the behavior during unexpected disconnects 486d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * (and subsequent connections). In that case, all state is preserved to allow for 487d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * more seamless error recovery. 488d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 489d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void disconnect() { 490d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen disconnect(new Presence(Presence.Type.unavailable)); 491d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 492d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 493d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 494d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Closes the connection. A custom unavailable presence is sent to the server, followed 495d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * by closing the stream. The Connection can still be used for connecting to the server 496d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * again. A custom unavilable presence is useful for communicating offline presence 497d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * information such as "On vacation". Typically, just the status text of the presence 498d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * packet is set with online information, but most XMPP servers will deliver the full 499d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * presence packet with whatever data is set.<p> 500d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <p/> 501d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * This method cleans up all resources used by the connection. Therefore, the roster, 502d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * listeners and other stateful objects cannot be re-used by simply calling connect() 503d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * on this connection again. This is unlike the behavior during unexpected disconnects 504d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * (and subsequent connections). In that case, all state is preserved to allow for 505d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * more seamless error recovery. 506d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 507d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param unavailablePresence the presence packet to send during shutdown. 508d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 509d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public abstract void disconnect(Presence unavailablePresence); 510d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 511d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 512d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Adds a new listener that will be notified when new Connections are created. Note 513d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * that newly created connections will not be actually connected to the server. 514d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 515d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param connectionCreationListener a listener interested on new connections. 516d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 517d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static void addConnectionCreationListener( 518d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ConnectionCreationListener connectionCreationListener) { 519d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connectionEstablishedListeners.add(connectionCreationListener); 520d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 521d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 522d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 523d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Removes a listener that was interested in connection creation events. 524d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 525d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param connectionCreationListener a listener interested on new connections. 526d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 527d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public static void removeConnectionCreationListener( 528d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ConnectionCreationListener connectionCreationListener) { 529d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connectionEstablishedListeners.remove(connectionCreationListener); 530d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 531d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 532d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 533d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Get the collection of listeners that are interested in connection creation events. 534d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 535d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return a collection of listeners interested on new connections. 536d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 537d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected static Collection<ConnectionCreationListener> getConnectionCreationListeners() { 538d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return Collections.unmodifiableCollection(connectionEstablishedListeners); 539d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 540d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 541d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 542d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Adds a connection listener to this connection that will be notified when 543d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the connection closes or fails. The connection needs to already be connected 544d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * or otherwise an IllegalStateException will be thrown. 545d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 546d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param connectionListener a connection listener. 547d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 548d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void addConnectionListener(ConnectionListener connectionListener) { 549d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (!isConnected()) { 550d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalStateException("Not connected to server."); 551d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 552d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (connectionListener == null) { 553d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return; 554d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 555d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (!connectionListeners.contains(connectionListener)) { 556d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connectionListeners.add(connectionListener); 557d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 558d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 559d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 560d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 561d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Removes a connection listener from this connection. 562d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 563d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param connectionListener a connection listener. 564d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 565d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void removeConnectionListener(ConnectionListener connectionListener) { 566d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connectionListeners.remove(connectionListener); 567d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 568d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 569d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 570d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Get the collection of listeners that are interested in connection events. 571d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 572d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return a collection of listeners interested on connection events. 573d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 574d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected Collection<ConnectionListener> getConnectionListeners() { 575d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return connectionListeners; 576d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 577d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 578d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 579d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Creates a new packet collector for this connection. A packet filter determines 580d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * which packets will be accumulated by the collector. A PacketCollector is 581d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * more suitable to use than a {@link PacketListener} when you need to wait for 582d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * a specific result. 583d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 584d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packetFilter the packet filter to use. 585d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return a new packet collector. 586d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 587d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public PacketCollector createPacketCollector(PacketFilter packetFilter) { 588d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketCollector collector = new PacketCollector(this, packetFilter); 589d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Add the collector to the list of active collectors. 590d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen collectors.add(collector); 591d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return collector; 592d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 593d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 594d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 595d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Remove a packet collector of this connection. 596d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 597d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param collector a packet collectors which was created for this connection. 598d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 599d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected void removePacketCollector(PacketCollector collector) { 600d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen collectors.remove(collector); 601d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 602d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 603d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 604d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Get the collection of all packet collectors for this connection. 605d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 606d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return a collection of packet collectors for this connection. 607d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 608d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected Collection<PacketCollector> getPacketCollectors() { 609d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return collectors; 610d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 611d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 612d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 613d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Registers a packet listener with this connection. A packet filter determines 614d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * which packets will be delivered to the listener. If the same packet listener 615d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * is added again with a different filter, only the new filter will be used. 616d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 617d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packetListener the packet listener to notify of new received packets. 618d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packetFilter the packet filter to use. 619d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 620d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void addPacketListener(PacketListener packetListener, PacketFilter packetFilter) { 621d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (packetListener == null) { 622d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new NullPointerException("Packet listener is null."); 623d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 624d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ListenerWrapper wrapper = new ListenerWrapper(packetListener, packetFilter); 625d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen recvListeners.put(packetListener, wrapper); 626d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 627d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 628d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 629d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Removes a packet listener for received packets from this connection. 630d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 631d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packetListener the packet listener to remove. 632d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 633d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void removePacketListener(PacketListener packetListener) { 634d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen recvListeners.remove(packetListener); 635d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 636d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 637d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 638d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Get a map of all packet listeners for received packets of this connection. 639d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 640d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return a map of all packet listeners for received packets. 641d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 642d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected Map<PacketListener, ListenerWrapper> getPacketListeners() { 643d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return recvListeners; 644d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 645d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 646d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 647d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Registers a packet listener with this connection. The listener will be 648d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * notified of every packet that this connection sends. A packet filter determines 649d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * which packets will be delivered to the listener. Note that the thread 650d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * that writes packets will be used to invoke the listeners. Therefore, each 651d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * packet listener should complete all operations quickly or use a different 652d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * thread for processing. 653d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 654d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packetListener the packet listener to notify of sent packets. 655d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packetFilter the packet filter to use. 656d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 657d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void addPacketSendingListener(PacketListener packetListener, PacketFilter packetFilter) { 658d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (packetListener == null) { 659d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new NullPointerException("Packet listener is null."); 660d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 661d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ListenerWrapper wrapper = new ListenerWrapper(packetListener, packetFilter); 662d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sendListeners.put(packetListener, wrapper); 663d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 664d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 665d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 666d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Removes a packet listener for sending packets from this connection. 667d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 668d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packetListener the packet listener to remove. 669d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 670d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void removePacketSendingListener(PacketListener packetListener) { 671d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sendListeners.remove(packetListener); 672d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 673d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 674d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 675d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Get a map of all packet listeners for sending packets of this connection. 676d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 677d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return a map of all packet listeners for sent packets. 678d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 679d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected Map<PacketListener, ListenerWrapper> getPacketSendingListeners() { 680d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return sendListeners; 681d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 682d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 683d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 684d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 685d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Process all packet listeners for sending packets. 686d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 687d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packet the packet to process. 688d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 689d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected void firePacketSendingListeners(Packet packet) { 690d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Notify the listeners of the new sent packet 691d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (ListenerWrapper listenerWrapper : sendListeners.values()) { 692d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen listenerWrapper.notifyListener(packet); 693d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 694d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 695d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 696d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 697d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Registers a packet interceptor with this connection. The interceptor will be 698d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * invoked every time a packet is about to be sent by this connection. Interceptors 699d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * may modify the packet to be sent. A packet filter determines which packets 700d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * will be delivered to the interceptor. 701d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 702d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packetInterceptor the packet interceptor to notify of packets about to be sent. 703d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packetFilter the packet filter to use. 704d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 705d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void addPacketInterceptor(PacketInterceptor packetInterceptor, 706d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketFilter packetFilter) { 707d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (packetInterceptor == null) { 708d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new NullPointerException("Packet interceptor is null."); 709d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 710d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen interceptors.put(packetInterceptor, new InterceptorWrapper(packetInterceptor, packetFilter)); 711d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 712d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 713d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 714d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Removes a packet interceptor. 715d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 716d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packetInterceptor the packet interceptor to remove. 717d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 718d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void removePacketInterceptor(PacketInterceptor packetInterceptor) { 719d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen interceptors.remove(packetInterceptor); 720d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 721d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 722d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean isSendPresence() { 723d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return config.isSendPresence(); 724d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 725d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 726d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 727d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Get a map of all packet interceptors for sending packets of this connection. 728d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 729d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return a map of all packet interceptors for sending packets. 730d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 731d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected Map<PacketInterceptor, InterceptorWrapper> getPacketInterceptors() { 732d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return interceptors; 733d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 734d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 735d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 736d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Process interceptors. Interceptors may modify the packet that is about to be sent. 737d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Since the thread that requested to send the packet will invoke all interceptors, it 738d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * is important that interceptors perform their work as soon as possible so that the 739d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * thread does not remain blocked for a long period. 740d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 741d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packet the packet that is going to be sent to the server 742d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 743d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected void firePacketInterceptors(Packet packet) { 744d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (packet != null) { 745d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (InterceptorWrapper interceptorWrapper : interceptors.values()) { 746d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen interceptorWrapper.notifyListener(packet); 747d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 748d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 749d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 750d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 751d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 752d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Initialize the {@link #debugger}. You can specify a customized {@link SmackDebugger} 753d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * by setup the system property <code>smack.debuggerClass</code> to the implementation. 754d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 755d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IllegalStateException if the reader or writer isn't yet initialized. 756d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IllegalArgumentException if the SmackDebugger can't be loaded. 757d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 758d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected void initDebugger() { 759d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (reader == null || writer == null) { 760d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new NullPointerException("Reader or writer isn't initialized."); 761d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 762d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // If debugging is enabled, we open a window and write out all network traffic. 763d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (config.isDebuggerEnabled()) { 764d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (debugger == null) { 765d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Detect the debugger class to use. 766d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen String className = null; 767d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Use try block since we may not have permission to get a system 768d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // property (for example, when an applet). 769d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 770d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen className = System.getProperty("smack.debuggerClass"); 771d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 772d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (Throwable t) { 773d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Ignore. 774d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 775d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Class<?> debuggerClass = null; 776d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (className != null) { 777d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 778d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen debuggerClass = Class.forName(className); 779d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 780d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (Exception e) { 781d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen e.printStackTrace(); 782d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 783d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 784d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (debuggerClass == null) { 785d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 786d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen debuggerClass = 787d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Class.forName("de.measite.smack.AndroidDebugger"); 788d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 789d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (Exception ex) { 790d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 791d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen debuggerClass = 792d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Class.forName("org.jivesoftware.smack.debugger.ConsoleDebugger"); 793d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 794d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (Exception ex2) { 795d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ex2.printStackTrace(); 796d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 797d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 798d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 799d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Create a new debugger instance. If an exception occurs then disable the debugging 800d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // option 801d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 802d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Constructor<?> constructor = debuggerClass 803d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen .getConstructor(Connection.class, Writer.class, Reader.class); 804d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen debugger = (SmackDebugger) constructor.newInstance(this, writer, reader); 805d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen reader = debugger.getReader(); 806d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen writer = debugger.getWriter(); 807d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 808d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (Exception e) { 809d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalArgumentException("Can't initialize the configured debugger!", e); 810d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 811d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 812d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else { 813d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Obtain new reader and writer from the existing debugger 814d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen reader = debugger.newConnectionReader(reader); 815d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen writer = debugger.newConnectionWriter(writer); 816d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 817d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 818d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 819d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 820d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 821d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 822d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Set the servers Entity Caps node 823d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 824d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Connection holds this information in order to avoid a dependency to 825d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * smackx where EntityCapsManager lives from smack. 826d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 827d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param node 828d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 829d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected void setServiceCapsNode(String node) { 830d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen serviceCapsNode = node; 831d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 832d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 833d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 834d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Retrieve the servers Entity Caps node 835d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 836d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Connection holds this information in order to avoid a dependency to 837d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * smackx where EntityCapsManager lives from smack. 838d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 839d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return 840d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 841d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getServiceCapsNode() { 842d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return serviceCapsNode; 843d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 844d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 845d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 846d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * A wrapper class to associate a packet filter with a listener. 847d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 848d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected static class ListenerWrapper { 849d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 850d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private PacketListener packetListener; 851d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private PacketFilter packetFilter; 852d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 853d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 854d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Create a class which associates a packet filter with a listener. 855d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 856d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packetListener the packet listener. 857d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packetFilter the associated filter or null if it listen for all packets. 858d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 859d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public ListenerWrapper(PacketListener packetListener, PacketFilter packetFilter) { 860d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.packetListener = packetListener; 861d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.packetFilter = packetFilter; 862d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 863d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 864d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 865d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Notify and process the packet listener if the filter matches the packet. 866d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 867d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packet the packet which was sent or received. 868d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 869d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void notifyListener(Packet packet) { 870d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (packetFilter == null || packetFilter.accept(packet)) { 871d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packetListener.processPacket(packet); 872d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 873d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 874d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 875d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 876d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 877d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * A wrapper class to associate a packet filter with an interceptor. 878d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 879d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen protected static class InterceptorWrapper { 880d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 881d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private PacketInterceptor packetInterceptor; 882d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private PacketFilter packetFilter; 883d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 884d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 885d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Create a class which associates a packet filter with an interceptor. 886d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 887d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packetInterceptor the interceptor. 888d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packetFilter the associated filter or null if it intercepts all packets. 889d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 890d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public InterceptorWrapper(PacketInterceptor packetInterceptor, PacketFilter packetFilter) { 891d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.packetInterceptor = packetInterceptor; 892d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.packetFilter = packetFilter; 893d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 894d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 895d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean equals(Object object) { 896d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (object == null) { 897d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 898d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 899d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (object instanceof InterceptorWrapper) { 900d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return ((InterceptorWrapper) object).packetInterceptor 901d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen .equals(this.packetInterceptor); 902d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 903d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (object instanceof PacketInterceptor) { 904d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return object.equals(this.packetInterceptor); 905d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 906d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 907d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 908d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 909d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 910d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Notify and process the packet interceptor if the filter matches the packet. 911d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 912d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param packet the packet which will be sent. 913d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 914d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void notifyListener(Packet packet) { 915d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (packetFilter == null || packetFilter.accept(packet)) { 916d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packetInterceptor.interceptPacket(packet); 917d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 918d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 919d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 920d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 921