gnu.xml.pipeline

Class EventFilter

Implemented Interfaces:
ContentHandler, DeclHandler, DTDHandler, EventConsumer, LexicalHandler
Known Direct Subclasses:
LinkFilter, NSFilter, ValidationConsumer, WellFormednessFilter, XIncludeFilter, XsltFilter

public class EventFilter
extends Object
implements EventConsumer, ContentHandler, DTDHandler, LexicalHandler, DeclHandler

A customizable event consumer, used to assemble various kinds of filters using SAX handlers and an optional second consumer. It can be constructed in two ways:

Additionally, SAX handlers may be assigned, which completely replace the "upstream" view (through EventConsumer) of handlers, initially null or the "next" consumer provided to the constructor. To make it easier to build specialized filter classes, this class implements all the standard SAX consumer handlers, and those implementations delegate "downstream" to the consumer accessed by getNext().

The simplest way to create a custom a filter class is to create a subclass which overrides one or more handler interface methods. The constructor for that subclass then registers itself as a handler for those interfaces using a call such as setContentHandler(this), so the "upstream" view of event delivery is modified from the state established in the base class constructor. That way, the overridden methods intercept those event callbacks as they go "downstream", and all other event callbacks will pass events to any next consumer. Overridden methods may invoke superclass methods (perhaps after modifying parameters) if they wish to delegate such calls. Such subclasses should use getErrorHandler() to report errors using the common error reporting mechanism.

Another important technique is to construct a filter consisting of only a few specific types of handler. For example, one could easily prune out lexical events or various declarations by providing handlers which don't pass those events downstream, or by providing null handlers.


This may be viewed as the consumer oriented analogue of the SAX2 XMLFilterImpl class. Key differences include:

The chainTo() convenience routine supports chaining to an XMLFilterImpl, in its role as a limited functionality event consumer. Its event producer role (XMLFilter) is ignored.


The bind() routine may be used associate event pipelines with any kind of XMLReader that will produce the events. Such pipelines don't necessarily need to have any members which are implemented using this class. That routine has some intelligence which supports automatic changes to parser feature flags, letting event piplines become largely independent of the particular feature sets of parsers.

Field Summary

static String
DECL_HANDLER
SAX2 property identifier for DeclHandler events
static String
FEATURE_URI
SAX2 URI prefix for standard feature flags.
static String
LEXICAL_HANDLER
SAX2 property identifier for LexicalHandler events
static String
PROPERTY_URI
SAX2 URI prefix for standard properties (mostly for handlers).

Constructor Summary

EventFilter()
Initializes all handlers to null.
EventFilter(EventConsumer consumer)
Handlers that are not otherwise set will default to those from the specified consumer, making it easy to pass events through.

Method Summary

void
attributeDecl(String eName, String aName, String type, String mode, String value)
SAX2: passes this callback to the next consumer, if any
static void
bind(XMLReader producer, EventConsumer consumer)
Binds the standard SAX2 handlers from the specified consumer pipeline to the specified producer.
void
chainTo(XMLFilterImpl next)
Treats the XMLFilterImpl as a limited functionality event consumer, by arranging to deliver events to it; this lets such classes be "wrapped" as pipeline stages.
void
characters(ch[] , int start, int length)
SAX2: passes this callback to the next consumer, if any
void
comment(ch[] , int start, int length)
SAX2: passes this callback to the next consumer, if any
void
elementDecl(String name, String model)
SAX2: passes this callback to the next consumer, if any
void
endCDATA()
SAX2: passes this callback to the next consumer, if any
void
endDTD()
SAX2: passes this callback to the next consumer, if any
void
endDocument()
SAX2: passes this callback to the next consumer, if any
void
endElement(String uri, String localName, String qName)
SAX2: passes this callback to the next consumer, if any
void
endEntity(String name)
SAX2: passes this callback to the next consumer, if any.
void
endPrefixMapping(String prefix)
SAX2: passes this callback to the next consumer, if any
void
externalEntityDecl(String name, String publicId, String systemId)
SAX2: passes this callback to the next consumer, if any
ContentHandler
getContentHandler()
Returns the content handler being used.
DTDHandler
getDTDHandler()
Returns the dtd handler being used.
Locator
getDocumentLocator()
Returns any locator provided to the next consumer, if this class (or a subclass) is handling ContentHandler events.
ErrorHandler
getErrorHandler()
Returns the error handler assigned this filter stage, or null if no such assigment has been made.
EventConsumer
getNext()
Returns the next event consumer in sequence; or null if there is no such handler.
Object
getProperty(String id)
Retrieves a property of unknown intent (usually a handler)
void
ignorableWhitespace(ch[] , int start, int length)
SAX2: passes this callback to the next consumer, if any
void
internalEntityDecl(String name, String value)
SAX2: passes this callback to the next consumer, if any
void
notationDecl(String name, String publicId, String systemId)
SAX1: passes this callback to the next consumer, if any
void
processingInstruction(String target, String data)
SAX2: passes this callback to the next consumer, if any
void
setContentHandler(ContentHandler h)
Assigns the content handler to use; a null handler indicates that these events will not be forwarded.
void
setDTDHandler(DTDHandler h)
Assigns the DTD handler to use; a null handler indicates that these events will not be forwarded.
void
setDocumentLocator(Locator locator)
SAX2: passes this callback to the next consumer, if any
void
setErrorHandler(ErrorHandler handler)
Records the error handler that should be used by this stage, and passes it "downstream" to any subsequent stage.
void
setProperty(String id, Object o)
Stores the property, normally a handler; a null handler indicates that these events will not be forwarded.
void
skippedEntity(String name)
SAX2: passes this callback to the next consumer, if any
void
startCDATA()
SAX2: passes this callback to the next consumer, if any
void
startDTD(String name, String publicId, String systemId)
SAX2: passes this callback to the next consumer, if any
void
startDocument()
SAX2: passes this callback to the next consumer, if any
void
startElement(String uri, String localName, String qName, Attributes atts)
SAX2: passes this callback to the next consumer, if any
void
startEntity(String name)
SAX2: passes this callback to the next consumer, if any.
void
startPrefixMapping(String prefix, String uri)
SAX2: passes this callback to the next consumer, if any
void
unparsedEntityDecl(String name, String publicId, String systemId, String notationName)
SAX1: passes this callback to the next consumer, if any

