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