SAXAdapter.java
/*
* SAXAdapter
*
* $Id$
* $HeadURL$
*/
package gov.usgs.util;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.util.LinkedList;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
/**
* SAXAdapter is a sax handler that accumulates element content, which is a
* common sax handler task.
*
* Users should be cautious because this in some ways removes efficiency gained
* by handling streaming events, because element content is being buffered. One
* buffer for each element nesting is maintained, so this works best for shallow
* documents, whose elements contain little content.
*/
public class SAXAdapter extends DefaultHandler {
/** Buffers for element content, since it may be delivered in pieces. */
private LinkedList<StringBuffer> buffers = new LinkedList<StringBuffer>();
/**
* SAXAdapter start element handler.
*
* @param uri element uri.
* @param localName element localName.
* @param qName element qName.
* @param attributes element attributes.
* @throws SAXException if there is an error.
*/
public void onStartElement(final String uri, final String localName, final String qName, final Attributes attributes)
throws SAXException {
}
/**
* SAXAdapter end element handler. Content only includes characters that were
* read from this element, NOT any characters from child elements.
*
* @param uri element uri.
* @param localName element localName.
* @param qName element qName.
* @param content element content.
* @throws SAXException if onEndElement throws a SAXException.
*/
public void onEndElement(final String uri, final String localName, final String qName, final String content)
throws SAXException {
}
/**
* Override DefaultHandler startElement. Adds a new element content buffer and
* calls onStartElement.
*
* @param uri element uri.
* @param localName element localName.
* @param qName element qName.
* @param attributes element attributes.
* @throws SAXException if onStartElement throws a SAXException.
*/
public final void startElement(final String uri, final String localName, final String qName,
final Attributes attributes) throws SAXException {
buffers.add(new StringBuffer());
onStartElement(uri, localName, qName, attributes);
}
/**
* Override DefaultHandler endElement. Retrieves element content buffer and
* passes it to onEndElement.
*
* @param uri element uri.
* @param localName element localName.
* @param qName element qName.
* @throws SAXException if onEndElement throws a SAXException.
*/
public final void endElement(final String uri, final String localName, final String qName) throws SAXException {
String elementContent = buffers.removeLast().toString();
onEndElement(uri, localName, qName, elementContent);
}
/**
* Override DefaultHandler characters. Appends content to current element
* buffer, or skips if before first element.
*
* @param ch content.
* @param start position in content to read.
* @param length lenth of content to read.
* @throws SAXException never.
*/
public final void characters(final char[] ch, final int start, final int length) throws SAXException {
if (buffers.size() > 0) {
buffers.getLast().append(ch, start, length);
}
}
/**
* Use this handler to parse a string. Wraps string bytes in a
* ByteArrayInputStream.
*
* @param xml string containing xml to parse.
* @return any exception that occurs while parsing, or null if no exceptions
* occur.
*/
public final Exception parse(final String xml) {
return parse(new ByteArrayInputStream(xml.getBytes()));
}
/**
* Use this handler to parse an input stream. Uses self as a content and error
* handler in an XMLReader. If an error occurs, use getException to retrieve the
* error.
*
* @param xml input stream of xml to parse.
* @return any exception that occurs while parsing, or null if no exceptions
* occur.
*/
public final Exception parse(InputStream xml) {
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
xr.setContentHandler(this);
xr.setErrorHandler(this);
xr.parse(new InputSource(xml));
return null;
} catch (Exception e) {
return e;
} finally {
StreamUtils.closeStream(xml);
}
}
}