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