/*
* Copyright (c) 2008, SQL Power Group Inc.
*
* This file is part of SQL Power Library.
*
* SQL Power Library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* SQL Power Library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package ca.sqlpower.xml;
import java.io.IOException;
import org.apache.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.DTDHandler;
import org.xml.sax.EntityResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
/**
* An implementation of DefaultHandler that wraps around another DefaultHandler instance,
* or around ndividual DTDHandler, ContentHandler, ErrorHandler, and EntityResolver
* instances. It is used by the UnescapingSaxParser for reading XML documents generated using
* the XMLHelper class.
*
*/
public class UnescapingDefaultHandler extends DefaultHandler {
private static final Logger logger = Logger.getLogger(UnescapingDefaultHandler.class);
/**
* The EntityResolver that this instance of UnescapingDefaultHandler wraps around.
*/
private final EntityResolver entityResolver;
/**
* The DTDHandler that this instance of UnescapingDefaultHandler wraps around.
*/
private final DTDHandler dtdHandler;
/**
* The ContentHandler that this instance of UnescapingDefaultHandler wraps around.
*/
private final ContentHandler contentHandler;
/**
* The ErrorHandler that this instance of UnescapingDefaultHandler wraps around.
*/
private final ErrorHandler errorHandler;
public UnescapingDefaultHandler(DefaultHandler defaultHandler) {
this(defaultHandler, defaultHandler, defaultHandler, defaultHandler);
}
public UnescapingDefaultHandler(DTDHandler dtdHandler) {
this(null, dtdHandler, null, null);
}
public UnescapingDefaultHandler(ContentHandler contentHandler) {
this(null, null, contentHandler, null);
}
public UnescapingDefaultHandler(ErrorHandler errorHandler) {
this(null, null, null, errorHandler);
}
public UnescapingDefaultHandler(EntityResolver entityResolver) {
this(entityResolver, null, null, null);
}
/**
* This is the constructor to which all others delegate. It sets all four interface
* implementations on this instance.
*
* @param entityResolver
* @param dtdHandler
* @param contentHandler
* @param errorHandler
*/
public UnescapingDefaultHandler(
EntityResolver entityResolver,
DTDHandler dtdHandler,
ContentHandler contentHandler,
ErrorHandler errorHandler) {
super();
this.entityResolver = entityResolver;
this.dtdHandler = dtdHandler;
this.contentHandler = contentHandler;
this.errorHandler = errorHandler;
}
// ================ ContentHandler delegates ===================
/**
* Takes the passed in char[] escapedCh and unescapes it using XMLHelper.
* Then passes the unescaped string into the wrapped ContentHandler's implmentation
* of the method.
*
* @param ch A character array containing escaped characters from an XML document.
* @param start
* @param length
* @throws SAXException
* @see org.xml.sax.ContentHandler#characters(char[], int, int)
*/
public void characters(char[] escapedCh, int start, int length) throws SAXException {
logger.debug("Unescaping character data");
String original = new String(escapedCh, start, length);
String unescaped = XMLHelper.unescape(original);
contentHandler.characters(unescaped.toCharArray(), 0, unescaped.length());
}
/**
* Delegates to the wrapped ContentHandler's implementation of the method.
*
* @throws SAXException
* @see org.xml.sax.ContentHandler#endDocument()
*/
public void endDocument() throws SAXException {
contentHandler.endDocument();
}
/**
* Delegates to the wrapped ContentHandler's implementation of the method.
*
* @param uri
* @param localName
* @param qName
* @throws SAXException
* @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
*/
public void endElement(String uri, String localName, String qName) throws SAXException {
contentHandler.endElement(uri, localName, qName);
}
/**
* Delegates to the wrapped ContentHandler's implementation of the method.
*
* @param prefix
* @throws SAXException
* @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
*/
public void endPrefixMapping(String prefix) throws SAXException {
contentHandler.endPrefixMapping(prefix);
}
/**
* Delegates to the wrapped ContentHandler's implementation of the method.
*
* @param ch
* @param start
* @param length
* @throws SAXException
* @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
*/
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
contentHandler.ignorableWhitespace(ch, start, length);
}
/**
* Delegates to the wrapped ContentHandler's implementation of the method.
*
* @param target
* @param data
* @throws SAXException
* @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
*/
public void processingInstruction(String target, String data) throws SAXException {
contentHandler.processingInstruction(target, data);
}
/**
* Delegates to the wrapped ContentHandler's implementation of the method.
*
* @param locator
* @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
*/
public void setDocumentLocator(Locator locator) {
contentHandler.setDocumentLocator(locator);
}
/**
* Delegates to the wrapped ContentHandler's implementation of the method.
*
* @param name
* @throws SAXException
* @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
*/
public void skippedEntity(String name) throws SAXException {
contentHandler.skippedEntity(name);
}
/**
* Delegates to the wrapped ContentHandler's implementation of the method.
*
* @throws SAXException
* @see org.xml.sax.ContentHandler#startDocument()
*/
public void startDocument() throws SAXException {
contentHandler.startDocument();
}
/**
* Takes the Attributes atts and wraps within an UnescapingAttributes instance.
* Passes the UnescapingAttributes and the other arguments into the wrapped
* ContentHandler's implementation of the method.
*
* @param uri
* @param localName
* @param qName
* @param atts
* @throws SAXException
* @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
logger.debug("Wrapping Attribute data");
contentHandler.startElement(uri, localName, qName, new UnescapingAttributes(atts));
}
/**
* Delegates to the wrapped ContentHandler's implementation of the method.
*
* @param prefix
* @param uri
* @throws SAXException
* @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
*/
public void startPrefixMapping(String prefix, String uri) throws SAXException {
contentHandler.startPrefixMapping(prefix, uri);
}
// ================ DTDHandler delegates ===================
/**
* Delegates to the wrapped DTDHandler's implementation of the method
*
* @param arg0
* @param arg1
* @param arg2
* @throws SAXException
* @see org.xml.sax.DTDHandler#notationDecl(java.lang.String, java.lang.String, java.lang.String)
*/
public void notationDecl(String arg0, String arg1, String arg2) throws SAXException {
dtdHandler.notationDecl(arg0, arg1, arg2);
}
/**
* Delegates to the wrapped DTDHandler's implementation of the method
*
* @param arg0
* @param arg1
* @param arg2
* @param arg3
* @throws SAXException
* @see org.xml.sax.DTDHandler#unparsedEntityDecl(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
*/
public void unparsedEntityDecl(String arg0, String arg1, String arg2, String arg3) throws SAXException {
dtdHandler.unparsedEntityDecl(arg0, arg1, arg2, arg3);
}
// ================ EntityResolver delegate ===================
/**
* Delegates to the wrapped EntityResolver's implementation of the method
*
* @param publicId
* @param systemId
* @return
* @throws SAXException
* @throws IOException
* @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, java.lang.String)
*/
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
return entityResolver.resolveEntity(publicId, systemId);
}
// ================ ErrorHandler delegates ===================
/**
* Delegates to the wrapped ErrorHandler's implementation of the method
*
* @param exception
* @throws SAXException
* @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
*/
public void error(SAXParseException exception) throws SAXException {
errorHandler.error(exception);
}
/**
* Delegates to the wrapped ErrorHandler's implementation of the method
*
* @param exception
* @throws SAXException
* @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
*/
public void fatalError(SAXParseException exception) throws SAXException {
errorHandler.fatalError(exception);
}
/**
* Delegates to the wrapped ErrorHandler's implementation of the method
*
* @param exception
* @throws SAXException
* @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
*/
public void warning(SAXParseException exception) throws SAXException {
errorHandler.warning(exception);
}
}