mirror of
https://github.com/jezhiggins/arabica
synced 2024-12-28 22:23:21 +01:00
516 lines
15 KiB
C++
516 lines
15 KiB
C++
#ifndef ARABICA_XML_FILTER_IMPL_H
|
|
#define ARABICA_XML_FILTER_IMPL_H
|
|
|
|
// XMLFilter.h
|
|
// $Id$
|
|
|
|
#include <SAX/ArabicaConfig.h>
|
|
#include <string>
|
|
#include <SAX/XMLFilter.h>
|
|
#include <SAX/helpers/DefaultHandler.h>
|
|
#include <SAX/SAXNotRecognizedException.h>
|
|
#include <Utils/StringAdaptor.h>
|
|
|
|
namespace SAX
|
|
{
|
|
|
|
/**
|
|
* Base class for deriving an XML filter.
|
|
*
|
|
* <p>This class is designed to sit between an {@link basic_XMLReader
|
|
* XMLReader} and the client application's event handlers. By default, it
|
|
* does nothing but pass requests up to the reader and events
|
|
* on to the handlers unmodified, but subclasses can override
|
|
* specific methods to modify the event stream or the configuration
|
|
* requests as they pass through.</p>
|
|
*
|
|
* @since SAX 2.0
|
|
* @author Jez Higgins,
|
|
* <a href="mailto:jez@jezuk.co.uk">jez@jezuk.co.uk</a>
|
|
* @version 2.0
|
|
* @see basic_XMLFilter
|
|
* @see basic_XMLReader
|
|
* @see basic_EntityResolver
|
|
* @see basic_DTDHandler
|
|
* @see basic_ContentHandler
|
|
* @see basic_ErrorHandler
|
|
*/
|
|
template<class string_type, class string_adaptor_type = Arabica::default_string_adaptor<string_type> >
|
|
class basic_XMLFilterImpl : public basic_XMLFilter<string_type>,
|
|
public basic_EntityResolver<string_type>,
|
|
public basic_DTDHandler<string_type>,
|
|
public basic_ContentHandler<string_type>,
|
|
public basic_ErrorHandler<string_type>
|
|
{
|
|
public:
|
|
typedef string_type stringT;
|
|
typedef string_adaptor_type string_adaptorT;
|
|
typedef basic_XMLReader<stringT> XMLReaderT;
|
|
typedef basic_EntityResolver<stringT> EntityResolverT;
|
|
typedef basic_DTDHandler<stringT> DTDHandlerT;
|
|
typedef basic_ContentHandler<stringT> ContentHandlerT;
|
|
typedef basic_InputSource<stringT> InputSourceT;
|
|
typedef basic_Locator<stringT> LocatorT;
|
|
typedef basic_ErrorHandler<stringT> ErrorHandlerT;
|
|
typedef typename basic_ErrorHandler<stringT>::SAXParseExceptionT SAXParseExceptionT;
|
|
|
|
|
|
basic_XMLFilterImpl() :
|
|
parent_(0)
|
|
{
|
|
setDefaults();
|
|
} // basic_XMLFilterImpl
|
|
basic_XMLFilterImpl(XMLReaderT& parent) :
|
|
parent_(&parent)
|
|
{
|
|
setDefaults();
|
|
} // basic_XMLFilterImpl
|
|
|
|
virtual ~basic_XMLFilterImpl() { }
|
|
|
|
/////////////////////////////////////////////////
|
|
// XMLFilter implementation
|
|
/**
|
|
* Set the parent reader.
|
|
*
|
|
* <p>This is the {@link basic_XMLReader XMLReader} from which
|
|
* this filter will obtain its events and to which it will pass its
|
|
* configuration requests. The parent may itself be another filter.</p>
|
|
*
|
|
* <p>If there is no parent reader set, any attempt to parse
|
|
* or to set or get a feature or property will fail.</p>
|
|
*
|
|
* @param parent The parent XML reader.
|
|
* @see #getParent
|
|
*/
|
|
virtual void setParent(XMLReaderT& parent) { parent_ = &parent; }
|
|
/**
|
|
* Get the parent reader.
|
|
*
|
|
* @return The parent XML reader, or null if none is set.
|
|
* @see #setParent
|
|
*/
|
|
virtual XMLReaderT* getParent() const { return parent_; }
|
|
|
|
/////////////////////////////////////////////////
|
|
// XMLReader implementation
|
|
/**
|
|
* Set the state of a feature.
|
|
*
|
|
* <p>This will always fail if the parent is null.</p>
|
|
*
|
|
* @param name The feature name.
|
|
* @param value The requested feature value.
|
|
* @exception SAXNotRecognizedException When the
|
|
* XMLReader does not recognize the feature name.
|
|
* @exception SAXNotSupportedException When the
|
|
* XMLReader recognizes the feature name but
|
|
* cannot set the requested value.
|
|
* @see basic_XMLReader#setFeature
|
|
*/
|
|
virtual void setFeature(const stringT& name, bool value)
|
|
{
|
|
if(!parent_)
|
|
{
|
|
stringT ex = string_adaptorT::construct_from_utf8("Feature: ");
|
|
string_adaptorT::append(ex, name);
|
|
throw SAXNotRecognizedException(string_adaptorT::asStdString(ex));
|
|
} // if ...
|
|
|
|
parent_->setFeature(name, value);
|
|
} // setFeature
|
|
/**
|
|
* Look up the state of a feature.
|
|
*
|
|
* <p>This will always fail if the parent is null.</p>
|
|
*
|
|
* @param name The feature name.
|
|
* @return The current state of the feature.
|
|
* @exception SAXNotRecognizedException When the
|
|
* XMLReader does not recognize the feature name.
|
|
* @exception SAXNotSupportedException When the
|
|
* XMLReader recognizes the feature name but
|
|
* cannot determine its state at this time.
|
|
* @see basic_XMLReader#getFeature
|
|
*/
|
|
virtual bool getFeature(const stringT& name) const
|
|
{
|
|
if(!parent_)
|
|
{
|
|
stringT ex = string_adaptorT::construct_from_utf8("Feature: ");
|
|
string_adaptorT::append(ex, name);
|
|
throw SAXNotRecognizedException(string_adaptorT::asStdString(ex));
|
|
} // if ...
|
|
|
|
return parent_->getFeature(name);
|
|
} // setFeature
|
|
|
|
/**
|
|
* Set the entity resolver.
|
|
*
|
|
* @param resolver The new entity resolver.
|
|
* @see basic_XMLReader#setEntityResolver
|
|
*/
|
|
virtual void setEntityResolver(EntityResolverT& resolver) { entityResolver_ = &resolver; }
|
|
/**
|
|
* Get the current entity resolver.
|
|
*
|
|
* @return The current entity resolver, or null if none was set.
|
|
* @see basic_XMLReader#getEntityResolver
|
|
*/
|
|
virtual EntityResolverT* getEntityResolver() const { return entityResolver_ ; }
|
|
/**
|
|
* Set the DTD event handler.
|
|
*
|
|
* @param handler The new DTD handler.
|
|
* @see basic_XMLReader#setDTDHandler
|
|
*/
|
|
virtual void setDTDHandler(DTDHandlerT& handler) { dtdHandler_ = &handler; }
|
|
/**
|
|
* Get the current DTD event handler.
|
|
*
|
|
* @return The current DTD handler, or null if none was set.
|
|
* @see basic_XMLReader#getDTDHandler
|
|
*/
|
|
virtual DTDHandlerT* getDTDHandler() const { return dtdHandler_; }
|
|
/**
|
|
* Set the content event handler.
|
|
*
|
|
* @param handler The new content handler.
|
|
* @see basic_XMLReader#setContentHandler
|
|
*/
|
|
virtual void setContentHandler(ContentHandlerT& handler) { contentHandler_ = &handler; }
|
|
/**
|
|
* Get the content event handler.
|
|
*
|
|
* @return The current content handler, or null if none was set.
|
|
* @see basic_XMLReader#getContentHandler
|
|
*/
|
|
virtual ContentHandlerT* getContentHandler() const { return contentHandler_; }
|
|
/**
|
|
* Set the error event handler.
|
|
*
|
|
* @param handler The new error handler.
|
|
* @see basic_XMLReader#setErrorHandler
|
|
*/
|
|
virtual void setErrorHandler(ErrorHandlerT& handler) { errorHandler_ = &handler; }
|
|
/**
|
|
* Get the current error event handler.
|
|
*
|
|
* @return The current error handler, or null if none was set.
|
|
* @see basic_XMLReader#getErrorHandler
|
|
*/
|
|
virtual ErrorHandlerT* getErrorHandler() const { return errorHandler_; }
|
|
|
|
/**
|
|
* Parse a document.
|
|
*
|
|
* @param input The input source for the document entity.
|
|
* @see basic_XMLReader#parse(basic_InputSource)
|
|
*/
|
|
virtual void parse(InputSourceT& input)
|
|
{
|
|
setupParse();
|
|
parent_->parse(input);
|
|
} // parse
|
|
|
|
virtual std::auto_ptr<typename XMLReaderT::PropertyBase> doGetProperty(const stringT& name)
|
|
{
|
|
if(parent_)
|
|
return parent_->doGetProperty(name);
|
|
|
|
stringT ex = string_adaptorT::construct_from_utf8("Property: ");
|
|
string_adaptorT::append(ex, name);
|
|
throw SAXNotRecognizedException(string_adaptorT::asStdString(ex));
|
|
} // doGetProperty
|
|
|
|
virtual void doSetProperty(const stringT& name, typename std::auto_ptr<typename XMLReaderT::PropertyBase> value)
|
|
{
|
|
if(parent_)
|
|
{
|
|
parent_->doSetProperty(name, value);
|
|
return;
|
|
} // if(parent_)
|
|
|
|
stringT ex = string_adaptorT::construct_from_utf8("Property: ");
|
|
string_adaptorT::append(ex, name);
|
|
throw SAXNotRecognizedException(string_adaptorT::asStdString(ex));
|
|
} // doSetProperty
|
|
|
|
public:
|
|
//////////////////////////////////////////////////
|
|
// EntityResolver
|
|
/**
|
|
* Filter an external entity resolution.
|
|
*
|
|
* @param publicId The entity's public identifier, or an empty string.
|
|
* @param systemId The entity's system identifier.
|
|
* @return A new InputSource or a default-constructed
|
|
* <code>InputSourceT</code> for the default.
|
|
* @see basic_EntityResolver#resolveEntity
|
|
*/
|
|
virtual InputSourceT resolveEntity(const stringT& publicId, const stringT& systemId)
|
|
{
|
|
if(entityResolver_)
|
|
return entityResolver_->resolveEntity(publicId, systemId);
|
|
return InputSourceT();
|
|
} // resolveEntity
|
|
|
|
//////////////////////////////////////////////////
|
|
// DTDHandler
|
|
/**
|
|
* Filter a notation declaration event.
|
|
*
|
|
* @param name The notation name.
|
|
* @param publicId The notation's public identifier, or an empty string.
|
|
* @param systemId The notation's system identifier, or an empty string.
|
|
* @see basic_DTDHandler#notationDecl
|
|
*/
|
|
virtual void notationDecl(const stringT& name,
|
|
const stringT& publicId,
|
|
const stringT& systemId)
|
|
{
|
|
if(dtdHandler_)
|
|
dtdHandler_->notationDecl(name, publicId, systemId);
|
|
} // notationDecl
|
|
|
|
/**
|
|
* Filter an unparsed entity declaration event.
|
|
*
|
|
* @param name The entity name.
|
|
* @param publicId The entity's public identifier, or an empty string.
|
|
* @param systemId The entity's system identifier, or an empty string.
|
|
* @param notationName The name of the associated notation.
|
|
* @see basic_DTDHandler#unparsedEntityDecl
|
|
*/
|
|
virtual void unparsedEntityDecl(const stringT& name,
|
|
const stringT& publicId,
|
|
const stringT& systemId,
|
|
const stringT& notationName)
|
|
{
|
|
if(dtdHandler_)
|
|
dtdHandler_->unparsedEntityDecl(name, publicId, systemId, notationName);
|
|
} // unparsedEntityDecl
|
|
|
|
//////////////////////////////////////////////////
|
|
// ContentHandler
|
|
/**
|
|
* Filter a new document locator event.
|
|
*
|
|
* @param locator The document locator.
|
|
* @see basic_ContentHandler#setDocumentLocator
|
|
*/
|
|
virtual void setDocumentLocator(const LocatorT& locator)
|
|
{
|
|
locator_ = &locator;
|
|
if(contentHandler_)
|
|
contentHandler_->setDocumentLocator(locator);
|
|
} // setDocumentLocator
|
|
|
|
/**
|
|
* Filter a start document event.
|
|
*
|
|
* @see basic_ContentHandler#startDocument
|
|
*/
|
|
virtual void startDocument()
|
|
{
|
|
if(contentHandler_)
|
|
contentHandler_->startDocument();
|
|
} // startDocument
|
|
|
|
/**
|
|
* Filter an end document event.
|
|
*
|
|
* @see basic_ContentHandler#endDocument
|
|
*/
|
|
virtual void endDocument()
|
|
{
|
|
if(contentHandler_)
|
|
contentHandler_->endDocument();
|
|
} // endDocument
|
|
|
|
/**
|
|
* Filter a start Namespace prefix mapping event.
|
|
*
|
|
* @param prefix The Namespace prefix.
|
|
* @param uri The Namespace URI.
|
|
* @see basic_ContentHandler#startPrefixMapping
|
|
*/
|
|
virtual void startPrefixMapping(const stringT& prefix, const stringT& uri)
|
|
{
|
|
if(contentHandler_)
|
|
contentHandler_->startPrefixMapping(prefix, uri);
|
|
} // startPrefixMapping
|
|
|
|
/**
|
|
* Filter an end Namespace prefix mapping event.
|
|
*
|
|
* @param prefix The Namespace prefix.
|
|
* @see basic_ContentHandler#endPrefixMapping
|
|
*/
|
|
virtual void endPrefixMapping(const stringT& prefix)
|
|
{
|
|
if(contentHandler_)
|
|
contentHandler_->endPrefixMapping(prefix);
|
|
} // endPrefixMapping
|
|
|
|
/**
|
|
* Filter a start element event.
|
|
*
|
|
* @param namespaceURI The element's Namespace URI, or the empty string.
|
|
* @param localName The element's local name, or the empty string.
|
|
* @param qName The element's qualified (prefixed) name, or the empty
|
|
* string.
|
|
* @param atts The element's attributes.
|
|
* @see basic_ContentHandler#startElement
|
|
*/
|
|
virtual void startElement(const stringT& namespaceURI, const stringT& localName,
|
|
const stringT& qName, const typename ContentHandlerT::AttributesT& atts)
|
|
{
|
|
if(contentHandler_)
|
|
contentHandler_->startElement(namespaceURI, localName, qName, atts);
|
|
} // startElement
|
|
|
|
/**
|
|
* Filter an end element event.
|
|
*
|
|
* @param namespaceURI The element's Namespace URI, or the empty string.
|
|
* @param localName The element's local name, or the empty string.
|
|
* @param qName The element's qualified (prefixed) name, or the empty
|
|
* string.
|
|
* @see basic_ContentHandler#endElement
|
|
*/
|
|
virtual void endElement(const stringT& namespaceURI, const stringT& localName,
|
|
const stringT& qName)
|
|
{
|
|
if(contentHandler_)
|
|
contentHandler_->endElement(namespaceURI, localName, qName);
|
|
} // endElement
|
|
|
|
/**
|
|
* Filter a character data event.
|
|
*
|
|
* @param ch The characters.
|
|
* @see basic_ContentHandler#characters
|
|
*/
|
|
virtual void characters(const stringT& ch)
|
|
{
|
|
if(contentHandler_)
|
|
contentHandler_->characters(ch);
|
|
} // characters
|
|
|
|
/**
|
|
* Filter an ignorable whitespace event.
|
|
*
|
|
* @param ch The whitespace
|
|
* @see basic_ContentHandler#ignorableWhitespace
|
|
*/
|
|
virtual void ignorableWhitespace(const stringT& ch)
|
|
{
|
|
if(contentHandler_)
|
|
contentHandler_->ignorableWhitespace(ch);
|
|
} // ignorableWhitespace
|
|
|
|
/**
|
|
* Filter a processing instruction event.
|
|
*
|
|
* @param target The processing instruction target.
|
|
* @param data The text following the target.
|
|
* @see basic_ContentHandler#processingInstruction
|
|
*/
|
|
virtual void processingInstruction(const stringT& target, const stringT& data)
|
|
{
|
|
if(contentHandler_)
|
|
contentHandler_->processingInstruction(target, data);
|
|
} // processingInstruction
|
|
|
|
/**
|
|
* Filter a skipped entity event.
|
|
*
|
|
* @param name The name of the skipped entity.
|
|
* @see basic_ContentHandler#skippedEntity
|
|
*/
|
|
virtual void skippedEntity(const stringT& name)
|
|
{
|
|
if(contentHandler_)
|
|
contentHandler_->skippedEntity(name);
|
|
} // skippedEntity
|
|
|
|
//////////////////////////////////////////////////
|
|
// ErrorHandler
|
|
/**
|
|
* Filter a warning event.
|
|
*
|
|
* @param exception The warning as an exception.
|
|
* @see basic_ErrorHandler#warning
|
|
*/
|
|
virtual void warning(const SAXParseExceptionT& exception)
|
|
{
|
|
if(errorHandler_)
|
|
errorHandler_->warning(exception);
|
|
} // warning
|
|
|
|
/**
|
|
* Filter an error event.
|
|
*
|
|
* @param exception The error as an exception.
|
|
* @see basic_ErrorHandler#error
|
|
*/
|
|
virtual void error(const SAXParseExceptionT& exception)
|
|
{
|
|
if(errorHandler_)
|
|
errorHandler_->error(exception);
|
|
} // error
|
|
|
|
/**
|
|
* Filter a fatal error event.
|
|
*
|
|
* @param exception The error as an exception.
|
|
* @see basic_ErrorHandler#fatalError
|
|
*/
|
|
virtual void fatalError(const SAXParseExceptionT& exception)
|
|
{
|
|
if(errorHandler_)
|
|
errorHandler_->fatalError(exception);
|
|
} // fatalError
|
|
|
|
|
|
private:
|
|
void setDefaults()
|
|
{
|
|
setEntityResolver(defaultHandler_);
|
|
setDTDHandler(defaultHandler_);
|
|
setContentHandler(defaultHandler_);
|
|
setErrorHandler(defaultHandler_);
|
|
} // setDefaults
|
|
|
|
void setupParse()
|
|
{
|
|
parent_->setEntityResolver(*this);
|
|
parent_->setDTDHandler(*this);
|
|
parent_->setContentHandler(*this);
|
|
parent_->setErrorHandler(*this);
|
|
} // setupParse
|
|
|
|
basic_XMLFilterImpl(const basic_XMLFilterImpl&);
|
|
basic_XMLFilterImpl& operator=(const basic_XMLFilterImpl&); // no impl
|
|
bool operator==(const basic_XMLFilterImpl&); // no impl
|
|
|
|
XMLReaderT* parent_;
|
|
EntityResolverT* entityResolver_;
|
|
DTDHandlerT* dtdHandler_;
|
|
ContentHandlerT* contentHandler_;
|
|
ErrorHandlerT* errorHandler_;
|
|
const LocatorT* locator_;
|
|
basic_DefaultHandler<stringT> defaultHandler_;
|
|
}; // class basic_XMLFilter
|
|
|
|
typedef basic_XMLFilterImpl<std::string> XMLFilterImpl;
|
|
#ifndef ARABICA_NO_WCHAR_T
|
|
typedef basic_XMLFilterImpl<std::wstring> wXMLFilterImpl;
|
|
#endif
|
|
|
|
}; // namespace SAX
|
|
|
|
#endif
|
|
// end of file
|