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 }