Methods inherited from class java.lang.Object

clone, equals, extends Object> getClass, finalize, hashCode, notify, notifyAll, toString, wait, wait, wait

Field Details

DECL_HANDLER

public static final String DECL_HANDLER
SAX2 property identifier for DeclHandler events
Field Value:
"http://xml.org/sax/properties/declaration-handler"

FEATURE_URI

public static final String FEATURE_URI
SAX2 URI prefix for standard feature flags.
Field Value:
"http://xml.org/sax/features/"

LEXICAL_HANDLER

public static final String LEXICAL_HANDLER
SAX2 property identifier for LexicalHandler events
Field Value:
"http://xml.org/sax/properties/lexical-handler"

PROPERTY_URI

public static final String PROPERTY_URI
SAX2 URI prefix for standard properties (mostly for handlers).
Field Value:
"http://xml.org/sax/properties/"

Constructor Details

EventFilter

public EventFilter()
Initializes all handlers to null.

EventFilter

public EventFilter(EventConsumer consumer)
Handlers that are not otherwise set will default to those from the specified consumer, making it easy to pass events through. If the consumer is null, all handlers are initialzed to null.

Method Details

attributeDecl

public void attributeDecl(String eName,
                          String aName,
                          String type,
                          String mode,
                          String value)
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
attributeDecl in interface DeclHandler

bind

public static void bind(XMLReader producer,
                        EventConsumer consumer)
Binds the standard SAX2 handlers from the specified consumer pipeline to the specified producer. These handlers include the core ContentHandler and DTDHandler, plus the extension DeclHandler and LexicalHandler. Any additional application-specific handlers need to be bound separately. The ErrorHandler is handled differently: the producer's error handler is passed through to the consumer pipeline. The producer is told to include namespace prefix information if it can, since many pipeline stages need that Infoset information to work well.

At the head of the pipeline, certain standard event filters are recognized and handled specially. This facilitates construction of processing pipelines that work regardless of the capabilities of the XMLReader implementation in use; for example, it permits validating output of a DomParser.

  • NSFilter will be removed if the producer can be told not to discard namespace data, using the "namespace-prefixes" feature flag.
  • ValidationConsumer will be removed if the producer can be told to validate, using the "validation" feature flag.
  • WellFormednessFilter is always removed, on the grounds that no XMLReader is permitted to producee malformed event streams and this would just be processing overhead.
  • XIncludeFilter stops the special handling, except that it's told about the "namespace-prefixes" feature of the event producer so that the event stream is internally consistent.
  • The first consumer which is not one of those classes stops such special handling. This means that if you want to force one of those filters to be used, you could just precede it with an instance of EventFilter configured as a pass-through. You might need to do that if you are using an NSFilter subclass to fix names found in attributes or character data.

Other than that, this method works with any kind of event consumer, not just event filters. Note that in all cases, the standard handlers are assigned; any previous handler assignments for the handler will be overridden.

Parameters:
producer - will deliver events to the specified consumer
consumer - pipeline supplying event handlers to be associated with the producer (may not be null)

chainTo

public void chainTo(XMLFilterImpl next)
Treats the XMLFilterImpl as a limited functionality event consumer, by arranging to deliver events to it; this lets such classes be "wrapped" as pipeline stages.

Upstream Event Setup: If no handlers have been assigned to this EventFilter, then the handlers from specified XMLFilterImpl are returned from this EventConsumer: the XMLFilterImpl is just "wrapped". Otherwise the specified handlers will be returned.

Downstream Event Setup: Subclasses may chain event delivery to the specified XMLFilterImpl by invoking the appropiate superclass methods, as if their constructor passed a "next" EventConsumer to the constructor for this class. If this EventFilter has an ErrorHandler, it is assigned as the error handler for the XMLFilterImpl, just as would be done for a next stage implementing EventConsumer.

Parameters:
next - the next downstream component of the pipeline.
Throws:
IllegalStateException - if the "next" consumer has already been set through the constructor.

