KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jivesoftware > whack > SocketReadThread


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

20
21 package org.jivesoftware.whack;
22
23 import org.dom4j.Element;
24 import org.dom4j.io.XPPPacketReader;
25 import org.xmlpull.v1.XmlPullParserException;
26 import org.xmpp.packet.*;
27
28 import java.io.EOFException JavaDoc;
29 import java.net.SocketException JavaDoc;
30
31 /**
32  * Reads XMPP XML packets from a socket and asks the component to process the packets.
33  *
34  * @author Gaston Dombiak
35  */

36 class SocketReadThread extends Thread JavaDoc {
37
38     private ExternalComponent component;
39     private boolean shutdown = false;
40
41     XPPPacketReader reader = null;
42
43     /**
44      * Create dedicated read thread for this socket.
45      *
46      * @param component The component for which this thread is reading for
47      * @param reader The reader to use for reading
48      */

49     public SocketReadThread(ExternalComponent component, XPPPacketReader reader) {
50         super("Component socket reader");
51         this.component = component;
52         this.reader = reader;
53     }
54
55     /**
56      * A dedicated thread loop for reading the stream and sending incoming
57      * packets to the appropriate router.
58      */

59     public void run() {
60         try {
61             readStream();
62         }
63         catch (EOFException JavaDoc eof) {
64             // Normal disconnect
65
}
66         catch (SocketException JavaDoc se) {
67             // Do nothing if the exception occured while shutting down the component otherwise
68
// log the error and try to establish a new connection
69
if (!shutdown) {
70                 component.getManager().getLog().error(se);
71                 component.connectionLost();
72             }
73         }
74         catch (XmlPullParserException ie) {
75             component.getManager().getLog().error(ie);
76         }
77         catch (Exception JavaDoc e) {
78             component.getManager().getLog().warn(e);
79         }
80     }
81
82     /**
83      * Read the incoming stream until it ends.
84      */

85     private void readStream() throws Exception JavaDoc {
86         while (!shutdown) {
87             Element doc = reader.parseDocument().getRootElement();
88
89             if (doc == null) {
90                 // Stop reading the stream since the server has sent an end of stream element and
91
// probably closed the connection
92
return;
93             }
94
95             Packet packet;
96             String JavaDoc tag = doc.getName();
97             if ("message".equals(tag)) {
98                 packet = new Message(doc);
99             }
100             else if ("presence".equals(tag)) {
101                 packet = new Presence(doc);
102             }
103             else if ("iq".equals(tag)) {
104                 packet = getIQ(doc);
105             }
106             else {
107                 throw new XmlPullParserException("Unknown packet type was read: " + tag);
108             }
109             // Request the component to process the received packet
110
component.processPacket(packet);
111         }
112     }
113
114     private IQ getIQ(Element doc) {
115         Element query = doc.element("query");
116         if (query != null && "jabber:iq:roster".equals(query.getNamespaceURI())) {
117             return new Roster(doc);
118         }
119         else {
120             return new IQ(doc);
121         }
122     }
123
124     /**
125      * Aks the thread to stop reading packets. The thread may not stop immediatelly so if a socket
126      * exception occurs because the connection was lost then no exception will be logged nor the
127      * component will try to reestablish the connection.<p>
128      *
129      * Once this method was sent this instance should be discarded and created a new one if a new
130      * connection with the server is established.
131      */

132     public void shutdown() {
133         shutdown = true;
134     }
135 }
136
Popular Tags