Java tutorial
/** * $RCSfile$ * $Revision: 2597 $ * $Date: 2005-03-31 15:05:58 -0800 (Thu, 31 Mar 2005) $ * * Copyright 2005 Jive Software. * * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.tu_berlin.cit.rwx4j.xmpp.whack; import org.dom4j.Element; import org.dom4j.io.XPPPacketReader; import org.xmlpull.v1.XmlPullParserException; import de.tu_berlin.cit.rwx4j.xmpp.packet.IQ; import de.tu_berlin.cit.rwx4j.xmpp.packet.Message; import de.tu_berlin.cit.rwx4j.xmpp.packet.Packet; import de.tu_berlin.cit.rwx4j.xmpp.packet.Presence; import de.tu_berlin.cit.rwx4j.xmpp.packet.Roster; import java.io.EOFException; import java.net.SocketException; /** * Reads XMPP XML packets from a socket and asks the component to process the packets. * * @author Gaston Dombiak */ class SocketReadThread extends Thread { private ExternalComponent component; private boolean shutdown = false; XPPPacketReader reader = null; /** * Create dedicated read thread for this socket. * * @param component The component for which this thread is reading for * @param reader The reader to use for reading */ public SocketReadThread(ExternalComponent component, XPPPacketReader reader) { super("Component socket reader"); this.component = component; this.reader = reader; } /** * A dedicated thread loop for reading the stream and sending incoming * packets to the appropriate router. */ public void run() { try { readStream(); } catch (EOFException eof) { // Normal disconnect } catch (SocketException se) { // Do nothing if the exception occured while shutting down the component otherwise // log the error and try to establish a new connection if (!shutdown) { component.getManager().getLog().error(se.getMessage()); component.connectionLost(); } } catch (XmlPullParserException ie) { component.getManager().getLog().error(ie.getMessage()); } catch (Exception e) { component.getManager().getLog().warn(e.getMessage()); } } /** * Read the incoming stream until it ends. */ private void readStream() throws Exception { while (!shutdown) { Element doc = reader.parseDocument().getRootElement(); if (doc == null) { // Stop reading the stream since the server has sent an end of stream element and // probably closed the connection return; } Packet packet; String tag = doc.getName(); if ("message".equals(tag)) { packet = new Message(doc); } else if ("presence".equals(tag)) { packet = new Presence(doc); } else if ("iq".equals(tag)) { packet = getIQ(doc); } else { throw new XmlPullParserException("Unknown packet type was read: " + tag); } // Request the component to process the received packet component.processPacket(packet); } } private IQ getIQ(Element doc) { Element query = doc.element("query"); if (query != null && "jabber:iq:roster".equals(query.getNamespaceURI())) { return new Roster(doc); } else { return new IQ(doc); } } /** * Aks the thread to stop reading packets. The thread may not stop immediatelly so if a socket * exception occurs because the connection was lost then no exception will be logged nor the * component will try to reestablish the connection.<p> * * Once this method was sent this instance should be discarded and created a new one if a new * connection with the server is established. */ public void shutdown() { shutdown = true; } }