diff options
Diffstat (limited to 'gnu/xml/pipeline')
-rw-r--r-- | gnu/xml/pipeline/CallFilter.java | 160 | ||||
-rw-r--r-- | gnu/xml/pipeline/DomConsumer.java | 1374 | ||||
-rw-r--r-- | gnu/xml/pipeline/EventConsumer.java | 4 | ||||
-rw-r--r-- | gnu/xml/pipeline/EventFilter.java | 636 | ||||
-rw-r--r-- | gnu/xml/pipeline/LinkFilter.java | 192 | ||||
-rw-r--r-- | gnu/xml/pipeline/NSFilter.java | 400 | ||||
-rw-r--r-- | gnu/xml/pipeline/PipelineFactory.java | 1036 | ||||
-rw-r--r-- | gnu/xml/pipeline/TeeConsumer.java | 310 | ||||
-rw-r--r-- | gnu/xml/pipeline/TextConsumer.java | 26 | ||||
-rw-r--r-- | gnu/xml/pipeline/ValidationConsumer.java | 2822 | ||||
-rw-r--r-- | gnu/xml/pipeline/WellFormednessFilter.java | 330 | ||||
-rw-r--r-- | gnu/xml/pipeline/XIncludeFilter.java | 620 | ||||
-rw-r--r-- | gnu/xml/pipeline/XsltFilter.java | 100 |
13 files changed, 4005 insertions, 4005 deletions
diff --git a/gnu/xml/pipeline/CallFilter.java b/gnu/xml/pipeline/CallFilter.java index 3b3375173..2398b8685 100644 --- a/gnu/xml/pipeline/CallFilter.java +++ b/gnu/xml/pipeline/CallFilter.java @@ -1,4 +1,4 @@ -/* CallFilter.java -- +/* CallFilter.java -- Copyright (C) 1999,2000,2001 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -99,11 +99,11 @@ import gnu.xml.util.XMLWriter; */ final public class CallFilter implements EventConsumer { - private Requestor req; - private EventConsumer next; - private URL target; - private URLConnection conn; - private ErrorHandler errHandler; + private Requestor req; + private EventConsumer next; + private URL target; + private URLConnection conn; + private ErrorHandler errHandler; /** @@ -113,13 +113,13 @@ final public class CallFilter implements EventConsumer * * @exception IOException if the URI isn't accepted as a URL */ - // constructor used by PipelineFactory + // constructor used by PipelineFactory public CallFilter (String uri, EventConsumer next) throws IOException { - this.next = next; - req = new Requestor (); - setCallTarget (uri); + this.next = next; + req = new Requestor (); + setCallTarget (uri); } /** @@ -129,7 +129,7 @@ final public class CallFilter implements EventConsumer final public void setCallTarget (String uri) throws IOException { - target = new URL (uri); + target = new URL (uri); } /** @@ -138,7 +138,7 @@ final public class CallFilter implements EventConsumer */ public void setErrorHandler (ErrorHandler handler) { - req.setErrorHandler (handler); + req.setErrorHandler (handler); } @@ -147,19 +147,19 @@ final public class CallFilter implements EventConsumer */ final public String getCallTarget () { - return target.toString (); + return target.toString (); } /** Returns the content handler currently in use. */ final public org.xml.sax.ContentHandler getContentHandler () { - return req; + return req; } /** Returns the DTD handler currently in use. */ final public DTDHandler getDTDHandler () { - return req; + return req; } @@ -170,11 +170,11 @@ final public class CallFilter implements EventConsumer 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); + if (EventFilter.DECL_HANDLER.equals (id)) + return req; + if (EventFilter.LEXICAL_HANDLER.equals (id)) + return req; + throw new SAXNotRecognizedException (id); } @@ -187,71 +187,71 @@ final public class CallFilter implements EventConsumer // 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 ()); + 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); + 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; + 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); - } - } + } catch (IOException e) { + fatal ("I/O Exception reading response, " + e.getMessage (), e); + } + } } } diff --git a/gnu/xml/pipeline/DomConsumer.java b/gnu/xml/pipeline/DomConsumer.java index 53f7f24a2..141f36eca 100644 --- a/gnu/xml/pipeline/DomConsumer.java +++ b/gnu/xml/pipeline/DomConsumer.java @@ -1,4 +1,4 @@ -/* DomConsumer.java -- +/* DomConsumer.java -- Copyright (C) 1999,2000,2001 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -105,17 +105,17 @@ import org.w3c.dom.Text; */ public class DomConsumer implements EventConsumer { - private Class domImpl; + private Class domImpl; - private boolean hidingCDATA = true; - private boolean hidingComments = true; - private boolean hidingWhitespace = true; - private boolean hidingReferences = true; + private boolean hidingCDATA = true; + private boolean hidingComments = true; + private boolean hidingWhitespace = true; + private boolean hidingReferences = true; - private Handler handler; - private ErrorHandler errHandler; + private Handler handler; + private ErrorHandler errHandler; - private EventConsumer next; + 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 @@ -127,16 +127,16 @@ public class DomConsumer implements EventConsumer * of DOM when constructing its result value. * * @param impl class implementing {@link org.w3c.dom.Document Document} - * which publicly exposes a default constructor + * which publicly exposes a default constructor * * @exception SAXException when there is a problem creating an - * empty DOM document using the specified implementation + * empty DOM document using the specified implementation */ public DomConsumer (Class impl) throws SAXException { - domImpl = impl; - handler = new Handler (this); + domImpl = impl; + handler = new Handler (this); } /** @@ -148,22 +148,22 @@ public class DomConsumer implements EventConsumer */ protected void setHandler (Handler h) { - 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 ()); - } + 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 ()); + } } @@ -178,18 +178,18 @@ public class DomConsumer implements EventConsumer * 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 + * which publicly exposes a default constructor * @param next receives a "replayed" sequence of parse events when - * the <em>endDocument</em> method is invoked. + * the <em>endDocument</em> method is invoked. * * @exception SAXException when there is a problem creating an - * empty DOM document using the specified DOM implementation + * empty DOM document using the specified DOM implementation */ public DomConsumer (Class impl, EventConsumer n) throws SAXException { - this (impl); - next = n; + this (impl); + next = n; } @@ -197,16 +197,16 @@ public class DomConsumer implements EventConsumer * 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. + * given to this EventConsumer. */ final public Document getDocument () { - return handler.clearDocument (); + return handler.clearDocument (); } public void setErrorHandler (ErrorHandler handler) { - errHandler = handler; + errHandler = handler; } @@ -219,8 +219,8 @@ public class DomConsumer implements EventConsumer * * @see #setHidingReferences */ - final public boolean isHidingReferences () - { return hidingReferences; } + final public boolean isHidingReferences () + { return hidingReferences; } /** * Controls whether the consumer will hide entity expansions, @@ -229,9 +229,9 @@ public class DomConsumer implements EventConsumer * @see #isHidingReferences * @param flag False if entity reference nodes will appear */ - final public void setHidingReferences (boolean flag) - { hidingReferences = flag; } - + final public void setHidingReferences (boolean flag) + { hidingReferences = flag; } + /** * Returns true if the consumer is hiding comments (the default), @@ -240,7 +240,7 @@ public class DomConsumer implements EventConsumer * @see #setHidingComments */ public final boolean isHidingComments () - { return hidingComments; } + { return hidingComments; } /** * Controls whether the consumer is hiding comments. @@ -248,7 +248,7 @@ public class DomConsumer implements EventConsumer * @see #isHidingComments */ public final void setHidingComments (boolean flag) - { hidingComments = flag; } + { hidingComments = flag; } /** @@ -259,7 +259,7 @@ public class DomConsumer implements EventConsumer * @see #setHidingWhitespace */ public final boolean isHidingWhitespace () - { return hidingWhitespace; } + { return hidingWhitespace; } /** * Controls whether the consumer hides ignorable whitespace @@ -267,7 +267,7 @@ public class DomConsumer implements EventConsumer * @see #isHidingComments */ public final void setHidingWhitespace (boolean flag) - { hidingWhitespace = flag; } + { hidingWhitespace = flag; } /** @@ -276,28 +276,28 @@ public class DomConsumer implements EventConsumer * * @see #setHidingCDATA */ - final public boolean isHidingCDATA () - { return hidingCDATA; } + 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 + * text nodes */ - final public void setHidingCDATA (boolean flag) - { hidingCDATA = flag; } - + final public void setHidingCDATA (boolean flag) + { hidingCDATA = flag; } + /** Returns the document handler being used. */ final public ContentHandler getContentHandler () - { return handler; } + { return handler; } /** Returns the DTD handler being used. */ final public DTDHandler getDTDHandler () - { return handler; } + { return handler; } /** * Returns the lexical handler being used. @@ -306,11 +306,11 @@ public class DomConsumer implements EventConsumer 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); + 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; } @@ -320,7 +320,7 @@ public class DomConsumer implements EventConsumer /** * 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 + * backdoors into specific DOM implementations, used to implement * DTD-related functionality. * * <p> Note that if this ever throws a DOMException (runtime exception) @@ -329,639 +329,639 @@ public class DomConsumer implements EventConsumer * accepted illegal input data). </p> */ public static class Handler - implements ContentHandler, LexicalHandler, - DTDHandler, DeclHandler + 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; - } + 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/gnu/xml/pipeline/EventConsumer.java b/gnu/xml/pipeline/EventConsumer.java index 017bc7f74..a0a8824f7 100644 --- a/gnu/xml/pipeline/EventConsumer.java +++ b/gnu/xml/pipeline/EventConsumer.java @@ -1,4 +1,4 @@ -/* EventConsumer.java -- +/* EventConsumer.java -- Copyright (C) 1999,2000,2001 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -75,7 +75,7 @@ public interface EventConsumer * @return The value of that property, if it is defined. * * @exception SAXNotRecognizedException Thrown if the particular - * pipeline stage does not understand the specified identifier. + * pipeline stage does not understand the specified identifier. */ public Object getProperty (String id) throws SAXNotRecognizedException; diff --git a/gnu/xml/pipeline/EventFilter.java b/gnu/xml/pipeline/EventFilter.java index af2113f97..b3cc2d654 100644 --- a/gnu/xml/pipeline/EventFilter.java +++ b/gnu/xml/pipeline/EventFilter.java @@ -1,4 +1,4 @@ -/* EventFilter.java -- +/* EventFilter.java -- Copyright (C) 1999,2000,2001 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -89,35 +89,35 @@ import org.xml.sax.helpers.XMLFilterImpl; * {@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> 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> "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> 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> 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. + * <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> + * </ul> * * <p> The {@link #chainTo chainTo()} convenience routine supports chaining to * an XMLFilterImpl, in its role as a limited functionality event @@ -137,34 +137,34 @@ import org.xml.sax.helpers.XMLFilterImpl; */ public class EventFilter implements EventConsumer, ContentHandler, DTDHandler, - LexicalHandler, DeclHandler + LexicalHandler, DeclHandler { // SAX handlers - private ContentHandler docHandler, docNext; - private DTDHandler dtdHandler, dtdNext; - private LexicalHandler lexHandler, lexNext; - private DeclHandler declHandler, declNext; + 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; + 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/"; + 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/"; + 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"; + 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"; - + 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 @@ -176,11 +176,11 @@ public class EventFilter // 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; + private static boolean loaded; + private static Class nsClass; + private static Class validClass; + private static Class wfClass; + private static Class xincClass; static ClassLoader getClassLoader () { @@ -206,25 +206,25 @@ public class EventFilter 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; - } + 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 (); + 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; + 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; } @@ -246,146 +246,146 @@ public class EventFilter * 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 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 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 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> {@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. + * <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> + * </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 producer will deliver events to the specified consumer * @param consumer pipeline supplying event handlers to be associated - * with the producer (may not be null) + * 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 ()); - } - + 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 + // constructor used by PipelineFactory public EventFilter () { } @@ -394,30 +394,30 @@ public class EventFilter * 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 + // constructor used by PipelineFactory public EventFilter (EventConsumer consumer) { - if (consumer == null) - return; + if (consumer == null) + return; - next = consumer; + next = consumer; - // We delegate through the "xxNext" handlers, and - // report the "xxHandler" ones on our input side. + // 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". + // 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 */ } + 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 */ } } /** @@ -442,33 +442,33 @@ public class EventFilter * * @param next the next downstream component of the pipeline. * @exception IllegalStateException if the "next" consumer has - * already been set through the constructor. + * already been set through the constructor. */ public void chainTo (XMLFilterImpl next) { - if (this.next != null) - throw new IllegalStateException (); + if (this.next != null) + throw new IllegalStateException (); - docNext = next.getContentHandler (); - if (docHandler == null) - docHandler = docNext; - dtdNext = next.getDTDHandler (); - if (dtdHandler == null) - dtdHandler = dtdNext; + 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 */ } + 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); + if (errHandler != null) + next.setErrorHandler (errHandler); } /** @@ -477,9 +477,9 @@ public class EventFilter */ final public void setErrorHandler (ErrorHandler handler) { - errHandler = handler; - if (next != null) - next.setErrorHandler (handler); + errHandler = handler; + if (next != null) + next.setErrorHandler (handler); } /** @@ -488,7 +488,7 @@ public class EventFilter */ final public ErrorHandler getErrorHandler () { - return errHandler; + return errHandler; } @@ -497,7 +497,7 @@ public class EventFilter * is no such handler. */ final public EventConsumer getNext () - { return next; } + { return next; } /** @@ -508,13 +508,13 @@ public class EventFilter */ final public void setContentHandler (ContentHandler h) { - docHandler = h; + docHandler = h; } /** Returns the content handler being used. */ final public ContentHandler getContentHandler () { - return docHandler; + return docHandler; } /** @@ -524,12 +524,12 @@ public class EventFilter * probably pointed to the next consumer by the base class constructor. */ final public void setDTDHandler (DTDHandler h) - { dtdHandler = h; } + { dtdHandler = h; } /** Returns the dtd handler being used. */ final public DTDHandler getDTDHandler () { - return dtdHandler; + return dtdHandler; } /** @@ -541,36 +541,36 @@ public class EventFilter 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); - } + 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; + if (DECL_HANDLER.equals (id)) + return declHandler; + if (LEXICAL_HANDLER.equals (id)) + return lexHandler; - throw new SAXNotRecognizedException (id); + throw new SAXNotRecognizedException (id); } /** @@ -578,7 +578,7 @@ public class EventFilter * (or a subclass) is handling {@link ContentHandler } events. */ public Locator getDocumentLocator () - { return locator; } + { return locator; } // CONTENT HANDLER DELEGATIONS @@ -586,113 +586,113 @@ public class EventFilter /** <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); + 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 (); + 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); + 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); + 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); + 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); + 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); + 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 + String uri, String localName, + String qName, Attributes atts ) throws SAXException { - if (docNext != null) - docNext.startElement (uri, localName, qName, atts); + 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); + 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); + 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; + 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 + String name, + String publicId, + String systemId, + String notationName ) throws SAXException { - if (dtdNext != null) - dtdNext.unparsedEntityDecl (name, publicId, systemId, notationName); + 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); + if (dtdNext != null) + dtdNext.notationDecl (name, publicId, systemId); } - + // LEXICAL HANDLER DELEGATIONS @@ -700,40 +700,40 @@ public class EventFilter public void startDTD (String name, String publicId, String systemId) throws SAXException { - if (lexNext != null) - lexNext.startDTD (name, publicId, systemId); + 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 (); + 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); + 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 (); + 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 (); + if (lexNext != null) + lexNext.endCDATA (); } /** @@ -742,8 +742,8 @@ public class EventFilter public void startEntity (String name) throws SAXException { - if (lexNext != null) - lexNext.startEntity (name); + if (lexNext != null) + lexNext.startEntity (name); } /** @@ -752,10 +752,10 @@ public class EventFilter public void endEntity (String name) throws SAXException { - if (lexNext != null) - lexNext.endEntity (name); + if (lexNext != null) + lexNext.endEntity (name); } - + // DECLARATION HANDLER DELEGATIONS @@ -764,33 +764,33 @@ public class EventFilter public void elementDecl (String name, String model) throws SAXException { - if (declNext != null) - declNext.elementDecl (name, model); + 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) + String type, String mode, String value) throws SAXException { - if (declNext != null) - declNext.attributeDecl (eName, aName, type, mode, value); + 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) + String publicId, String systemId) throws SAXException { - if (declNext != null) - declNext.externalEntityDecl (name, publicId, systemId); + 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); + if (declNext != null) + declNext.internalEntityDecl (name, value); } } diff --git a/gnu/xml/pipeline/LinkFilter.java b/gnu/xml/pipeline/LinkFilter.java index ddb9fda2e..e11a5eca6 100644 --- a/gnu/xml/pipeline/LinkFilter.java +++ b/gnu/xml/pipeline/LinkFilter.java @@ -1,4 +1,4 @@ -/* LinkFilter.java -- +/* LinkFilter.java -- Copyright (C) 1999,2000,2001 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,7 +38,7 @@ exception statement from your version. */ package gnu.xml.pipeline; import java.io.IOException; -import java.net.URL; +import java.net.URL; import java.util.Enumeration; import java.util.Vector; @@ -65,21 +65,21 @@ import org.xml.sax.SAXException; public class LinkFilter extends EventFilter { // for storing URIs - private Vector vector = new Vector (); + 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) + // 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 ? + // XLink model of the link ... for inter-site pairups ? - private String baseURI; + private String baseURI; - private boolean siteRestricted = false; + private boolean siteRestricted = false; // // XXX leverage blacklist info (like robots.txt) @@ -93,10 +93,10 @@ public class LinkFilter extends EventFilter * Constructs a new event filter, which collects links in private data * structure for later enumeration. */ - // constructor used by PipelineFactory + // constructor used by PipelineFactory public LinkFilter () { - super.setContentHandler (this); + super.setContentHandler (this); } @@ -105,11 +105,11 @@ public class LinkFilter extends EventFilter * structure for later enumeration and passes all events, unmodified, * to the next consumer. */ - // constructor used by PipelineFactory + // constructor used by PipelineFactory public LinkFilter (EventConsumer next) { - super (next); - super.setContentHandler (this); + super (next); + super.setContentHandler (this); } @@ -121,7 +121,7 @@ public class LinkFilter extends EventFilter */ public Enumeration getLinks () { - return vector.elements (); + return vector.elements (); } /** @@ -130,7 +130,7 @@ public class LinkFilter extends EventFilter */ public void removeAllLinks () { - vector = new Vector (); + vector = new Vector (); } @@ -138,84 +138,84 @@ public class LinkFilter extends EventFilter * Collects URIs for (X)HTML content from elements which hold them. */ public void startElement ( - String uri, - String localName, - String qName, - Attributes atts + 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); + 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; + 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; } /** @@ -224,8 +224,8 @@ public class LinkFilter extends EventFilter public void startDocument () throws SAXException { - if (getDocumentLocator () == null) - throw new SAXException ("no Locator!"); + if (getDocumentLocator () == null) + throw new SAXException ("no Locator!"); } /** @@ -236,7 +236,7 @@ public class LinkFilter extends EventFilter public void endDocument () throws SAXException { - baseURI = null; - super.endDocument (); + baseURI = null; + super.endDocument (); } } diff --git a/gnu/xml/pipeline/NSFilter.java b/gnu/xml/pipeline/NSFilter.java index db875e1de..0fa4621d3 100644 --- a/gnu/xml/pipeline/NSFilter.java +++ b/gnu/xml/pipeline/NSFilter.java @@ -1,4 +1,4 @@ -/* NSFilter.java -- +/* NSFilter.java -- Copyright (C) 1999,2000,2001 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -56,23 +56,23 @@ import org.xml.sax.helpers.NamespaceSupport; * 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> 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> 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. + * <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> + * </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 @@ -91,55 +91,55 @@ import org.xml.sax.helpers.NamespaceSupport; */ public class NSFilter extends EventFilter { - private NamespaceSupport nsStack = new NamespaceSupport (); - private Stack elementStack = new Stack (); + 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; + 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-"; + 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 + // constructor used by PipelineFactory public NSFilter (EventConsumer next) { - super (next); + super (next); - setContentHandler (this); + 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; + 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 (); + elementStack.removeAllElements (); + nsStack.reset (); + pushedContext = false; + super.startDocument (); } /** @@ -151,176 +151,176 @@ public class NSFilter extends EventFilter 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); + 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; + 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 + 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); + 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); + nsStack.popContext (); + qName = (String) elementStack.pop (); + super.endElement (uri, localName, qName); } /** @@ -330,12 +330,12 @@ public class NSFilter extends EventFilter */ public void endPrefixMapping (String prefix) throws SAXException - { } + { } public void endDocument () throws SAXException { - elementStack.removeAllElements (); - nsStack.reset (); - super.endDocument (); + elementStack.removeAllElements (); + nsStack.reset (); + super.endDocument (); } } diff --git a/gnu/xml/pipeline/PipelineFactory.java b/gnu/xml/pipeline/PipelineFactory.java index f88ab1643..c2adab021 100644 --- a/gnu/xml/pipeline/PipelineFactory.java +++ b/gnu/xml/pipeline/PipelineFactory.java @@ -1,4 +1,4 @@ -/* PipelineFactory.java -- +/* PipelineFactory.java -- Copyright (C) 1999,2000,2001 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -69,120 +69,120 @@ import org.xml.sax.ext.*; * 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> + <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> + <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> + <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> + <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> + <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> + <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> + <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> + <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> + <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> + <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> + <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> + <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 @@ -200,7 +200,7 @@ public class PipelineFactory public static EventConsumer createPipeline (String description) throws IOException { - return createPipeline (description, null); + return createPipeline (description, null); } /** @@ -211,25 +211,25 @@ public class PipelineFactory * segments with easily configured ones. */ public static EventConsumer createPipeline ( - String description, - EventConsumer next + String description, + EventConsumer next ) throws IOException { - // tokens are (for now) what's separated by whitespace; - // very easy to parse, but IDs never have spaces. + // tokens are (for now) what's separated by whitespace; + // very easy to parse, but IDs never have spaces. - StringTokenizer tokenizer; - String tokens []; + 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 (); + 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); + PipelineFactory factory = new PipelineFactory (); + Pipeline pipeline = factory.parsePipeline (tokens, next); - return pipeline.createPipeline (); + return pipeline.createPipeline (); } @@ -242,70 +242,70 @@ public class PipelineFactory * predefined aliases) left and right parenthesis, and the vertical bar. */ public static EventConsumer createPipeline ( - String tokens [], - EventConsumer next + String tokens [], + EventConsumer next ) throws IOException { - PipelineFactory factory = new PipelineFactory (); - Pipeline pipeline = factory.parsePipeline (tokens, next); + PipelineFactory factory = new PipelineFactory (); + Pipeline pipeline = factory.parsePipeline (tokens, next); - return pipeline.createPipeline (); + return pipeline.createPipeline (); } - private String tokens []; - private int index; + 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; + 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; + 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; + 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; } @@ -313,12 +313,12 @@ public class PipelineFactory // 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 + // - 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 (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 @@ -326,397 +326,397 @@ public class PipelineFactory // 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" }, + { "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 + // 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); + 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.isAbsolute ()) + fail ("require absolute file paths"); */ - if (f.exists ()) - fail ("file already exists: " + f.getName ()); + 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; - } + 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; - } + 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 ( + 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 (); - } + // 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/gnu/xml/pipeline/TeeConsumer.java b/gnu/xml/pipeline/TeeConsumer.java index 8186de4df..3ac860575 100644 --- a/gnu/xml/pipeline/TeeConsumer.java +++ b/gnu/xml/pipeline/TeeConsumer.java @@ -1,4 +1,4 @@ -/* TeeConsumer.java -- +/* TeeConsumer.java -- Copyright (C) 1999,2000,2001 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -68,16 +68,16 @@ import org.xml.sax.ext.LexicalHandler; * @author David Brownell */ final public class TeeConsumer - implements EventConsumer, - ContentHandler, DTDHandler, - LexicalHandler,DeclHandler + implements EventConsumer, + ContentHandler, DTDHandler, + LexicalHandler,DeclHandler { - private EventConsumer first, rest; + private EventConsumer first, rest; // cached to minimize time overhead - private ContentHandler docFirst, docRest; - private DeclHandler declFirst, declRest; - private LexicalHandler lexFirst, lexRest; + private ContentHandler docFirst, docRest; + private DeclHandler declFirst, declRest; + private LexicalHandler lexFirst, lexRest; /** @@ -91,39 +91,39 @@ final public class TeeConsumer */ 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) {} + 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 @@ -132,78 +132,78 @@ final public class TeeConsumer * two-consumer constructor for this class. * * @param first Description of the first pipeline to get events, - * which will be passed to {@link PipelineFactory#createPipeline} + * which will be passed to {@link PipelineFactory#createPipeline} * @param rest The second pipeline to get the events * / - // constructor used by PipelineFactory + // constructor used by PipelineFactory public TeeConsumer (String first, EventConsumer rest) throws IOException { - this (PipelineFactory.createPipeline (first), rest); + this (PipelineFactory.createPipeline (first), rest); } */ /** Returns the first pipeline to get event calls. */ public EventConsumer getFirst () - { return first; } + { return first; } /** Returns the second pipeline to get event calls. */ public EventConsumer getRest () - { return rest; } + { return rest; } /** Returns the content handler being used. */ final public ContentHandler getContentHandler () { - if (docRest == null) - return docFirst; - if (docFirst == null) - return docRest; - return this; + 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; + // 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); + // + // 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); } /** @@ -212,8 +212,8 @@ final public class TeeConsumer */ public void setErrorHandler (ErrorHandler handler) { - first.setErrorHandler (handler); - rest.setErrorHandler (handler); + first.setErrorHandler (handler); + rest.setErrorHandler (handler); } @@ -222,83 +222,83 @@ final public class TeeConsumer // public void setDocumentLocator (Locator locator) { - // this call is not made by all parsers - docFirst.setDocumentLocator (locator); - docRest.setDocumentLocator (locator); + // this call is not made by all parsers + docFirst.setDocumentLocator (locator); + docRest.setDocumentLocator (locator); } public void startDocument () throws SAXException { - docFirst.startDocument (); - docRest.startDocument (); + docFirst.startDocument (); + docRest.startDocument (); } public void endDocument () throws SAXException { - try { - docFirst.endDocument (); - } finally { - docRest.endDocument (); - } + try { + docFirst.endDocument (); + } finally { + docRest.endDocument (); + } } public void startPrefixMapping (String prefix, String uri) throws SAXException { - docFirst.startPrefixMapping (prefix, uri); - docRest.startPrefixMapping (prefix, uri); + docFirst.startPrefixMapping (prefix, uri); + docRest.startPrefixMapping (prefix, uri); } public void endPrefixMapping (String prefix) throws SAXException { - docFirst.endPrefixMapping (prefix); - docRest.endPrefixMapping (prefix); + docFirst.endPrefixMapping (prefix); + docRest.endPrefixMapping (prefix); } public void skippedEntity (String name) throws SAXException { - docFirst.skippedEntity (name); - docRest.skippedEntity (name); + docFirst.skippedEntity (name); + docRest.skippedEntity (name); } public void startElement (String uri, String localName, - String qName, Attributes atts) + String qName, Attributes atts) throws SAXException { - docFirst.startElement (uri, localName, qName, atts); - docRest.startElement (uri, localName, qName, atts); + 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); + 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); + 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); + 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); + docFirst.ignorableWhitespace (ch, start, length); + docRest.ignorableWhitespace (ch, start, length); } @@ -308,23 +308,23 @@ final public class TeeConsumer public void notationDecl (String name, String publicId, String systemId) throws SAXException { - DTDHandler l1 = first.getDTDHandler (); - DTDHandler l2 = rest.getDTDHandler (); + DTDHandler l1 = first.getDTDHandler (); + DTDHandler l2 = rest.getDTDHandler (); - l1.notationDecl (name, publicId, systemId); - l2.notationDecl (name, publicId, systemId); + l1.notationDecl (name, publicId, systemId); + l2.notationDecl (name, publicId, systemId); } public void unparsedEntityDecl (String name, - String publicId, String systemId, - String notationName + String publicId, String systemId, + String notationName ) throws SAXException { - DTDHandler l1 = first.getDTDHandler (); - DTDHandler l2 = rest.getDTDHandler (); + DTDHandler l1 = first.getDTDHandler (); + DTDHandler l2 = rest.getDTDHandler (); - l1.unparsedEntityDecl (name, publicId, systemId, notationName); - l2.unparsedEntityDecl (name, publicId, systemId, notationName); + l1.unparsedEntityDecl (name, publicId, systemId, notationName); + l2.unparsedEntityDecl (name, publicId, systemId, notationName); } @@ -332,34 +332,34 @@ final public class TeeConsumer // DeclHandler // public void attributeDecl (String eName, String aName, - String type, - String mode, String value) + String type, + String mode, String value) throws SAXException { - declFirst.attributeDecl (eName, aName, type, mode, value); - declRest.attributeDecl (eName, aName, type, mode, value); + 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); + declFirst.elementDecl (name, model); + declRest.elementDecl (name, model); } public void externalEntityDecl (String name, - String publicId, String systemId) + String publicId, String systemId) throws SAXException { - declFirst.externalEntityDecl (name, publicId, systemId); - declRest.externalEntityDecl (name, publicId, systemId); + 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); + declFirst.internalEntityDecl (name, value); + declRest.internalEntityDecl (name, value); } @@ -369,49 +369,49 @@ final public class TeeConsumer public void comment (char ch [], int start, int length) throws SAXException { - lexFirst.comment (ch, start, length); - lexRest.comment (ch, start, length); + lexFirst.comment (ch, start, length); + lexRest.comment (ch, start, length); } - + public void startCDATA () throws SAXException { - lexFirst.startCDATA (); - lexRest.startCDATA (); + lexFirst.startCDATA (); + lexRest.startCDATA (); } - + public void endCDATA () throws SAXException { - lexFirst.endCDATA (); - lexRest.endCDATA (); + lexFirst.endCDATA (); + lexRest.endCDATA (); } - + public void startEntity (String name) throws SAXException { - lexFirst.startEntity (name); - lexRest.startEntity (name); + lexFirst.startEntity (name); + lexRest.startEntity (name); } - + public void endEntity (String name) throws SAXException { - lexFirst.endEntity (name); - lexRest.endEntity (name); + 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); + lexFirst.startDTD (name, publicId, systemId); + lexRest.startDTD (name, publicId, systemId); } - + public void endDTD () throws SAXException { - lexFirst.endDTD (); - lexRest.endDTD (); + lexFirst.endDTD (); + lexRest.endDTD (); } } diff --git a/gnu/xml/pipeline/TextConsumer.java b/gnu/xml/pipeline/TextConsumer.java index 67bd23b00..13dcfa7f6 100644 --- a/gnu/xml/pipeline/TextConsumer.java +++ b/gnu/xml/pipeline/TextConsumer.java @@ -1,4 +1,4 @@ -/* TextConsumer.java -- +/* TextConsumer.java -- Copyright (C) 1999,2000,2001 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -72,8 +72,8 @@ public class TextConsumer extends XMLWriter implements EventConsumer public TextConsumer (Writer w, boolean isXhtml) throws IOException { - super (w, isXhtml ? "US-ASCII" : null); - setXhtml (isXhtml); + super (w, isXhtml ? "US-ASCII" : null); + setXhtml (isXhtml); } /** @@ -83,9 +83,9 @@ public class TextConsumer extends XMLWriter implements EventConsumer public TextConsumer (Writer w) throws IOException { - this (w, false); + this (w, false); } - + /** * Constructs a consumer that writes its input as XML text, * encoded in UTF-8. XHTML rules are not followed. @@ -93,25 +93,25 @@ public class TextConsumer extends XMLWriter implements EventConsumer public TextConsumer (OutputStream out) throws IOException { - this (new OutputStreamWriter (out, "UTF8"), false); + this (new OutputStreamWriter (out, "UTF8"), false); } /** <b>EventConsumer</b> Returns the document handler being used. */ public ContentHandler getContentHandler () - { return this; } + { return this; } /** <b>EventConsumer</b> Returns the dtd handler being used. */ public DTDHandler getDTDHandler () - { return this; } + { 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); + if (EventFilter.LEXICAL_HANDLER.equals (propertyId)) + return this; + if (EventFilter.DECL_HANDLER.equals (propertyId)) + return this; + throw new SAXNotRecognizedException (propertyId); } } diff --git a/gnu/xml/pipeline/ValidationConsumer.java b/gnu/xml/pipeline/ValidationConsumer.java index 839176749..0346984d3 100644 --- a/gnu/xml/pipeline/ValidationConsumer.java +++ b/gnu/xml/pipeline/ValidationConsumer.java @@ -1,4 +1,4 @@ -/* ValidationConsumer.java -- +/* ValidationConsumer.java -- Copyright (C) 1999,2000,2001 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -62,24 +62,24 @@ import org.xml.sax.helpers.XMLReaderFactory; * 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> 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> 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 "<").</li> + * <li> Make SAX2 DeclHandler callbacks, with default + * attribute values already normalized (and without "<").</li> * - * <li> Make SAX2 LexicalHandler startDTD() and endDTD () - * callbacks. </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> + * <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> + * </ol> * * <p> At this writing, the major SAX2 parsers (such as Ælfred2, * Crimson, and Xerces) meet these requirements, and this validation @@ -128,51 +128,51 @@ import org.xml.sax.helpers.XMLReaderFactory; * 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>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>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.) + * <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> + * </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. (Ælfred2 reports these validity - * errors directly.)</li> + * <li> The <em>Unique Element Type Declaration</em> VC may not be + * reportable, if the underlying parser happens not to expose + * multiple declarations. (Æ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. (Ælfred 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. (Ælfred reports these + * validity errors directly.) </li> * - * </ul> + * </ul> * * <p> A third category relates to ease of implementation. (Think of this * as "bugs".) The most notable issue here is character handling. Rather @@ -199,15 +199,15 @@ 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; + private static final boolean warnNonDeterministic = false; // for tracking active content models - private String rootName; - private Stack contentStack = new Stack (); + private String rootName; + private Stack contentStack = new Stack (); // flags for "saved DTD" processing - private boolean disableDeclarations; - private boolean disableReset; + private boolean disableDeclarations; + private boolean disableReset; // // most VCs get tested when we see element start tags. the per-element @@ -217,25 +217,25 @@ public final class ValidationConsumer extends EventFilter // // key = element name; value = ElementInfo - private Hashtable elements = new Hashtable (); + 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 (); + 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) + 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 @@ -244,11 +244,11 @@ public final class ValidationConsumer extends EventFilter * * @see #setErrorHandler */ - // constructor used by PipelineFactory - // ... and want one taking system ID of an external subset + // constructor used by PipelineFactory + // ... and want one taking system ID of an external subset public ValidationConsumer () { - this (null); + this (null); } /** @@ -257,25 +257,25 @@ public final class ValidationConsumer extends EventFilter * * @see #setErrorHandler */ - // constructor used by PipelineFactory - // ... and want one taking system ID of an external subset - // (which won't send declaration events) + // 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" */ } + 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:"; - + + 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 @@ -287,182 +287,182 @@ public final class ValidationConsumer extends EventFilter * 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. + * 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. + * 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. + * 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. + * 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). + * 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). + * 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. + * not support the standard lexical or declaration handlers. * @exception SAXParseException If the specified DTD has either - * well-formedness or validity errors + * well-formedness or validity errors * @exception IOException If the specified DTD can't be read for - * some reason + * some reason */ public ValidationConsumer ( - String rootName, - String publicId, - String systemId, - String internalSubset, - EntityResolver resolver, - String minimalDocument + 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; + 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 (); - } + 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); + 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; + 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; + 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); + // [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); } @@ -470,86 +470,86 @@ public final class ValidationConsumer extends EventFilter 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 + 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 + 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); + 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; + 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; } /** @@ -561,11 +561,11 @@ public final class ValidationConsumer extends EventFilter public void startDTD (String name, String publicId, String systemId) throws SAXException { - if (disableDeclarations) - return; + if (disableDeclarations) + return; - rootName = name; - super.startDTD (name, publicId, systemId); + rootName = name; + super.startDTD (name, publicId, systemId); } /** @@ -577,37 +577,37 @@ public final class ValidationConsumer extends EventFilter 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 (); + 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 (); } @@ -615,10 +615,10 @@ public final class ValidationConsumer extends EventFilter // all attributes except enumerations ... // "(this|or|that|...)" and "NOTATION (this|or|that|...)" static final String types [] = { - "CDATA", - "ID", "IDREF", "IDREFS", - "NMTOKEN", "NMTOKENS", - "ENTITY", "ENTITIES" + "CDATA", + "ID", "IDREF", "IDREFS", + "NMTOKEN", "NMTOKENS", + "ENTITY", "ENTITIES" }; @@ -630,172 +630,172 @@ public final class ValidationConsumer extends EventFilter * preloaded with a particular DTD. */ public void attributeDecl ( - String eName, - String aName, - String type, - String mode, - String value + 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); + 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); } /** @@ -807,29 +807,29 @@ public final class ValidationConsumer extends EventFilter 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); + 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); } /** @@ -839,8 +839,8 @@ public final class ValidationConsumer extends EventFilter public void internalEntityDecl (String name, String value) throws SAXException { - if (!disableDeclarations) - super.internalEntityDecl (name, value); + if (!disableDeclarations) + super.internalEntityDecl (name, value); } /** @@ -848,11 +848,11 @@ public final class ValidationConsumer extends EventFilter * one was preloaded with a particular DTD */ public void externalEntityDecl (String name, - String publicId, String systemId) + String publicId, String systemId) throws SAXException { - if (!disableDeclarations) - super.externalEntityDecl (name, publicId, systemId); + if (!disableDeclarations) + super.externalEntityDecl (name, publicId, systemId); } @@ -865,11 +865,11 @@ public final class ValidationConsumer extends EventFilter public void notationDecl (String name, String publicId, String systemId) throws SAXException { - if (disableDeclarations) - return; + if (disableDeclarations) + return; - notations.addElement (name); - super.notationDecl (name, publicId, systemId); + notations.addElement (name); + super.notationDecl (name, publicId, systemId); } /** @@ -879,22 +879,22 @@ public final class ValidationConsumer extends EventFilter * unless this one was preloaded with a particular DTD. */ public void unparsedEntityDecl ( - String name, - String publicId, - String systemId, - String notationName + String name, + String publicId, + String systemId, + String notationName ) throws SAXException { - if (disableDeclarations) - return; + if (disableDeclarations) + return; - unparsed.addElement (name); - if (!notations.contains (notationName)) - nDeferred.addElement (notationName); - super.unparsedEntityDecl (name, publicId, systemId, notationName); + 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. @@ -903,14 +903,14 @@ public final class ValidationConsumer extends EventFilter public void startDocument () throws SAXException { - resetState (); - super.startDocument (); + resetState (); + super.startDocument (); } private static boolean isAsciiLetter (char c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } @@ -921,7 +921,7 @@ public final class ValidationConsumer extends EventFilter public void skippedEntity (String name) throws SAXException { - fatalError ("may not skip entities"); + fatalError ("may not skip entities"); } /* @@ -930,14 +930,14 @@ public final class ValidationConsumer extends EventFilter private String expandDefaultRefs (String s) throws SAXException { - if (s.indexOf ('&') < 0) - return s; - + if (s.indexOf ('&') < 0) + return s; + // FIXME: handle &#nn; &#xnn; &name; - String message = "Can't expand refs in attribute default: " + s; - warning (message); + String message = "Can't expand refs in attribute default: " + s; + warning (message); - return s; + return s; } /** @@ -946,248 +946,248 @@ public final class ValidationConsumer extends EventFilter * Passed to the next consumer. */ public void startElement ( - String uri, - String localName, - String qName, - Attributes atts + 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); + // + // 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); } /** @@ -1198,25 +1198,25 @@ public final class ValidationConsumer extends EventFilter 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); + 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 @@ -1227,95 +1227,95 @@ public final class ValidationConsumer extends EventFilter 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); + 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. + * 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 (); + 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; - } + 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 + String type; + String mode; // #REQUIRED, etc (or null) + String value; // or null } @@ -1323,120 +1323,120 @@ public final class ValidationConsumer extends EventFilter // Content model validation // - static private final Recognizer ANY = new Recognizer (null); + 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; } + 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); } + public EmptyRecognizer (ElementInfo type) + { super (type); } - // VC: Element Valid (first clause) - boolean acceptCharacters () - { return false; } + // VC: Element Valid (first clause) + boolean acceptCharacters () + { return false; } - // VC: Element Valid (first clause) - Recognizer acceptElement (String name) - { return null; } + // 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; - } + 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; + 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; + private static int nodeCount; /** * "Children" content model -- these are nodes in NDFA state graphs. @@ -1463,466 +1463,466 @@ public final class ValidationConsumer extends EventFilter * graph to have one exit node (or more EMPTY nodes). */ private static final class ChildrenRecognizer extends Recognizer - implements Cloneable + 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 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 (">"); - } + // 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/gnu/xml/pipeline/WellFormednessFilter.java b/gnu/xml/pipeline/WellFormednessFilter.java index ef4301652..7a3db6593 100644 --- a/gnu/xml/pipeline/WellFormednessFilter.java +++ b/gnu/xml/pipeline/WellFormednessFilter.java @@ -1,4 +1,4 @@ -/* WellFormednessFilter.java -- +/* WellFormednessFilter.java -- Copyright (C) 1999,2000,2001 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -50,27 +50,27 @@ 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>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>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>startElement/endElement ... must be correctly paired, and + * may never appear within CDATA sections. * - * <li>comment ... can't contain "--" + * <li>comment ... can't contain "--" * - * <li>character data ... can't contain "]]>" + * <li>character data ... can't contain "]]>" * - * <li>whitespace ... can't contain CR + * <li>whitespace ... can't contain CR * - * <li>whitespace and character data must be within an element + * <li>whitespace and character data must be within an element * - * <li>processing instruction ... can't contain "?>" or CR + * <li>processing instruction ... can't contain "?>" or CR * - * <li>startCDATA/endCDATA ... must be correctly paired. + * <li>startCDATA/endCDATA ... must be correctly paired. * - * </ul> + * </ul> * * <p> Other checks for event stream correctness may be provided in * the future. For example, insisting that @@ -84,35 +84,35 @@ import org.xml.sax.SAXParseException; */ public final class WellFormednessFilter extends EventFilter { - private boolean startedDoc; - private Stack elementStack = new Stack (); - private boolean startedCDATA; - private String dtdState = "before"; + 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 + // constructor used by PipelineFactory public WellFormednessFilter () - { this (null); } + { this (null); } /** * Passes events through to the specified consumer, after first * processing them. */ - // constructor used by PipelineFactory + // 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 */ } + super (consumer); + + setContentHandler (this); + setDTDHandler (this); + + try { + setProperty (LEXICAL_HANDLER, this); + } catch (SAXException e) { /* can't happen */ } } /** @@ -122,123 +122,123 @@ public final class WellFormednessFilter extends EventFilter */ public void reset () { - startedDoc = false; - startedCDATA = false; - elementStack.removeAllElements (); + startedDoc = false; + startedCDATA = false; + elementStack.removeAllElements (); } private SAXParseException getException (String message) { - SAXParseException e; - Locator locator = getDocumentLocator (); + SAXParseException e; + Locator locator = getDocumentLocator (); - if (locator == null) - return new SAXParseException (message, null, null, -1, -1); - else - return new SAXParseException (message, locator); + 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 (); + SAXParseException e = getException (message); + ErrorHandler handler = getErrorHandler (); - if (handler != null) - handler.fatalError (e); - throw e; + 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. + * URI resolution. * * @exception IllegalStateException when called after the document - * has already been started + * has already been started */ public void setDocumentLocator (Locator locator) { - if (startedDoc) - throw new IllegalStateException ( - "setDocumentLocator called after startDocument"); - super.setDocumentLocator (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 (); + 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 + 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); + 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); + 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 (); + 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 (!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); + 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) @@ -247,19 +247,19 @@ public final class WellFormednessFilter extends EventFilter // 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); + fatalError ("not inside DTD"); + super.notationDecl (name, publicId, systemId); } public void unparsedEntityDecl (String name, - String publicId, String systemId, String notationName) + 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); + fatalError ("not inside DTD"); + super.unparsedEntityDecl (name, publicId, systemId, notationName); } // FIXME: add the four DeclHandler calls too @@ -267,97 +267,97 @@ public final class WellFormednessFilter extends EventFilter public void endDTD () throws SAXException { - if (!startedDoc) - fatalError ("callback outside of document?"); - if ("inside" != dtdState) - fatalError ("DTD ends without start?"); - dtdState = "after"; - super.endDTD (); + 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); + 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); + 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 \"?>\""); + 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); + 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 (); + 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 (); + if (!startedDoc) + fatalError ("callback outside of document?"); + if (!startedCDATA) + fatalError ("CDATA end without start?"); + startedCDATA = false; + super.endCDATA (); } } diff --git a/gnu/xml/pipeline/XIncludeFilter.java b/gnu/xml/pipeline/XIncludeFilter.java index 02607a4e0..a1445fa0c 100644 --- a/gnu/xml/pipeline/XIncludeFilter.java +++ b/gnu/xml/pipeline/XIncludeFilter.java @@ -1,4 +1,4 @@ -/* XIncludeFilter.java -- +/* XIncludeFilter.java -- Copyright (C) 2001,2002 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -40,8 +40,8 @@ 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.net.URL; +import java.net.URLConnection; import java.util.Hashtable; import java.util.Stack; import java.util.Vector; @@ -77,7 +77,7 @@ import gnu.xml.util.Resolver; * currently supported. * * <li> DTDs are not supported in included files, since the SAX DTD events - * must have completely preceded any included file. + * 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. * @@ -101,33 +101,33 @@ import gnu.xml.util.Resolver; */ 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; + 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); + 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; + ErrorHandler eh; + + eh = getErrorHandler (); + if (eh != null) + eh.fatalError (e); + throw e; } /** @@ -135,29 +135,29 @@ public class XIncludeFilter extends EventFilter implements Locator */ public void setDocumentLocator (Locator locator) { - this.locator = locator; - super.setDocumentLocator (this); + this.locator = locator; + super.setDocumentLocator (this); } /** Used for proxy locator; do not call directly. */ public String getSystemId () - { return (locator == null) ? null : locator.getSystemId (); } + { return (locator == null) ? null : locator.getSystemId (); } /** Used for proxy locator; do not call directly. */ public String getPublicId () - { return (locator == null) ? null : locator.getPublicId (); } + { return (locator == null) ? null : locator.getPublicId (); } /** Used for proxy locator; do not call directly. */ public int getLineNumber () - { return (locator == null) ? -1 : locator.getLineNumber (); } + { return (locator == null) ? -1 : locator.getLineNumber (); } /** Used for proxy locator; do not call directly. */ public int getColumnNumber () - { return (locator == null) ? -1 : locator.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; } + { savingPrefixes = flag; } /** * Returns the flag controlling the setting of the SAX2 @@ -166,49 +166,49 @@ public class XIncludeFilter extends EventFilter implements Locator * information that can be useful. */ public boolean isSavingPrefixes () - { return savingPrefixes; } + { 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. + // - 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; + 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 (); + inclusions.removeElement (uri); + uris.pop (); } // @@ -216,66 +216,66 @@ public class XIncludeFilter extends EventFilter implements Locator // public void startDocument () throws SAXException { - ignoreCount = 0; - addMarker (null); - super.startDocument (); + ignoreCount = 0; + addMarker (null); + super.startDocument (); } public void endDocument () throws SAXException { - inclusions.setSize (0); - extEntities.clear (); - uris.setSize (0); - super.endDocument (); + 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) + 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); + 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); + 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; - } + if (ignoreCount != 0) { + if (--ignoreCount != 0) + return; + } - String uri = (String) extEntities.get (name); + String uri = (String) extEntities.get (name); - if (uri != null) - pop (uri); - super.endEntity (name); + if (uri != null) + pop (uri); + super.endEntity (name); } - + // // element boundaries only affect the base URI stack, // unless they're XInclude elements. @@ -284,103 +284,103 @@ public class XIncludeFilter extends EventFilter implements Locator 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); - } + 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); + 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); } // @@ -389,66 +389,66 @@ public class XIncludeFilter extends EventFilter implements Locator public void characters (char ch [], int start, int length) throws SAXException { - if (ignoreCount == 0) - super.characters (ch, start, length); + if (ignoreCount == 0) + super.characters (ch, start, length); } public void processingInstruction (String target, String value) throws SAXException { - if (ignoreCount == 0) - super.processingInstruction (target, value); + 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); + 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); + if (ignoreCount == 0) + super.comment (ch, start, length); } public void startCDATA () throws SAXException { - if (ignoreCount == 0) - super.startCDATA (); + if (ignoreCount == 0) + super.startCDATA (); } public void endCDATA () throws SAXException { - if (ignoreCount == 0) - super.endCDATA (); + if (ignoreCount == 0) + super.endCDATA (); } public void startPrefixMapping (String prefix, String uri) throws SAXException { - if (ignoreCount == 0) - super.startPrefixMapping (prefix, uri); + if (ignoreCount == 0) + super.startPrefixMapping (prefix, uri); } public void endPrefixMapping (String prefix) throws SAXException { - if (ignoreCount == 0) - super.endPrefixMapping (prefix); + if (ignoreCount == 0) + super.endPrefixMapping (prefix); } public void skippedEntity (String name) throws SAXException { - if (ignoreCount == 0) - super.skippedEntity (name); + 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 @@ -456,45 +456,45 @@ public class XIncludeFilter extends EventFilter implements Locator // 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 + 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' ...> @@ -502,40 +502,40 @@ public class XIncludeFilter extends EventFilter implements Locator 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; - } + 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' ...> @@ -543,37 +543,37 @@ public class XIncludeFilter extends EventFilter implements Locator 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); - } + 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/gnu/xml/pipeline/XsltFilter.java b/gnu/xml/pipeline/XsltFilter.java index 0a1872c5a..86b6190c5 100644 --- a/gnu/xml/pipeline/XsltFilter.java +++ b/gnu/xml/pipeline/XsltFilter.java @@ -1,4 +1,4 @@ -/* XsltFilter.java -- +/* XsltFilter.java -- Copyright (C) 2001 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -49,8 +49,8 @@ import org.xml.sax.ext.LexicalHandler; /** - * Packages an XSLT transform as a pipeline component. - * Note that all DTD events (callbacks to DeclHandler and DTDHandler + * 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, @@ -72,59 +72,59 @@ final public class XsltFilter extends EventFilter * or ErrorHandler support. * * @param stylesheet URI for the stylesheet specifying the - * XSLT transform + * XSLT transform * @param next provides the ContentHandler and LexicalHandler - * to receive XSLT output. + * 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. + * 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); + // 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); } } |