• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * $RCSfile$
3  * $Revision$
4  * $Date$
5  *
6  * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 package org.jivesoftware.smack.debugger;
19 
20 import org.jivesoftware.smack.ConnectionListener;
21 import org.jivesoftware.smack.PacketListener;
22 import org.jivesoftware.smack.Connection;
23 import org.jivesoftware.smack.packet.Packet;
24 import org.jivesoftware.smack.util.*;
25 
26 import java.io.Reader;
27 import java.io.Writer;
28 import java.text.SimpleDateFormat;
29 import java.util.Date;
30 
31 /**
32  * Very simple debugger that prints to the console (stdout) the sent and received stanzas. Use
33  * this debugger with caution since printing to the console is an expensive operation that may
34  * even block the thread since only one thread may print at a time.<p>
35  * <p/>
36  * It is possible to not only print the raw sent and received stanzas but also the interpreted
37  * packets by Smack. By default interpreted packets won't be printed. To enable this feature
38  * just change the <tt>printInterpreted</tt> static variable to <tt>true</tt>.
39  *
40  * @author Gaston Dombiak
41  */
42 public class ConsoleDebugger implements SmackDebugger {
43 
44     public static boolean printInterpreted = false;
45     private SimpleDateFormat dateFormatter = new SimpleDateFormat("hh:mm:ss aaa");
46 
47     private Connection connection = null;
48 
49     private PacketListener listener = null;
50     private ConnectionListener connListener = null;
51 
52     private Writer writer;
53     private Reader reader;
54     private ReaderListener readerListener;
55     private WriterListener writerListener;
56 
ConsoleDebugger(Connection connection, Writer writer, Reader reader)57     public ConsoleDebugger(Connection connection, Writer writer, Reader reader) {
58         this.connection = connection;
59         this.writer = writer;
60         this.reader = reader;
61         createDebug();
62     }
63 
64     /**
65      * Creates the listeners that will print in the console when new activity is detected.
66      */
createDebug()67     private void createDebug() {
68         // Create a special Reader that wraps the main Reader and logs data to the GUI.
69         ObservableReader debugReader = new ObservableReader(reader);
70         readerListener = new ReaderListener() {
71             public void read(String str) {
72                 System.out.println(
73                         dateFormatter.format(new Date()) + " RCV  (" + connection.hashCode() +
74                         "): " +
75                         str);
76             }
77         };
78         debugReader.addReaderListener(readerListener);
79 
80         // Create a special Writer that wraps the main Writer and logs data to the GUI.
81         ObservableWriter debugWriter = new ObservableWriter(writer);
82         writerListener = new WriterListener() {
83             public void write(String str) {
84                 System.out.println(
85                         dateFormatter.format(new Date()) + " SENT (" + connection.hashCode() +
86                         "): " +
87                         str);
88             }
89         };
90         debugWriter.addWriterListener(writerListener);
91 
92         // Assign the reader/writer objects to use the debug versions. The packet reader
93         // and writer will use the debug versions when they are created.
94         reader = debugReader;
95         writer = debugWriter;
96 
97         // Create a thread that will listen for all incoming packets and write them to
98         // the GUI. This is what we call "interpreted" packet data, since it's the packet
99         // data as Smack sees it and not as it's coming in as raw XML.
100         listener = new PacketListener() {
101             public void processPacket(Packet packet) {
102                 if (printInterpreted) {
103                     System.out.println(
104                             dateFormatter.format(new Date()) + " RCV PKT (" +
105                             connection.hashCode() +
106                             "): " +
107                             packet.toXML());
108                 }
109             }
110         };
111 
112         connListener = new ConnectionListener() {
113             public void connectionClosed() {
114                 System.out.println(
115                         dateFormatter.format(new Date()) + " Connection closed (" +
116                         connection.hashCode() +
117                         ")");
118             }
119 
120             public void connectionClosedOnError(Exception e) {
121                 System.out.println(
122                         dateFormatter.format(new Date()) +
123                         " Connection closed due to an exception (" +
124                         connection.hashCode() +
125                         ")");
126                 e.printStackTrace();
127             }
128             public void reconnectionFailed(Exception e) {
129                 System.out.println(
130                         dateFormatter.format(new Date()) +
131                         " Reconnection failed due to an exception (" +
132                         connection.hashCode() +
133                         ")");
134                 e.printStackTrace();
135             }
136             public void reconnectionSuccessful() {
137                 System.out.println(
138                         dateFormatter.format(new Date()) + " Connection reconnected (" +
139                         connection.hashCode() +
140                         ")");
141             }
142             public void reconnectingIn(int seconds) {
143                 System.out.println(
144                         dateFormatter.format(new Date()) + " Connection (" +
145                         connection.hashCode() +
146                         ") will reconnect in " + seconds);
147             }
148         };
149     }
150 
newConnectionReader(Reader newReader)151     public Reader newConnectionReader(Reader newReader) {
152         ((ObservableReader)reader).removeReaderListener(readerListener);
153         ObservableReader debugReader = new ObservableReader(newReader);
154         debugReader.addReaderListener(readerListener);
155         reader = debugReader;
156         return reader;
157     }
158 
newConnectionWriter(Writer newWriter)159     public Writer newConnectionWriter(Writer newWriter) {
160         ((ObservableWriter)writer).removeWriterListener(writerListener);
161         ObservableWriter debugWriter = new ObservableWriter(newWriter);
162         debugWriter.addWriterListener(writerListener);
163         writer = debugWriter;
164         return writer;
165     }
166 
userHasLogged(String user)167     public void userHasLogged(String user) {
168         boolean isAnonymous = "".equals(StringUtils.parseName(user));
169         String title =
170                 "User logged (" + connection.hashCode() + "): "
171                 + (isAnonymous ? "" : StringUtils.parseBareAddress(user))
172                 + "@"
173                 + connection.getServiceName()
174                 + ":"
175                 + connection.getPort();
176         title += "/" + StringUtils.parseResource(user);
177         System.out.println(title);
178         // Add the connection listener to the connection so that the debugger can be notified
179         // whenever the connection is closed.
180         connection.addConnectionListener(connListener);
181     }
182 
getReader()183     public Reader getReader() {
184         return reader;
185     }
186 
getWriter()187     public Writer getWriter() {
188         return writer;
189     }
190 
getReaderListener()191     public PacketListener getReaderListener() {
192         return listener;
193     }
194 
getWriterListener()195     public PacketListener getWriterListener() {
196         return null;
197     }
198 }
199