/** * $RCSfile$ * $Revision$ * $Date$ * * Copyright (C) 2002-2003 Jive Software. All rights reserved. * ==================================================================== * The Jive Software License (based on Apache Software License, Version 1.1) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * Jive Software (http://www.jivesoftware.com)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Smack" and "Jive Software" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact webmaster@jivesoftware.com. * * 5. Products derived from this software may not be called "Smack", * nor may "Smack" appear in their name, without prior written * permission of Jive Software. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL JIVE SOFTWARE OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== */ package org.jivesoftware.smack; import org.xmlpull.v1.*; import java.util.*; import java.util.List; import java.io.ObjectInputStream; import java.io.ByteArrayInputStream; import java.beans.PropertyDescriptor; import org.jivesoftware.smack.packet.*; import org.jivesoftware.smack.packet.XMPPError; import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.provider.*; /** * Listens for XML traffic from the XMPP server and parses it into packet objects. * The packet reader also manages all packet listeners and collectors.
*
* @see PacketCollector
* @see PacketListener
* @author Matt Tucker
*/
class PacketReader {
/**
* Namespace used to store packet properties.
*/
private static final String PROPERTIES_NAMESPACE =
"http://www.jivesoftware.com/xmlns/xmpp/properties";
private Thread readerThread;
private Thread listenerThread;
private XMPPConnection connection;
private XmlPullParser parser;
private boolean done = false;
protected List collectors = new ArrayList();
private List listeners = new ArrayList();
protected List connectionListeners = new ArrayList();
private String connectionID = null;
private Object connectionIDLock = new Object();
private int packetsRead = 0;
protected PacketReader(XMPPConnection connection) {
this.connection = connection;
readerThread = new Thread() {
public void run() {
parsePackets();
}
};
readerThread.setName("Smack Packet Reader");
readerThread.setDaemon(true);
listenerThread = new Thread() {
public void run() {
processListeners();
}
};
listenerThread.setName("Smack Listener Processor");
listenerThread.setDaemon(true);
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance(
"org.xmlpull.mxp1.MXParserFactory", null);
factory.setNamespaceAware(true);
parser = factory.newPullParser();
parser.setInput(connection.reader);
}
catch (XmlPullParserException xppe) {
xppe.printStackTrace();
}
}
/**
* Creates a new packet collector for this reader. A packet filter determines
* which packets will be accumulated by the collector.
*
* @param packetFilter the packet filter to use.
* @return a new packet collector.
*/
public PacketCollector createPacketCollector(PacketFilter packetFilter) {
PacketCollector packetCollector = new PacketCollector(this, packetFilter);
return packetCollector;
}
/**
* Registers a packet listener with this reader. A packet filter determines
* which packets will be delivered to the listener.
*
* @param packetListener the packet listener to notify of new packets.
* @param packetFilter the packet filter to use.
*/
public void addPacketListener(PacketListener packetListener, PacketFilter packetFilter) {
ListenerWrapper wrapper = new ListenerWrapper(this, packetListener,
packetFilter);
synchronized (listeners) {
listeners.add(wrapper);
}
}
/**
* Removes a packet listener.
*
* @param packetListener the packet listener to remove.
*/
public void removePacketListener(PacketListener packetListener) {
synchronized (listeners) {
for (int i=0; i