com.jsftoolkit.utils.HtmlWriterContentHandler Maven / Gradle / Ivy
Go to download
The core classes for the JSF Toolkit Component Framework. Includes all
framework base and utility classes as well as component
kick-start/code-generation and registration tools.
Also includes some classes for testing that are reused in other projects.
They cannot be factored out into a separate project because they are
referenced by the tests and they reference this code (circular
dependence).
The newest version!
package com.jsftoolkit.utils;
import java.io.IOException;
import java.io.Writer;
import java.util.Set;
import java.util.Stack;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* (More or less) "Pretty Prints" XHTML.
*
* @author noah
*
*/
public class HtmlWriterContentHandler extends DefaultHandler {
private final Writer writer;
private String tab = " ";
private boolean elementClosed = true;
private boolean wasWhitespace;
private int openElementCount;
private boolean newLine;
private Set blockElements = Utils.asSet("address", "blockquote",
"center", "dir", "div", "dl", "dt", "dd", "fieldset", "form", "h1",
"h2", "h3", "h4", "h5", "h6", "hr", "menu", "noscript", "ol", "p",
"pre", "table", "ul", "li", "tbody", "td", "tfoot", "th", "thead",
"tr", "button", "del", "ins", "map", "script");
private Stack openElements = new Stack();
/**
*
* @param writer
* the writer to write the XML to.
*/
public HtmlWriterContentHandler(Writer writer) {
super();
this.writer = writer;
}
/**
*
* @param writer
* the writer to write the XML to
* @param openElementCount
* the number of open elements preceding the first event
*/
public HtmlWriterContentHandler(final Writer writer, int openElementCount) {
this(writer);
this.openElementCount = openElementCount;
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
try {
openElements.push(qName);
checkOpenTag();
if (newLine) {
indent();
}
elementClosed = false;
writer.write('<');
writer.write(qName);
writer.write(' ');
for (int i = 0; i < attributes.getLength(); i++) {
writer.write(attributes.getQName(i));
writer.write("=\"");
writer.write(attributes.getValue(i));
writer.write("\" ");
}
openElementCount++;
} catch (IOException e) {
throw new SAXException(e);
}
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
try {
checkOpenTag();
if (newLine) {
indent();
}
for (int i = start; i < start + length; i++) {
if (!(Character.isWhitespace(ch[i]) && wasWhitespace)
|| "pre".equalsIgnoreCase(openElements.peek())) {
writer.write(ch[i]);
if (ch[i] == '\n') {
indent();
}
}
wasWhitespace = Character.isWhitespace(ch[i]);
}
newLine = false;
} catch (IOException e) {
throw new SAXException(e);
}
}
protected void checkOpenTag() throws IOException {
if (!elementClosed) {
writer.write('>');
elementClosed = true;
if (blockElements.contains(openElements.peek().toLowerCase())) {
writer.write('\n');
newLine = true;
}
}
}
private void indent() throws IOException {
for (int i = 0; i < openElementCount; i++) {
writer.write(tab);
}
newLine = false;
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
try {
openElementCount--;
openElements.pop();
if (elementClosed) {
if (blockElements.contains(qName.toLowerCase())) {
writer.write('\n');
indent();
}
writer.write("");
writer.write(qName);
writer.write(">");
} else {
elementClosed = true;
writer.write("/>");
}
if (blockElements.contains(qName.toLowerCase())) {
writer.write('\n');
newLine = true;
}
} catch (IOException e) {
throw new SAXException(e);
}
}
public int getOpenElementCount() {
return openElementCount;
}
public void setOpenElementCount(int openElementCount) {
this.openElementCount = openElementCount;
}
public String getTab() {
return tab;
}
public void setTab(String tab) {
this.tab = tab;
}
}