/*
* This software is Copyright 2005,2006,2007,2008 Langdale Consultants.
* Langdale Consultants can be contacted at: http://www.langdale.com.au
*/
package au.com.langdale.sax;
import org.xml.sax.XMLReader;
import org.xml.sax.EntityResolver;
import org.xml.sax.DTDHandler;
import org.xml.sax.ContentHandler;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.ext.LexicalHandler;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
/**
* A support class for SAX XMLReader, XMLFilter and our own XMLTransformer
* implementations. This class is only declared as an
* XMLReader, leaving it open to the derived class to ignore the more
* specialized support.
*/
public abstract class XMLReaderBase implements XMLReader {
/**
* The child's ContentHandler.
*/
protected ContentHandler output;
/**
* The child's entity resolver
*/
protected EntityResolver resolver = new DummyResolver();
/**
* The source specified in the parse() message.
*/
protected InputSource input;
/**
* The child's ErrorHandler.
*/
protected ErrorHandler errors;
/**
* The parent.
*/
protected XMLReader parent;
/**
* The extended properties.
*/
protected Map properties = new HashMap();
/**
* The extended features.
*/
protected Map features = new HashMap();
/**
* The name of the extended property for a lexical-handler object.
*/
protected final String LEXICAL_HANDLER = "http://xml.org/sax/handlers/LexicalHandler";
/**
* Construct with default features.
*/
public XMLReaderBase() {
// we assume these features are always on.
features.put("http://xml.org/sax/features/namespaces", Boolean.TRUE);
features.put("http://xml.org/sax/features/namespace-prefixes", Boolean.TRUE);
}
/**
* Switches on a feature of the reader.
*
*/
public void setFeature(String parm1, boolean parm2) throws SAXNotRecognizedException, SAXNotSupportedException {
if (!features.containsKey(parm1)) {
throw new SAXNotRecognizedException(parm1);
}
features.put(parm1, new Boolean(parm2));
}
/**
* Sets a property of the reader (e.g. a special handler).
*/
public void setProperty(String parm1, Object parm2) throws SAXNotRecognizedException, SAXNotSupportedException {
properties.put(parm1, parm2);
}
/**
* Nominally sets the EntityResolver attribute of the XMLReaderBase object
* (but not implemented).
*/
public void setEntityResolver(EntityResolver parm1) {
resolver = parm1;
}
/**
* Sets the Lexical handler for the reader. This is eqivalent to setting
* the lexical handler property and is not a SAX method.
*
*/
public void setLexicalHandler(LexicalHandler lexical) {
properties.put(LEXICAL_HANDLER, lexical);
}
/**
* Nominally sets the DTDHandler attribute of the XMLReaderBase object
* (but is not implemented).
*/
public void setDTDHandler(DTDHandler parm1) {
}
/**
* Sets the ContentHandler attribute of the XMLReaderBase object
*
*/
public void setContentHandler(ContentHandler handler) {
output = handler;
}
/**
* Sets the parent reader (if this is a filter).
*/
public void setParent(XMLReader reader) {
parent = reader;
}
/**
* Sets the ErrorHandler attribute of the XMLReaderBase object
*/
public void setErrorHandler(ErrorHandler handler) {
errors = handler;
}
/**
* Tests whether a feature is switched on.
*/
public boolean getFeature(String parm1) throws SAXNotRecognizedException, SAXNotSupportedException {
if (!features.containsKey(parm1)) {
throw new SAXNotRecognizedException(parm1);
}
return features.get(parm1).equals(Boolean.TRUE);
}
/**
* Gets a property object.
*
*/
public Object getProperty(String parm1) throws SAXNotRecognizedException, SAXNotSupportedException {
if (!properties.containsKey(parm1)) {
throw new SAXNotRecognizedException(parm1);
}
return properties.get(parm1);
}
/**
* Gets the EntityResolver attribute of the XMLReaderBase object
*/
public EntityResolver getEntityResolver() {
return resolver;
}
/**
* Gets the Lexical handler. (This is not a SAX method.)
*/
public LexicalHandler getLexicalHandler() {
return (LexicalHandler) properties.get(LEXICAL_HANDLER);
}
/**
* Gets the DTDHandler attribute of the XMLReaderBase object
*
*/
public DTDHandler getDTDHandler() {
return null;
}
/**
* Gets the ContentHandler attribute of the XMLReaderBase object
*
*/
public ContentHandler getContentHandler() {
return output;
}
/**
* Gets the parent reader.
*/
public XMLReader getParent() {
return parent;
}
/**
* Gets the ErrorHandler attribute of the XMLReaderBase object
*/
public ErrorHandler getErrorHandler() {
return errors;
}
static class DummyResolver implements EntityResolver
{
static class EmptyStream extends InputStream
{
/**
* @see java.io.InputStream#read()
*/
@Override
public int read() throws IOException {
return -1;
}
};
/**
* @see org.xml.sax.EntityResolver#resolveEntity(String, String)
*/
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
return new InputSource( new InputStreamReader( new EmptyStream() ));
}
};
/**
* Accepts a specification of what to parse, and initiates parsing.
*
*/
public void parse(InputSource source) throws java.io.IOException, SAXException {
input = source;
parse();
}
/**
* Convenience method that accepts the filename of a file to parse.
*
*/
public void parse(String name) throws java.io.IOException, SAXException {
parse(new InputSource(new java.io.FileReader(name)));
}
/**
* A utility to configure a delegate (e.g. parent) reader.
*/
protected void setup(XMLReader delegate) throws SAXException {
delegate.setContentHandler(output);
delegate.setEntityResolver( resolver );
if( errors != null)
delegate.setErrorHandler(errors);
if(! delegate.getFeature("http://xml.org/sax/features/namespaces")) {
delegate.setFeature("http://xml.org/sax/features/namespaces", true);
}
for (Iterator ix = properties.keySet().iterator(); ix.hasNext(); ) {
String key = (String) ix.next();
try {
delegate.setProperty(key, properties.get(key));
}
catch (SAXException ex) {
// ignore
}
}
}
/**
* Overide this method to solicit SAX events from the parent
* and/or generate SAX events into the currently set handlers.
*/
protected abstract void parse() throws SAXException, java.io.IOException;
}