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