characters

public void characters(ch[] ,
                       int start,
                       int length)
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
characters in interface ContentHandler

comment

public void comment(ch[] ,
                    int start,
                    int length)
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
comment in interface LexicalHandler

elementDecl

public void elementDecl(String name,
                        String model)
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
elementDecl in interface DeclHandler

endCDATA

public void endCDATA()
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
endCDATA in interface LexicalHandler

endDTD

public void endDTD()
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
endDTD in interface LexicalHandler

endDocument

public void endDocument()
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
endDocument in interface ContentHandler

endElement

public void endElement(String uri,
                       String localName,
                       String qName)
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
endElement in interface ContentHandler

endEntity

public void endEntity(String name)
            throws SAXException
SAX2: passes this callback to the next consumer, if any.
Specified by:
endEntity in interface LexicalHandler

endPrefixMapping

public void endPrefixMapping(String prefix)
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
endPrefixMapping in interface ContentHandler

externalEntityDecl

public void externalEntityDecl(String name,
                               String publicId,
                               String systemId)
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
externalEntityDecl in interface DeclHandler

getContentHandler

public final ContentHandler getContentHandler()
Returns the content handler being used.
Specified by:
getContentHandler in interface EventConsumer

getDTDHandler

public final DTDHandler getDTDHandler()
Returns the dtd handler being used.
Specified by:
getDTDHandler in interface EventConsumer

getDocumentLocator

public Locator getDocumentLocator()
Returns any locator provided to the next consumer, if this class (or a subclass) is handling ContentHandler events.

getErrorHandler

public final ErrorHandler getErrorHandler()
Returns the error handler assigned this filter stage, or null if no such assigment has been made.

getNext

public final EventConsumer getNext()
Returns the next event consumer in sequence; or null if there is no such handler.

getProperty

public final Object getProperty(String id)
            throws SAXNotRecognizedException
Retrieves a property of unknown intent (usually a handler)
Specified by:
getProperty in interface EventConsumer

ignorableWhitespace

public void ignorableWhitespace(ch[] ,
                                int start,
                                int length)
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
ignorableWhitespace in interface ContentHandler

internalEntityDecl

public void internalEntityDecl(String name,
                               String value)
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
internalEntityDecl in interface DeclHandler

notationDecl

public void notationDecl(String name,
                         String publicId,
                         String systemId)
            throws SAXException
SAX1: passes this callback to the next consumer, if any
Specified by:
notationDecl in interface DTDHandler

processingInstruction

public void processingInstruction(String target,
                                  String data)
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
processingInstruction in interface ContentHandler

setContentHandler

public final void setContentHandler(ContentHandler h)
Assigns the content handler to use; a null handler indicates that these events will not be forwarded. This overrides the previous settting for this handler, which was probably pointed to the next consumer by the base class constructor.

setDTDHandler

public final void setDTDHandler(DTDHandler h)
Assigns the DTD handler to use; a null handler indicates that these events will not be forwarded. This overrides the previous settting for this handler, which was probably pointed to the next consumer by the base class constructor.

setDocumentLocator

public void setDocumentLocator(Locator locator)
SAX2: passes this callback to the next consumer, if any
Specified by:
setDocumentLocator in interface ContentHandler

setErrorHandler

public final void setErrorHandler(ErrorHandler handler)
Records the error handler that should be used by this stage, and passes it "downstream" to any subsequent stage.
Specified by:
setErrorHandler in interface EventConsumer

setProperty

public final void setProperty(String id,
                              Object o)
            throws SAXNotRecognizedException,
                   SAXNotSupportedException
Stores the property, normally a handler; a null handler indicates that these events will not be forwarded. This overrides the previous handler settting, which was probably pointed to the next consumer by the base class constructor.

skippedEntity

public void skippedEntity(String name)
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
skippedEntity in interface ContentHandler

startCDATA

public void startCDATA()
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
startCDATA in interface LexicalHandler

startDTD

public void startDTD(String name,
                     String publicId,
                     String systemId)
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
startDTD in interface LexicalHandler

startDocument

public void startDocument()
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
startDocument in interface ContentHandler

startElement

public void startElement(String uri,
                         String localName,
                         String qName,
                         Attributes atts)
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
startElement in interface ContentHandler

startEntity

public void startEntity(String name)
            throws SAXException
SAX2: passes this callback to the next consumer, if any.
Specified by:
startEntity in interface LexicalHandler

startPrefixMapping

public void startPrefixMapping(String prefix,
                               String uri)
            throws SAXException
SAX2: passes this callback to the next consumer, if any
Specified by:
startPrefixMapping in interface ContentHandler

unparsedEntityDecl

public void unparsedEntityDecl(String name,
                               String publicId,
                               String systemId,
                               String notationName)
            throws SAXException
SAX1: passes this callback to the next consumer, if any
Specified by:
unparsedEntityDecl in interface DTDHandler

EventFilter.java -- Copyright (C) 1999,2000,2001 Free Software Foundation, Inc. This file is part of GNU Classpath. GNU Classpath 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 2, or (at your option) any later version. GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU General Public License cover the whole combination. As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version.