aboutsummaryrefslogtreecommitdiff
path: root/libjava/gnu/xml/pipeline/EventFilter.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/gnu/xml/pipeline/EventFilter.java')
-rw-r--r--libjava/gnu/xml/pipeline/EventFilter.java809
1 files changed, 809 insertions, 0 deletions
diff --git a/libjava/gnu/xml/pipeline/EventFilter.java b/libjava/gnu/xml/pipeline/EventFilter.java
new file mode 100644
index 0000000..8587808
--- /dev/null
+++ b/libjava/gnu/xml/pipeline/EventFilter.java
@@ -0,0 +1,809 @@
+/* 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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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. */
+
+package gnu.xml.pipeline;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.xml.sax.*;
+import org.xml.sax.ext.*;
+import org.xml.sax.helpers.XMLFilterImpl;
+
+import gnu.xml.aelfred2.ContentHandler2;
+
+/**
+ * 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: <ul>
+ *
+ * <li> To serve as a passthrough, sending all events to a second consumer.
+ * The second consumer may be identified through {@link #getNext}.
+ *
+ * <li> To serve as a dead end, with all handlers null;
+ * {@link #getNext} returns null.
+ *
+ * </ul>
+ *
+ * <p> Additionally, SAX handlers may be assigned, which completely replace
+ * the "upstream" view (through {@link 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 {@link #getNext}.
+ *
+ * <p> 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 <em>setContentHandler(this)</em>,
+ * 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 {@link #getErrorHandler} to report errors using the
+ * common error reporting mechanism.
+ *
+ * <p> 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.
+ *
+ * <hr />
+ *
+ * <p> This may be viewed as the consumer oriented analogue of the SAX2
+ * {@link org.xml.sax.helpers.XMLFilterImpl XMLFilterImpl} class.
+ * Key differences include: <ul>
+ *
+ * <li> This fully separates consumer and producer roles: it
+ * does not implement the producer side <em>XMLReader</em> or
+ * <em>EntityResolver</em> interfaces, so it can only be used
+ * in "push" mode (it has no <em>parse()</em> methods).
+ *
+ * <li> "Extension" handlers are fully supported, enabling a
+ * richer set of application requirements.
+ * And it implements {@link EventConsumer}, which groups related
+ * consumer methods together, rather than leaving them separated.
+ *
+ * <li> The chaining which is visible is "downstream" to the next
+ * consumer, not "upstream" to the preceding producer.
+ * It supports "fan-in", where
+ * a consumer can be fed by several producers. (For "fan-out",
+ * see the {@link TeeConsumer} class.)
+ *
+ * <li> Event chaining is set up differently. It is intended to
+ * work "upstream" from terminus towards producer, during filter
+ * construction, as described above.
+ * This is part of an early binding model:
+ * events don't need to pass through stages which ignore them.
+ *
+ * <li> ErrorHandler support is separated, on the grounds that
+ * pipeline stages need to share the same error handling policy.
+ * For the same reason, error handler setup goes "downstream":
+ * when error handlers get set, they are passed to subsequent
+ * consumers.
+ *
+ * </ul>
+ *
+ * <p> The {@link #chainTo chainTo()} convenience routine supports chaining to
+ * an XMLFilterImpl, in its role as a limited functionality event
+ * consumer. Its event producer role ({@link XMLFilter}) is ignored.
+ *
+ * <hr />
+ *
+ * <p> The {@link #bind bind()} routine may be used associate event pipelines
+ * with any kind of {@link 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.
+ *
+ * @author David Brownell
+ */
+public class EventFilter
+ implements EventConsumer, ContentHandler2, DTDHandler,
+ LexicalHandler, DeclHandler
+{
+ // SAX handlers
+ private ContentHandler docHandler, docNext;
+ private DTDHandler dtdHandler, dtdNext;
+ private LexicalHandler lexHandler, lexNext;
+ private DeclHandler declHandler, declNext;
+ // and ideally, one more for the stuff SAX2 doesn't show
+
+ private Locator locator;
+ private EventConsumer next;
+ private ErrorHandler errHandler;
+
+
+ /** SAX2 URI prefix for standard feature flags. */
+ public static final String FEATURE_URI
+ = "http://xml.org/sax/features/";
+ /** SAX2 URI prefix for standard properties (mostly for handlers). */
+ public static final String PROPERTY_URI
+ = "http://xml.org/sax/properties/";
+
+ /** SAX2 property identifier for {@link DeclHandler} events */
+ public static final String DECL_HANDLER
+ = PROPERTY_URI + "declaration-handler";
+ /** SAX2 property identifier for {@link LexicalHandler} events */
+ public static final String LEXICAL_HANDLER
+ = PROPERTY_URI + "lexical-handler";
+
+ //
+ // These class objects will be null if the relevant class isn't linked.
+ // Small configurations (pJava and some kinds of embedded systems) need
+ // to facilitate smaller executables. So "instanceof" is undesirable
+ // when bind() sees if it can remove some stages.
+ //
+ // SECURITY NOTE: assuming all these classes are part of the same sealed
+ // package, there's no problem saving these in the instance of this class
+ // that's associated with "this" class loader. But that wouldn't be true
+ // for classes in another package.
+ //
+ private static boolean loaded;
+ private static Class nsClass;
+ private static Class validClass;
+ private static Class wfClass;
+ private static Class xincClass;
+
+ static ClassLoader getClassLoader ()
+ {
+ Method m = null;
+
+ try {
+ m = Thread.class.getMethod("getContextClassLoader", null);
+ } catch (NoSuchMethodException e) {
+ // Assume that we are running JDK 1.1, use the current ClassLoader
+ return EventFilter.class.getClassLoader();
+ }
+
+ try {
+ return (ClassLoader) m.invoke(Thread.currentThread(), null);
+ } catch (IllegalAccessException e) {
+ // assert(false)
+ throw new UnknownError(e.getMessage());
+ } catch (InvocationTargetException e) {
+ // assert(e.getTargetException() instanceof SecurityException)
+ throw new UnknownError(e.getMessage());
+ }
+ }
+
+ static Class loadClass (ClassLoader classLoader, String className)
+ {
+ try {
+ if (classLoader == null)
+ return Class.forName(className);
+ else
+ return classLoader.loadClass(className);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ static private void loadClasses ()
+ {
+ ClassLoader loader = getClassLoader ();
+
+ nsClass = loadClass (loader, "gnu.xml.pipeline.NSFilter");
+ validClass = loadClass (loader, "gnu.xml.pipeline.ValidationConsumer");
+ wfClass = loadClass (loader, "gnu.xml.pipeline.WellFormednessFilter");
+ xincClass = loadClass (loader, "gnu.xml.pipeline.XIncludeFilter");
+ loaded = true;
+ }
+
+
+ /**
+ * Binds the standard SAX2 handlers from the specified consumer
+ * pipeline to the specified producer. These handlers include the core
+ * {@link ContentHandler} and {@link DTDHandler}, plus the extension
+ * {@link DeclHandler} and {@link LexicalHandler}. Any additional
+ * application-specific handlers need to be bound separately.
+ * The {@link 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.
+ *
+ * <p> 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 {@link gnu.xml.util.DomParser}. <ul>
+ *
+ * <li> {@link NSFilter} will be removed if the producer can be
+ * told not to discard namespace data, using the "namespace-prefixes"
+ * feature flag.
+ *
+ * <li> {@link ValidationConsumer} will be removed if the producer
+ * can be told to validate, using the "validation" feature flag.
+ *
+ * <li> {@link WellFormednessFilter} is always removed, on the
+ * grounds that no XMLReader is permitted to producee malformed
+ * event streams and this would just be processing overhead.
+ *
+ * <li> {@link 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.
+ *
+ * <li> 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 {@link EventFilter} configured as a pass-through.
+ * You might need to do that if you are using an {@link NSFilter}
+ * subclass to fix names found in attributes or character data.
+ *
+ * </ul>
+ *
+ * <p> 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.
+ *
+ * @param producer will deliver events to the specified consumer
+ * @param consumer pipeline supplying event handlers to be associated
+ * with the producer (may not be null)
+ */
+ public static void bind (XMLReader producer, EventConsumer consumer)
+ {
+ Class klass = null;
+ boolean prefixes;
+
+ if (!loaded)
+ loadClasses ();
+
+ // DOM building, printing, layered validation, and other
+ // things don't work well when prefix info is discarded.
+ // Include it by default, whenever possible.
+ try {
+ producer.setFeature (FEATURE_URI + "namespace-prefixes",
+ true);
+ prefixes = true;
+ } catch (SAXException e) {
+ prefixes = false;
+ }
+
+ // NOTE: This loop doesn't use "instanceof", since that
+ // would prevent compiling/linking without those classes
+ // being present.
+ while (consumer != null) {
+ klass = consumer.getClass ();
+
+ // we might have already changed this problematic SAX2 default.
+ if (nsClass != null && nsClass.isAssignableFrom (klass)) {
+ if (!prefixes)
+ break;
+ consumer = ((EventFilter)consumer).getNext ();
+
+ // the parser _might_ do DTD validation by default ...
+ // if not, maybe we can change this setting.
+ } else if (validClass != null
+ && validClass.isAssignableFrom (klass)) {
+ try {
+ producer.setFeature (FEATURE_URI + "validation",
+ true);
+ consumer = ((ValidationConsumer)consumer).getNext ();
+ } catch (SAXException e) {
+ break;
+ }
+
+ // parsers are required not to have such bugs
+ } else if (wfClass != null && wfClass.isAssignableFrom (klass)) {
+ consumer = ((WellFormednessFilter)consumer).getNext ();
+
+ // stop on the first pipeline stage we can't remove
+ } else
+ break;
+
+ if (consumer == null)
+ klass = null;
+ }
+
+ // the actual setting here doesn't matter as much
+ // as that producer and consumer agree
+ if (xincClass != null && klass != null
+ && xincClass.isAssignableFrom (klass))
+ ((XIncludeFilter)consumer).setSavingPrefixes (prefixes);
+
+ // Some SAX parsers can't handle null handlers -- bleech
+ DefaultHandler2 h = new DefaultHandler2 ();
+
+ if (consumer != null && consumer.getContentHandler () != null)
+ producer.setContentHandler (consumer.getContentHandler ());
+ else
+ producer.setContentHandler (h);
+ if (consumer != null && consumer.getDTDHandler () != null)
+ producer.setDTDHandler (consumer.getDTDHandler ());
+ else
+ producer.setDTDHandler (h);
+
+ try {
+ Object dh;
+
+ if (consumer != null)
+ dh = consumer.getProperty (DECL_HANDLER);
+ else
+ dh = null;
+ if (dh == null)
+ dh = h;
+ producer.setProperty (DECL_HANDLER, dh);
+ } catch (Exception e) { /* ignore */ }
+ try {
+ Object lh;
+
+ if (consumer != null)
+ lh = consumer.getProperty (LEXICAL_HANDLER);
+ else
+ lh = null;
+ if (lh == null)
+ lh = h;
+ producer.setProperty (LEXICAL_HANDLER, lh);
+ } catch (Exception e) { /* ignore */ }
+
+ // this binding goes the other way around
+ if (producer.getErrorHandler () == null)
+ producer.setErrorHandler (h);
+ if (consumer != null)
+ consumer.setErrorHandler (producer.getErrorHandler ());
+ }
+
+ /**
+ * Initializes all handlers to null.
+ */
+ // constructor used by PipelineFactory
+ public EventFilter () { }
+
+
+ /**
+ * 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.
+ */
+ // constructor used by PipelineFactory
+ public EventFilter (EventConsumer consumer)
+ {
+ if (consumer == null)
+ return;
+
+ next = consumer;
+
+ // We delegate through the "xxNext" handlers, and
+ // report the "xxHandler" ones on our input side.
+
+ // Normally a subclass would both override handler
+ // methods and register itself as the "xxHandler".
+
+ docHandler = docNext = consumer.getContentHandler ();
+ dtdHandler = dtdNext = consumer.getDTDHandler ();
+ try {
+ declHandler = declNext = (DeclHandler)
+ consumer.getProperty (DECL_HANDLER);
+ } catch (SAXException e) { /* leave value null */ }
+ try {
+ lexHandler = lexNext = (LexicalHandler)
+ consumer.getProperty (LEXICAL_HANDLER);
+ } catch (SAXException e) { /* leave value null */ }
+ }
+
+ /**
+ * 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.
+ *
+ * <p> <em>Upstream Event Setup:</em>
+ * If no handlers have been assigned to this EventFilter, then the
+ * handlers from specified XMLFilterImpl are returned from this
+ * {@link EventConsumer}: the XMLFilterImpl is just "wrapped".
+ * Otherwise the specified handlers will be returned.
+ *
+ * <p> <em>Downstream Event Setup:</em>
+ * 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 {@link EventConsumer}.
+ *
+ * @param next the next downstream component of the pipeline.
+ * @exception IllegalStateException if the "next" consumer has
+ * already been set through the constructor.
+ */
+ public void chainTo (XMLFilterImpl next)
+ {
+ if (this.next != null)
+ throw new IllegalStateException ();
+
+ docNext = next.getContentHandler ();
+ if (docHandler == null)
+ docHandler = docNext;
+ dtdNext = next.getDTDHandler ();
+ if (dtdHandler == null)
+ dtdHandler = dtdNext;
+
+ try {
+ declNext = (DeclHandler) next.getProperty (DECL_HANDLER);
+ if (declHandler == null)
+ declHandler = declNext;
+ } catch (SAXException e) { /* leave value null */ }
+ try {
+ lexNext = (LexicalHandler) next.getProperty (LEXICAL_HANDLER);
+ if (lexHandler == null)
+ lexHandler = lexNext;
+ } catch (SAXException e) { /* leave value null */ }
+
+ if (errHandler != null)
+ next.setErrorHandler (errHandler);
+ }
+
+ /**
+ * Records the error handler that should be used by this stage, and
+ * passes it "downstream" to any subsequent stage.
+ */
+ final public void setErrorHandler (ErrorHandler handler)
+ {
+ errHandler = handler;
+ if (next != null)
+ next.setErrorHandler (handler);
+ }
+
+ /**
+ * Returns the error handler assigned this filter stage, or null
+ * if no such assigment has been made.
+ */
+ final public ErrorHandler getErrorHandler ()
+ {
+ return errHandler;
+ }
+
+
+ /**
+ * Returns the next event consumer in sequence; or null if there
+ * is no such handler.
+ */
+ final public EventConsumer getNext ()
+ { return next; }
+
+
+ /**
+ * 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.
+ */
+ final public void setContentHandler (ContentHandler h)
+ {
+ docHandler = h;
+ }
+
+ /** Returns the content handler being used. */
+ final public ContentHandler getContentHandler ()
+ {
+ return docHandler;
+ }
+
+ /**
+ * 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.
+ */
+ final public void setDTDHandler (DTDHandler h)
+ { dtdHandler = h; }
+
+ /** Returns the dtd handler being used. */
+ final public DTDHandler getDTDHandler ()
+ {
+ return dtdHandler;
+ }
+
+ /**
+ * 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.
+ */
+ final public void setProperty (String id, Object o)
+ throws SAXNotRecognizedException, SAXNotSupportedException
+ {
+ try {
+ Object value = getProperty (id);
+
+ if (value == o)
+ return;
+ if (DECL_HANDLER.equals (id)) {
+ declHandler = (DeclHandler) o;
+ return;
+ }
+ if (LEXICAL_HANDLER.equals (id)) {
+ lexHandler = (LexicalHandler) o;
+ return;
+ }
+ throw new SAXNotSupportedException (id);
+
+ } catch (ClassCastException e) {
+ throw new SAXNotSupportedException (id);
+ }
+ }
+
+ /** Retrieves a property of unknown intent (usually a handler) */
+ final public Object getProperty (String id)
+ throws SAXNotRecognizedException
+ {
+ if (DECL_HANDLER.equals (id))
+ return declHandler;
+ if (LEXICAL_HANDLER.equals (id))
+ return lexHandler;
+
+ throw new SAXNotRecognizedException (id);
+ }
+
+ /**
+ * Returns any locator provided to the next consumer, if this class
+ * (or a subclass) is handling {@link ContentHandler } events.
+ */
+ public Locator getDocumentLocator ()
+ { return locator; }
+
+
+ // CONTENT HANDLER DELEGATIONS
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void setDocumentLocator (Locator locator)
+ {
+ this.locator = locator;
+ if (docNext != null)
+ docNext.setDocumentLocator (locator);
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void startDocument () throws SAXException
+ {
+ if (docNext != null)
+ docNext.startDocument ();
+ }
+
+ public void xmlDecl(String version, String encoding, boolean standalone,
+ String inputEncoding)
+ throws SAXException
+ {
+ if (docNext != null && docNext instanceof ContentHandler2)
+ {
+ ((ContentHandler2) docNext).xmlDecl(version, encoding, standalone,
+ inputEncoding);
+ }
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void skippedEntity (String name) throws SAXException
+ {
+ if (docNext != null)
+ docNext.skippedEntity (name);
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void processingInstruction (String target, String data)
+ throws SAXException
+ {
+ if (docNext != null)
+ docNext.processingInstruction (target, data);
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void characters (char ch [], int start, int length)
+ throws SAXException
+ {
+ if (docNext != null)
+ docNext.characters (ch, start, length);
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void ignorableWhitespace (char ch [], int start, int length)
+ throws SAXException
+ {
+ if (docNext != null)
+ docNext.ignorableWhitespace (ch, start, length);
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void startPrefixMapping (String prefix, String uri)
+ throws SAXException
+ {
+ if (docNext != null)
+ docNext.startPrefixMapping (prefix, uri);
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void startElement (
+ String uri, String localName,
+ String qName, Attributes atts
+ ) throws SAXException
+ {
+ if (docNext != null)
+ docNext.startElement (uri, localName, qName, atts);
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void endElement (String uri, String localName, String qName)
+ throws SAXException
+ {
+ if (docNext != null)
+ docNext.endElement (uri, localName, qName);
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void endPrefixMapping (String prefix) throws SAXException
+ {
+ if (docNext != null)
+ docNext.endPrefixMapping (prefix);
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void endDocument () throws SAXException
+ {
+ if (docNext != null)
+ docNext.endDocument ();
+ locator = null;
+ }
+
+
+ // DTD HANDLER DELEGATIONS
+
+ /** <b>SAX1:</b> passes this callback to the next consumer, if any */
+ public void unparsedEntityDecl (
+ String name,
+ String publicId,
+ String systemId,
+ String notationName
+ ) throws SAXException
+ {
+ if (dtdNext != null)
+ dtdNext.unparsedEntityDecl (name, publicId, systemId, notationName);
+ }
+
+ /** <b>SAX1:</b> passes this callback to the next consumer, if any */
+ public void notationDecl (String name, String publicId, String systemId)
+ throws SAXException
+ {
+ if (dtdNext != null)
+ dtdNext.notationDecl (name, publicId, systemId);
+ }
+
+
+ // LEXICAL HANDLER DELEGATIONS
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void startDTD (String name, String publicId, String systemId)
+ throws SAXException
+ {
+ if (lexNext != null)
+ lexNext.startDTD (name, publicId, systemId);
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void endDTD ()
+ throws SAXException
+ {
+ if (lexNext != null)
+ lexNext.endDTD ();
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void comment (char ch [], int start, int length)
+ throws SAXException
+ {
+ if (lexNext != null)
+ lexNext.comment (ch, start, length);
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void startCDATA ()
+ throws SAXException
+ {
+ if (lexNext != null)
+ lexNext.startCDATA ();
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void endCDATA ()
+ throws SAXException
+ {
+ if (lexNext != null)
+ lexNext.endCDATA ();
+ }
+
+ /**
+ * <b>SAX2:</b> passes this callback to the next consumer, if any.
+ */
+ public void startEntity (String name)
+ throws SAXException
+ {
+ if (lexNext != null)
+ lexNext.startEntity (name);
+ }
+
+ /**
+ * <b>SAX2:</b> passes this callback to the next consumer, if any.
+ */
+ public void endEntity (String name)
+ throws SAXException
+ {
+ if (lexNext != null)
+ lexNext.endEntity (name);
+ }
+
+
+ // DECLARATION HANDLER DELEGATIONS
+
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void elementDecl (String name, String model)
+ throws SAXException
+ {
+ if (declNext != null)
+ declNext.elementDecl (name, model);
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void attributeDecl (String eName, String aName,
+ String type, String mode, String value)
+ throws SAXException
+ {
+ if (declNext != null)
+ declNext.attributeDecl (eName, aName, type, mode, value);
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void externalEntityDecl (String name,
+ String publicId, String systemId)
+ throws SAXException
+ {
+ if (declNext != null)
+ declNext.externalEntityDecl (name, publicId, systemId);
+ }
+
+ /** <b>SAX2:</b> passes this callback to the next consumer, if any */
+ public void internalEntityDecl (String name, String value)
+ throws SAXException
+ {
+ if (declNext != null)
+ declNext.internalEntityDecl (name, value);
+ }
+}