001 /* 002 * Copyright (c) 2007 Henri Sivonen 003 * 004 * Permission is hereby granted, free of charge, to any person obtaining a 005 * copy of this software and associated documentation files (the "Software"), 006 * to deal in the Software without restriction, including without limitation 007 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 008 * and/or sell copies of the Software, and to permit persons to whom the 009 * Software is furnished to do so, subject to the following conditions: 010 * 011 * The above copyright notice and this permission notice shall be included in 012 * all copies or substantial portions of the Software. 013 * 014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 017 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 019 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 020 * DEALINGS IN THE SOFTWARE. 021 */ 022 023 package nu.validator.htmlparser.test; 024 025 import java.io.IOException; 026 import java.io.Writer; 027 import java.util.Map; 028 import java.util.TreeMap; 029 030 import org.xml.sax.Attributes; 031 import org.xml.sax.ContentHandler; 032 import org.xml.sax.Locator; 033 import org.xml.sax.SAXException; 034 import org.xml.sax.ext.LexicalHandler; 035 036 public class TreeDumpContentHandler implements ContentHandler, LexicalHandler { 037 038 private final Writer writer; 039 040 private int level = 0; 041 042 private boolean inCharacters = false; 043 044 private boolean close; 045 046 /** 047 * @param writer 048 */ 049 public TreeDumpContentHandler(final Writer writer, boolean close) { 050 this.writer = writer; 051 this.close = close; 052 } 053 054 public TreeDumpContentHandler(final Writer writer) { 055 this(writer, true); 056 } 057 058 private void printLead() throws IOException { 059 if (inCharacters) { 060 writer.write("\"\n"); 061 inCharacters = false; 062 } 063 writer.write("| "); 064 for (int i = 0; i < level; i++) { 065 writer.write(" "); 066 } 067 } 068 069 public void characters(char[] ch, int start, int length) 070 throws SAXException { 071 try { 072 if (!inCharacters) { 073 printLead(); 074 writer.write('"'); 075 inCharacters = true; 076 } 077 writer.write(ch, start, length); 078 } catch (IOException e) { 079 throw new SAXException(e); 080 } 081 } 082 083 public void endElement(String uri, String localName, String qName) 084 throws SAXException { 085 try { 086 if (inCharacters) { 087 writer.write("\"\n"); 088 inCharacters = false; 089 } 090 level--; 091 } catch (IOException e) { 092 throw new SAXException(e); 093 } 094 } 095 096 public void startElement(String uri, String localName, String qName, 097 Attributes atts) throws SAXException { 098 try { 099 printLead(); 100 writer.write('<'); 101 writer.write(qName); 102 writer.write(">\n"); 103 level++; 104 105 TreeMap<String, String> map = new TreeMap<String, String>(); 106 for (int i = 0; i < atts.getLength(); i++) { 107 map.put(atts.getQName(i), atts.getValue(i)); 108 } 109 for (Map.Entry<String, String> entry : map.entrySet()) { 110 printLead(); 111 writer.write(entry.getKey()); 112 writer.write("=\""); 113 writer.write(entry.getValue()); 114 writer.write("\"\n"); 115 } 116 } catch (IOException e) { 117 throw new SAXException(e); 118 } 119 } 120 121 public void comment(char[] ch, int offset, int len) throws SAXException { 122 try { 123 printLead(); 124 writer.write("<!-- "); 125 writer.write(ch, offset, len); 126 writer.write(" -->\n"); 127 } catch (IOException e) { 128 throw new SAXException(e); 129 } 130 } 131 132 public void startDTD(String name, String publicIdentifier, 133 String systemIdentifier) throws SAXException { 134 try { 135 printLead(); 136 writer.write("<!DOCTYPE "); 137 writer.write(name); 138 writer.write(">\n"); 139 } catch (IOException e) { 140 throw new SAXException(e); 141 } 142 } 143 144 public void endDocument() throws SAXException { 145 try { 146 if (inCharacters) { 147 writer.write("\"\n"); 148 inCharacters = false; 149 } 150 if (close) { 151 writer.flush(); 152 writer.close(); 153 } 154 } catch (IOException e) { 155 throw new SAXException(e); 156 } 157 } 158 159 public void startPrefixMapping(String prefix, String uri) 160 throws SAXException { 161 } 162 163 public void startEntity(String arg0) throws SAXException { 164 } 165 166 public void endCDATA() throws SAXException { 167 } 168 169 public void endDTD() throws SAXException { 170 } 171 172 public void endEntity(String arg0) throws SAXException { 173 } 174 175 public void startCDATA() throws SAXException { 176 } 177 178 public void endPrefixMapping(String prefix) throws SAXException { 179 } 180 181 public void ignorableWhitespace(char[] ch, int start, int length) 182 throws SAXException { 183 } 184 185 public void processingInstruction(String target, String data) 186 throws SAXException { 187 } 188 189 public void setDocumentLocator(Locator locator) { 190 } 191 192 public void skippedEntity(String name) throws SAXException { 193 } 194 195 public void startDocument() throws SAXException { 196 } 197 198 }