aboutsummaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/xml/pipeline
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2016-09-30 16:24:48 +0000
committerAndrew Haley <aph@gcc.gnu.org>2016-09-30 16:24:48 +0000
commit07b78716af6a9d7c9fd1e94d9baf94a52c873947 (patch)
tree3f22b3241c513ad168c8353805614ae1249410f4 /libjava/classpath/gnu/xml/pipeline
parenteae993948bae8b788c53772bcb9217c063716f93 (diff)
downloadgcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.zip
gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.tar.gz
gcc-07b78716af6a9d7c9fd1e94d9baf94a52c873947.tar.bz2
Makefile.def: Remove libjava.
2016-09-30 Andrew Haley <aph@redhat.com> * Makefile.def: Remove libjava. * Makefile.tpl: Likewise. * Makefile.in: Regenerate. * configure.ac: Likewise. * configure: Likewise. * gcc/java: Remove. * libjava: Likewise. From-SVN: r240662
Diffstat (limited to 'libjava/classpath/gnu/xml/pipeline')
-rw-r--r--libjava/classpath/gnu/xml/pipeline/CallFilter.java257
-rw-r--r--libjava/classpath/gnu/xml/pipeline/DomConsumer.java967
-rw-r--r--libjava/classpath/gnu/xml/pipeline/EventConsumer.java95
-rw-r--r--libjava/classpath/gnu/xml/pipeline/EventFilter.java796
-rw-r--r--libjava/classpath/gnu/xml/pipeline/LinkFilter.java242
-rw-r--r--libjava/classpath/gnu/xml/pipeline/NSFilter.java341
-rw-r--r--libjava/classpath/gnu/xml/pipeline/PipelineFactory.java723
-rw-r--r--libjava/classpath/gnu/xml/pipeline/TeeConsumer.java417
-rw-r--r--libjava/classpath/gnu/xml/pipeline/TextConsumer.java117
-rw-r--r--libjava/classpath/gnu/xml/pipeline/ValidationConsumer.java1928
-rw-r--r--libjava/classpath/gnu/xml/pipeline/WellFormednessFilter.java363
-rw-r--r--libjava/classpath/gnu/xml/pipeline/XIncludeFilter.java579
-rw-r--r--libjava/classpath/gnu/xml/pipeline/XsltFilter.java130
-rw-r--r--libjava/classpath/gnu/xml/pipeline/package.html255
14 files changed, 0 insertions, 7210 deletions
diff --git a/libjava/classpath/gnu/xml/pipeline/CallFilter.java b/libjava/classpath/gnu/xml/pipeline/CallFilter.java
deleted file mode 100644
index 2398b86..0000000
--- a/libjava/classpath/gnu/xml/pipeline/CallFilter.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/* CallFilter.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. */
-
-package gnu.xml.pipeline;
-
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.net.URL;
-import java.net.URLConnection;
-import java.io.Writer;
-
-import org.xml.sax.DTDHandler;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXNotRecognizedException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-import gnu.xml.util.Resolver;
-import gnu.xml.util.XMLWriter;
-
-
-/**
- * Input is sent as an XML request to given URI, and the output of this
- * filter is the parsed response to that request.
- * A connection is opened to the remote URI when the startDocument call is
- * issued through this filter, and the request is finished when the
- * endDocument call is issued. Events should be written quickly enough to
- * prevent the remote HTTP server from aborting the connection due to
- * inactivity; you may want to buffer text in an earlier pipeline stage.
- * If your application requires validity checking of such
- * outputs, have the output pipeline include a validation stage.
- *
- * <p>In effect, this makes a remote procedure call to the URI, with the
- * request and response document syntax as chosen by the application.
- * <em>Note that all the input events must be seen, and sent to the URI,
- * before the first output event can be seen. </em> Clients are delayed
- * at least by waiting for the server to respond, constraining concurrency.
- * Services can thus be used to synchronize concurrent activities, and
- * even to prioritize service among different clients.
- *
- * <p> You are advised to avoid restricting yourself to an "RPC" model
- * for distributed computation. With a World Wide Web, network latencies
- * and failures (e.g. non-availability)
- * are significant; adopting a "procedure" model, rather than a workflow
- * model where bulk requests are sent and worked on asynchronously, is not
- * generally an optimal system-wide architecture. When the messages may
- * need authentication, such as with an OpenPGP signature, or when server
- * loads don't argue in favor of immediate responses, non-RPC models can
- * be advantageous. (So-called "peer to peer" computing models are one
- * additional type of model, though too often that term is applied to
- * systems that still have a centralized control structure.)
- *
- * <p> <em>Be strict in what you send, liberal in what you accept,</em> as
- * the Internet tradition goes. Strictly conformant data should never cause
- * problems to its receiver; make your request pipeline be very strict, and
- * don't compromise on that. Make your response pipeline strict as well,
- * but be ready to tolerate specific mild, temporary, and well-documented
- * variations from specific communications peers.
- *
- * @see XmlServlet
- *
- * @author David Brownell
- */
-final public class CallFilter implements EventConsumer
-{
- private Requestor req;
- private EventConsumer next;
- private URL target;
- private URLConnection conn;
- private ErrorHandler errHandler;
-
-
- /**
- * Initializes a call filter so that its inputs are sent to the
- * specified URI, and its outputs are sent to the next consumer
- * provided.
- *
- * @exception IOException if the URI isn't accepted as a URL
- */
- // constructor used by PipelineFactory
- public CallFilter (String uri, EventConsumer next)
- throws IOException
- {
- this.next = next;
- req = new Requestor ();
- setCallTarget (uri);
- }
-
- /**
- * Assigns the URI of the call target to be used.
- * Does not affect calls currently being made.
- */
- final public void setCallTarget (String uri)
- throws IOException
- {
- target = new URL (uri);
- }
-
- /**
- * Assigns the error handler to be used to present most fatal
- * errors.
- */
- public void setErrorHandler (ErrorHandler handler)
- {
- req.setErrorHandler (handler);
- }
-
-
- /**
- * Returns the call target's URI.
- */
- final public String getCallTarget ()
- {
- return target.toString ();
- }
-
- /** Returns the content handler currently in use. */
- final public org.xml.sax.ContentHandler getContentHandler ()
- {
- return req;
- }
-
- /** Returns the DTD handler currently in use. */
- final public DTDHandler getDTDHandler ()
- {
- return req;
- }
-
-
- /**
- * Returns the declaration or lexical handler currently in
- * use, or throws an exception for other properties.
- */
- final public Object getProperty (String id)
- throws SAXNotRecognizedException
- {
- if (EventFilter.DECL_HANDLER.equals (id))
- return req;
- if (EventFilter.LEXICAL_HANDLER.equals (id))
- return req;
- throw new SAXNotRecognizedException (id);
- }
-
-
- // JDK 1.1 seems to need it to be done this way, sigh
- ErrorHandler getErrorHandler () { return errHandler; }
-
- //
- // Takes input and echoes to server as POST input.
- // Then sends the POST reply to the next pipeline element.
- //
- final class Requestor extends XMLWriter
- {
- Requestor ()
- {
- super ((Writer)null);
- }
-
- public synchronized void startDocument () throws SAXException
- {
- // Connect to remote object and set up to send it XML text
- try {
- if (conn != null)
- throw new IllegalStateException ("call is being made");
-
- conn = target.openConnection ();
- conn.setDoOutput (true);
- conn.setRequestProperty ("Content-Type",
- "application/xml;charset=UTF-8");
-
- setWriter (new OutputStreamWriter (
- conn.getOutputStream (),
- "UTF8"), "UTF-8");
-
- } catch (IOException e) {
- fatal ("can't write (POST) to URI: " + target, e);
- }
-
- // NOW base class can safely write that text!
- super.startDocument ();
- }
-
- public void endDocument () throws SAXException
- {
- //
- // Finish writing the request (for HTTP, a POST);
- // this closes the output stream.
- //
- super.endDocument ();
-
- //
- // Receive the response.
- // Produce events for the next stage.
- //
- InputSource source;
- XMLReader producer;
- String encoding;
-
- try {
-
- source = new InputSource (conn.getInputStream ());
-
-// FIXME if status is anything but success, report it!! It'd be good to
-// save the request data just in case we need to deal with a forward.
-
- encoding = Resolver.getEncoding (conn.getContentType ());
- if (encoding != null)
- source.setEncoding (encoding);
-
- producer = XMLReaderFactory.createXMLReader ();
- producer.setErrorHandler (getErrorHandler ());
- EventFilter.bind (producer, next);
- producer.parse (source);
- conn = null;
-
- } catch (IOException e) {
- fatal ("I/O Exception reading response, " + e.getMessage (), e);
- }
- }
- }
-}
diff --git a/libjava/classpath/gnu/xml/pipeline/DomConsumer.java b/libjava/classpath/gnu/xml/pipeline/DomConsumer.java
deleted file mode 100644
index 141f36e..0000000
--- a/libjava/classpath/gnu/xml/pipeline/DomConsumer.java
+++ /dev/null
@@ -1,967 +0,0 @@
-/* DomConsumer.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. */
-
-package gnu.xml.pipeline;
-
-import gnu.xml.util.DomParser;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.DTDHandler;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXNotRecognizedException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.ext.DeclHandler;
-import org.xml.sax.ext.LexicalHandler;
-import org.xml.sax.helpers.AttributesImpl;
-import org.w3c.dom.Attr;
-import org.w3c.dom.CDATASection;
-import org.w3c.dom.CharacterData;
-import org.w3c.dom.Document;
-import org.w3c.dom.DOMImplementation;
-import org.w3c.dom.Element;
-import org.w3c.dom.EntityReference;
-import org.w3c.dom.Node;
-import org.w3c.dom.ProcessingInstruction;
-import org.w3c.dom.Text;
-
-/**
- * This consumer builds a DOM Document from its input, acting either as a
- * pipeline terminus or as an intermediate buffer. When a document's worth
- * of events has been delivered to this consumer, that document is read with
- * a {@link DomParser} and sent to the next consumer. It is also available
- * as a read-once property.
- *
- * <p>The DOM tree is constructed as faithfully as possible. There are some
- * complications since a DOM should expose behaviors that can't be implemented
- * without API backdoors into that DOM, and because some SAX parsers don't
- * report all the information that DOM permits to be exposed. The general
- * problem areas involve information from the Document Type Declaration (DTD).
- * DOM only represents a limited subset, but has some behaviors that depend
- * on much deeper knowledge of a document's DTD. You shouldn't have much to
- * worry about unless you change handling of "noise" nodes from its default
- * setting (which ignores them all); note if you use JAXP to populate your
- * DOM trees, it wants to save "noise" nodes by default. (Such nodes include
- * ignorable whitespace, comments, entity references and CDATA boundaries.)
- * Otherwise, your
- * main worry will be if you use a SAX parser that doesn't flag ignorable
- * whitespace unless it's validating (few don't).
- *
- * <p> The SAX2 events used as input must contain XML Names for elements
- * and attributes, with original prefixes. In SAX2,
- * this is optional unless the "namespace-prefixes" parser feature is set.
- * Moreover, many application components won't provide completely correct
- * structures anyway. <em>Before you convert a DOM to an output document,
- * you should plan to postprocess it to create or repair such namespace
- * information.</em> The {@link NSFilter} pipeline stage does such work.
- *
- * <p> <em>Note: changes late in DOM L2 process made it impractical to
- * attempt to create the DocumentType node in any implementation-neutral way,
- * much less to populate it (L1 didn't support even creating such nodes).
- * To create and populate such a node, subclass the inner
- * {@link DomConsumer.Handler} class and teach it about the backdoors into
- * whatever DOM implementation you want. It's possible that some revised
- * DOM API (L3?) will make this problem solvable again. </em>
- *
- * @see DomParser
- *
- * @author David Brownell
- */
-public class DomConsumer implements EventConsumer
-{
- private Class domImpl;
-
- private boolean hidingCDATA = true;
- private boolean hidingComments = true;
- private boolean hidingWhitespace = true;
- private boolean hidingReferences = true;
-
- private Handler handler;
- private ErrorHandler errHandler;
-
- private EventConsumer next;
-
- // FIXME: this can't be a generic pipeline stage just now,
- // since its input became a Class not a String (to be turned
- // into a class, using the right class loader)
-
-
- /**
- * Configures this pipeline terminus to use the specified implementation
- * of DOM when constructing its result value.
- *
- * @param impl class implementing {@link org.w3c.dom.Document Document}
- * which publicly exposes a default constructor
- *
- * @exception SAXException when there is a problem creating an
- * empty DOM document using the specified implementation
- */
- public DomConsumer (Class impl)
- throws SAXException
- {
- domImpl = impl;
- handler = new Handler (this);
- }
-
- /**
- * This is the hook through which a subclass provides a handler
- * which knows how to access DOM extensions, specific to some
- * implementation, to record additional data in a DOM.
- * Treat this as part of construction; don't call it except
- * before (or between) parses.
- */
- protected void setHandler (Handler h)
- {
- handler = h;
- }
-
-
- private Document emptyDocument ()
- throws SAXException
- {
- try {
- return (Document) domImpl.newInstance ();
- } catch (IllegalAccessException e) {
- throw new SAXException ("can't access constructor: "
- + e.getMessage ());
- } catch (InstantiationException e) {
- throw new SAXException ("can't instantiate Document: "
- + e.getMessage ());
- }
- }
-
-
- /**
- * Configures this consumer as a buffer/filter, using the specified
- * DOM implementation when constructing its result value.
- *
- * <p> This event consumer acts as a buffer and filter, in that it
- * builds a DOM tree and then writes it out when <em>endDocument</em>
- * is invoked. Because of the limitations of DOM, much information
- * will as a rule not be seen in that replay. To get a full fidelity
- * copy of the input event stream, use a {@link TeeConsumer}.
- *
- * @param impl class implementing {@link org.w3c.dom.Document Document}
- * which publicly exposes a default constructor
- * @param next receives a "replayed" sequence of parse events when
- * the <em>endDocument</em> method is invoked.
- *
- * @exception SAXException when there is a problem creating an
- * empty DOM document using the specified DOM implementation
- */
- public DomConsumer (Class impl, EventConsumer n)
- throws SAXException
- {
- this (impl);
- next = n;
- }
-
-
- /**
- * Returns the document constructed from the preceding
- * sequence of events. This method should not be
- * used again until another sequence of events has been
- * given to this EventConsumer.
- */
- final public Document getDocument ()
- {
- return handler.clearDocument ();
- }
-
- public void setErrorHandler (ErrorHandler handler)
- {
- errHandler = handler;
- }
-
-
- /**
- * Returns true if the consumer is hiding entity references nodes
- * (the default), and false if EntityReference nodes should
- * instead be created. Such EntityReference nodes will normally be
- * empty, unless an implementation arranges to populate them and then
- * turn them back into readonly objects.
- *
- * @see #setHidingReferences
- */
- final public boolean isHidingReferences ()
- { return hidingReferences; }
-
- /**
- * Controls whether the consumer will hide entity expansions,
- * or will instead mark them with entity reference nodes.
- *
- * @see #isHidingReferences
- * @param flag False if entity reference nodes will appear
- */
- final public void setHidingReferences (boolean flag)
- { hidingReferences = flag; }
-
-
- /**
- * Returns true if the consumer is hiding comments (the default),
- * and false if they should be placed into the output document.
- *
- * @see #setHidingComments
- */
- public final boolean isHidingComments ()
- { return hidingComments; }
-
- /**
- * Controls whether the consumer is hiding comments.
- *
- * @see #isHidingComments
- */
- public final void setHidingComments (boolean flag)
- { hidingComments = flag; }
-
-
- /**
- * Returns true if the consumer is hiding ignorable whitespace
- * (the default), and false if such whitespace should be placed
- * into the output document as children of element nodes.
- *
- * @see #setHidingWhitespace
- */
- public final boolean isHidingWhitespace ()
- { return hidingWhitespace; }
-
- /**
- * Controls whether the consumer hides ignorable whitespace
- *
- * @see #isHidingComments
- */
- public final void setHidingWhitespace (boolean flag)
- { hidingWhitespace = flag; }
-
-
- /**
- * Returns true if the consumer is saving CDATA boundaries, or
- * false (the default) otherwise.
- *
- * @see #setHidingCDATA
- */
- final public boolean isHidingCDATA ()
- { return hidingCDATA; }
-
- /**
- * Controls whether the consumer will save CDATA boundaries.
- *
- * @see #isHidingCDATA
- * @param flag True to treat CDATA text differently from other
- * text nodes
- */
- final public void setHidingCDATA (boolean flag)
- { hidingCDATA = flag; }
-
-
-
- /** Returns the document handler being used. */
- final public ContentHandler getContentHandler ()
- { return handler; }
-
- /** Returns the DTD handler being used. */
- final public DTDHandler getDTDHandler ()
- { return handler; }
-
- /**
- * Returns the lexical handler being used.
- * (DOM construction can't really use declaration handlers.)
- */
- final public Object getProperty (String id)
- throws SAXNotRecognizedException
- {
- if ("http://xml.org/sax/properties/lexical-handler".equals (id))
- return handler;
- if ("http://xml.org/sax/properties/declaration-handler".equals (id))
- return handler;
- throw new SAXNotRecognizedException (id);
- }
-
- EventConsumer getNext () { return next; }
-
- ErrorHandler getErrorHandler () { return errHandler; }
-
- /**
- * Class used to intercept various parsing events and use them to
- * populate a DOM document. Subclasses would typically know and use
- * backdoors into specific DOM implementations, used to implement
- * DTD-related functionality.
- *
- * <p> Note that if this ever throws a DOMException (runtime exception)
- * that will indicate a bug in the DOM (e.g. doesn't support something
- * per specification) or the parser (e.g. emitted an illegal name, or
- * accepted illegal input data). </p>
- */
- public static class Handler
- implements ContentHandler, LexicalHandler,
- DTDHandler, DeclHandler
- {
- protected DomConsumer consumer;
-
- private DOMImplementation impl;
- private Document document;
- private boolean isL2;
-
- private Locator locator;
- private Node top;
- private boolean inCDATA;
- private boolean mergeCDATA;
- private boolean inDTD;
- private String currentEntity;
-
- private boolean recreatedAttrs;
- private AttributesImpl attributes = new AttributesImpl ();
-
- /**
- * Subclasses may use SAX2 events to provide additional
- * behaviors in the resulting DOM.
- */
- protected Handler (DomConsumer consumer)
- throws SAXException
- {
- this.consumer = consumer;
- document = consumer.emptyDocument ();
- impl = document.getImplementation ();
- isL2 = impl.hasFeature ("XML", "2.0");
- }
-
- private void fatal (String message, Exception x)
- throws SAXException
- {
- SAXParseException e;
- ErrorHandler errHandler = consumer.getErrorHandler ();
-
- if (locator == null)
- e = new SAXParseException (message, null, null, -1, -1, x);
- else
- e = new SAXParseException (message, locator, x);
- if (errHandler != null)
- errHandler.fatalError (e);
- throw e;
- }
-
- /**
- * Returns and forgets the document produced. If the handler is
- * reused, a new document may be created.
- */
- Document clearDocument ()
- {
- Document retval = document;
- document = null;
- locator = null;
- return retval;
- }
-
- /**
- * Returns the document under construction.
- */
- protected Document getDocument ()
- { return document; }
-
- /**
- * Returns the current node being populated. This is usually
- * an Element or Document, but it might be an EntityReference
- * node if some implementation-specific code knows how to put
- * those into the result tree and later mark them as readonly.
- */
- protected Node getTop ()
- { return top; }
-
-
- // SAX1
- public void setDocumentLocator (Locator locator)
- {
- this.locator = locator;
- }
-
- // SAX1
- public void startDocument ()
- throws SAXException
- {
- if (document == null)
- try {
- if (isL2) {
- // couple to original implementation
- document = impl.createDocument (null, "foo", null);
- document.removeChild (document.getFirstChild ());
- } else {
- document = consumer.emptyDocument ();
- }
- } catch (Exception e) {
- fatal ("DOM create document", e);
- }
- top = document;
- }
-
- // SAX1
- public void endDocument ()
- throws SAXException
- {
- try {
- if (consumer.getNext () != null && document != null) {
- DomParser parser = new DomParser (document);
-
- EventFilter.bind (parser, consumer.getNext ());
- parser.parse ("ignored");
- }
- } finally {
- top = null;
- }
- }
-
- // SAX1
- public void processingInstruction (String target, String data)
- throws SAXException
- {
- // we can't create populated entity ref nodes using
- // only public DOM APIs (they've got to be readonly)
- if (currentEntity != null)
- return;
-
- ProcessingInstruction pi;
-
- if (isL2
- // && consumer.isUsingNamespaces ()
- && target.indexOf (':') != -1)
- namespaceError (
- "PI target name is namespace nonconformant: "
- + target);
- if (inDTD)
- return;
- pi = document.createProcessingInstruction (target, data);
- top.appendChild (pi);
- }
-
- /**
- * Subclasses may overrride this method to provide a more efficient
- * way to construct text nodes.
- * Typically, copying the text into a single character array will
- * be more efficient than doing that as well as allocating other
- * needed for a String, including an internal StringBuffer.
- * Those additional memory and CPU costs can be incurred later,
- * if ever needed.
- * Unfortunately the standard DOM factory APIs encourage those costs
- * to be incurred early.
- */
- protected Text createText (
- boolean isCDATA,
- char ch [],
- int start,
- int length
- ) {
- String value = new String (ch, start, length);
-
- if (isCDATA)
- return document.createCDATASection (value);
- else
- return document.createTextNode (value);
- }
-
- // SAX1
- public void characters (char ch [], int start, int length)
- throws SAXException
- {
- // we can't create populated entity ref nodes using
- // only public DOM APIs (they've got to be readonly
- // at creation time)
- if (currentEntity != null)
- return;
-
- Node lastChild = top.getLastChild ();
-
- // merge consecutive text or CDATA nodes if appropriate.
- if (lastChild instanceof Text) {
- if (consumer.isHidingCDATA ()
- // consecutive Text content ... always merge
- || (!inCDATA
- && !(lastChild instanceof CDATASection))
- // consecutive CDATASection content ... don't
- // merge between sections, only within them
- || (inCDATA && mergeCDATA
- && lastChild instanceof CDATASection)
- ) {
- CharacterData last = (CharacterData) lastChild;
- String value = new String (ch, start, length);
-
- last.appendData (value);
- return;
- }
- }
- if (inCDATA && !consumer.isHidingCDATA ()) {
- top.appendChild (createText (true, ch, start, length));
- mergeCDATA = true;
- } else
- top.appendChild (createText (false, ch, start, length));
- }
-
- // SAX2
- public void skippedEntity (String name)
- throws SAXException
- {
- // this callback is useless except to report errors, since
- // we can't know if the ref was in content, within an
- // attribute, within a declaration ... only one of those
- // cases supports more intelligent action than a panic.
- fatal ("skipped entity: " + name, null);
- }
-
- // SAX2
- public void startPrefixMapping (String prefix, String uri)
- throws SAXException
- {
- // reconstruct "xmlns" attributes deleted by all
- // SAX2 parsers without "namespace-prefixes" = true
- if ("".equals (prefix))
- attributes.addAttribute ("", "", "xmlns",
- "CDATA", uri);
- else
- attributes.addAttribute ("", "", "xmlns:" + prefix,
- "CDATA", uri);
- recreatedAttrs = true;
- }
-
- // SAX2
- public void endPrefixMapping (String prefix)
- throws SAXException
- { }
-
- // SAX2
- public void startElement (
- String uri,
- String localName,
- String qName,
- Attributes atts
- ) throws SAXException
- {
- // we can't create populated entity ref nodes using
- // only public DOM APIs (they've got to be readonly)
- if (currentEntity != null)
- return;
-
- // parser discarded basic information; DOM tree isn't writable
- // without massaging to assign prefixes to all nodes.
- // the "NSFilter" class does that massaging.
- if (qName.length () == 0)
- qName = localName;
-
-
- Element element;
- int length = atts.getLength ();
-
- if (!isL2) {
- element = document.createElement (qName);
-
- // first the explicit attributes ...
- length = atts.getLength ();
- for (int i = 0; i < length; i++)
- element.setAttribute (atts.getQName (i),
- atts.getValue (i));
- // ... then any recreated ones (DOM deletes duplicates)
- if (recreatedAttrs) {
- recreatedAttrs = false;
- length = attributes.getLength ();
- for (int i = 0; i < length; i++)
- element.setAttribute (attributes.getQName (i),
- attributes.getValue (i));
- attributes.clear ();
- }
-
- top.appendChild (element);
- top = element;
- return;
- }
-
- // For an L2 DOM when namespace use is enabled, use
- // createElementNS/createAttributeNS except when
- // (a) it's an element in the default namespace, or
- // (b) it's an attribute with no prefix
- String namespace;
-
- if (localName.length () != 0)
- namespace = (uri.length () == 0) ? null : uri;
- else
- namespace = getNamespace (getPrefix (qName), atts);
-
- if (namespace == null)
- element = document.createElement (qName);
- else
- element = document.createElementNS (namespace, qName);
-
- populateAttributes (element, atts);
- if (recreatedAttrs) {
- recreatedAttrs = false;
- // ... DOM deletes any duplicates
- populateAttributes (element, attributes);
- attributes.clear ();
- }
-
- top.appendChild (element);
- top = element;
- }
-
- final static String xmlnsURI = "http://www.w3.org/2000/xmlns/";
-
- private void populateAttributes (Element element, Attributes attrs)
- throws SAXParseException
- {
- int length = attrs.getLength ();
-
- for (int i = 0; i < length; i++) {
- String type = attrs.getType (i);
- String value = attrs.getValue (i);
- String name = attrs.getQName (i);
- String local = attrs.getLocalName (i);
- String uri = attrs.getURI (i);
-
- // parser discarded basic information, DOM tree isn't writable
- if (name.length () == 0)
- name = local;
-
- // all attribute types other than these three may not
- // contain scoped names... enumerated attributes get
- // reported as NMTOKEN, except for NOTATION values
- if (!("CDATA".equals (type)
- || "NMTOKEN".equals (type)
- || "NMTOKENS".equals (type))) {
- if (value.indexOf (':') != -1) {
- namespaceError (
- "namespace nonconformant attribute value: "
- + "<" + element.getNodeName ()
- + " " + name + "='" + value + "' ...>");
- }
- }
-
- // xmlns="" is legal (undoes default NS)
- // xmlns:foo="" is illegal
- String prefix = getPrefix (name);
- String namespace;
-
- if ("xmlns".equals (prefix)) {
- if ("".equals (value))
- namespaceError ("illegal null namespace decl, " + name);
- namespace = xmlnsURI;
- } else if ("xmlns".equals (name))
- namespace = xmlnsURI;
-
- else if (prefix == null)
- namespace = null;
- else if (!"".equals(uri) && uri.length () != 0)
- namespace = uri;
- else
- namespace = getNamespace (prefix, attrs);
-
- if (namespace == null)
- element.setAttribute (name, value);
- else
- element.setAttributeNS (namespace, name, value);
- }
- }
-
- private String getPrefix (String name)
- {
- int temp;
-
- if ((temp = name.indexOf (':')) > 0)
- return name.substring (0, temp);
- return null;
- }
-
- // used with SAX1-level parser output
- private String getNamespace (String prefix, Attributes attrs)
- throws SAXParseException
- {
- String namespace;
- String decl;
-
- // defaulting
- if (prefix == null) {
- decl = "xmlns";
- namespace = attrs.getValue (decl);
- if ("".equals (namespace))
- return null;
- else if (namespace != null)
- return namespace;
-
- // "xmlns" is like a keyword
- // ... according to the Namespace REC, but DOM L2 CR2+
- // and Infoset violate that by assigning a namespace.
- // that conflict is resolved elsewhere.
- } else if ("xmlns".equals (prefix))
- return null;
-
- // "xml" prefix is fixed
- else if ("xml".equals (prefix))
- return "http://www.w3.org/XML/1998/namespace";
-
- // otherwise, expect a declaration
- else {
- decl = "xmlns:" + prefix;
- namespace = attrs.getValue (decl);
- }
-
- // if we found a local declaration, great
- if (namespace != null)
- return namespace;
-
-
- // ELSE ... search up the tree we've been building
- for (Node n = top;
- n != null && n.getNodeType () != Node.DOCUMENT_NODE;
- n = n.getParentNode ()) {
- if (n.getNodeType () == Node.ENTITY_REFERENCE_NODE)
- continue;
- Element e = (Element) n;
- Attr attr = e.getAttributeNode (decl);
- if (attr != null)
- return attr.getNodeValue ();
- }
- // see above re "xmlns" as keyword
- if ("xmlns".equals (decl))
- return null;
-
- namespaceError ("Undeclared namespace prefix: " + prefix);
- return null;
- }
-
- // SAX2
- public void endElement (String uri, String localName, String qName)
- throws SAXException
- {
- // we can't create populated entity ref nodes using
- // only public DOM APIs (they've got to be readonly)
- if (currentEntity != null)
- return;
-
- top = top.getParentNode ();
- }
-
- // SAX1 (mandatory reporting if validating)
- public void ignorableWhitespace (char ch [], int start, int length)
- throws SAXException
- {
- if (consumer.isHidingWhitespace ())
- return;
- characters (ch, start, length);
- }
-
- // SAX2 lexical event
- public void startCDATA ()
- throws SAXException
- {
- inCDATA = true;
- // true except for the first fragment of a cdata section
- mergeCDATA = false;
- }
-
- // SAX2 lexical event
- public void endCDATA ()
- throws SAXException
- {
- inCDATA = false;
- }
-
- // SAX2 lexical event
- //
- // this SAX2 callback merges two unrelated things:
- // - Declaration of the root element type ... belongs with
- // the other DTD declaration methods, NOT HERE.
- // - IDs for the optional external subset ... belongs here
- // with other lexical information.
- //
- // ...and it doesn't include the internal DTD subset, desired
- // both to support DOM L2 and to enable "pass through" processing
- //
- public void startDTD (String name, String publicId, String SystemId)
- throws SAXException
- {
- // need to filter out comments and PIs within the DTD
- inDTD = true;
- }
-
- // SAX2 lexical event
- public void endDTD ()
- throws SAXException
- {
- inDTD = false;
- }
-
- // SAX2 lexical event
- public void comment (char ch [], int start, int length)
- throws SAXException
- {
- Node comment;
-
- // we can't create populated entity ref nodes using
- // only public DOM APIs (they've got to be readonly)
- if (consumer.isHidingComments ()
- || inDTD
- || currentEntity != null)
- return;
- comment = document.createComment (new String (ch, start, length));
- top.appendChild (comment);
- }
-
- /**
- * May be overridden by subclasses to return true, indicating
- * that entity reference nodes can be populated and then made
- * read-only.
- */
- public boolean canPopulateEntityRefs ()
- { return false; }
-
- // SAX2 lexical event
- public void startEntity (String name)
- throws SAXException
- {
- // are we ignoring what would be contents of an
- // entity ref, since we can't populate it?
- if (currentEntity != null)
- return;
-
- // Are we hiding all entity boundaries?
- if (consumer.isHidingReferences ())
- return;
-
- // SAX2 shows parameter entities; DOM hides them
- if (name.charAt (0) == '%' || "[dtd]".equals (name))
- return;
-
- // Since we can't create a populated entity ref node in any
- // standard way, we create an unpopulated one.
- EntityReference ref = document.createEntityReference (name);
- top.appendChild (ref);
- top = ref;
-
- // ... allowing subclasses to populate them
- if (!canPopulateEntityRefs ())
- currentEntity = name;
- }
-
- // SAX2 lexical event
- public void endEntity (String name)
- throws SAXException
- {
- if (name.charAt (0) == '%' || "[dtd]".equals (name))
- return;
- if (name.equals (currentEntity))
- currentEntity = null;
- if (!consumer.isHidingReferences ())
- top = top.getParentNode ();
- }
-
-
- // SAX1 DTD event
- public void notationDecl (
- String name,
- String publicId, String SystemId
- ) throws SAXException
- {
- /* IGNORE -- no public DOM API lets us store these
- * into the doctype node
- */
- }
-
- // SAX1 DTD event
- public void unparsedEntityDecl (
- String name,
- String publicId, String SystemId,
- String notationName
- ) throws SAXException
- {
- /* IGNORE -- no public DOM API lets us store these
- * into the doctype node
- */
- }
-
- // SAX2 declaration event
- public void elementDecl (String name, String model)
- throws SAXException
- {
- /* IGNORE -- no content model support in DOM L2 */
- }
-
- // SAX2 declaration event
- public void attributeDecl (
- String eName,
- String aName,
- String type,
- String mode,
- String value
- ) throws SAXException
- {
- /* IGNORE -- no attribute model support in DOM L2 */
- }
-
- // SAX2 declaration event
- public void internalEntityDecl (String name, String value)
- throws SAXException
- {
- /* IGNORE -- no public DOM API lets us store these
- * into the doctype node
- */
- }
-
- // SAX2 declaration event
- public void externalEntityDecl (
- String name,
- String publicId,
- String SystemId
- ) throws SAXException
- {
- /* IGNORE -- no public DOM API lets us store these
- * into the doctype node
- */
- }
-
- //
- // These really should offer the option of nonfatal handling,
- // like other validity errors, though that would cause major
- // chaos in the DOM data structures. DOM is already spec'd
- // to treat many of these as fatal, so this is consistent.
- //
- private void namespaceError (String description)
- throws SAXParseException
- {
- SAXParseException err;
-
- err = new SAXParseException (description, locator);
- throw err;
- }
- }
-}
diff --git a/libjava/classpath/gnu/xml/pipeline/EventConsumer.java b/libjava/classpath/gnu/xml/pipeline/EventConsumer.java
deleted file mode 100644
index a0a8824..0000000
--- a/libjava/classpath/gnu/xml/pipeline/EventConsumer.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/* EventConsumer.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. */
-
-package gnu.xml.pipeline;
-
-import org.xml.sax.*;
-
-
-/**
- * Collects the event consumption apparatus of a SAX pipeline stage.
- * Consumers which permit some handlers or other characteristics to be
- * configured will provide methods to support that configuration.
- *
- * <p> Two important categories of consumers include <em>filters</em>, which
- * process events and pass them on to other consumers, and <em>terminus</em>
- * (or <em>terminal</em>) stages, which don't pass events on. Filters are not
- * necessarily derived from the {@link EventFilter} class, although that
- * class can substantially simplify their construction by automating the
- * most common activities.
- *
- * <p> Event consumers which follow certain conventions for the signatures
- * of their constructors can be automatically assembled into pipelines
- * by the {@link PipelineFactory} class.
- *
- * @author David Brownell
- */
-public interface EventConsumer
-{
- /** Most stages process these core SAX callbacks. */
- public ContentHandler getContentHandler ();
-
- /** Few stages will use unparsed entities. */
- public DTDHandler getDTDHandler ();
-
- /**
- * This method works like the SAX2 XMLReader method of the same name,
- * and is used to retrieve the optional lexical and declaration handlers
- * in a pipeline.
- *
- * @param id This is a URI identifying the type of property desired.
- * @return The value of that property, if it is defined.
- *
- * @exception SAXNotRecognizedException Thrown if the particular
- * pipeline stage does not understand the specified identifier.
- */
- public Object getProperty (String id)
- throws SAXNotRecognizedException;
-
- /**
- * This method provides a filter stage with a handler that abstracts
- * presentation of warnings and both recoverable and fatal errors.
- * Most pipeline stages should share a single policy and mechanism
- * for such reports, since application components require consistency
- * in such activities. Accordingly, typical responses to this method
- * invocation involve saving the handler for use; filters will pass
- * it on to any other consumers they use.
- *
- * @param handler encapsulates error handling policy for this stage
- */
- public void setErrorHandler (ErrorHandler handler);
-}
diff --git a/libjava/classpath/gnu/xml/pipeline/EventFilter.java b/libjava/classpath/gnu/xml/pipeline/EventFilter.java
deleted file mode 100644
index b3cc2d6..0000000
--- a/libjava/classpath/gnu/xml/pipeline/EventFilter.java
+++ /dev/null
@@ -1,796 +0,0 @@
-/* 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. */
-
-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;
-
-/**
- * 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, ContentHandler, 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");
- } 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());
- } 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 ();
- }
-
- /** <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);
- }
-}
diff --git a/libjava/classpath/gnu/xml/pipeline/LinkFilter.java b/libjava/classpath/gnu/xml/pipeline/LinkFilter.java
deleted file mode 100644
index e11a5ec..0000000
--- a/libjava/classpath/gnu/xml/pipeline/LinkFilter.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/* LinkFilter.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. */
-
-package gnu.xml.pipeline;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.Enumeration;
-import java.util.Vector;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
-
-
-/**
- * Pipeline filter to remember XHTML links found in a document,
- * so they can later be crawled. Fragments are not counted, and duplicates
- * are ignored. Callers are responsible for filtering out URLs they aren't
- * interested in. Events are passed through unmodified.
- *
- * <p> Input MUST include a setDocumentLocator() call, as it's used to
- * resolve relative links in the absence of a "base" element. Input MUST
- * also include namespace identifiers, since it is the XHTML namespace
- * identifier which is used to identify the relevant elements.
- *
- * <p><em>FIXME:</em> handle xml:base attribute ... in association with
- * a stack of base URIs. Similarly, recognize/support XLink data.
- *
- * @author David Brownell
- */
-public class LinkFilter extends EventFilter
-{
- // for storing URIs
- private Vector vector = new Vector ();
-
- // struct for "full" link record (tbd)
- // these for troubleshooting original source:
- // original uri
- // uri as resolved (base, relative, etc)
- // URI of originating doc
- // line #
- // original element + attrs (img src, desc, etc)
-
- // XLink model of the link ... for inter-site pairups ?
-
- private String baseURI;
-
- private boolean siteRestricted = false;
-
- //
- // XXX leverage blacklist info (like robots.txt)
- //
- // XXX constructor w/param ... pipeline for sending link data
- // probably XHTML --> XLink, providing info as sketched above
- //
-
-
- /**
- * Constructs a new event filter, which collects links in private data
- * structure for later enumeration.
- */
- // constructor used by PipelineFactory
- public LinkFilter ()
- {
- super.setContentHandler (this);
- }
-
-
- /**
- * Constructs a new event filter, which collects links in private data
- * structure for later enumeration and passes all events, unmodified,
- * to the next consumer.
- */
- // constructor used by PipelineFactory
- public LinkFilter (EventConsumer next)
- {
- super (next);
- super.setContentHandler (this);
- }
-
-
- /**
- * Returns an enumeration of the links found since the filter
- * was constructed, or since removeAllLinks() was called.
- *
- * @return enumeration of strings.
- */
- public Enumeration getLinks ()
- {
- return vector.elements ();
- }
-
- /**
- * Removes records about all links reported to the event
- * stream, as if the filter were newly created.
- */
- public void removeAllLinks ()
- {
- vector = new Vector ();
- }
-
-
- /**
- * Collects URIs for (X)HTML content from elements which hold them.
- */
- public void startElement (
- String uri,
- String localName,
- String qName,
- Attributes atts
- ) throws SAXException
- {
- String link;
-
- // Recognize XHTML links.
- if ("http://www.w3.org/1999/xhtml".equals (uri)) {
-
- if ("a".equals (localName) || "base".equals (localName)
- || "area".equals (localName))
- link = atts.getValue ("href");
- else if ("iframe".equals (localName) || "frame".equals (localName))
- link = atts.getValue ("src");
- else if ("blockquote".equals (localName) || "q".equals (localName)
- || "ins".equals (localName) || "del".equals (localName))
- link = atts.getValue ("cite");
- else
- link = null;
- link = maybeAddLink (link);
-
- // "base" modifies designated baseURI
- if ("base".equals (localName) && link != null)
- baseURI = link;
-
- if ("iframe".equals (localName) || "img".equals (localName))
- maybeAddLink (atts.getValue ("longdesc"));
- }
-
- super.startElement (uri, localName, qName, atts);
- }
-
- private String maybeAddLink (String link)
- {
- int index;
-
- // ignore empty links and fragments inside docs
- if (link == null)
- return null;
- if ((index = link.indexOf ("#")) >= 0)
- link = link.substring (0, index);
- if (link.equals (""))
- return null;
-
- try {
- // get the real URI
- URL base = new URL ((baseURI != null)
- ? baseURI
- : getDocumentLocator ().getSystemId ());
- URL url = new URL (base, link);
-
- link = url.toString ();
-
- // ignore duplicates
- if (vector.contains (link))
- return link;
-
- // other than what "base" does, stick to original site:
- if (siteRestricted) {
- // don't switch protocols
- if (!base.getProtocol ().equals (url.getProtocol ()))
- return link;
- // don't switch servers
- if (base.getHost () != null
- && !base.getHost ().equals (url.getHost ()))
- return link;
- }
-
- vector.addElement (link);
-
- return link;
-
- } catch (IOException e) {
- // bad URLs we don't want
- }
- return null;
- }
-
- /**
- * Reports an error if no Locator has been made available.
- */
- public void startDocument ()
- throws SAXException
- {
- if (getDocumentLocator () == null)
- throw new SAXException ("no Locator!");
- }
-
- /**
- * Forgets about any base URI information that may be recorded.
- * Applications will often want to call removeAllLinks(), likely
- * after examining the links which were reported.
- */
- public void endDocument ()
- throws SAXException
- {
- baseURI = null;
- super.endDocument ();
- }
-}
diff --git a/libjava/classpath/gnu/xml/pipeline/NSFilter.java b/libjava/classpath/gnu/xml/pipeline/NSFilter.java
deleted file mode 100644
index 0fa4621..0000000
--- a/libjava/classpath/gnu/xml/pipeline/NSFilter.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/* NSFilter.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. */
-
-package gnu.xml.pipeline;
-
-import java.util.Enumeration;
-import java.util.Stack;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-import org.xml.sax.helpers.AttributesImpl;
-import org.xml.sax.helpers.NamespaceSupport;
-
-/**
- * This filter ensures that element and attribute names are properly prefixed,
- * and that such prefixes are declared. Such data is critical for operations
- * like writing XML text, and validating against DTDs: names or their prefixes
- * may have been discarded, although they are essential to the exchange of
- * information using XML. There are various common ways that such data
- * gets discarded: <ul>
- *
- * <li> By default, SAX2 parsers must discard the "xmlns*"
- * attributes, and may also choose not to report properly prefixed
- * names for elements or attributes. (Some parsers may support
- * changing the <em>namespace-prefixes</em> value from the default
- * to <em>true</em>, effectively eliminating the need to use this
- * filter on their output.)
- *
- * <li> When event streams are generated from a DOM tree, they may
- * have never have had prefixes or declarations for namespaces; or
- * the existing prefixes or declarations may have been invalidated
- * by structural modifications to that DOM tree.
- *
- * <li> Other software writing SAX event streams won't necessarily
- * be worrying about prefix management, and so they will need to
- * have a transparent solution for managing them.
- *
- * </ul>
- *
- * <p> This filter uses a heuristic to choose the prefix to assign to any
- * particular name which wasn't already corectly prefixed. The associated
- * namespace will be correct, and the prefix will be declared. Original
- * structures facilitating text editing, such as conventions about use of
- * mnemonic prefix names or the scoping of prefixes, can't always be
- * reconstructed after they are discarded, as strongly encouraged by the
- * current SAX2 defaults.
- *
- * <p> Note that this can't possibly know whether values inside attribute
- * value or document content involve prefixed names. If your application
- * requires using prefixed names in such locations you'll need to add some
- * appropriate logic (perhaps adding additional heuristics in a subclass).
- *
- * @author David Brownell
- */
-public class NSFilter extends EventFilter
-{
- private NamespaceSupport nsStack = new NamespaceSupport ();
- private Stack elementStack = new Stack ();
-
- private boolean pushedContext;
- private String nsTemp [] = new String [3];
- private AttributesImpl attributes = new AttributesImpl ();
- private boolean usedDefault;
-
- // gensymmed prefixes use this root name
- private static final String prefixRoot = "prefix-";
-
-
- /**
- * Passes events through to the specified consumer, after first
- * processing them.
- *
- * @param next the next event consumer to receive events.
- */
- // constructor used by PipelineFactory
- public NSFilter (EventConsumer next)
- {
- super (next);
-
- setContentHandler (this);
- }
-
- private void fatalError (String message)
- throws SAXException
- {
- SAXParseException e;
- ErrorHandler handler = getErrorHandler ();
- Locator locator = getDocumentLocator ();
-
- if (locator == null)
- e = new SAXParseException (message, null, null, -1, -1);
- else
- e = new SAXParseException (message, locator);
- if (handler != null)
- handler.fatalError (e);
- throw e;
- }
-
-
- public void startDocument () throws SAXException
- {
- elementStack.removeAllElements ();
- nsStack.reset ();
- pushedContext = false;
- super.startDocument ();
- }
-
- /**
- * This call is not passed to the next consumer in the chain.
- * Prefix declarations and scopes are only exposed in the form
- * of attributes; this callback just records a declaration that
- * will be exposed as an attribute.
- */
- public void startPrefixMapping (String prefix, String uri)
- throws SAXException
- {
- if (pushedContext == false) {
- nsStack.pushContext ();
- pushedContext = true;
- }
-
- // this check is awkward, but the paranoia prevents big trouble
- for (Enumeration e = nsStack.getDeclaredPrefixes ();
- e.hasMoreElements ();
- /* NOP */ ) {
- String declared = (String) e.nextElement ();
-
- if (!declared.equals (prefix))
- continue;
- if (uri.equals (nsStack.getURI (prefix)))
- return;
- fatalError ("inconsistent binding for prefix '" + prefix
- + "' ... " + uri + " (was " + nsStack.getURI (prefix) + ")");
- }
-
- if (!nsStack.declarePrefix (prefix, uri))
- fatalError ("illegal prefix declared: " + prefix);
- }
-
- private String fixName (String ns, String l, String name, boolean isAttr)
- throws SAXException
- {
- if ("".equals (name) || name == null) {
- name = l;
- if ("".equals (name) || name == null)
- fatalError ("empty/null name");
- }
-
- // can we correctly process the name as-is?
- // handles "element scope" attribute names here.
- if (nsStack.processName (name, nsTemp, isAttr) != null
- && nsTemp [0].equals (ns)
- ) {
- return nsTemp [2];
- }
-
- // nope, gotta modify the name or declare a default mapping
- int temp;
-
- // get rid of any current prefix
- if ((temp = name.indexOf (':')) >= 0) {
- name = name.substring (temp + 1);
-
- // ... maybe that's enough (use/prefer default namespace) ...
- if (!isAttr && nsStack.processName (name, nsTemp, false) != null
- && nsTemp [0].equals (ns)
- ) {
- return nsTemp [2];
- }
- }
-
- // must we define and use the default/undefined prefix?
- if ("".equals (ns)) {
- if (isAttr)
- fatalError ("processName bug");
- if (attributes.getIndex ("xmlns") != -1)
- fatalError ("need to undefine default NS, but it's bound: "
- + attributes.getValue ("xmlns"));
-
- nsStack.declarePrefix ("", "");
- attributes.addAttribute ("", "", "xmlns", "CDATA", "");
- return name;
- }
-
- // is there at least one non-null prefix we can use?
- for (Enumeration e = nsStack.getDeclaredPrefixes ();
- e.hasMoreElements ();
- /* NOP */) {
- String prefix = (String) e.nextElement ();
- String uri = nsStack.getURI (prefix);
-
- if (uri == null || !uri.equals (ns))
- continue;
- return prefix + ":" + name;
- }
-
- // no such luck. create a prefix name, declare it, use it.
- for (temp = 0; temp >= 0; temp++) {
- String prefix = prefixRoot + temp;
-
- if (nsStack.getURI (prefix) == null) {
- nsStack.declarePrefix (prefix, ns);
- attributes.addAttribute ("", "", "xmlns:" + prefix,
- "CDATA", ns);
- return prefix + ":" + name;
- }
- }
- fatalError ("too many prefixes genned");
- // NOTREACHED
- return null;
- }
-
- public void startElement (
- String uri, String localName,
- String qName, Attributes atts
- ) throws SAXException
- {
- if (!pushedContext)
- nsStack.pushContext ();
- pushedContext = false;
-
- // make sure we have all NS declarations handy before we start
- int length = atts.getLength ();
-
- for (int i = 0; i < length; i++) {
- String aName = atts.getQName (i);
-
- if (!aName.startsWith ("xmlns"))
- continue;
-
- String prefix;
-
- if ("xmlns".equals (aName))
- prefix = "";
- else if (aName.indexOf (':') == 5)
- prefix = aName.substring (6);
- else // "xmlnsfoo" etc.
- continue;
- startPrefixMapping (prefix, atts.getValue (i));
- }
-
- // put namespace decls at the start of our regenned attlist
- attributes.clear ();
- for (Enumeration e = nsStack.getDeclaredPrefixes ();
- e.hasMoreElements ();
- /* NOP */) {
- String prefix = (String) e.nextElement ();
-
- attributes.addAttribute ("", "",
- ("".equals (prefix)
- ? "xmlns"
- : "xmlns:" + prefix),
- "CDATA",
- nsStack.getURI (prefix));
- }
-
- // name fixups: element, then attributes.
- // fixName may declare a new prefix or, for the element,
- // redeclare the default (if element name needs it).
- qName = fixName (uri, localName, qName, false);
-
- for (int i = 0; i < length; i++) {
- String aName = atts.getQName (i);
- String aNS = atts.getURI (i);
- String aLocal = atts.getLocalName (i);
- String aType = atts.getType (i);
- String aValue = atts.getValue (i);
-
- if (aName.startsWith ("xmlns"))
- continue;
- aName = fixName (aNS, aLocal, aName, true);
- attributes.addAttribute (aNS, aLocal, aName, aType, aValue);
- }
-
- elementStack.push (qName);
-
- // pass event along, with cleaned-up names and decls.
- super.startElement (uri, localName, qName, attributes);
- }
-
- public void endElement (String uri, String localName, String qName)
- throws SAXException
- {
- nsStack.popContext ();
- qName = (String) elementStack.pop ();
- super.endElement (uri, localName, qName);
- }
-
- /**
- * This call is not passed to the next consumer in the chain.
- * Prefix declarations and scopes are only exposed in their
- * attribute form.
- */
- public void endPrefixMapping (String prefix)
- throws SAXException
- { }
-
- public void endDocument () throws SAXException
- {
- elementStack.removeAllElements ();
- nsStack.reset ();
- super.endDocument ();
- }
-}
diff --git a/libjava/classpath/gnu/xml/pipeline/PipelineFactory.java b/libjava/classpath/gnu/xml/pipeline/PipelineFactory.java
deleted file mode 100644
index c2adab0..0000000
--- a/libjava/classpath/gnu/xml/pipeline/PipelineFactory.java
+++ /dev/null
@@ -1,723 +0,0 @@
-/* PipelineFactory.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. */
-
-package gnu.xml.pipeline;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.lang.reflect.Constructor;
-import java.util.StringTokenizer;
-
-import org.xml.sax.*;
-import org.xml.sax.ext.*;
-
-
-/**
- * This provides static factory methods for creating simple event pipelines.
- * These pipelines are specified by strings, suitable for passing on
- * command lines or embedding in element attributes. For example, one way
- * to write a pipeline that restores namespace syntax, validates (stopping
- * the pipeline on validity errors) and then writes valid data to standard
- * output is this: <pre>
- * nsfix | validate | write ( stdout )</pre>
- *
- * <p> In this syntax, the tokens are always separated by whitespace, and each
- * stage of the pipeline may optionally have a parameter (which can be a
- * pipeline) in parentheses. Interior stages are called filters, and the
- * rightmost end of a pipeline is called a terminus.
- *
- * <p> Stages are usually implemented by a single class, which may not be
- * able to act as both a filter and a terminus; but any terminus can be
- * automatically turned into a filter, through use of a {@link TeeConsumer}.
- * The stage identifiers are either class names, or are one of the following
- * short identifiers built into this class. (Most of these identifiers are
- * no more than aliases for classes.) The built-in identifiers include:</p>
-
- <table border="1" cellpadding="3" cellspacing="0">
- <tr bgcolor="#ccccff" class="TableHeadingColor">
- <th align="center" width="5%">Stage</th>
- <th align="center" width="9%">Parameter</th>
- <th align="center" width="1%">Terminus</th>
- <th align="center">Description</th>
- </tr>
-
- <tr valign="top" align="center">
- <td><a href="../dom/Consumer.html">dom</a></td>
- <td><em>none</em></td>
- <td> yes </td>
- <td align="left"> Applications code can access a DOM Document built
- from the input event stream. When used as a filter, this buffers
- data up to an <em>endDocument</em> call, and then uses a DOM parser
- to report everything that has been recorded (which can easily be
- less than what was reported to it). </td>
- </tr>
- <tr valign="top" align="center">
- <td><a href="NSFilter.html">nsfix</a></td>
- <td><em>none</em></td>
- <td>no</td>
- <td align="left">This stage ensures that the XML element and attribute
- names in its output use namespace prefixes and declarations correctly.
- That is, so that they match the "Namespace plus LocalName" naming data
- with which each XML element and attribute is already associated. </td>
- </tr>
- <tr valign="top" align="center">
- <td><a href="EventFilter.html">null</a></td>
- <td><em>none</em></td>
- <td>yes</td>
- <td align="left">This stage ignores all input event data.</td>
- </tr>
- <tr valign="top" align="center">
- <td><a href="CallFilter.html">server</a></td>
- <td><em>required</em><br> server URL </td>
- <td>no</td>
- <td align="left">Sends its input as XML request to a remote server,
- normally a web application server using the HTTP or HTTPS protocols.
- The output of this stage is the parsed response from that server.</td>
- </tr>
- <tr valign="top" align="center">
- <td><a href="TeeConsumer.html">tee</a></td>
- <td><em>required</em><br> first pipeline</td>
- <td>no</td>
- <td align="left">This sends its events down two paths; its parameter
- is a pipeline descriptor for the first path, and the second path
- is the output of this stage.</td>
- </tr>
-
- <tr valign="top" align="center">
- <td><a href="ValidationConsumer.html">validate</a></td>
- <td><em>none</em></td>
- <td>yes</td>
- <td align="left">This checks for validity errors, and reports them
- through its error handler. The input must include declaration events
- and some lexical events. </td>
- </tr>
- <tr valign="top" align="center">
- <td><a href="WellFormednessFilter.html">wf</a></td>
- <td><em>none</em></td>
- <td>yes</td>
- <td align="left"> This class provides some basic "well formedness"
- tests on the input event stream, and reports a fatal error if any
- of them fail. One example: start/end calls for elements must match.
- No SAX parser is permitted to produce malformed output, but other
- components can easily do so.</td>
- </tr>
- <tr valign="top" align="center">
- <td>write</td>
- <td><em>required</em><br> "stdout", "stderr", or filename</td>
- <td>yes</td>
- <td align="left"> Writes its input to the specified output, as pretty
- printed XML text encoded using UTF-8. Input events must be well
- formed and "namespace fixed", else the output won't be XML (or possibly
- namespace) conformant. The symbolic names represent
- <em>System.out</em> and <em>System.err</em> respectively; names must
- correspond to files which don't yet exist.</td>
- </tr>
- <tr valign="top" align="center">
- <td>xhtml</td>
- <td><em>required</em><br> "stdout", "stderr", or filename</td>
- <td>yes</td>
- <td align="left"> Like <em>write</em> (above), except that XHTML rules
- are followed. The XHTML 1.0 Transitional document type is declared,
- and only ASCII characters are written (for interoperability). Other
- characters are written as entity or character references; the text is
- pretty printed.</td>
- </tr>
- <tr valign="top" align="center">
- <td><a href="XIncludeFilter.html">xinclude</a></td>
- <td><em>none</em></td>
- <td>no</td>
- <td align="left">This stage handles XInclude processing.
- This is like entity inclusion, except that the included content
- is declared in-line rather than in the DTD at the beginning of
- a document.
- </td>
- </tr>
- <tr valign="top" align="center">
- <td><a href="XsltFilter.html">xslt</a></td>
- <td><em>required</em><br> XSLT stylesheet URI</td>
- <td>no</td>
- <td align="left">This stage handles XSLT transformation
- according to a stylesheet.
- The implementation of the transformation may not actually
- stream data, although if such an XSLT engine is in use
- then that can happen.
- </td>
- </tr>
-
- </table>
-
- * <p> Note that {@link EventFilter#bind} can automatically eliminate
- * some filters by setting SAX2 parser features appropriately. This means
- * that you can routinely put filters like "nsfix", "validate", or "wf" at the
- * front of a pipeline (for components that need inputs conditioned to match
- * that level of correctness), and know that it won't actually be used unless
- * it's absolutely necessary.
- *
- * @author David Brownell
- */
-public class PipelineFactory
-{
- /**
- * Creates a simple pipeline according to the description string passed in.
- */
- public static EventConsumer createPipeline (String description)
- throws IOException
- {
- return createPipeline (description, null);
- }
-
- /**
- * Extends an existing pipeline by prepending the filter pipeline to the
- * specified consumer. Some pipelines need more customization than can
- * be done through this simplified syntax. When they are set up with
- * direct API calls, use this method to merge more complex pipeline
- * segments with easily configured ones.
- */
- public static EventConsumer createPipeline (
- String description,
- EventConsumer next
- ) throws IOException
- {
- // tokens are (for now) what's separated by whitespace;
- // very easy to parse, but IDs never have spaces.
-
- StringTokenizer tokenizer;
- String tokens [];
-
- tokenizer = new StringTokenizer (description);
- tokens = new String [tokenizer.countTokens ()];
- for (int i = 0; i < tokens.length; i++)
- tokens [i] = tokenizer.nextToken ();
-
- PipelineFactory factory = new PipelineFactory ();
- Pipeline pipeline = factory.parsePipeline (tokens, next);
-
- return pipeline.createPipeline ();
- }
-
-
- private PipelineFactory () { /* NYET */ }
-
-
- /**
- * Extends an existing pipeline by prepending a pre-tokenized filter
- * pipeline to the specified consumer. Tokens are class names (or the
- * predefined aliases) left and right parenthesis, and the vertical bar.
- */
- public static EventConsumer createPipeline (
- String tokens [],
- EventConsumer next
- ) throws IOException
- {
- PipelineFactory factory = new PipelineFactory ();
- Pipeline pipeline = factory.parsePipeline (tokens, next);
-
- return pipeline.createPipeline ();
- }
-
-
- private String tokens [];
- private int index;
-
- private Pipeline parsePipeline (String toks [], EventConsumer next)
- {
- tokens = toks;
- index = 0;
-
- Pipeline retval = parsePipeline (next);
-
- if (index != toks.length)
- throw new ArrayIndexOutOfBoundsException (
- "extra token: " + tokens [index]);
- return retval;
- }
-
- // pipeline ::= stage | stage '|' pipeline
- private Pipeline parsePipeline (EventConsumer next)
- {
- Pipeline retval = new Pipeline (parseStage ());
-
- // minimal pipelines: "stage" and "... | id"
- if (index > (tokens.length - 2)
- || !"|".equals (tokens [index])
- ) {
- retval.next = next;
- return retval;
- }
- index++;
- retval.rest = parsePipeline (next);
- return retval;
- }
-
- // stage ::= id | id '(' pipeline ')'
- private Stage parseStage ()
- {
- Stage retval = new Stage (tokens [index++]);
-
- // minimal stages: "id" and "id ( id )"
- if (index > (tokens.length - 2)
- || !"(".equals (tokens [index]) /*)*/
- )
- return retval;
-
- index++;
- retval.param = parsePipeline (null);
- if (index >= tokens.length)
- throw new ArrayIndexOutOfBoundsException (
- "missing right paren");
- if (/*(*/ !")".equals (tokens [index++]))
- throw new ArrayIndexOutOfBoundsException (
- "required right paren, not: " + tokens [index - 1]);
- return retval;
- }
-
-
- //
- // these classes obey the conventions for constructors, so they're
- // only built in to this table of shortnames
- //
- // - filter (one or two types of arglist)
- // * last constructor is 'next' element
- // * optional (first) string parameter
- //
- // - terminus (one or types of arglist)
- // * optional (only) string parameter
- //
- // terminus stages are transformed into filters if needed, by
- // creating a "tee". filter stages aren't turned to terminus
- // stages though; either eliminate such stages, or add some
- // terminus explicitly.
- //
- private static final String builtinStages [][] = {
- { "dom", "gnu.xml.dom.Consumer" },
- { "nsfix", "gnu.xml.pipeline.NSFilter" },
- { "null", "gnu.xml.pipeline.EventFilter" },
- { "server", "gnu.xml.pipeline.CallFilter" },
- { "tee", "gnu.xml.pipeline.TeeConsumer" },
- { "validate", "gnu.xml.pipeline.ValidationConsumer" },
- { "wf", "gnu.xml.pipeline.WellFormednessFilter" },
- { "xinclude", "gnu.xml.pipeline.XIncludeFilter" },
- { "xslt", "gnu.xml.pipeline.XsltFilter" },
-
-// XXX want: option for validate, to preload external part of a DTD
-
- // xhtml, write ... nyet generic-ready
- };
-
- private static class Stage
- {
- String id;
- Pipeline param;
-
- Stage (String name)
- { id = name; }
-
- public String toString ()
- {
- if (param == null)
- return id;
- return id + " ( " + param + " )";
- }
-
- private void fail (String message)
- throws IOException
- {
- throw new IOException ("in '" + id
- + "' stage of pipeline, " + message);
- }
-
- EventConsumer createStage (EventConsumer next)
- throws IOException
- {
- String name = id;
-
- // most builtins are just class aliases
- for (int i = 0; i < builtinStages.length; i++) {
- if (id.equals (builtinStages [i][0])) {
- name = builtinStages [i][1];
- break;
- }
- }
-
- // Save output as XML or XHTML text
- if ("write".equals (name) || "xhtml".equals (name)) {
- String filename;
- boolean isXhtml = "xhtml".equals (name);
- OutputStream out = null;
- TextConsumer consumer;
-
- if (param == null)
- fail ("parameter is required");
-
- filename = param.toString ();
- if ("stdout".equals (filename))
- out = System.out;
- else if ("stderr".equals (filename))
- out = System.err;
- else {
- File f = new File (filename);
-
-/*
- if (!f.isAbsolute ())
- fail ("require absolute file paths");
- */
- if (f.exists ())
- fail ("file already exists: " + f.getName ());
-
-// XXX this races against the existence test
- out = new FileOutputStream (f);
- }
-
- if (!isXhtml)
- consumer = new TextConsumer (out);
- else
- consumer = new TextConsumer (
- new OutputStreamWriter (out, "8859_1"),
- true);
-
- consumer.setPrettyPrinting (true);
- if (next == null)
- return consumer;
- return new TeeConsumer (consumer, next);
-
- } else {
- //
- // Here go all the builtins that are just aliases for
- // classes, and all stage IDs that started out as such
- // class names. The following logic relies on several
- // documented conventions for constructor invocation.
- //
- String msg = null;
-
- try {
- Class klass = Class.forName (name);
- Class argTypes [] = null;
- Constructor constructor = null;
- boolean filter = false;
- Object params [] = null;
- Object obj = null;
-
- // do we need a filter stage?
- if (next != null) {
- // "next" consumer is always passed, with
- // or without the optional string param
- if (param == null) {
- argTypes = new Class [1];
- argTypes [0] = EventConsumer.class;
-
- params = new Object [1];
- params [0] = next;
-
- msg = "no-param filter";
- } else {
- argTypes = new Class [2];
- argTypes [0] = String.class;
- argTypes [1] = EventConsumer.class;
-
- params = new Object [2];
- params [0] = param.toString ();
- params [1] = next;
-
- msg = "one-param filter";
- }
-
-
- try {
- constructor = klass.getConstructor (argTypes);
- } catch (NoSuchMethodException e) {
- // try creating a filter from a
- // terminus and a tee
- filter = true;
- msg += " built from ";
- }
- }
-
- // build from a terminus stage, with or
- // without the optional string param
- if (constructor == null) {
- String tmp;
-
- if (param == null) {
- argTypes = new Class [0];
- params = new Object [0];
-
- tmp = "no-param terminus";
- } else {
- argTypes = new Class [1];
- argTypes [0] = String.class;
-
- params = new Object [1];
- params [0] = param.toString ();
-
- tmp = "one-param terminus";
- }
- if (msg == null)
- msg = tmp;
- else
- msg += tmp;
- constructor = klass.getConstructor (argTypes);
- // NOT creating terminus by dead-ending
- // filters ... users should think about
- // that one, something's likely wrong
- }
-
- obj = constructor.newInstance (params);
-
- // return EventConsumers directly, perhaps after
- // turning them into a filter
- if (obj instanceof EventConsumer) {
- if (filter)
- return new TeeConsumer ((EventConsumer) obj, next);
- return (EventConsumer) obj;
- }
-
- // if it's not a handler, it's an error
- // we can wrap handlers in a filter
- EventFilter retval = new EventFilter ();
- boolean updated = false;
-
- if (obj instanceof ContentHandler) {
- retval.setContentHandler ((ContentHandler) obj);
- updated = true;
- }
- if (obj instanceof DTDHandler) {
- retval.setDTDHandler ((DTDHandler) obj);
- updated = true;
- }
- if (obj instanceof LexicalHandler) {
- retval.setProperty (
- EventFilter.PROPERTY_URI + "lexical-handler",
- obj);
- updated = true;
- }
- if (obj instanceof DeclHandler) {
- retval.setProperty (
- EventFilter.PROPERTY_URI + "declaration-handler",
- obj);
- updated = true;
- }
-
- if (!updated)
- fail ("class is neither Consumer nor Handler");
-
- if (filter)
- return new TeeConsumer (retval, next);
- return retval;
-
- } catch (IOException e) {
- throw e;
-
- } catch (NoSuchMethodException e) {
- fail (name + " constructor missing -- " + msg);
-
- } catch (ClassNotFoundException e) {
- fail (name + " class not found");
-
- } catch (Exception e) {
- // e.printStackTrace ();
- fail ("stage not available: " + e.getMessage ());
- }
- }
- // NOTREACHED
- return null;
- }
- }
-
- private static class Pipeline
- {
- Stage stage;
-
- // rest may be null
- Pipeline rest;
- EventConsumer next;
-
- Pipeline (Stage s)
- { stage = s; }
-
- public String toString ()
- {
- if (rest == null && next == null)
- return stage.toString ();
- if (rest != null)
- return stage + " | " + rest;
- throw new IllegalArgumentException ("next");
- }
-
- EventConsumer createPipeline ()
- throws IOException
- {
- if (next == null) {
- if (rest == null)
- next = stage.createStage (null);
- else
- next = stage.createStage (rest.createPipeline ());
- }
- return next;
- }
- }
-
-/*
- public static void main (String argv [])
- {
- try {
- // three basic terminus cases
- createPipeline ("null");
- createPipeline ("validate");
- createPipeline ("write ( stdout )");
-
- // four basic filters
- createPipeline ("nsfix | write ( stderr )");
- createPipeline ("wf | null");
- createPipeline ("null | null");
- createPipeline (
-"call ( http://www.example.com/services/xml-1a ) | xhtml ( stdout )");
-
- // tee junctions
- createPipeline ("tee ( validate ) | write ( stdout )");
- createPipeline ("tee ( nsfix | write ( stdout ) ) | validate");
-
- // longer pipeline
- createPipeline ("nsfix | tee ( validate ) | write ( stdout )");
- createPipeline (
- "null | wf | nsfix | tee ( validate ) | write ( stdout )");
-
- // try some parsing error cases
- try {
- createPipeline ("null ("); // extra token '('
- System.err.println ("** didn't report error");
- } catch (Exception e) {
- System.err.println ("== err: " + e.getMessage ()); }
-
- try {
- createPipeline ("nsfix |"); // extra token '|'
- System.err.println ("** didn't report error");
- } catch (Exception e) {
- System.err.println ("== err: " + e.getMessage ()); }
-
- try {
- createPipeline ("xhtml ( foo"); // missing right paren
- System.err.println ("** didn't report error");
- } catch (Exception e) {
- System.err.println ("== err: " + e.getMessage ()); }
-
- try {
- createPipeline ("xhtml ( foo bar"); // required right paren
- System.err.println ("** didn't report error");
- } catch (Exception e) {
- System.err.println ("== err: " + e.getMessage ()); }
-
- try {
- createPipeline ("tee ( nsfix | validate");// missing right paren
- System.err.println ("** didn't report error");
- } catch (Exception e) {
- System.err.println ("== err: " + e.getMessage ()); }
-
- // try some construction error cases
-
- try {
- createPipeline ("call"); // missing param
- System.err.println ("** didn't report error");
- } catch (Exception e) {
- System.err.println ("== err: " + e.getMessage ()); }
- try {
- createPipeline ("call ( foobar )"); // broken param
- System.err.println ("** didn't report error");
- } catch (Exception e) {
- System.err.println ("== err: " + e.getMessage ()); }
- try {
- createPipeline ("nsfix ( foobar )"); // illegal param
- System.err.println ("** didn't report error");
- } catch (Exception e) {
- System.err.println ("== err: " + e.getMessage ()); }
- try {
- createPipeline ("null ( foobar )"); // illegal param
- System.err.println ("** didn't report error");
- } catch (Exception e) {
- System.err.println ("== err: " + e.getMessage ()); }
- try {
- createPipeline ("wf ( foobar )"); // illegal param
- System.err.println ("** didn't report error");
- } catch (Exception e) {
- System.err.println ("== err: " + e.getMessage ()); }
- try {
- createPipeline ("xhtml ( foobar.html )");
- new File ("foobar.html").delete ();
- // now supported
- } catch (Exception e) {
- System.err.println ("** err: " + e.getMessage ()); }
- try {
- createPipeline ("xhtml"); // missing param
- System.err.println ("** didn't report error");
- } catch (Exception e) {
- System.err.println ("== err: " + e.getMessage ()); }
- try {
- createPipeline ("write ( stdout ) | null"); // nonterminal
- System.err.println ("** didn't report error");
- } catch (Exception e) {
- System.err.println ("== err: " + e.getMessage ()); }
- try {
- createPipeline ("validate | null");
- // now supported
- } catch (Exception e) {
- System.err.println ("** err: " + e.getMessage ()); }
- try {
- createPipeline ("validate ( foo )"); // illegal param
- System.err.println ("** didn't report error");
- } catch (Exception e) {
- System.err.println ("== err: " + e.getMessage ()); }
- try {
- createPipeline ("tee"); // missing param
- System.err.println ("** didn't report error");
- } catch (Exception e) {
- System.err.println ("== err: " + e.getMessage ()); }
- try {
- // only builtins so far
- createPipeline ("com.example.xml.FilterClass");
- System.err.println ("** didn't report error");
- } catch (Exception e) {
- System.err.println ("== err: " + e.getMessage ()); }
-
- } catch (Exception e) {
- e.printStackTrace ();
- }
- }
-/**/
-
-}
diff --git a/libjava/classpath/gnu/xml/pipeline/TeeConsumer.java b/libjava/classpath/gnu/xml/pipeline/TeeConsumer.java
deleted file mode 100644
index 3ac86057..0000000
--- a/libjava/classpath/gnu/xml/pipeline/TeeConsumer.java
+++ /dev/null
@@ -1,417 +0,0 @@
-/* TeeConsumer.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. */
-
-package gnu.xml.pipeline;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.DTDHandler;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXNotRecognizedException;
-import org.xml.sax.ext.DeclHandler;
-import org.xml.sax.ext.LexicalHandler;
-
-/**
- * Fans its events out to two other consumers, a "tee" filter stage in an
- * event pipeline. Networks can be assembled with multiple output points.
- *
- * <p> Error handling should be simple if you remember that exceptions
- * you throw will cancel later stages in that callback's pipeline, and
- * generally the producer will stop if it sees such an exception. You
- * may want to protect your pipeline against such backflows, making a
- * kind of reverse filter (or valve?) so that certain exceptions thrown by
- * your pipeline will caught and handled before the producer sees them.
- * Just use a "try/catch" block, rememebering that really important
- * cleanup tasks should be in "finally" clauses.
- *
- * <p> That issue isn't unique to "tee" consumers, but tee consumers have
- * the additional twist that exceptions thrown by the first consumer
- * will cause the second consumer not to see the callback (except for
- * the endDocument callback, which signals state cleanup).
- *
- * @author David Brownell
- */
-final public class TeeConsumer
- implements EventConsumer,
- ContentHandler, DTDHandler,
- LexicalHandler,DeclHandler
-{
- private EventConsumer first, rest;
-
- // cached to minimize time overhead
- private ContentHandler docFirst, docRest;
- private DeclHandler declFirst, declRest;
- private LexicalHandler lexFirst, lexRest;
-
-
- /**
- * Constructs a consumer which sends all its events to the first
- * consumer, and then the second one. If the first consumer throws
- * an exception, the second one will not see the event which
- * caused that exception to be reported.
- *
- * @param car The first consumer to get the events
- * @param cdr The second consumer to get the events
- */
- public TeeConsumer (EventConsumer car, EventConsumer cdr)
- {
- if (car == null || cdr == null)
- throw new NullPointerException ();
- first = car;
- rest = cdr;
-
- //
- // Cache the handlers.
- //
- docFirst = first.getContentHandler ();
- docRest = rest.getContentHandler ();
- // DTD handler isn't cached (rarely needed)
-
- try {
- declFirst = null;
- declFirst = (DeclHandler) first.getProperty (
- EventFilter.DECL_HANDLER);
- } catch (SAXException e) {}
- try {
- declRest = null;
- declRest = (DeclHandler) rest.getProperty (
- EventFilter.DECL_HANDLER);
- } catch (SAXException e) {}
-
- try {
- lexFirst = null;
- lexFirst = (LexicalHandler) first.getProperty (
- EventFilter.LEXICAL_HANDLER);
- } catch (SAXException e) {}
- try {
- lexRest = null;
- lexRest = (LexicalHandler) rest.getProperty (
- EventFilter.LEXICAL_HANDLER);
- } catch (SAXException e) {}
- }
-
-/* FIXME
- /**
- * Constructs a pipeline, and is otherwise a shorthand for the
- * two-consumer constructor for this class.
- *
- * @param first Description of the first pipeline to get events,
- * which will be passed to {@link PipelineFactory#createPipeline}
- * @param rest The second pipeline to get the events
- * /
- // constructor used by PipelineFactory
- public TeeConsumer (String first, EventConsumer rest)
- throws IOException
- {
- this (PipelineFactory.createPipeline (first), rest);
- }
-*/
-
- /** Returns the first pipeline to get event calls. */
- public EventConsumer getFirst ()
- { return first; }
-
- /** Returns the second pipeline to get event calls. */
- public EventConsumer getRest ()
- { return rest; }
-
- /** Returns the content handler being used. */
- final public ContentHandler getContentHandler ()
- {
- if (docRest == null)
- return docFirst;
- if (docFirst == null)
- return docRest;
- return this;
- }
-
- /** Returns the dtd handler being used. */
- final public DTDHandler getDTDHandler ()
- {
- // not cached (hardly used)
- if (rest.getDTDHandler () == null)
- return first.getDTDHandler ();
- if (first.getDTDHandler () == null)
- return rest.getDTDHandler ();
- return this;
- }
-
- /** Returns the declaration or lexical handler being used. */
- final public Object getProperty (String id)
- throws SAXNotRecognizedException
- {
- //
- // in degenerate cases, we have no work to do.
- //
- Object firstProp = null, restProp = null;
-
- try { firstProp = first.getProperty (id); }
- catch (SAXNotRecognizedException e) { /* ignore */ }
- try { restProp = rest.getProperty (id); }
- catch (SAXNotRecognizedException e) { /* ignore */ }
-
- if (restProp == null)
- return firstProp;
- if (firstProp == null)
- return restProp;
-
- //
- // we've got work to do; handle two builtin cases.
- //
- if (EventFilter.DECL_HANDLER.equals (id))
- return this;
- if (EventFilter.LEXICAL_HANDLER.equals (id))
- return this;
-
- //
- // non-degenerate, handled by both consumers, but we don't know
- // how to handle this.
- //
- throw new SAXNotRecognizedException ("can't tee: " + id);
- }
-
- /**
- * Provides the error handler to both subsequent nodes of
- * this filter stage.
- */
- public void setErrorHandler (ErrorHandler handler)
- {
- first.setErrorHandler (handler);
- rest.setErrorHandler (handler);
- }
-
-
- //
- // ContentHandler
- //
- public void setDocumentLocator (Locator locator)
- {
- // this call is not made by all parsers
- docFirst.setDocumentLocator (locator);
- docRest.setDocumentLocator (locator);
- }
-
- public void startDocument ()
- throws SAXException
- {
- docFirst.startDocument ();
- docRest.startDocument ();
- }
-
- public void endDocument ()
- throws SAXException
- {
- try {
- docFirst.endDocument ();
- } finally {
- docRest.endDocument ();
- }
- }
-
- public void startPrefixMapping (String prefix, String uri)
- throws SAXException
- {
- docFirst.startPrefixMapping (prefix, uri);
- docRest.startPrefixMapping (prefix, uri);
- }
-
- public void endPrefixMapping (String prefix)
- throws SAXException
- {
- docFirst.endPrefixMapping (prefix);
- docRest.endPrefixMapping (prefix);
- }
-
- public void skippedEntity (String name)
- throws SAXException
- {
- docFirst.skippedEntity (name);
- docRest.skippedEntity (name);
- }
-
- public void startElement (String uri, String localName,
- String qName, Attributes atts)
- throws SAXException
- {
- docFirst.startElement (uri, localName, qName, atts);
- docRest.startElement (uri, localName, qName, atts);
- }
-
- public void endElement (String uri, String localName, String qName)
- throws SAXException
- {
- docFirst.endElement (uri, localName, qName);
- docRest.endElement (uri, localName, qName);
- }
-
- public void processingInstruction (String target, String data)
- throws SAXException
- {
- docFirst.processingInstruction (target, data);
- docRest.processingInstruction (target, data);
- }
-
- public void characters (char ch [], int start, int length)
- throws SAXException
- {
- docFirst.characters (ch, start, length);
- docRest.characters (ch, start, length);
- }
-
- public void ignorableWhitespace (char ch [], int start, int length)
- throws SAXException
- {
- docFirst.ignorableWhitespace (ch, start, length);
- docRest.ignorableWhitespace (ch, start, length);
- }
-
-
- //
- // DTDHandler
- //
- public void notationDecl (String name, String publicId, String systemId)
- throws SAXException
- {
- DTDHandler l1 = first.getDTDHandler ();
- DTDHandler l2 = rest.getDTDHandler ();
-
- l1.notationDecl (name, publicId, systemId);
- l2.notationDecl (name, publicId, systemId);
- }
-
- public void unparsedEntityDecl (String name,
- String publicId, String systemId,
- String notationName
- ) throws SAXException
- {
- DTDHandler l1 = first.getDTDHandler ();
- DTDHandler l2 = rest.getDTDHandler ();
-
- l1.unparsedEntityDecl (name, publicId, systemId, notationName);
- l2.unparsedEntityDecl (name, publicId, systemId, notationName);
- }
-
-
- //
- // DeclHandler
- //
- public void attributeDecl (String eName, String aName,
- String type,
- String mode, String value)
- throws SAXException
- {
- declFirst.attributeDecl (eName, aName, type, mode, value);
- declRest.attributeDecl (eName, aName, type, mode, value);
- }
-
- public void elementDecl (String name, String model)
- throws SAXException
- {
- declFirst.elementDecl (name, model);
- declRest.elementDecl (name, model);
- }
-
- public void externalEntityDecl (String name,
- String publicId, String systemId)
- throws SAXException
- {
- declFirst.externalEntityDecl (name, publicId, systemId);
- declRest.externalEntityDecl (name, publicId, systemId);
- }
-
- public void internalEntityDecl (String name, String value)
- throws SAXException
- {
- declFirst.internalEntityDecl (name, value);
- declRest.internalEntityDecl (name, value);
- }
-
-
- //
- // LexicalHandler
- //
- public void comment (char ch [], int start, int length)
- throws SAXException
- {
- lexFirst.comment (ch, start, length);
- lexRest.comment (ch, start, length);
- }
-
- public void startCDATA ()
- throws SAXException
- {
- lexFirst.startCDATA ();
- lexRest.startCDATA ();
- }
-
- public void endCDATA ()
- throws SAXException
- {
- lexFirst.endCDATA ();
- lexRest.endCDATA ();
- }
-
- public void startEntity (String name)
- throws SAXException
- {
- lexFirst.startEntity (name);
- lexRest.startEntity (name);
- }
-
- public void endEntity (String name)
- throws SAXException
- {
- lexFirst.endEntity (name);
- lexRest.endEntity (name);
- }
-
- public void startDTD (String name, String publicId, String systemId)
- throws SAXException
- {
- lexFirst.startDTD (name, publicId, systemId);
- lexRest.startDTD (name, publicId, systemId);
- }
-
- public void endDTD ()
- throws SAXException
- {
- lexFirst.endDTD ();
- lexRest.endDTD ();
- }
-}
diff --git a/libjava/classpath/gnu/xml/pipeline/TextConsumer.java b/libjava/classpath/gnu/xml/pipeline/TextConsumer.java
deleted file mode 100644
index 13dcfa7..0000000
--- a/libjava/classpath/gnu/xml/pipeline/TextConsumer.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/* TextConsumer.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. */
-
-package gnu.xml.pipeline;
-
-import java.io.*;
-
-import org.xml.sax.*;
-
-import gnu.xml.util.XMLWriter;
-
-
-/**
- * Terminates a pipeline, consuming events to print them as well formed
- * XML (or XHTML) text.
- *
- * <p> Input must be well formed, and must include XML names (e.g. the
- * prefixes and prefix declarations must be present), or the output of
- * this class is undefined.
- *
- * @see NSFilter
- * @see WellFormednessFilter
- *
- * @author David Brownell
- */
-public class TextConsumer extends XMLWriter implements EventConsumer
-{
- /**
- * Constructs an event consumer which echoes its input as text,
- * optionally adhering to some basic XHTML formatting options
- * which increase interoperability with old (v3) browsers.
- *
- * <p> For the best interoperability, when writing as XHTML only
- * ASCII characters are emitted; other characters are turned to
- * entity or character references as needed, and no XML declaration
- * is provided in the document.
- */
- public TextConsumer (Writer w, boolean isXhtml)
- throws IOException
- {
- super (w, isXhtml ? "US-ASCII" : null);
- setXhtml (isXhtml);
- }
-
- /**
- * Constructs a consumer that writes its input as XML text.
- * XHTML rules are not followed.
- */
- public TextConsumer (Writer w)
- throws IOException
- {
- this (w, false);
- }
-
- /**
- * Constructs a consumer that writes its input as XML text,
- * encoded in UTF-8. XHTML rules are not followed.
- */
- public TextConsumer (OutputStream out)
- throws IOException
- {
- this (new OutputStreamWriter (out, "UTF8"), false);
- }
-
- /** <b>EventConsumer</b> Returns the document handler being used. */
- public ContentHandler getContentHandler ()
- { return this; }
-
- /** <b>EventConsumer</b> Returns the dtd handler being used. */
- public DTDHandler getDTDHandler ()
- { return this; }
-
- /** <b>XMLReader</b>Retrieves a property (lexical and decl handlers) */
- public Object getProperty (String propertyId)
- throws SAXNotRecognizedException
- {
- if (EventFilter.LEXICAL_HANDLER.equals (propertyId))
- return this;
- if (EventFilter.DECL_HANDLER.equals (propertyId))
- return this;
- throw new SAXNotRecognizedException (propertyId);
- }
-}
diff --git a/libjava/classpath/gnu/xml/pipeline/ValidationConsumer.java b/libjava/classpath/gnu/xml/pipeline/ValidationConsumer.java
deleted file mode 100644
index 0346984..0000000
--- a/libjava/classpath/gnu/xml/pipeline/ValidationConsumer.java
+++ /dev/null
@@ -1,1928 +0,0 @@
-/* ValidationConsumer.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. */
-
-package gnu.xml.pipeline;
-
-import java.io.IOException;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.util.EmptyStackException;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Stack;
-import java.util.StringTokenizer;
-import java.util.Vector;
-
-import org.xml.sax.Attributes;
-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.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-/**
- * This class checks SAX2 events to report validity errors; it works as
- * both a filter and a terminus on an event pipeline. It relies on the
- * producer of SAX events to: </p> <ol>
- *
- * <li> Conform to the specification of a non-validating XML parser that
- * reads all external entities, reported using SAX2 events. </li>
- *
- * <li> Report ignorable whitespace as such (through the ContentHandler
- * interface). This is, strictly speaking, optional for nonvalidating
- * XML processors. </li>
- *
- * <li> Make SAX2 DeclHandler callbacks, with default
- * attribute values already normalized (and without "&lt;").</li>
- *
- * <li> Make SAX2 LexicalHandler startDTD() and endDTD ()
- * callbacks. </li>
- *
- * <li> Act as if the <em>(URI)/namespace-prefixes</em> property were
- * set to true, by providing XML 1.0 names and all <code>xmlns*</code>
- * attributes (rather than omitting either or both). </li>
- *
- * </ol>
- *
- * <p> At this writing, the major SAX2 parsers (such as &AElig;lfred2,
- * Crimson, and Xerces) meet these requirements, and this validation
- * module is used by the optional &AElig;lfred2 validation support.
- * </p>
- *
- * <p> Note that because this is a layered validator, it has to duplicate some
- * work that the parser is doing; there are also other cost to layering.
- * However, <em>because of layering it doesn't need a parser</em> in order
- * to work! You can use it with anything that generates SAX events, such
- * as an application component that wants to detect invalid content in
- * a changed area without validating an entire document, or which wants to
- * ensure that it doesn't write invalid data to a communications partner.</p>
- *
- * <p> Also, note that because this is a layered validator, the line numbers
- * reported for some errors may seem strange. For example, if an element does
- * not permit character content, the validator
- * will use the locator provided to it.
- * That might reflect the last character of a <em>characters</em> event
- * callback, rather than the first non-whitespace character. </p>
- *
- * <hr />
- *
- * <!--
- * <p> Of interest is the fact that unlike most currently known XML validators,
- * this one can report some cases of non-determinism in element content models.
- * It is a compile-time option, enabled by default. This will only report
- * such XML errors if they relate to content actually appearing in a document;
- * content models aren't aggressively scanned for non-deterministic structure.
- * Documents which trigger such non-deterministic transitions may be handled
- * differently by different validating parsers, without losing conformance
- * to the XML specification. </p>
- * -->
- *
- * <p> Current limitations of the validation performed are in roughly three
- * categories. </p>
- *
- * <p> The first category represents constraints which demand violations
- * of software layering: exposing lexical details, one of the first things
- * that <em>application</em> programming interfaces (APIs) hide. These
- * invariably relate to XML entity handling, and to historical oddities
- * of the XML validation semantics. Curiously,
- * recent (Autumn 1999) conformance testing showed that these constraints are
- * among those handled worst by existing XML validating parsers. Arguments
- * have been made that each of these VCs should be turned into WFCs (most
- * of them) or discarded (popular for the standalone declaration); in short,
- * that these are bugs in the XML specification (not all via SGML): </p><ul>
- *
- * <li> The <em>Proper Declaration/PE Nesting</em> and
- * <em>Proper Group/PE Nesting</em> VCs can't be tested because they
- * require access to particularly low level lexical level information.
- * In essence, the reason XML isn't a simple thing to parse is that
- * it's not a context free grammar, and these constraints elevate that
- * SGML-derived context sensitivity to the level of a semantic rule.
- *
- * <li> The <em>Standalone Document Declaration</em> VC can't be
- * tested. This is for two reasons. First, this flag isn't made
- * available through SAX2. Second, it also requires breaking that
- * lexical layering boundary. (If you ever wondered why classes
- * in compiler construction or language design barely mention the
- * existence of context-sensitive grammars, it's because of messy
- * issues like these.)
- *
- * <li> The <em>Entity Declared</em> VC can't be tested, because it
- * also requires breaking that lexical layering boundary! There's also
- * another issue: the VC wording (and seemingly intent) is ambiguous.
- * (This is still true in the "Second edition" XML spec.)
- * Since there is a WFC of the same name, everyone's life would be
- * easier if references to undeclared parsed entities were always well
- * formedness errors, regardless of whether they're parameter entities
- * or not. (Note that nonvalidating parsers are not required
- * to report all such well formedness errors if they don't read external
- * parameter entities, although currently most XML parsers read them
- * in an attempt to avoid problems from inconsistent parser behavior.)
- *
- * </ul>
- *
- * <p> The second category of limitations on this validation represent
- * constraints associated with information that is not guaranteed to be
- * available (or in one case, <em>is guaranteed not to be available</em>,
- * through the SAX2 API: </p><ul>
- *
- * <li> The <em>Unique Element Type Declaration</em> VC may not be
- * reportable, if the underlying parser happens not to expose
- * multiple declarations. (&AElig;lfred2 reports these validity
- * errors directly.)</li>
- *
- * <li> Similarly, the <em>Unique Notation Name</em> VC, added in the
- * 14-January-2000 XML spec errata to restrict typing models used by
- * elements, may not be reportable. (&AElig;lfred reports these
- * validity errors directly.) </li>
- *
- * </ul>
- *
- * <p> A third category relates to ease of implementation. (Think of this
- * as "bugs".) The most notable issue here is character handling. Rather
- * than attempting to implement the voluminous character tables in the XML
- * specification (Appendix B), Unicode rules are used directly from
- * the java.lang.Character class. Recent JVMs have begun to diverge from
- * the original specification for that class (Unicode 2.0), meaning that
- * different JVMs may handle that aspect of conformance differently.
- * </p>
- *
- * <p> Note that for some of the validity errors that SAX2 does not
- * expose, a nonvalidating parser is permitted (by the XML specification)
- * to report validity errors. When used with a parser that does so for
- * the validity constraints mentioned above (or any other SAX2 event
- * stream producer that does the same thing), overall conformance is
- * substantially improved.
- *
- * @see gnu.xml.aelfred2.SAXDriver
- * @see gnu.xml.aelfred2.XmlReader
- *
- * @author David Brownell
- */
-public final class ValidationConsumer extends EventFilter
-{
- // report error if we happen to notice a non-deterministic choice?
- // we won't report buggy content models; just buggy instances
- private static final boolean warnNonDeterministic = false;
-
- // for tracking active content models
- private String rootName;
- private Stack contentStack = new Stack ();
-
- // flags for "saved DTD" processing
- private boolean disableDeclarations;
- private boolean disableReset;
-
- //
- // most VCs get tested when we see element start tags. the per-element
- // info (including attributes) recorded here duplicates that found inside
- // many nonvalidating parsers, hence dual lookups etc ... that's why a
- // layered validator isn't going to be as fast as a non-layered one.
- //
-
- // key = element name; value = ElementInfo
- private Hashtable elements = new Hashtable ();
-
- // some VCs relate to ID/IDREF/IDREFS attributes
- // key = id; value = boolean true (defd) or false (refd)
- private Hashtable ids = new Hashtable ();
-
- // we just record declared notation and unparsed entity names.
- // the implementation here is simple/slow; these features
- // are seldom used, one hopes they'll wither away soon
- private Vector notations = new Vector (5, 5);
- private Vector nDeferred = new Vector (5, 5);
- private Vector unparsed = new Vector (5, 5);
- private Vector uDeferred = new Vector (5, 5);
-
- // note: DocBk 3.1.7 XML defines over 2 dozen notations,
- // used when defining unparsed entities for graphics
- // (and maybe in other places)
-
-
-
- /**
- * Creates a pipeline terminus which consumes all events passed to
- * it; this will report validity errors as if they were fatal errors,
- * unless an error handler is assigned.
- *
- * @see #setErrorHandler
- */
- // constructor used by PipelineFactory
- // ... and want one taking system ID of an external subset
- public ValidationConsumer ()
- {
- this (null);
- }
-
- /**
- * Creates a pipeline filter which reports validity errors and then
- * passes events on to the next consumer if they were not fatal.
- *
- * @see #setErrorHandler
- */
- // constructor used by PipelineFactory
- // ... and want one taking system ID of an external subset
- // (which won't send declaration events)
- public ValidationConsumer (EventConsumer next)
- {
- super (next);
-
- setContentHandler (this);
- setDTDHandler (this);
- try { setProperty (DECL_HANDLER, this); }
- catch (Exception e) { /* "can't happen" */ }
- try { setProperty (LEXICAL_HANDLER, this); }
- catch (Exception e) { /* "can't happen" */ }
- }
-
-
- private static final String fakeRootName
- = ":Nobody:in:their_Right.Mind_would:use:this-name:1x:";
-
- /**
- * Creates a validation consumer which is preloaded with the DTD provided.
- * It does this by constructing a document with that DTD, then parsing
- * that document and recording its DTD declarations. Then it arranges
- * not to modify that information.
- *
- * <p> The resulting validation consumer will only validate against
- * the specified DTD, regardless of whether some other DTD is found
- * in a document being parsed.
- *
- * @param rootName The name of the required root element; if this is
- * null, any root element name will be accepted.
- * @param publicId If non-null and there is a non-null systemId, this
- * identifier provides an alternate access identifier for the DTD's
- * external subset.
- * @param systemId If non-null, this is a URI (normally URL) that
- * may be used to access the DTD's external subset.
- * @param internalSubset If non-null, holds literal markup declarations
- * comprising the DTD's internal subset.
- * @param resolver If non-null, this will be provided to the parser for
- * use when resolving parameter entities (including any external subset).
- * @param resolver If non-null, this will be provided to the parser for
- * use when resolving parameter entities (including any external subset).
- * @param minimalElement If non-null, a minimal valid document.
- *
- * @exception SAXNotSupportedException If the default SAX parser does
- * not support the standard lexical or declaration handlers.
- * @exception SAXParseException If the specified DTD has either
- * well-formedness or validity errors
- * @exception IOException If the specified DTD can't be read for
- * some reason
- */
- public ValidationConsumer (
- String rootName,
- String publicId,
- String systemId,
- String internalSubset,
- EntityResolver resolver,
- String minimalDocument
- ) throws SAXException, IOException
- {
- this (null);
-
- disableReset = true;
- if (rootName == null)
- rootName = fakeRootName;
-
- //
- // Synthesize document with that DTD; is it possible to do
- // better for the declaration of the root element?
- //
- // NOTE: can't use SAX2 to write internal subsets.
- //
- StringWriter writer = new StringWriter ();
-
- writer.write ("<!DOCTYPE ");
- writer.write (rootName);
- if (systemId != null) {
- writer.write ("\n ");
- if (publicId != null) {
- writer.write ("PUBLIC '");
- writer.write (publicId);
- writer.write ("'\n\t'");
- } else
- writer.write ("SYSTEM '");
- writer.write (systemId);
- writer.write ("'");
- }
- writer.write (" [ ");
- if (rootName == fakeRootName) {
- writer.write ("\n<!ELEMENT ");
- writer.write (rootName);
- writer.write (" EMPTY>");
- }
- if (internalSubset != null)
- writer.write (internalSubset);
- writer.write ("\n ]>");
-
- if (minimalDocument != null) {
- writer.write ("\n");
- writer.write (minimalDocument);
- writer.write ("\n");
- } else {
- writer.write (" <");
- writer.write (rootName);
- writer.write ("/>\n");
- }
- minimalDocument = writer.toString ();
-
- //
- // OK, load it
- //
- XMLReader producer;
-
- producer = XMLReaderFactory.createXMLReader ();
- bind (producer, this);
-
- if (resolver != null)
- producer.setEntityResolver (resolver);
-
- InputSource in;
-
- in = new InputSource (new StringReader (minimalDocument));
- producer.parse (in);
-
- disableDeclarations = true;
- if (rootName == fakeRootName)
- this.rootName = null;
- }
-
- private void resetState ()
- {
- if (!disableReset) {
- rootName = null;
- contentStack.removeAllElements ();
- elements.clear ();
- ids.clear ();
-
- notations.removeAllElements ();
- nDeferred.removeAllElements ();
- unparsed.removeAllElements ();
- uDeferred.removeAllElements ();
- }
- }
-
-
- private void warning (String description)
- throws SAXException
- {
- ErrorHandler errHandler = getErrorHandler ();
- Locator locator = getDocumentLocator ();
- SAXParseException err;
-
- if (errHandler == null)
- return;
-
- if (locator == null)
- err = new SAXParseException (description, null, null, -1, -1);
- else
- err = new SAXParseException (description, locator);
- errHandler.warning (err);
- }
-
- // package private (for ChildrenRecognizer)
- private void error (String description)
- throws SAXException
- {
- ErrorHandler errHandler = getErrorHandler ();
- Locator locator = getDocumentLocator ();
- SAXParseException err;
-
- if (locator == null)
- err = new SAXParseException (description, null, null, -1, -1);
- else
- err = new SAXParseException (description, locator);
- if (errHandler != null)
- errHandler.error (err);
- else // else we always treat it as fatal!
- throw err;
- }
-
- private void fatalError (String description)
- throws SAXException
- {
- ErrorHandler errHandler = getErrorHandler ();
- Locator locator = getDocumentLocator ();
- SAXParseException err;
-
- if (locator != null)
- err = new SAXParseException (description, locator);
- else
- err = new SAXParseException (description, null, null, -1, -1);
- if (errHandler != null)
- errHandler.fatalError (err);
- // we always treat this as fatal, regardless of the handler
- throw err;
- }
-
-
- private static boolean isExtender (char c)
- {
- // [88] Extender ::= ...
- return c == 0x00b7 || c == 0x02d0 || c == 0x02d1 || c == 0x0387
- || c == 0x0640 || c == 0x0e46 || c == 0x0ec6 || c == 0x3005
- || (c >= 0x3031 && c <= 0x3035)
- || (c >= 0x309d && c <= 0x309e)
- || (c >= 0x30fc && c <= 0x30fe);
- }
-
-
- // use augmented Unicode rules, not full XML rules
- private boolean isName (String name, String context, String id)
- throws SAXException
- {
- char buf [] = name.toCharArray ();
- boolean pass = true;
-
- if (!Character.isUnicodeIdentifierStart (buf [0])
- && ":_".indexOf (buf [0]) == -1)
- pass = false;
- else {
- int max = buf.length;
- for (int i = 1; pass && i < max; i++) {
- char c = buf [i];
- if (!Character.isUnicodeIdentifierPart (c)
- && ":-_.".indexOf (c) == -1
- && !isExtender (c))
- pass = false;
- }
- }
-
- if (!pass)
- error ("In " + context + " for " + id
- + ", '" + name + "' is not a name");
- return pass; // true == OK
- }
-
- // use augmented Unicode rules, not full XML rules
- private boolean isNmtoken (String nmtoken, String context, String id)
- throws SAXException
- {
- char buf [] = nmtoken.toCharArray ();
- boolean pass = true;
- int max = buf.length;
-
- // XXX make this share code with isName
-
- for (int i = 0; pass && i < max; i++) {
- char c = buf [i];
- if (!Character.isUnicodeIdentifierPart (c)
- && ":-_.".indexOf (c) == -1
- && !isExtender (c))
- pass = false;
- }
-
- if (!pass)
- error ("In " + context + " for " + id
- + ", '" + nmtoken + "' is not a name token");
- return pass; // true == OK
- }
-
- private void checkEnumeration (String value, String type, String name)
- throws SAXException
- {
- if (!hasMatch (value, type))
- // VC: Enumeration
- error ("Value '" + value
- + "' for attribute '" + name
- + "' is not permitted: " + type);
- }
-
- // used to test enumerated attributes and mixed content models
- // package private
- static boolean hasMatch (String value, String orList)
- {
- int len = value.length ();
- int max = orList.length () - len;
-
- for (int start = 0;
- (start = orList.indexOf (value, start)) != -1;
- start++) {
- char c;
-
- if (start > max)
- break;
- c = orList.charAt (start - 1);
- if (c != '|' && c != '('/*)*/)
- continue;
- c = orList.charAt (start + len);
- if (c != '|' && /*(*/ c != ')')
- continue;
- return true;
- }
- return false;
- }
-
- /**
- * <b>LexicalHandler</b> Records the declaration of the root
- * element, so it can be verified later.
- * Passed to the next consumer, unless this one was
- * preloaded with a particular DTD.
- */
- public void startDTD (String name, String publicId, String systemId)
- throws SAXException
- {
- if (disableDeclarations)
- return;
-
- rootName = name;
- super.startDTD (name, publicId, systemId);
- }
-
- /**
- * <b>LexicalHandler</b> Verifies that all referenced notations
- * and unparsed entities have been declared.
- * Passed to the next consumer, unless this one was
- * preloaded with a particular DTD.
- */
- public void endDTD ()
- throws SAXException
- {
- if (disableDeclarations)
- return;
-
- // this is a convenient hook for end-of-dtd checks, but we
- // could also trigger it in the first startElement call.
- // locator info is more appropriate here though.
-
- // VC: Notation Declared (NDATA can refer to them before decls,
- // as can NOTATION attribute enumerations and defaults)
- int length = nDeferred.size ();
- for (int i = 0; i < length; i++) {
- String notation = (String) nDeferred.elementAt (i);
- if (!notations.contains (notation)) {
- error ("A declaration referred to notation '" + notation
- + "' which was never declared");
- }
- }
- nDeferred.removeAllElements ();
-
- // VC: Entity Name (attribute values can refer to them
- // before they're declared); VC Attribute Default Legal
- length = uDeferred.size ();
- for (int i = 0; i < length; i++) {
- String entity = (String) uDeferred.elementAt (i);
- if (!unparsed.contains (entity)) {
- error ("An attribute default referred to entity '" + entity
- + "' which was never declared");
- }
- }
- uDeferred.removeAllElements ();
- super.endDTD ();
- }
-
-
- // These are interned, so we can rely on "==" to find the type of
- // all attributes except enumerations ...
- // "(this|or|that|...)" and "NOTATION (this|or|that|...)"
- static final String types [] = {
- "CDATA",
- "ID", "IDREF", "IDREFS",
- "NMTOKEN", "NMTOKENS",
- "ENTITY", "ENTITIES"
- };
-
-
- /**
- * <b>DecllHandler</b> Records attribute declaration for later use
- * in validating document content, and checks validity constraints
- * that are applicable to attribute declarations.
- * Passed to the next consumer, unless this one was
- * preloaded with a particular DTD.
- */
- public void attributeDecl (
- String eName,
- String aName,
- String type,
- String mode,
- String value
- ) throws SAXException
- {
- if (disableDeclarations)
- return;
-
- ElementInfo info = (ElementInfo) elements.get (eName);
- AttributeInfo ainfo = new AttributeInfo ();
- boolean checkOne = false;
- boolean interned = false;
-
- // cheap interning of type names and #FIXED, #REQUIRED
- // for faster startElement (we can use "==")
- for (int i = 0; i < types.length; i++) {
- if (types [i].equals (type)) {
- type = types [i];
- interned = true;
- break;
- }
- }
- if ("#FIXED".equals (mode))
- mode = "#FIXED";
- else if ("#REQUIRED".equals (mode))
- mode = "#REQUIRED";
-
- ainfo.type = type;
- ainfo.mode = mode;
- ainfo.value = value;
-
- // we might not have seen the content model yet
- if (info == null) {
- info = new ElementInfo (eName);
- elements.put (eName, info);
- }
- if ("ID" == type) {
- checkOne = true;
- if (!("#REQUIRED" == mode || "#IMPLIED".equals (mode))) {
- // VC: ID Attribute Default
- error ("ID attribute '" + aName
- + "' must be #IMPLIED or #REQUIRED");
- }
-
- } else if (!interned && type.startsWith ("NOTATION ")) {
- checkOne = true;
-
- // VC: Notation Attributes (notations must be declared)
- StringTokenizer tokens = new StringTokenizer (
- type.substring (10, type.lastIndexOf (')')),
- "|");
- while (tokens.hasMoreTokens ()) {
- String token = tokens.nextToken ();
- if (!notations.contains (token))
- nDeferred.addElement (token);
- }
- }
- if (checkOne) {
- for (Enumeration e = info.attributes.keys ();
- e.hasMoreElements ();
- /* NOP */) {
- String name;
- AttributeInfo ainfo2;
-
- name = (String) e.nextElement ();
- ainfo2 = (AttributeInfo) info.attributes.get (name);
- if (type == ainfo2.type || !interned /* NOTATION */) {
- // VC: One ID per Element Type
- // VC: One Notation per Element TYpe
- error ("Element '" + eName
- + "' already has an attribute of type "
- + (interned ? "NOTATION" : type)
- + " ('" + name
- + "') so '" + aName
- + "' is a validity error");
- }
- }
- }
-
- // VC: Attribute Default Legal
- if (value != null) {
-
- if ("CDATA" == type) {
- // event source rejected '<'
-
- } else if ("NMTOKEN" == type) {
- // VC: Name Token (is a nmtoken)
- isNmtoken (value, "attribute default", aName);
-
- } else if ("NMTOKENS" == type) {
- // VC: Name Token (is a nmtoken; at least one value)
- StringTokenizer tokens = new StringTokenizer (value);
- if (!tokens.hasMoreTokens ())
- error ("Default for attribute '" + aName
- + "' must have at least one name token.");
- else do {
- String token = tokens.nextToken ();
- isNmtoken (token, "attribute default", aName);
- } while (tokens.hasMoreTokens ());
-
- } else if ("IDREF" == type || "ENTITY" == type) {
- // VC: Entity Name (is a name)
- // VC: IDREF (is a name) (is declared)
- isName (value, "attribute default", aName);
- if ("ENTITY" == type && !unparsed.contains (value))
- uDeferred.addElement (value);
-
- } else if ("IDREFS" == type || "ENTITIES" == type) {
- // VC: Entity Name (is a name; at least one value)
- // VC: IDREF (is a name; at least one value)
- StringTokenizer names = new StringTokenizer (value);
- if (!names.hasMoreTokens ())
- error ("Default for attribute '" + aName
- + "' must have at least one name.");
- else do {
- String name = names.nextToken ();
- isName (name, "attribute default", aName);
- if ("ENTITIES" == type && !unparsed.contains (name))
- uDeferred.addElement (value);
- } while (names.hasMoreTokens ());
-
- } else if (type.charAt (0) == '(' /*)*/ ) {
- // VC: Enumeration (must match)
- checkEnumeration (value, type, aName);
-
- } else if (!interned && checkOne) { /* NOTATION */
- // VC: Notation attributes (must be names)
- isName (value, "attribute default", aName);
-
- // VC: Notation attributes (must be declared)
- if (!notations.contains (value))
- nDeferred.addElement (value);
-
- // VC: Enumeration (must match)
- checkEnumeration (value, type, aName);
-
- } else if ("ID" != type)
- throw new RuntimeException ("illegal attribute type: " + type);
- }
-
- if (info.attributes.get (aName) == null)
- info.attributes.put (aName, ainfo);
- /*
- else
- warning ("Element '" + eName
- + "' already has an attribute named '" + aName + "'");
- */
-
- if ("xml:space".equals (aName)) {
- if (!("(default|preserve)".equals (type)
- || "(preserve|default)".equals (type)
- // these next two are arguable; XHTML's DTD doesn't
- // deserve errors. After all, it's not like any
- // illegal _value_ could pass ...
- || "(preserve)".equals (type)
- || "(default)".equals (type)
- ))
- error (
- "xml:space attribute type must be like '(default|preserve)'"
- + " not '" + type + "'"
- );
-
- }
- super.attributeDecl (eName, aName, type, mode, value);
- }
-
- /**
- * <b>DecllHandler</b> Records the element declaration for later use
- * when checking document content, and checks validity constraints that
- * apply to element declarations. Passed to the next consumer, unless
- * this one was preloaded with a particular DTD.
- */
- public void elementDecl (String name, String model)
- throws SAXException
- {
- if (disableDeclarations)
- return;
-
- ElementInfo info = (ElementInfo) elements.get (name);
-
- // we might have seen an attribute decl already
- if (info == null) {
- info = new ElementInfo (name);
- elements.put (name, info);
- }
- if (info.model != null) {
- // NOTE: not all parsers can report such duplicates.
- // VC: Unique Element Type Declaration
- error ("Element type '" + name
- + "' was already declared.");
- } else {
- info.model = model;
-
- // VC: No Duplicate Types (in mixed content models)
- if (model.charAt (1) == '#') // (#PCDATA...
- info.getRecognizer (this);
- }
- super.elementDecl (name, model);
- }
-
- /**
- * <b>DecllHandler</b> passed to the next consumer, unless this
- * one was preloaded with a particular DTD
- */
- public void internalEntityDecl (String name, String value)
- throws SAXException
- {
- if (!disableDeclarations)
- super.internalEntityDecl (name, value);
- }
-
- /**
- * <b>DecllHandler</b> passed to the next consumer, unless this
- * one was preloaded with a particular DTD
- */
- public void externalEntityDecl (String name,
- String publicId, String systemId)
- throws SAXException
- {
- if (!disableDeclarations)
- super.externalEntityDecl (name, publicId, systemId);
- }
-
-
- /**
- * <b>DTDHandler</b> Records the notation name, for checking
- * NOTATIONS attribute values and declararations of unparsed
- * entities. Passed to the next consumer, unless this one was
- * preloaded with a particular DTD.
- */
- public void notationDecl (String name, String publicId, String systemId)
- throws SAXException
- {
- if (disableDeclarations)
- return;
-
- notations.addElement (name);
- super.notationDecl (name, publicId, systemId);
- }
-
- /**
- * <b>DTDHandler</b> Records the entity name, for checking
- * ENTITY and ENTITIES attribute values; records the notation
- * name if it hasn't yet been declared. Passed to the next consumer,
- * unless this one was preloaded with a particular DTD.
- */
- public void unparsedEntityDecl (
- String name,
- String publicId,
- String systemId,
- String notationName
- ) throws SAXException
- {
- if (disableDeclarations)
- return;
-
- unparsed.addElement (name);
- if (!notations.contains (notationName))
- nDeferred.addElement (notationName);
- super.unparsedEntityDecl (name, publicId, systemId, notationName);
- }
-
-
- /**
- * <b>ContentHandler</b> Ensures that state from any previous parse
- * has been deleted.
- * Passed to the next consumer.
- */
- public void startDocument ()
- throws SAXException
- {
- resetState ();
- super.startDocument ();
- }
-
-
- private static boolean isAsciiLetter (char c)
- {
- return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
- }
-
-
- /**
- * <b>ContentHandler</b> Reports a fatal exception. Validating
- * XML processors may not skip any entities.
- */
- public void skippedEntity (String name)
- throws SAXException
- {
- fatalError ("may not skip entities");
- }
-
- /*
- * SAX2 doesn't expand non-PE refs in attribute defaults...
- */
- private String expandDefaultRefs (String s)
- throws SAXException
- {
- if (s.indexOf ('&') < 0)
- return s;
-
-// FIXME: handle &#nn; &#xnn; &name;
- String message = "Can't expand refs in attribute default: " + s;
- warning (message);
-
- return s;
- }
-
- /**
- * <b>ContentHandler</b> Performs validity checks against element
- * (and document) content models, and attribute values.
- * Passed to the next consumer.
- */
- public void startElement (
- String uri,
- String localName,
- String qName,
- Attributes atts
- ) throws SAXException
- {
- //
- // First check content model for the enclosing scope.
- //
- if (contentStack.isEmpty ()) {
- // VC: Root Element Type
- if (!qName.equals (rootName)) {
- if (rootName == null)
- warning ("This document has no DTD, can't be valid");
- else
- error ("Root element type '" + qName
- + "' was declared to be '" + rootName + "'");
- }
- } else {
- Recognizer state = (Recognizer) contentStack.peek ();
-
- if (state != null) {
- Recognizer newstate = state.acceptElement (qName);
-
- if (newstate == null)
- error ("Element type '" + qName
- + "' in element '" + state.type.name
- + "' violates content model " + state.type.model
- );
- if (newstate != state) {
- contentStack.pop ();
- contentStack.push (newstate);
- }
- }
- }
-
- //
- // Then check that this element was declared, and push the
- // object used to validate its content model onto our stack.
- //
- // This is where the recognizer gets created, if needed; if
- // it's a "children" (elements) content model, an NDFA is
- // created. (One recognizer is used per content type, no
- // matter how complex that recognizer is.)
- //
- ElementInfo info;
-
- info = (ElementInfo) elements.get (qName);
- if (info == null || info.model == null) {
- // VC: Element Valid (base clause)
- error ("Element type '" + qName + "' was not declared");
- contentStack.push (null);
-
- // for less diagnostic noise, fake a declaration.
- elementDecl (qName, "ANY");
- } else
- contentStack.push (info.getRecognizer (this));
-
- //
- // Then check each attribute present
- //
- int len;
- String aname;
- AttributeInfo ainfo;
-
- if (atts != null)
- len = atts.getLength ();
- else
- len = 0;
-
- for (int i = 0; i < len; i++) {
- aname = atts.getQName (i);
-
- if (info == null
- || (ainfo = (AttributeInfo) info.attributes.get (aname))
- == null) {
- // VC: Attribute Value Type
- error ("Attribute '" + aname
- + "' was not declared for element type " + qName);
- continue;
- }
-
- String value = atts.getValue (i);
-
- // note that "==" for type names and "#FIXED" is correct
- // (and fast) since we've interned those literals.
-
- if ("#FIXED" == ainfo.mode) {
- String expanded = expandDefaultRefs (ainfo.value);
-
- // VC: Fixed Attribute Default
- if (!value.equals (expanded)) {
- error ("Attribute '" + aname
- + "' must match " + expanded
- );
- continue;
- }
- }
-
- if ("CDATA" == ainfo.type)
- continue;
-
- //
- // For all other attribute types, there are various
- // rules to follow.
- //
-
- if ("ID" == ainfo.type) {
- // VC: ID (must be a name)
- if (isName (value, "ID attribute", aname)) {
- if (Boolean.TRUE == ids.get (value))
- // VC: ID (appears once)
- error ("ID attribute " + aname
- + " uses an ID value '" + value
- + "' which was already declared.");
- else
- // any forward refs are no longer problems
- ids.put (value, Boolean.TRUE);
- }
- continue;
- }
-
- if ("IDREF" == ainfo.type) {
- // VC: IDREF (value must be a name)
- if (isName (value, "IDREF attribute", aname)) {
- // VC: IDREF (must match some ID attribute)
- if (ids.get (value) == null)
- // new -- assume it's a forward ref
- ids.put (value, Boolean.FALSE);
- }
- continue;
- }
-
- if ("IDREFS" == ainfo.type) {
- StringTokenizer tokens = new StringTokenizer (value, " ");
-
- if (!tokens.hasMoreTokens ()) {
- // VC: IDREF (one or more values)
- error ("IDREFS attribute " + aname
- + " must have at least one ID ref");
- } else do {
- String id = tokens.nextToken ();
-
- // VC: IDREF (value must be a name)
- if (isName (id, "IDREFS attribute", aname)) {
- // VC: IDREF (must match some ID attribute)
- if (ids.get (id) == null)
- // new -- assume it's a forward ref
- ids.put (id, Boolean.FALSE);
- }
- } while (tokens.hasMoreTokens ());
- continue;
- }
-
- if ("NMTOKEN" == ainfo.type) {
- // VC: Name Token (is a name token)
- isNmtoken (value, "NMTOKEN attribute", aname);
- continue;
- }
-
- if ("NMTOKENS" == ainfo.type) {
- StringTokenizer tokens = new StringTokenizer (value, " ");
-
- if (!tokens.hasMoreTokens ()) {
- // VC: Name Token (one or more values)
- error ("NMTOKENS attribute " + aname
- + " must have at least one name token");
- } else do {
- String token = tokens.nextToken ();
-
- // VC: Name Token (is a name token)
- isNmtoken (token, "NMTOKENS attribute", aname);
- } while (tokens.hasMoreTokens ());
- continue;
- }
-
- if ("ENTITY" == ainfo.type) {
- if (!unparsed.contains (value))
- // VC: Entity Name
- error ("Value of attribute '" + aname
- + "' refers to unparsed entity '" + value
- + "' which was not declared.");
- continue;
- }
-
- if ("ENTITIES" == ainfo.type) {
- StringTokenizer tokens = new StringTokenizer (value, " ");
-
- if (!tokens.hasMoreTokens ()) {
- // VC: Entity Name (one or more values)
- error ("ENTITIES attribute " + aname
- + " must have at least one name token");
- } else do {
- String entity = tokens.nextToken ();
-
- if (!unparsed.contains (entity))
- // VC: Entity Name
- error ("Value of attribute '" + aname
- + "' refers to unparsed entity '" + entity
- + "' which was not declared.");
- } while (tokens.hasMoreTokens ());
- continue;
- }
-
- //
- // check for enumerations last; more expensive
- //
- if (ainfo.type.charAt (0) == '(' /*)*/
- || ainfo.type.startsWith ("NOTATION ")
- ) {
- // VC: Enumeration (value must be defined)
- checkEnumeration (value, ainfo.type, aname);
- continue;
- }
- }
-
- //
- // Last, check that all #REQUIRED attributes were provided
- //
- if (info != null) {
- Hashtable table = info.attributes;
-
- if (table.size () != 0) {
- Enumeration e = table.keys ();
-
- // XXX table.keys uses the heap, bleech -- slows things
-
- while (e.hasMoreElements ()) {
- aname = (String) e.nextElement ();
- ainfo = (AttributeInfo) table.get (aname);
-
- // "#REQUIRED" mode was interned in attributeDecl
- if ("#REQUIRED" == ainfo.mode
- && atts.getValue (aname) == null) {
- // VC: Required Attribute
- error ("Attribute '" + aname + "' must be specified "
- + "for element type " + qName);
- }
- }
- }
- }
- super.startElement (uri, localName, qName, atts);
- }
-
- /**
- * <b>ContentHandler</b> Reports a validity error if the element's content
- * model does not permit character data.
- * Passed to the next consumer.
- */
- public void characters (char ch [], int start, int length)
- throws SAXException
- {
- Recognizer state;
-
- if (contentStack.empty ())
- state = null;
- else
- state = (Recognizer) contentStack.peek ();
-
- // NOTE: if this ever supports with SAX parsers that don't
- // report ignorable whitespace as such (only XP?), this class
- // needs to morph it into ignorableWhitespace() as needed ...
-
- if (state != null && !state.acceptCharacters ())
- // VC: Element Valid (clauses three, four -- see recognizer)
- error ("Character content not allowed in element "
- + state.type.name);
-
- super.characters (ch, start, length);
- }
-
-
- /**
- * <b>ContentHandler</b> Reports a validity error if the element's content
- * model does not permit end-of-element yet, or a well formedness error
- * if there was no matching startElement call.
- * Passed to the next consumer.
- */
- public void endElement (String uri, String localName, String qName)
- throws SAXException
- {
- try {
- Recognizer state = (Recognizer) contentStack.pop ();
-
- if (state != null && !state.completed ())
- // VC: Element valid (clauses two, three, four; see Recognizer)
- error ("Premature end for element '"
- + state.type.name
- + "', content model "
- + state.type.model);
-
- // could insist on match of start element, but that's
- // something the input stream must to guarantee.
-
- } catch (EmptyStackException e) {
- fatalError ("endElement without startElement: " + qName
- + ((uri == null)
- ? ""
- : ( " { '" + uri + "', " + localName + " }")));
- }
- super.endElement (uri, localName, qName);
- }
-
- /**
- * <b>ContentHandler</b> Checks whether all ID values that were
- * referenced have been declared, and releases all resources.
- * Passed to the next consumer.
- *
- * @see #setDocumentLocator
- */
- public void endDocument ()
- throws SAXException
- {
- for (Enumeration idNames = ids.keys ();
- idNames.hasMoreElements ();
- /* NOP */) {
- String id = (String) idNames.nextElement ();
-
- if (Boolean.FALSE == ids.get (id)) {
- // VC: IDREF (must match ID)
- error ("Undeclared ID value '" + id
- + "' was referred to by an IDREF/IDREFS attribute");
- }
- }
-
- resetState ();
- super.endDocument ();
- }
-
-
- /** Holds per-element declarations */
- static private final class ElementInfo
- {
- String name;
- String model;
-
- // key = attribute name; value = AttributeInfo
- Hashtable attributes = new Hashtable (11);
-
- ElementInfo (String n) { name = n; }
-
- private Recognizer recognizer;
-
- // for validating content models: one per type, shared,
- // and constructed only on demand ... so unused elements do
- // not need to consume resources.
- Recognizer getRecognizer (ValidationConsumer consumer)
- throws SAXException
- {
- if (recognizer == null) {
- if ("ANY".equals (model))
- recognizer = ANY;
- else if ("EMPTY".equals (model))
- recognizer = new EmptyRecognizer (this);
- else if ('#' == model.charAt (1))
- // n.b. this constructor does a validity check
- recognizer = new MixedRecognizer (this, consumer);
- else
- recognizer = new ChildrenRecognizer (this, consumer);
- }
- return recognizer;
- }
- }
-
- /** Holds per-attribute declarations */
- static private final class AttributeInfo
- {
- String type;
- String mode; // #REQUIRED, etc (or null)
- String value; // or null
- }
-
-
- //
- // Content model validation
- //
-
- static private final Recognizer ANY = new Recognizer (null);
-
-
- // Base class defines the calls used to validate content,
- // and supports the "ANY" content model
- static private class Recognizer
- {
- final ElementInfo type;
-
- Recognizer (ElementInfo t) { type = t; }
-
- // return true iff character data is legal here
- boolean acceptCharacters ()
- throws SAXException
- // VC: Element Valid (third and fourth clauses)
- { return true; }
-
- // null return = failure
- // otherwise, next state (like an FSM)
- // prerequisite: tested that name was declared
- Recognizer acceptElement (String name)
- throws SAXException
- // VC: Element Valid (fourth clause)
- { return this; }
-
- // return true iff model is completed, can finish
- boolean completed ()
- throws SAXException
- // VC: Element Valid (fourth clause)
- { return true; }
-
- public String toString ()
- // n.b. "children" is the interesting case!
- { return (type == null) ? "ANY" : type.model; }
- }
-
- // "EMPTY" content model -- no characters or elements
- private static final class EmptyRecognizer extends Recognizer
- {
- public EmptyRecognizer (ElementInfo type)
- { super (type); }
-
- // VC: Element Valid (first clause)
- boolean acceptCharacters ()
- { return false; }
-
- // VC: Element Valid (first clause)
- Recognizer acceptElement (String name)
- { return null; }
- }
-
- // "Mixed" content model -- ANY, but restricts elements
- private static final class MixedRecognizer extends Recognizer
- {
- private String permitted [];
-
- // N.B. constructor tests for duplicated element names (VC)
- public MixedRecognizer (ElementInfo t, ValidationConsumer v)
- throws SAXException
- {
- super (t);
-
- // (#PCDATA...)* or (#PCDATA) ==> ... or empty
- // with the "..." being "|elname|..."
- StringTokenizer tokens = new StringTokenizer (
- t.model.substring (8, t.model.lastIndexOf (')')),
- "|");
- Vector vec = new Vector ();
-
- while (tokens.hasMoreTokens ()) {
- String token = tokens.nextToken ();
-
- if (vec.contains (token))
- v.error ("element " + token
- + " is repeated in mixed content model: "
- + t.model);
- else
- vec.addElement (token.intern ());
- }
- permitted = new String [vec.size ()];
- for (int i = 0; i < permitted.length; i++)
- permitted [i] = (String) vec.elementAt (i);
-
- // in one large machine-derived DTD sample, most of about
- // 250 mixed content models were empty, and 25 had ten or
- // more entries. 2 had over a hundred elements. Linear
- // search isn't obviously wrong.
- }
-
- // VC: Element Valid (third clause)
- Recognizer acceptElement (String name)
- {
- int length = permitted.length;
-
- // first pass -- optimistic w.r.t. event source interning
- // (and document validity)
- for (int i = 0; i < length; i++)
- if (permitted [i] == name)
- return this;
- // second pass -- pessimistic w.r.t. event source interning
- for (int i = 0; i < length; i++)
- if (permitted [i].equals (name))
- return this;
- return null;
- }
- }
-
-
- // recognizer loop flags, see later
- private static final int F_LOOPHEAD = 0x01;
- private static final int F_LOOPNEXT = 0x02;
-
- // for debugging -- used to label/count nodes in toString()
- private static int nodeCount;
-
- /**
- * "Children" content model -- these are nodes in NDFA state graphs.
- * They work in fixed space. Note that these graphs commonly have
- * cycles, handling features such as zero-or-more and one-or-more.
- *
- * <p>It's readonly, so only one copy is ever needed. The content model
- * stack may have any number of pointers into each graph, when a model
- * happens to be needed more than once due to element nesting. Since
- * traversing the graph just moves to another node, and never changes
- * it, traversals never interfere with each other.
- *
- * <p>There is an option to report non-deterministic models. These are
- * always XML errors, but ones which are not often reported despite the
- * fact that they can lead to different validating parsers giving
- * different results for the same input. (The XML spec doesn't require
- * them to be reported.)
- *
- * <p><b>FIXME</b> There's currently at least one known bug here, in that
- * it's not actually detecting the non-determinism it tries to detect.
- * (Of the "optional.xml" test, the once-or-twice-2* tests are all non-D;
- * maybe some others.) This may relate to the issue flagged below as
- * "should not" happen (but it was), which showed up when patching the
- * graph to have one exit node (or more EMPTY nodes).
- */
- private static final class ChildrenRecognizer extends Recognizer
- implements Cloneable
- {
- // for reporting non-deterministic content models
- // ... a waste of space if we're not reporting those!
- // ... along with the 'model' member (in base class)
- private ValidationConsumer consumer;
-
- // for CHOICE nodes -- each component is an arc that
- // accepts a different NAME (or is EMPTY indicating
- // NDFA termination).
- private Recognizer components [];
-
- // for NAME/SEQUENCE nodes -- accepts that NAME and
- // then goes to the next node (CHOICE, NAME, EMPTY).
- private String name;
- private Recognizer next;
-
- // loops always point back to a CHOICE node. we mark such choice
- // nodes (F_LOOPHEAD) for diagnostics and faster deep cloning.
- // We also mark nodes before back pointers (F_LOOPNEXT), to ensure
- // termination when we patch sequences and loops.
- private int flags;
-
-
- // prevent a needless indirection between 'this' and 'node'
- private void copyIn (ChildrenRecognizer node)
- {
- // model & consumer are already set
- components = node.components;
- name = node.name;
- next = node.next;
- flags = node.flags;
- }
-
- // used to construct top level "children" content models,
- public ChildrenRecognizer (ElementInfo type, ValidationConsumer vc)
- {
- this (vc, type);
- populate (type.model.toCharArray (), 0);
- patchNext (new EmptyRecognizer (type), null);
- }
-
- // used internally; populating is separate
- private ChildrenRecognizer (ValidationConsumer vc, ElementInfo type)
- {
- super (type);
- consumer = vc;
- }
-
-
- //
- // When rewriting some graph nodes we need deep clones in one case;
- // mostly shallow clones (what the JVM handles for us) are fine.
- //
- private ChildrenRecognizer shallowClone ()
- {
- try {
- return (ChildrenRecognizer) clone ();
- } catch (CloneNotSupportedException e) {
- throw new Error ("clone");
- }
- }
-
- private ChildrenRecognizer deepClone ()
- {
- return deepClone (new Hashtable (37));
- }
-
- private ChildrenRecognizer deepClone (Hashtable table)
- {
- ChildrenRecognizer retval;
-
- if ((flags & F_LOOPHEAD) != 0) {
- retval = (ChildrenRecognizer) table.get (this);
- if (retval != null)
- return this;
-
- retval = shallowClone ();
- table.put (this, retval);
- } else
- retval = shallowClone ();
-
- if (next != null) {
- if (next instanceof ChildrenRecognizer)
- retval.next = ((ChildrenRecognizer)next)
- .deepClone (table);
- else if (!(next instanceof EmptyRecognizer))
- throw new RuntimeException ("deepClone");
- }
-
- if (components != null) {
- retval.components = new Recognizer [components.length];
- for (int i = 0; i < components.length; i++) {
- Recognizer temp = components [i];
-
- if (temp == null)
- retval.components [i] = null;
- else if (temp instanceof ChildrenRecognizer)
- retval.components [i] = ((ChildrenRecognizer)temp)
- .deepClone (table);
- else if (!(temp instanceof EmptyRecognizer))
- throw new RuntimeException ("deepClone");
- }
- }
-
- return retval;
- }
-
- // connect subgraphs, first to next (sequencing)
- private void patchNext (Recognizer theNext, Hashtable table)
- {
- // backpointers must not be repatched or followed
- if ((flags & F_LOOPNEXT) != 0)
- return;
-
- // XXX this table "shouldn't" be needed, right?
- // but some choice nodes looped if it isn't there.
- if (table != null && table.get (this) != null)
- return;
- if (table == null)
- table = new Hashtable ();
-
- // NAME/SEQUENCE
- if (name != null) {
- if (next == null)
- next = theNext;
- else if (next instanceof ChildrenRecognizer) {
- ((ChildrenRecognizer)next).patchNext (theNext, table);
- } else if (!(next instanceof EmptyRecognizer))
- throw new RuntimeException ("patchNext");
- return;
- }
-
- // CHOICE
- for (int i = 0; i < components.length; i++) {
- if (components [i] == null)
- components [i] = theNext;
- else if (components [i] instanceof ChildrenRecognizer) {
- ((ChildrenRecognizer)components [i])
- .patchNext (theNext, table);
- } else if (!(components [i] instanceof EmptyRecognizer))
- throw new RuntimeException ("patchNext");
- }
-
- if (table != null && (flags & F_LOOPHEAD) != 0)
- table.put (this, this);
- }
-
- /**
- * Parses a 'children' spec (or recursively 'cp') and makes this
- * become a regular graph node.
- *
- * @return index after this particle
- */
- private int populate (char parseBuf [], int startPos)
- {
- int nextPos = startPos + 1;
- char c;
-
- if (nextPos < 0 || nextPos >= parseBuf.length)
- throw new IndexOutOfBoundsException ();
-
- // Grammar of the string is from the XML spec, but
- // with whitespace removed by the SAX parser.
-
- // children ::= (choice | seq) ('?' | '*' | '+')?
- // cp ::= (Name | choice | seq) ('?' | '*' | '+')?
- // choice ::= '(' cp ('|' choice)* ')'
- // seq ::= '(' cp (',' choice)* ')'
-
- // interior nodes only
- // cp ::= name ...
- if (parseBuf [startPos] != '('/*)*/) {
- boolean done = false;
- do {
- switch (c = parseBuf [nextPos]) {
- case '?': case '*': case '+':
- case '|': case ',':
- case /*(*/ ')':
- done = true;
- continue;
- default:
- nextPos++;
- continue;
- }
- } while (!done);
- name = new String (parseBuf, startPos, nextPos - startPos);
-
- // interior OR toplevel nodes
- // cp ::= choice ..
- // cp ::= seq ..
- } else {
- // collect everything as a separate list, and merge it
- // into "this" later if we can (SEQUENCE or singleton)
- ChildrenRecognizer first;
-
- first = new ChildrenRecognizer (consumer, type);
- nextPos = first.populate (parseBuf, nextPos);
- c = parseBuf [nextPos++];
-
- if (c == ',' || c == '|') {
- ChildrenRecognizer current = first;
- char separator = c;
- Vector v = null;
-
- if (separator == '|') {
- v = new Vector ();
- v.addElement (first);
- }
-
- do {
- ChildrenRecognizer link;
-
- link = new ChildrenRecognizer (consumer, type);
- nextPos = link.populate (parseBuf, nextPos);
-
- if (separator == ',') {
- current.patchNext (link, null);
- current = link;
- } else
- v.addElement (link);
-
- c = parseBuf [nextPos++];
- } while (c == separator);
-
- // choice ... collect everything into one array.
- if (separator == '|') {
- // assert v.size() > 1
- components = new Recognizer [v.size ()];
- for (int i = 0; i < components.length; i++) {
- components [i] = (Recognizer)
- v.elementAt (i);
- }
- // assert flags == 0
-
- // sequence ... merge into "this" to be smaller.
- } else
- copyIn (first);
-
- // treat singletons like one-node sequences.
- } else
- copyIn (first);
-
- if (c != /*(*/ ')')
- throw new RuntimeException ("corrupt content model");
- }
-
- //
- // Arity is optional, and the root of all fun. We keep the
- // FSM state graph simple by only having NAME/SEQUENCE and
- // CHOICE nodes (or EMPTY to terminate a model), easily
- // evaluated. So we rewrite each node that has arity, using
- // those primitives. We create loops here, if needed.
- //
- if (nextPos < parseBuf.length) {
- c = parseBuf [nextPos];
- if (c == '?' || c == '*' || c == '+') {
- nextPos++;
-
- // Rewrite 'zero-or-one' "?" arity to a CHOICE:
- // - SEQUENCE (clone, what's next)
- // - or, what's next
- // Size cost: N --> N + 1
- if (c == '?') {
- Recognizer once = shallowClone ();
-
- components = new Recognizer [2];
- components [0] = once;
- // components [1] initted to null
- name = null;
- next = null;
- flags = 0;
-
-
- // Rewrite 'zero-or-more' "*" arity to a CHOICE.
- // - LOOP (clone, back to this CHOICE)
- // - or, what's next
- // Size cost: N --> N + 1
- } else if (c == '*') {
- ChildrenRecognizer loop = shallowClone ();
-
- loop.patchNext (this, null);
- loop.flags |= F_LOOPNEXT;
- flags = F_LOOPHEAD;
-
- components = new Recognizer [2];
- components [0] = loop;
- // components [1] initted to null
- name = null;
- next = null;
-
-
- // Rewrite 'one-or-more' "+" arity to a SEQUENCE.
- // Basically (a)+ --> ((a),(a)*).
- // - this
- // - CHOICE
- // * LOOP (clone, back to the CHOICE)
- // * or, whatever's next
- // Size cost: N --> 2N + 1
- } else if (c == '+') {
- ChildrenRecognizer loop = deepClone ();
- ChildrenRecognizer choice;
-
- choice = new ChildrenRecognizer (consumer, type);
- loop.patchNext (choice, null);
- loop.flags |= F_LOOPNEXT;
- choice.flags = F_LOOPHEAD;
-
- choice.components = new Recognizer [2];
- choice.components [0] = loop;
- // choice.components [1] initted to null
- // choice.name, choice.next initted to null
-
- patchNext (choice, null);
- }
- }
- }
-
- return nextPos;
- }
-
- // VC: Element Valid (second clause)
- boolean acceptCharacters ()
- { return false; }
-
- // VC: Element Valid (second clause)
- Recognizer acceptElement (String type)
- throws SAXException
- {
- // NAME/SEQUENCE
- if (name != null) {
- if (name.equals (type))
- return next;
- return null;
- }
-
- // CHOICE ... optionally reporting nondeterminism we
- // run across. we won't check out every transition
- // for nondeterminism; only the ones we follow.
- Recognizer retval = null;
-
- for (int i = 0; i < components.length; i++) {
- Recognizer temp = components [i].acceptElement (type);
-
- if (temp == null)
- continue;
- else if (!warnNonDeterministic)
- return temp;
- else if (retval == null)
- retval = temp;
- else if (retval != temp)
- consumer.error ("Content model " + this.type.model
- + " is non-deterministic for " + type);
- }
- return retval;
- }
-
- // VC: Element Valid (second clause)
- boolean completed ()
- throws SAXException
- {
- // expecting a specific element
- if (name != null)
- return false;
-
- // choice, some sequences
- for (int i = 0; i < components.length; i++) {
- if (components [i].completed ())
- return true;
- }
-
- return false;
- }
-
-/** /
- // FOR DEBUGGING ... flattens the graph for printing.
-
- public String toString ()
- {
- StringBuffer buf = new StringBuffer ();
-
- // only one set of loop labels can be generated
- // at a time...
- synchronized (ANY) {
- nodeCount = 0;
-
- toString (buf, new Hashtable ());
- return buf.toString ();
- }
- }
-
- private void toString (StringBuffer buf, Hashtable table)
- {
- // When we visit a node, label and count it.
- // Nodes are never visited/counted more than once.
- // For small models labels waste space, but if arity
- // mappings were used the savings are substantial.
- // (Plus, the output can be more readily understood.)
- String temp = (String) table.get (this);
-
- if (temp != null) {
- buf.append ('{');
- buf.append (temp);
- buf.append ('}');
- return;
- } else {
- StringBuffer scratch = new StringBuffer (15);
-
- if ((flags & F_LOOPHEAD) != 0)
- scratch.append ("loop");
- else
- scratch.append ("node");
- scratch.append ('-');
- scratch.append (++nodeCount);
- temp = scratch.toString ();
-
- table.put (this, temp);
- buf.append ('[');
- buf.append (temp);
- buf.append (']');
- buf.append (':');
- }
-
- // NAME/SEQUENCE
- if (name != null) {
- // n.b. some output encodings turn some name chars into '?'
- // e.g. with Japanese names and ASCII output
- buf.append (name);
- if (components != null) // bug!
- buf.append ('$');
- if (next == null)
- buf.append (",*");
- else if (next instanceof EmptyRecognizer) // patch-to-next
- buf.append (",{}");
- else if (next instanceof ChildrenRecognizer) {
- buf.append (',');
- ((ChildrenRecognizer)next).toString (buf, table);
- } else // bug!
- buf.append (",+");
- return;
- }
-
- // CHOICE
- buf.append ("<");
- for (int i = 0; i < components.length; i++) {
- if (i != 0)
- buf.append ("|");
- if (components [i] instanceof EmptyRecognizer) {
- buf.append ("{}");
- } else if (components [i] == null) { // patch-to-next
- buf.append ('*');
- } else {
- ChildrenRecognizer r;
-
- r = (ChildrenRecognizer) components [i];
- r.toString (buf, table);
- }
- }
- buf.append (">");
- }
-/**/
- }
-}
diff --git a/libjava/classpath/gnu/xml/pipeline/WellFormednessFilter.java b/libjava/classpath/gnu/xml/pipeline/WellFormednessFilter.java
deleted file mode 100644
index 7a3db65..0000000
--- a/libjava/classpath/gnu/xml/pipeline/WellFormednessFilter.java
+++ /dev/null
@@ -1,363 +0,0 @@
-/* WellFormednessFilter.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. */
-
-package gnu.xml.pipeline;
-
-import java.util.EmptyStackException;
-import java.util.Stack;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXParseException;
-
-/**
- * This filter reports fatal exceptions in the case of event streams that
- * are not well formed. The rules currently tested include: <ul>
- *
- * <li>setDocumentLocator ... may be called only before startDocument
- *
- * <li>startDocument/endDocument ... must be paired, and all other
- * calls (except setDocumentLocator) must be nested within these.
- *
- * <li>startElement/endElement ... must be correctly paired, and
- * may never appear within CDATA sections.
- *
- * <li>comment ... can't contain "--"
- *
- * <li>character data ... can't contain "]]&gt;"
- *
- * <li>whitespace ... can't contain CR
- *
- * <li>whitespace and character data must be within an element
- *
- * <li>processing instruction ... can't contain "?&gt;" or CR
- *
- * <li>startCDATA/endCDATA ... must be correctly paired.
- *
- * </ul>
- *
- * <p> Other checks for event stream correctness may be provided in
- * the future. For example, insisting that
- * entity boundaries nest correctly,
- * namespace scopes nest correctly,
- * namespace values never contain relative URIs,
- * attributes don't have "&lt;" characters;
- * and more.
- *
- * @author David Brownell
- */
-public final class WellFormednessFilter extends EventFilter
-{
- private boolean startedDoc;
- private Stack elementStack = new Stack ();
- private boolean startedCDATA;
- private String dtdState = "before";
-
-
- /**
- * Swallows all events after performing well formedness checks.
- */
- // constructor used by PipelineFactory
- public WellFormednessFilter ()
- { this (null); }
-
-
- /**
- * Passes events through to the specified consumer, after first
- * processing them.
- */
- // constructor used by PipelineFactory
- public WellFormednessFilter (EventConsumer consumer)
- {
- super (consumer);
-
- setContentHandler (this);
- setDTDHandler (this);
-
- try {
- setProperty (LEXICAL_HANDLER, this);
- } catch (SAXException e) { /* can't happen */ }
- }
-
- /**
- * Resets state as if any preceding event stream was well formed.
- * Particularly useful if it ended through some sort of error,
- * and the endDocument call wasn't made.
- */
- public void reset ()
- {
- startedDoc = false;
- startedCDATA = false;
- elementStack.removeAllElements ();
- }
-
-
- private SAXParseException getException (String message)
- {
- SAXParseException e;
- Locator locator = getDocumentLocator ();
-
- if (locator == null)
- return new SAXParseException (message, null, null, -1, -1);
- else
- return new SAXParseException (message, locator);
- }
-
- private void fatalError (String message)
- throws SAXException
- {
- SAXParseException e = getException (message);
- ErrorHandler handler = getErrorHandler ();
-
- if (handler != null)
- handler.fatalError (e);
- throw e;
- }
-
- /**
- * Throws an exception when called after startDocument.
- *
- * @param locator the locator, to be used in error reporting or relative
- * URI resolution.
- *
- * @exception IllegalStateException when called after the document
- * has already been started
- */
- public void setDocumentLocator (Locator locator)
- {
- if (startedDoc)
- throw new IllegalStateException (
- "setDocumentLocator called after startDocument");
- super.setDocumentLocator (locator);
- }
-
- public void startDocument () throws SAXException
- {
- if (startedDoc)
- fatalError ("startDocument called more than once");
- startedDoc = true;
- startedCDATA = false;
- elementStack.removeAllElements ();
- super.startDocument ();
- }
-
- public void startElement (
- String uri, String localName,
- String qName, Attributes atts
- ) throws SAXException
- {
- if (!startedDoc)
- fatalError ("callback outside of document?");
- if ("inside".equals (dtdState))
- fatalError ("element inside DTD?");
- else
- dtdState = "after";
- if (startedCDATA)
- fatalError ("element inside CDATA section");
- if (qName == null || "".equals (qName))
- fatalError ("startElement name missing");
- elementStack.push (qName);
- super.startElement (uri, localName, qName, atts);
- }
-
- public void endElement (String uri, String localName, String qName)
- throws SAXException
- {
- if (!startedDoc)
- fatalError ("callback outside of document?");
- if (startedCDATA)
- fatalError ("element inside CDATA section");
- if (qName == null || "".equals (qName))
- fatalError ("endElement name missing");
-
- try {
- String top = (String) elementStack.pop ();
-
- if (!qName.equals (top))
- fatalError ("<" + top + " ...>...</" + qName + ">");
- // XXX could record/test namespace info
- } catch (EmptyStackException e) {
- fatalError ("endElement without startElement: </" + qName + ">");
- }
- super.endElement (uri, localName, qName);
- }
-
- public void endDocument () throws SAXException
- {
- if (!startedDoc)
- fatalError ("callback outside of document?");
- dtdState = "before";
- startedDoc = false;
- super.endDocument ();
- }
-
-
- public void startDTD (String root, String publicId, String systemId)
- throws SAXException
- {
- if (!startedDoc)
- fatalError ("callback outside of document?");
- if ("before" != dtdState)
- fatalError ("two DTDs?");
- if (!elementStack.empty ())
- fatalError ("DTD must precede root element");
- dtdState = "inside";
- super.startDTD (root, publicId, systemId);
- }
-
- public void notationDecl (String name, String publicId, String systemId)
- throws SAXException
- {
-// FIXME: not all parsers will report startDTD() ...
-// we'd rather insist we're "inside".
- if ("after" == dtdState)
- fatalError ("not inside DTD");
- super.notationDecl (name, publicId, systemId);
- }
-
- public void unparsedEntityDecl (String name,
- String publicId, String systemId, String notationName)
- throws SAXException
- {
-// FIXME: not all parsers will report startDTD() ...
-// we'd rather insist we're "inside".
- if ("after" == dtdState)
- fatalError ("not inside DTD");
- super.unparsedEntityDecl (name, publicId, systemId, notationName);
- }
-
- // FIXME: add the four DeclHandler calls too
-
- public void endDTD ()
- throws SAXException
- {
- if (!startedDoc)
- fatalError ("callback outside of document?");
- if ("inside" != dtdState)
- fatalError ("DTD ends without start?");
- dtdState = "after";
- super.endDTD ();
- }
-
- public void characters (char ch [], int start, int length)
- throws SAXException
- {
- int here = start, end = start + length;
- if (elementStack.empty ())
- fatalError ("characters must be in an element");
- while (here < end) {
- if (ch [here++] != ']')
- continue;
- if (here == end) // potential problem ...
- continue;
- if (ch [here++] != ']')
- continue;
- if (here == end) // potential problem ...
- continue;
- if (ch [here++] == '>')
- fatalError ("character data can't contain \"]]>\"");
- }
- super.characters (ch, start, length);
- }
-
- public void ignorableWhitespace (char ch [], int start, int length)
- throws SAXException
- {
- int here = start, end = start + length;
- if (elementStack.empty ())
- fatalError ("characters must be in an element");
- while (here < end) {
- if (ch [here++] == '\r')
- fatalError ("whitespace can't contain CR");
- }
- super.ignorableWhitespace (ch, start, length);
- }
-
- public void processingInstruction (String target, String data)
- throws SAXException
- {
- if (data.indexOf ('\r') > 0)
- fatalError ("PIs can't contain CR");
- if (data.indexOf ("?>") > 0)
- fatalError ("PIs can't contain \"?>\"");
- }
-
- public void comment (char ch [], int start, int length)
- throws SAXException
- {
- if (!startedDoc)
- fatalError ("callback outside of document?");
- if (startedCDATA)
- fatalError ("comments can't nest in CDATA");
- int here = start, end = start + length;
- while (here < end) {
- if (ch [here] == '\r')
- fatalError ("comments can't contain CR");
- if (ch [here++] != '-')
- continue;
- if (here == end)
- fatalError ("comments can't end with \"--->\"");
- if (ch [here++] == '-')
- fatalError ("comments can't contain \"--\"");
- }
- super.comment (ch, start, length);
- }
-
- public void startCDATA ()
- throws SAXException
- {
- if (!startedDoc)
- fatalError ("callback outside of document?");
- if (startedCDATA)
- fatalError ("CDATA starts can't nest");
- startedCDATA = true;
- super.startCDATA ();
- }
-
- public void endCDATA ()
- throws SAXException
- {
- if (!startedDoc)
- fatalError ("callback outside of document?");
- if (!startedCDATA)
- fatalError ("CDATA end without start?");
- startedCDATA = false;
- super.endCDATA ();
- }
-}
diff --git a/libjava/classpath/gnu/xml/pipeline/XIncludeFilter.java b/libjava/classpath/gnu/xml/pipeline/XIncludeFilter.java
deleted file mode 100644
index a1445fa..0000000
--- a/libjava/classpath/gnu/xml/pipeline/XIncludeFilter.java
+++ /dev/null
@@ -1,579 +0,0 @@
-/* XIncludeFilter.java --
- Copyright (C) 2001,2002 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. */
-
-package gnu.xml.pipeline;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.Hashtable;
-import java.util.Stack;
-import java.util.Vector;
-
-import org.xml.sax.Attributes;
-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.XMLReader;
-import org.xml.sax.helpers.XMLReaderFactory;
-
-import gnu.xml.util.Resolver;
-
-
-
-/**
- * Filter to process an XPointer-free subset of
- * <a href="http://www.w3.org/TR/xinclude">XInclude</a>, supporting its
- * use as a kind of replacement for parsed general entities.
- * XInclude works much like the <code>#include</code> of C/C++ but
- * works for XML documents as well as unparsed text files.
- * Restrictions from the 17-Sept-2002 CR draft of XInclude are as follows:
- *
- * <ul>
- *
- * <li> URIs must not include fragment identifiers.
- * The CR specifies support for XPointer <em>element()</em> fragment IDs,
- * which is not currently implemented here.
- *
- * <li> <em>xi:fallback</em> handling of resource errors is not
- * currently supported.
- *
- * <li> DTDs are not supported in included files, since the SAX DTD events
- * must have completely preceded any included file.
- * The CR explicitly allows the DTD related portions of the infoset to
- * grow as an effect of including XML documents.
- *
- * <li> <em>xml:base</em> fixup isn't done.
- *
- * </ul>
- *
- * <p> XML documents that are included will normally be processed using
- * the default SAX namespace rules, meaning that prefix information may
- * be discarded. This may be changed with {@link #setSavingPrefixes
- * setSavingPrefixes()}. <em>You are strongly advised to do this.</em>
- *
- * <p> Note that XInclude allows highly incompatible implementations, which
- * are specialized to handle application-specific infoset extensions. Some
- * such implementations can be implemented by subclassing this one, but
- * they may only be substituted in applications at "user option".
- *
- * <p>TBD: "IURI" handling.
- *
- * @author David Brownell
- */
-public class XIncludeFilter extends EventFilter implements Locator
-{
- private Hashtable extEntities = new Hashtable (5, 5);
- private int ignoreCount;
- private Stack uris = new Stack ();
- private Locator locator;
- private Vector inclusions = new Vector (5, 5);
- private boolean savingPrefixes;
-
- /**
- */
- public XIncludeFilter (EventConsumer next)
- throws SAXException
- {
- super (next);
- setContentHandler (this);
- // DTDHandler callbacks pass straight through
- setProperty (DECL_HANDLER, this);
- setProperty (LEXICAL_HANDLER, this);
- }
-
- private void fatal (SAXParseException e) throws SAXException
- {
- ErrorHandler eh;
-
- eh = getErrorHandler ();
- if (eh != null)
- eh.fatalError (e);
- throw e;
- }
-
- /**
- * Passes "this" down the filter chain as a proxy locator.
- */
- public void setDocumentLocator (Locator locator)
- {
- this.locator = locator;
- super.setDocumentLocator (this);
- }
-
- /** Used for proxy locator; do not call directly. */
- public String getSystemId ()
- { return (locator == null) ? null : locator.getSystemId (); }
- /** Used for proxy locator; do not call directly. */
- public String getPublicId ()
- { return (locator == null) ? null : locator.getPublicId (); }
- /** Used for proxy locator; do not call directly. */
- public int getLineNumber ()
- { return (locator == null) ? -1 : locator.getLineNumber (); }
- /** Used for proxy locator; do not call directly. */
- public int getColumnNumber ()
- { return (locator == null) ? -1 : locator.getColumnNumber (); }
-
- /**
- * Assigns the flag controlling the setting of the SAX2
- * <em>namespace-prefixes</em> flag.
- */
- public void setSavingPrefixes (boolean flag)
- { savingPrefixes = flag; }
-
- /**
- * Returns the flag controlling the setting of the SAX2
- * <em>namespace-prefixes</em> flag when parsing included documents.
- * The default value is the SAX2 default (false), which discards
- * information that can be useful.
- */
- public boolean isSavingPrefixes ()
- { return savingPrefixes; }
-
- //
- // Two mechanisms are interacting here.
- //
- // - XML Base implies a stack of base URIs, updated both by
- // "real entity" boundaries and element boundaries.
- //
- // - Active "Real Entities" (for document and general entities,
- // and by xincluded files) are tracked to prevent circular
- // inclusions.
- //
- private String addMarker (String uri)
- throws SAXException
- {
- if (locator != null && locator.getSystemId () != null)
- uri = locator.getSystemId ();
-
- // guard against InputSource objects without system IDs
- if (uri == null)
- fatal (new SAXParseException ("Entity URI is unknown", locator));
-
- try {
- URL url = new URL (uri);
-
- uri = url.toString ();
- if (inclusions.contains (uri))
- fatal (new SAXParseException (
- "XInclude, circular inclusion", locator));
- inclusions.addElement (uri);
- uris.push (url);
- } catch (IOException e) {
- // guard against illegal relative URIs (Xerces)
- fatal (new SAXParseException ("parser bug: relative URI",
- locator, e));
- }
- return uri;
- }
-
- private void pop (String uri)
- {
- inclusions.removeElement (uri);
- uris.pop ();
- }
-
- //
- // Document entity boundaries get both treatments.
- //
- public void startDocument () throws SAXException
- {
- ignoreCount = 0;
- addMarker (null);
- super.startDocument ();
- }
-
- public void endDocument () throws SAXException
- {
- inclusions.setSize (0);
- extEntities.clear ();
- uris.setSize (0);
- super.endDocument ();
- }
-
- //
- // External general entity boundaries get both treatments.
- //
- public void externalEntityDecl (String name,
- String publicId, String systemId)
- throws SAXException
- {
- if (name.charAt (0) == '%')
- return;
- try {
- URL url = new URL (locator.getSystemId ());
- systemId = new URL (url, systemId).toString ();
- } catch (IOException e) {
- // what could we do?
- }
- extEntities.put (name, systemId);
- }
-
- public void startEntity (String name)
- throws SAXException
- {
- if (ignoreCount != 0) {
- ignoreCount++;
- return;
- }
-
- String uri = (String) extEntities.get (name);
- if (uri != null)
- addMarker (uri);
- super.startEntity (name);
- }
-
- public void endEntity (String name)
- throws SAXException
- {
- if (ignoreCount != 0) {
- if (--ignoreCount != 0)
- return;
- }
-
- String uri = (String) extEntities.get (name);
-
- if (uri != null)
- pop (uri);
- super.endEntity (name);
- }
-
- //
- // element boundaries only affect the base URI stack,
- // unless they're XInclude elements.
- //
- public void
- startElement (String uri, String localName, String qName, Attributes atts)
- throws SAXException
- {
- if (ignoreCount != 0) {
- ignoreCount++;
- return;
- }
-
- URL baseURI = (URL) uris.peek ();
- String base;
-
- base = atts.getValue ("http://www.w3.org/XML/1998/namespace", "base");
- if (base == null)
- uris.push (baseURI);
- else {
- URL url;
-
- if (base.indexOf ('#') != -1)
- fatal (new SAXParseException (
- "xml:base with fragment: " + base,
- locator));
-
- try {
- baseURI = new URL (baseURI, base);
- uris.push (baseURI);
- } catch (Exception e) {
- fatal (new SAXParseException (
- "xml:base with illegal uri: " + base,
- locator, e));
- }
- }
-
- if (!"http://www.w3.org/2001/XInclude".equals (uri)) {
- super.startElement (uri, localName, qName, atts);
- return;
- }
-
- if ("include".equals (localName)) {
- String href = atts.getValue ("href");
- String parse = atts.getValue ("parse");
- String encoding = atts.getValue ("encoding");
- URL url = (URL) uris.peek ();
- SAXParseException x = null;
-
- if (href == null)
- fatal (new SAXParseException (
- "XInclude missing href",
- locator));
- if (href.indexOf ('#') != -1)
- fatal (new SAXParseException (
- "XInclude with fragment: " + href,
- locator));
-
- if (parse == null || "xml".equals (parse))
- x = xinclude (url, href);
- else if ("text".equals (parse))
- x = readText (url, href, encoding);
- else
- fatal (new SAXParseException (
- "unknown XInclude parsing mode: " + parse,
- locator));
- if (x == null) {
- // strip out all child content
- ignoreCount++;
- return;
- }
-
- // FIXME the 17-Sept-2002 CR of XInclude says we "must"
- // use xi:fallback elements to handle resource errors,
- // if they exist.
- fatal (x);
-
- } else if ("fallback".equals (localName)) {
- fatal (new SAXParseException (
- "illegal top level XInclude 'fallback' element",
- locator));
- } else {
- ErrorHandler eh = getErrorHandler ();
-
- // CR doesn't say this is an error
- if (eh != null)
- eh.warning (new SAXParseException (
- "unrecognized toplevel XInclude element: " + localName,
- locator));
- super.startElement (uri, localName, qName, atts);
- }
- }
-
- public void endElement (String uri, String localName, String qName)
- throws SAXException
- {
- if (ignoreCount != 0) {
- if (--ignoreCount != 0)
- return;
- }
-
- uris.pop ();
- if (!("http://www.w3.org/2001/XInclude".equals (uri)
- && "include".equals (localName)))
- super.endElement (uri, localName, qName);
- }
-
- //
- // ignore all content within non-empty xi:include elements
- //
- public void characters (char ch [], int start, int length)
- throws SAXException
- {
- if (ignoreCount == 0)
- super.characters (ch, start, length);
- }
-
- public void processingInstruction (String target, String value)
- throws SAXException
- {
- if (ignoreCount == 0)
- super.processingInstruction (target, value);
- }
-
- public void ignorableWhitespace (char ch [], int start, int length)
- throws SAXException
- {
- if (ignoreCount == 0)
- super.ignorableWhitespace (ch, start, length);
- }
-
- public void comment (char ch [], int start, int length)
- throws SAXException
- {
- if (ignoreCount == 0)
- super.comment (ch, start, length);
- }
-
- public void startCDATA () throws SAXException
- {
- if (ignoreCount == 0)
- super.startCDATA ();
- }
-
- public void endCDATA () throws SAXException
- {
- if (ignoreCount == 0)
- super.endCDATA ();
- }
-
- public void startPrefixMapping (String prefix, String uri)
- throws SAXException
- {
- if (ignoreCount == 0)
- super.startPrefixMapping (prefix, uri);
- }
-
- public void endPrefixMapping (String prefix) throws SAXException
- {
- if (ignoreCount == 0)
- super.endPrefixMapping (prefix);
- }
-
- public void skippedEntity (String name) throws SAXException
- {
- if (ignoreCount == 0)
- super.skippedEntity (name);
- }
-
- // JDK 1.1 seems to need it to be done this way, sigh
- void setLocator (Locator l) { locator = l; }
- Locator getLocator () { return locator; }
-
-
- //
- // for XIncluded entities, manage the current locator and
- // filter out events that would be incorrect to report
- //
- private class Scrubber extends EventFilter
- {
- Scrubber (EventFilter f)
- throws SAXException
- {
- // delegation passes to next in chain
- super (f);
-
- // process all content events
- super.setContentHandler (this);
- super.setProperty (LEXICAL_HANDLER, this);
-
- // drop all DTD events
- super.setDTDHandler (null);
- super.setProperty (DECL_HANDLER, null);
- }
-
- // maintain proxy locator
- // only one startDocument()/endDocument() pair per event stream
- public void setDocumentLocator (Locator l)
- { setLocator (l); }
- public void startDocument ()
- { }
- public void endDocument ()
- { }
-
- private void reject (String message) throws SAXException
- { fatal (new SAXParseException (message, getLocator ())); }
-
- // only the DTD from the "base document" gets reported
- public void startDTD (String root, String publicId, String systemId)
- throws SAXException
- { reject ("XIncluded DTD: " + systemId); }
- public void endDTD ()
- throws SAXException
- { reject ("XIncluded DTD"); }
- // ... so this should never happen
- public void skippedEntity (String name) throws SAXException
- { reject ("XInclude skipped entity: " + name); }
-
- // since we rejected DTDs, only builtin entities can be reported
- }
-
- // <xi:include parse='xml' ...>
- // relative to the base URI passed
- private SAXParseException xinclude (URL url, String href)
- throws SAXException
- {
- XMLReader helper;
- Scrubber scrubber;
- Locator savedLocator = locator;
-
- // start with a parser acting just like our input
- // modulo DTD-ish stuff (validation flag, entity resolver)
- helper = XMLReaderFactory.createXMLReader ();
- helper.setErrorHandler (getErrorHandler ());
- helper.setFeature (FEATURE_URI + "namespace-prefixes", true);
-
- // Set up the proxy locator and event filter.
- scrubber = new Scrubber (this);
- locator = null;
- bind (helper, scrubber);
-
- // Merge the included document, except its DTD
- try {
- url = new URL (url, href);
- href = url.toString ();
-
- if (inclusions.contains (href))
- fatal (new SAXParseException (
- "XInclude, circular inclusion", locator));
-
- inclusions.addElement (href);
- uris.push (url);
- helper.parse (new InputSource (href));
- return null;
- } catch (java.io.IOException e) {
- return new SAXParseException (href, locator, e);
- } finally {
- pop (href);
- locator = savedLocator;
- }
- }
-
- // <xi:include parse='text' ...>
- // relative to the base URI passed
- private SAXParseException readText (URL url, String href, String encoding)
- throws SAXException
- {
- InputStream in = null;
-
- try {
- URLConnection conn;
- InputStreamReader reader;
- char buf [] = new char [4096];
- int count;
-
- url = new URL (url, href);
- conn = url.openConnection ();
- in = conn.getInputStream ();
- if (encoding == null)
- encoding = Resolver.getEncoding (conn.getContentType ());
- if (encoding == null) {
- ErrorHandler eh = getErrorHandler ();
- if (eh != null)
- eh.warning (new SAXParseException (
- "guessing text encoding for URL: " + url,
- locator));
- reader = new InputStreamReader (in);
- } else
- reader = new InputStreamReader (in, encoding);
-
- while ((count = reader.read (buf, 0, buf.length)) != -1)
- super.characters (buf, 0, count);
- in.close ();
- return null;
- } catch (IOException e) {
- return new SAXParseException (
- "can't XInclude text",
- locator, e);
- }
- }
-}
diff --git a/libjava/classpath/gnu/xml/pipeline/XsltFilter.java b/libjava/classpath/gnu/xml/pipeline/XsltFilter.java
deleted file mode 100644
index 86b6190..0000000
--- a/libjava/classpath/gnu/xml/pipeline/XsltFilter.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/* XsltFilter.java --
- Copyright (C) 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. */
-
-package gnu.xml.pipeline;
-
-import java.io.IOException;
-
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.sax.*;
-import javax.xml.transform.stream.StreamSource;
-
-import org.xml.sax.SAXException;
-import org.xml.sax.ext.LexicalHandler;
-
-
-/**
- * Packages an XSLT transform as a pipeline component.
- * Note that all DTD events (callbacks to DeclHandler and DTDHandler
- * interfaces) are discarded, although XSLT transforms may be set up to
- * use the LexicalHandler to write DTDs with only an external subset.
- * Not every XSLT engine will necessarily be usable with this filter,
- * but current versions of
- * <a href="http://saxon.sourceforge.net">SAXON</a> and
- * <a href="http://xml.apache.org/xalan-j">Xalan</a> should work well.
- *
- * @see TransformerFactory
- *
- * @author David Brownell
- */
-final public class XsltFilter extends EventFilter
-{
- /**
- * Creates a filter that performs the specified transform.
- * Uses the JAXP 1.1 interfaces to access the default XSLT
- * engine configured for in the current execution context,
- * and parses the stylesheet without custom EntityResolver
- * or ErrorHandler support.
- *
- * @param stylesheet URI for the stylesheet specifying the
- * XSLT transform
- * @param next provides the ContentHandler and LexicalHandler
- * to receive XSLT output.
- * @exception SAXException if the stylesheet can't be parsed
- * @exception IOException if there are difficulties
- * bootstrapping the XSLT engine, such as it not supporting
- * SAX well enough to use this way.
- */
- public XsltFilter (String stylesheet, EventConsumer next)
- throws SAXException, IOException
- {
- // First, get a transformer with the stylesheet preloaded
- TransformerFactory tf = null;
- TransformerHandler th;
-
- try {
- SAXTransformerFactory stf;
-
- tf = TransformerFactory.newInstance ();
- if (!tf.getFeature (SAXTransformerFactory.FEATURE) // sax inputs
- || !tf.getFeature (SAXResult.FEATURE) // sax outputs
- || !tf.getFeature (StreamSource.FEATURE) // stylesheet
- )
- throw new IOException ("XSLT factory ("
- + tf.getClass ().getName ()
- + ") does not support SAX");
- stf = (SAXTransformerFactory) tf;
- th = stf.newTransformerHandler (new StreamSource (stylesheet));
- } catch (TransformerConfigurationException e) {
- throw new IOException ("XSLT factory ("
- + (tf == null
- ? "none available"
- : tf.getClass ().getName ())
- + ") configuration error, "
- + e.getMessage ()
- );
- }
-
- // Hook its outputs up to the pipeline ...
- SAXResult out = new SAXResult ();
-
- out.setHandler (next.getContentHandler ());
- try {
- LexicalHandler lh;
- lh = (LexicalHandler) next.getProperty (LEXICAL_HANDLER);
- out.setLexicalHandler (lh);
- } catch (Exception e) {
- // ignore
- }
- th.setResult (out);
-
- // ... and make sure its inputs look like ours.
- setContentHandler (th);
- setProperty (LEXICAL_HANDLER, th);
- }
-}
diff --git a/libjava/classpath/gnu/xml/pipeline/package.html b/libjava/classpath/gnu/xml/pipeline/package.html
deleted file mode 100644
index 352f4c8..0000000
--- a/libjava/classpath/gnu/xml/pipeline/package.html
+++ /dev/null
@@ -1,255 +0,0 @@
-<html><head><title>
-blah
-<!--
-/*
- * Copyright (C) 1999-2001 The Free Software Foundation, Inc.
- */
--->
-</title></head><body>
-
-<p>This package exposes a kind of XML processing pipeline, based on sending
-SAX events, which can be used as components of application architectures.
-Pipelines are used to convey streams of processing events from a producer
-to one or more consumers, and to let each consumer control the data seen by
-later consumers.
-
-<p> There is a <a href="PipelineFactory.html">PipelineFactory</a> class which
-accepts a syntax describing how to construct some simple pipelines. Strings
-describing such pipelines can be used in command line tools (see the
-<a href="../util/DoParse.html">DoParse</a> class)
-and in other places that it is
-useful to let processing be easily reconfigured. Pipelines can of course
-be constructed programmatically, providing access to options that the
-factory won't.
-
-<p> Web applications are supported by making it easy for servlets (or
-non-Java web application components) to be part of a pipeline. They can
-originate XML (or XHTML) data through an <em>InputSource</em> or in
-response to XML messages sent from clients using <em>CallFilter</em>
-pipeline stages. Such facilities are available using the simple syntax
-for pipeline construction.
-
-
-<h2> Programming Models </h2>
-
-<p> Pipelines should be simple to understand.
-
-<ul>
- <li> XML content, typically entire documents,
- is pushed through consumers by producers.
-
- <li> Pipelines are basically about consuming SAX2 callback events,
- where the events encapsulate XML infoset-level data.<ul>
-
- <li> Pipelines are constructed by taking one or more consumer
- stages and combining them to produce a composite consumer.
-
- <li> A pipeline is presumed to have pending tasks and state from
- the beginning of its ContentHandler.startDocument() callback until
- it's returned from its ContentHandler.doneDocument() callback.
-
- <li> Pipelines may have multiple output stages ("fan-out")
- or multiple input stages ("fan-in") when appropriate.
-
- <li> Pipelines may be long-lived, but need not be.
-
- </ul>
-
- <li> There is flexibility about event production. <ul>
-
- <li> SAX2 XMLReader objects are producers, which
- provide a high level "pull" model: documents (text or DOM) are parsed,
- and the parser pushes individual events through the pipeline.
-
- <li> Events can be pushed directly to event consumer components
- by application modules, if they invoke SAX2 callbacks directly.
- That is, application modules use the XML Infoset as exposed
- through SAX2 event callbacks.
-
- </ul>
-
- <li> Multiple producer threads may concurrently access a pipeline,
- if they coordinate appropriately.
-
- <li> Pipeline processing is not the only framework applications
- will use.
-
- </ul>
-
-
-<h3> Producers: XMLReader or Custom </h3>
-
-<p> Many producers will be SAX2 XMLReader objects, and
-will read (pull) data which is then written (pushed) as events.
-Typically these will parse XML text (acquired from
-<code>org.xml.sax.helpers.XMLReaderFactory</code>) or a DOM tree
-(using a <code><a href="../util/DomParser.html">DomParser</a></code>)
-These may be bound to event consumer using a convenience routine,
-<em><a href="EventFilter.html">EventFilter</a>.bind()</em>.
-Once bound, these producers may be given additional documents to
-sent through its pipeline.
-
-<p> In other cases, you will write producers yourself. For example, some
-data structures might know how to write themselves out using one or
-more XML models, expressed as sequences of SAX2 event callbacks.
-An application module might
-itself be a producer, issuing startDocument and endDocument events
-and then asking those data structures to write themselves out to a
-given EventConsumer, or walking data structures (such as JDBC query
-results) and applying its own conversion rules. WAP format XML
-(WBMXL) can be directly converted to producer output.
-
-<p> SAX2 introduced an "XMLFilter" interface, which is a kind of XMLReader.
-It is most useful in conjunction with its XMLFilterImpl helper class;
-see the <em><a href="EventFilter.html">EventFilter</a></em> javadoc
-for information contrasting that XMLFilterImpl approach with the
-relevant parts of this pipeline framework. Briefly, such XMLFilterImpl
-children can be either producers or consumers, and are more limited in
-configuration flexibility. In this framework, the focus of filters is
-on the EventConsumer side; see the section on
-<a href="#fitting">pipe fitting</a> below.
-
-
-<h3> Consume to Standard or Custom Data Representations </h3>
-
-<p> Many consumers will be used to create standard representations of XML
-data. The <a href="TextConsumer.html">TextConsumer</a> takes its events
-and writes them as text for a single XML document,
-using an internal <a href="../util/XMLWriter.html">XMLWriter</a>.
-The <a href="DomConsumer.html">DomConsumer</a> takes its events and uses
-them to create and populate a DOM Document.
-
-<p> In other cases, you will write consumers yourself. For example,
-you might use a particular unmarshaling filter to produce objects
-that fit your application's requirements, instead of using DOM.
-Such consumers work at the level of XML data models, rather than with
-specific representations such as XML text or a DOM tree. You could
-convert your output directly to WAP format data (WBXML).
-
-
-<h3><a name="fitting">Pipe Fitting</a></h3>
-
-<p> Pipelines are composite event consumers, with each stage having
-the opportunity to transform the data before delivering it to any
-subsequent stages.
-
-<p> The <a href="PipelineFactory.html">PipelineFactory</a> class
-provides access to much of this functionality through a simple syntax.
-See the table in that class's javadoc describing a number of standard
-components. Direct API calls are still needed for many of the most
-interesting pipeline configurations, including ones leveraging actual
-or logical concurrency.
-
-<p> Four basic types of pipe fitting are directly supported. These may
-be used to construct complex pipeline networks. <ul>
-
- <li> <a href="TeeConsumer.html">TeeConsumer</a> objects split event
- flow so it goes to two two different consumers, one before the other.
- This is a basic form of event fan-out; you can use this class to
- copy events to any number of output pipelines.
-
- <li> Clients can call remote components through HTTP or HTTPS using
- the <a href="CallFilter.html">CallFilter</a> component, and Servlets
- can implement such components by extending the
- <a href="XmlServlet.html">XmlServlet</a> component. Java is not
- required on either end, and transport protocols other than HTTP may
- also be used.
-
- <li> <a href="EventFilter.html">EventFilter</a> objects selectively
- provide handling for callbacks, and can pass unhandled ones to a
- subsequent stage. They are often subclassed, since much of the
- basic filtering machinery is already in place in the base class.
-
- <li> Applications can merge two event flows by just using the same
- consumer in each one. If multiple threads are in use, synchronization
- needs to be addressed by the appropriate application level policy.
-
- </ul>
-
-<p> Note that filters can be as complex as
-<a href="XsltFilter.html">XSLT transforms</a>
-available) on input data, or as simple as removing simple syntax data
-such as ignorable whitespace, comments, and CDATA delimiters.
-Some simple "built-in" filters are part of this package.
-
-
-<h3> Coding Conventions: Filter and Terminus Stages</h3>
-
-<p> If you follow these coding conventions, your classes may be used
-directly (give the full class name) in pipeline descriptions as understood
-by the PipelineFactory. There are four constructors the factory may
-try to use; in order of decreasing numbers of parameters, these are: <ul>
-
- <li> Filters that need a single String setup parameter should have
- a public constructor with two parameters: that string, then the
- EventConsumer holding the "next" consumer to get events.
-
- <li> Filters that don't need setup parameters should have a public
- constructor that accepts a single EventConsumer holding the "next"
- consumer to get events when they are done.
-
- <li> Terminus stages may have a public constructor taking a single
- paramter: the string value of that parameter.
-
- <li> Terminus stages may have a public no-parameters constructor.
-
- </ul>
-
-<p> Of course, classes may support more than one such usage convention;
-if they do, they can automatically be used in multiple modes. If you
-try to use a terminus class as a filter, and that terminus has a constructor
-with the appropriate number of arguments, it is automatically wrapped in
-a "tee" filter.
-
-
-<h2> Debugging Tip: "Tee" Joints can Snapshot Data</h2>
-
-<p> It can sometimes be hard to see what's happening, when something
-goes wrong. Easily fixed: just snapshot the data. Then you can find
-out where things start to go wrong.
-
-<p> If you're using pipeline descriptors so that they're easily
-administered, just stick a <em>write&nbsp;(&nbsp;filename&nbsp;)</em>
-filter into the pipeline at an appropriate point.
-
-<p> Inside your programs, you can do the same thing directly: perhaps
-by saving a Writer (perhaps a StringWriter) in a variable, using that
-to create a TextConsumer, and making that the first part of a tee --
-splicing that into your pipeline at a convenient location.
-
-<p> You can also use a DomConsumer to buffer the data, but remember
-that DOM doesn't save all the information that XML provides, so that DOM
-snapshots are relatively low fidelity. They also are substantially more
-expensive in terms of memory than a StringWriter holding similar data.
-
-<h2> Debugging Tip: Non-XML Producers</h2>
-
-<p> Producers in pipelines don't need to start from XML
-data structures, such as text in XML syntax (likely coming
-from some <em>XMLReader</em> that parses XML) or a
-DOM representation (perhaps with a
-<a href="../util/DomParser.html">DomParser</a>).
-
-<p> One common type of event producer will instead make
-direct calls to SAX event handlers returned from an
-<a href="EventConsumer.html">EventConsumer</a>.
-For example, making <em>ContentHandler.startElement</em>
-calls and matching <em>ContentHandler.endElement</em> calls.
-
-<p> Applications making such calls can catch certain
-common "syntax errors" by using a
-<a href="WellFormednessFilter.html">WellFormednessFilter</a>.
-That filter will detect (and report) erroneous input data
-such as mismatched document, element, or CDATA start/end calls.
-Use such a filter near the head of the pipeline that your
-producer feeds, at least while debugging, to help ensure that
-you're providing legal XML Infoset data.
-
-<p> You can also arrange to validate data on the fly.
-For DTD validation, you can configure a
-<a href="ValidationConsumer.html">ValidationConsumer</a>
-to work as a filter, using any DTD you choose.
-Other validation schemes can be handled with other
-validation filters.
-
-</body></html>