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);
}
}
}