001    /*Copyright (C) 2003 Adam Olsen
002     *This program is free software; you can redistribute it and/or modify
003     *it under the terms of the GNU General Public License as published by
004     *the Free Software Foundation; either version 1, or (at your option)
005     *any later version.
006     *This program is distributed in the hope that it will be useful,
007     *but WITHOUT ANY WARRANTY; without even the implied warranty of
008     *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
009     *GNU General Public License for more details.
010     *You should have received a copy of the GNU General Public License
011     *along with this program; if not, write to the Free Software
012     *Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
013     *
014     * Debugger.java
015     *
016     * Created on September 13, 2005, 7:02 PM
017     */
018    
019    package com.valhalla.jbother.jabber;
020    
021    import org.jivesoftware.smack.*;
022    import org.jivesoftware.smack.debugger.*;
023    import org.jivesoftware.smack.util.*;
024    import org.jivesoftware.smack.packet.*;
025    import java.io.*;
026    import com.valhalla.jbother.*;
027    import javax.swing.event.*;
028    import java.awt.event.*;
029    import javax.xml.transform.*;
030    import javax.xml.transform.stream.*;
031    import java.util.regex.*;
032    
033    /**
034     *
035     * @author synic
036     */
037    public class Debugger implements SmackDebugger {
038        Writer writer;
039        Reader reader;
040        XMPPConnection connection;
041        ReaderListener readerListener;
042        WriterListener writerListener;
043        StringBuffer read = new StringBuffer();
044        StringBuffer write = new StringBuffer();
045        Pattern p = Pattern.compile("^\\s*<([a-zA-Z0-9]+)\\s?[^>]*>");
046        
047        private PacketListener packetReaderListener = new PacketListener()
048        {
049            public void processPacket(Packet packet) { }
050        };
051        private PacketListener packetWriterListener = new PacketListener()
052        {
053            public void processPacket(Packet packet) { }
054        };
055        
056        /** Creates a new instance of Debugger */
057        public Debugger(XMPPConnection connection, Writer writer, Reader reader) {
058            this.connection = connection;
059            this.reader = reader;
060            this.writer = writer;
061            
062            
063            // Create a special Reader that wraps the main Reader and logs data to the GUI.
064            ObservableReader debugReader = new ObservableReader(reader);
065            readerListener = new ReaderListener() {
066                public void read(String str) {
067                    addReadPacket(str);
068                }
069            };
070                    
071                    
072            debugReader.addReaderListener(readerListener);
073    
074            // Create a special Writer that wraps the main Writer and logs data to the GUI.
075            ObservableWriter debugWriter = new ObservableWriter(writer);
076            writerListener = new WriterListener() {
077                public void write(String str) {
078                    addWritePacket(str);
079                }
080            };
081    
082            debugWriter.addWriterListener(writerListener);
083    
084            // Assign the reader/writer objects to use the debug versions. The packet reader
085            // and writer will use the debug versions when they are created.
086            this.reader = debugReader;
087            this.writer = debugWriter;                
088        }
089        
090        private boolean checkForm(String str)
091        {
092            Matcher m = p.matcher(str);
093            if(m.find())
094            {
095                String tag = m.group(1);
096                if(str.trim().endsWith("</"+tag+">")) return true;
097            }
098            
099            return false;
100        }
101        
102        /**
103         * Description of the Method
104         *
105         * @param str
106         *            Description of the Parameter
107         * @return Description of the Return Value
108         */
109        private String formatXML(String str) {
110            try {
111                // Use a Transformer for output
112                TransformerFactory tFactory = TransformerFactory.newInstance();
113                // Surround this setting in a try/catch for compatibility with Java
114                // 1.4. This setting is required for Java 1.5
115                try {
116                    tFactory.setAttribute("indent-number", new Integer(8));
117                } catch (IllegalArgumentException e) {
118                }
119                Transformer transformer = tFactory.newTransformer();
120                transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
121                        "yes");
122                transformer.setOutputProperty(OutputKeys.INDENT, "yes");
123                transformer.setOutputProperty(
124                        "{http://xml.apache.org/xalan}indent-amount", "8");
125                transformer.setOutputProperty(
126                        "{http://xml.apache.org/xslt}indent-amount", "8");
127    
128                // Transform the requested string into a nice formatted XML string
129                StreamSource source = new StreamSource(new StringReader(str));
130                StringWriter sw = new StringWriter();
131                StreamResult result = new StreamResult(sw);
132                transformer.transform(source, result);
133                return sw.toString().replaceAll("\\s*$", "");
134            } catch (TransformerConfigurationException tce) {
135    
136                // Use the contained exception, if any
137                Throwable x = tce;
138                if (tce.getException() != null) {
139                    x = tce.getException();
140                }
141    
142            } catch (TransformerException te) {
143                // Use the contained exception, if any
144                Throwable x = te;
145                if (te.getException() != null) {
146                    x = te.getException();
147                }
148    
149            }
150            return str.replaceAll("\\s*$", "");
151        }    
152        
153        private void addReadPacket( String string )
154        {
155            if( ConsolePanel.getInstance() != null )
156            {
157                if(string.trim().equals("")) return;
158                if(checkForm(string)) string = formatXML(string);
159                ConsolePanel.getInstance().append(string, false);
160            }
161        }
162        
163        private void addWritePacket( String string )
164        {
165            if( ConsolePanel.getInstance() != null )
166            {
167                if(string.trim().equals("")) return;
168                if(checkForm(string)) string = formatXML(string);
169                ConsolePanel.getInstance().append(string, true);
170            }
171        }    
172        
173        public PacketListener getReaderListener() { return packetReaderListener; }
174        public PacketListener getWriterListener() { return packetWriterListener; }    
175        
176        public Writer getWriter() { return writer; }
177        public Reader getReader() { return reader; }
178        
179        public void userHasLogged(String user) { }
180        
181        public Reader newConnectionReader(Reader newReader) {
182            ((ObservableReader)reader).removeReaderListener(readerListener);
183            ObservableReader debugReader = new ObservableReader(newReader);
184            debugReader.addReaderListener(readerListener);
185            reader = debugReader;
186            return reader;
187        }
188    
189        public Writer newConnectionWriter(Writer newWriter) {
190            ((ObservableWriter)writer).removeWriterListener(writerListener);
191            ObservableWriter debugWriter = new ObservableWriter(newWriter);
192            debugWriter.addWriterListener(writerListener);
193            writer = debugWriter;
194            return writer;
195        }
196        
197    }