< prev index next >

src/java.xml/share/classes/org/xml/sax/helpers/ParserAdapter.java

Print this page


   1 /*
   2  * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  64  * @version 2.0.1 (sax2r2)
  65  * @see org.xml.sax.helpers.XMLReaderAdapter
  66  * @see org.xml.sax.XMLReader
  67  * @see org.xml.sax.Parser
  68  */
  69 @SuppressWarnings("deprecation")
  70 public class ParserAdapter implements XMLReader, DocumentHandler
  71 {
  72 
  73     ////////////////////////////////////////////////////////////////////
  74     // Constructors.
  75     ////////////////////////////////////////////////////////////////////
  76 
  77 
  78     /**
  79      * Construct a new parser adapter.
  80      *
  81      * <p>Use the "org.xml.sax.parser" property to locate the
  82      * embedded SAX1 driver.</p>
  83      *
  84      * @exception SAXException If the embedded driver
  85      *            cannot be instantiated or if the
  86      *            org.xml.sax.parser property is not specified.
  87      */
  88     public ParserAdapter ()
  89       throws SAXException
  90     {
  91         super();
  92 
  93         String driver = SecuritySupport.getSystemProperty("org.xml.sax.parser");
  94 
  95         try {
  96             setup(ParserFactory.makeParser());
  97         } catch (ClassNotFoundException e1) {
  98             throw new
  99                 SAXException("Cannot find SAX1 driver class " +
 100                              driver, e1);
 101         } catch (IllegalAccessException e2) {
 102             throw new
 103                 SAXException("SAX1 driver class " +
 104                              driver +


 111         } catch (ClassCastException e4) {
 112             throw new
 113                 SAXException("SAX1 driver class " +
 114                              driver +
 115                              " does not implement org.xml.sax.Parser");
 116         } catch (NullPointerException e5) {
 117             throw new
 118                 SAXException("System property org.xml.sax.parser not specified");
 119         }
 120     }
 121 
 122 
 123     /**
 124      * Construct a new parser adapter.
 125      *
 126      * <p>Note that the embedded parser cannot be changed once the
 127      * adapter is created; to embed a different parser, allocate
 128      * a new ParserAdapter.</p>
 129      *
 130      * @param parser The SAX1 parser to embed.
 131      * @exception java.lang.NullPointerException If the parser parameter
 132      *            is null.
 133      */
 134     public ParserAdapter (Parser parser)
 135     {
 136         super();
 137         setup(parser);
 138     }
 139 
 140 
 141     /**
 142      * Internal setup method.
 143      *
 144      * @param parser The embedded parser.
 145      * @exception java.lang.NullPointerException If the parser parameter
 146      *            is null.
 147      */
 148     private void setup (Parser parser)
 149     {
 150         if (parser == null) {
 151             throw new
 152                 NullPointerException("Parser argument must not be null");
 153         }
 154         this.parser = parser;
 155         atts = new AttributesImpl();
 156         nsSupport = new NamespaceSupport();
 157         attAdapter = new AttributeListAdapter();
 158     }
 159 
 160 
 161 
 162     ////////////////////////////////////////////////////////////////////
 163     // Implementation of org.xml.sax.XMLReader.
 164     ////////////////////////////////////////////////////////////////////
 165 
 166 
 167     //
 168     // Internal constants for the sake of convenience.
 169     //
 170     private final static String FEATURES = "http://xml.org/sax/features/";
 171     private final static String NAMESPACES = FEATURES + "namespaces";
 172     private final static String NAMESPACE_PREFIXES = FEATURES + "namespace-prefixes";
 173     private final static String XMLNS_URIs = FEATURES + "xmlns-uris";
 174 
 175 
 176     /**
 177      * Set a feature flag for the parser.
 178      *
 179      * <p>The only features recognized are namespaces and
 180      * namespace-prefixes.</p>
 181      *
 182      * @param name The feature name, as a complete URI.
 183      * @param value The requested feature value.
 184      * @exception SAXNotRecognizedException If the feature
 185      *            can't be assigned or retrieved.
 186      * @exception SAXNotSupportedException If the feature
 187      *            can't be assigned that value.
 188      * @see org.xml.sax.XMLReader#setFeature
 189      */
 190     public void setFeature (String name, boolean value)
 191         throws SAXNotRecognizedException, SAXNotSupportedException
 192     {
 193         if (name.equals(NAMESPACES)) {
 194             checkNotParsing("feature", name);
 195             namespaces = value;
 196             if (!namespaces && !prefixes) {
 197                 prefixes = true;
 198             }
 199         } else if (name.equals(NAMESPACE_PREFIXES)) {
 200             checkNotParsing("feature", name);
 201             prefixes = value;
 202             if (!prefixes && !namespaces) {
 203                 namespaces = true;
 204             }
 205         } else if (name.equals(XMLNS_URIs)) {
 206             checkNotParsing("feature", name);
 207             uris = value;
 208         } else {
 209             throw new SAXNotRecognizedException("Feature: " + name);
 210         }
 211     }
 212 
 213 
 214     /**
 215      * Check a parser feature flag.
 216      *
 217      * <p>The only features recognized are namespaces and
 218      * namespace-prefixes.</p>
 219      *
 220      * @param name The feature name, as a complete URI.
 221      * @return The current feature value.
 222      * @exception SAXNotRecognizedException If the feature
 223      *            value can't be assigned or retrieved.
 224      * @exception SAXNotSupportedException If the
 225      *            feature is not currently readable.
 226      * @see org.xml.sax.XMLReader#setFeature
 227      */
 228     public boolean getFeature (String name)
 229         throws SAXNotRecognizedException, SAXNotSupportedException
 230     {
 231         if (name.equals(NAMESPACES)) {
 232             return namespaces;
 233         } else if (name.equals(NAMESPACE_PREFIXES)) {
 234             return prefixes;
 235         } else if (name.equals(XMLNS_URIs)) {
 236             return uris;
 237         } else {
 238             throw new SAXNotRecognizedException("Feature: " + name);
 239         }
 240     }
 241 
 242 
 243     /**
 244      * Set a parser property.
 245      *
 246      * <p>No properties are currently recognized.</p>
 247      *
 248      * @param name The property name.
 249      * @param value The property value.
 250      * @exception SAXNotRecognizedException If the property
 251      *            value can't be assigned or retrieved.
 252      * @exception SAXNotSupportedException If the property
 253      *            can't be assigned that value.
 254      * @see org.xml.sax.XMLReader#setProperty
 255      */
 256     public void setProperty (String name, Object value)
 257         throws SAXNotRecognizedException, SAXNotSupportedException
 258     {
 259         throw new SAXNotRecognizedException("Property: " + name);
 260     }
 261 
 262 
 263     /**
 264      * Get a parser property.
 265      *
 266      * <p>No properties are currently recognized.</p>
 267      *
 268      * @param name The property name.
 269      * @return The property value.
 270      * @exception SAXNotRecognizedException If the property
 271      *            value can't be assigned or retrieved.
 272      * @exception SAXNotSupportedException If the property
 273      *            value is not currently readable.
 274      * @see org.xml.sax.XMLReader#getProperty
 275      */
 276     public Object getProperty (String name)
 277         throws SAXNotRecognizedException, SAXNotSupportedException
 278     {
 279         throw new SAXNotRecognizedException("Property: " + name);
 280     }
 281 
 282 
 283     /**
 284      * Set the entity resolver.
 285      *
 286      * @param resolver The new entity resolver.
 287      * @see org.xml.sax.XMLReader#setEntityResolver
 288      */
 289     public void setEntityResolver (EntityResolver resolver)
 290     {
 291         entityResolver = resolver;
 292     }


 363         errorHandler = handler;
 364     }
 365 
 366 
 367     /**
 368      * Return the current error handler.
 369      *
 370      * @return The current error handler, or null if none was supplied.
 371      * @see org.xml.sax.XMLReader#getEntityResolver
 372      */
 373     public ErrorHandler getErrorHandler ()
 374     {
 375         return errorHandler;
 376     }
 377 
 378 
 379     /**
 380      * Parse an XML document.
 381      *
 382      * @param systemId The absolute URL of the document.
 383      * @exception java.io.IOException If there is a problem reading
 384      *            the raw content of the document.
 385      * @exception SAXException If there is a problem
 386      *            processing the document.
 387      * @see #parse(org.xml.sax.InputSource)
 388      * @see org.xml.sax.Parser#parse(java.lang.String)
 389      */
 390     public void parse (String systemId)
 391         throws IOException, SAXException
 392     {
 393         parse(new InputSource(systemId));
 394     }
 395 
 396 
 397     /**
 398      * Parse an XML document.
 399      *
 400      * @param input An input source for the document.
 401      * @exception java.io.IOException If there is a problem reading
 402      *            the raw content of the document.
 403      * @exception SAXException If there is a problem
 404      *            processing the document.
 405      * @see #parse(java.lang.String)
 406      * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
 407      */
 408     public void parse (InputSource input)
 409         throws IOException, SAXException
 410     {
 411         if (parsing) {
 412             throw new SAXException("Parser is already in use");
 413         }
 414         setupParser();
 415         parsing = true;
 416         try {
 417             parser.parse(input);
 418         } finally {
 419             parsing = false;
 420         }
 421         parsing = false;
 422     }
 423 


 431     /**
 432      * Adapter implementation method; do not call.
 433      * Adapt a SAX1 document locator event.
 434      *
 435      * @param locator A document locator.
 436      * @see org.xml.sax.ContentHandler#setDocumentLocator
 437      */
 438     public void setDocumentLocator (Locator locator)
 439     {
 440         this.locator = locator;
 441         if (contentHandler != null) {
 442             contentHandler.setDocumentLocator(locator);
 443         }
 444     }
 445 
 446 
 447     /**
 448      * Adapter implementation method; do not call.
 449      * Adapt a SAX1 start document event.
 450      *
 451      * @exception SAXException The client may raise a
 452      *            processing exception.
 453      * @see org.xml.sax.DocumentHandler#startDocument
 454      */
 455     public void startDocument ()
 456         throws SAXException
 457     {
 458         if (contentHandler != null) {
 459             contentHandler.startDocument();
 460         }
 461     }
 462 
 463 
 464     /**
 465      * Adapter implementation method; do not call.
 466      * Adapt a SAX1 end document event.
 467      *
 468      * @exception SAXException The client may raise a
 469      *            processing exception.
 470      * @see org.xml.sax.DocumentHandler#endDocument
 471      */
 472     public void endDocument ()
 473         throws SAXException
 474     {
 475         if (contentHandler != null) {
 476             contentHandler.endDocument();
 477         }
 478     }
 479 
 480 
 481     /**
 482      * Adapter implementation method; do not call.
 483      * Adapt a SAX1 startElement event.
 484      *
 485      * <p>If necessary, perform Namespace processing.</p>
 486      *
 487      * @param qName The qualified (prefixed) name.
 488      * @param qAtts The XML attribute list (with qnames).
 489      * @exception SAXException The client may raise a
 490      *            processing exception.
 491      */
 492     public void startElement (String qName, AttributeList qAtts)
 493         throws SAXException
 494     {
 495                                 // These are exceptions from the
 496                                 // first pass; they should be
 497                                 // ignored if there's a second pass,
 498                                 // but reported otherwise.
 499         List<SAXException> exceptions = null;
 500 
 501                                 // If we're not doing Namespace
 502                                 // processing, dispatch this quickly.
 503         if (!namespaces) {
 504             if (contentHandler != null) {
 505                 attAdapter.setAttributeList(qAtts);
 506                 contentHandler.startElement("", "", qName.intern(),
 507                                             attAdapter);
 508             }
 509             return;


 599         // now handle the deferred exception reports
 600         if (exceptions != null && errorHandler != null) {
 601             for (int i = 0; i < exceptions.size(); i++)
 602                 errorHandler.error((SAXParseException)
 603                                 (exceptions.get(i)));
 604         }
 605 
 606                                 // OK, finally report the event.
 607         if (contentHandler != null) {
 608             String name[] = processName(qName, false, false);
 609             contentHandler.startElement(name[0], name[1], name[2], atts);
 610         }
 611     }
 612 
 613 
 614     /**
 615      * Adapter implementation method; do not call.
 616      * Adapt a SAX1 end element event.
 617      *
 618      * @param qName The qualified (prefixed) name.
 619      * @exception SAXException The client may raise a
 620      *            processing exception.
 621      * @see org.xml.sax.DocumentHandler#endElement
 622      */
 623     public void endElement (String qName)
 624         throws SAXException
 625     {
 626                                 // If we're not doing Namespace
 627                                 // processing, dispatch this quickly.
 628         if (!namespaces) {
 629             if (contentHandler != null) {
 630                 contentHandler.endElement("", "", qName.intern());
 631             }
 632             return;
 633         }
 634 
 635                                 // Split the name.
 636         String names[] = processName(qName, false, false);
 637         if (contentHandler != null) {
 638             contentHandler.endElement(names[0], names[1], names[2]);
 639             Enumeration<String> ePrefixes = nsSupport.getDeclaredPrefixes();
 640             while (ePrefixes.hasMoreElements()) {
 641                 String prefix = ePrefixes.nextElement();
 642                 contentHandler.endPrefixMapping(prefix);
 643             }
 644         }
 645         nsSupport.popContext();
 646     }
 647 
 648 
 649     /**
 650      * Adapter implementation method; do not call.
 651      * Adapt a SAX1 characters event.
 652      *
 653      * @param ch An array of characters.
 654      * @param start The starting position in the array.
 655      * @param length The number of characters to use.
 656      * @exception SAXException The client may raise a
 657      *            processing exception.
 658      * @see org.xml.sax.DocumentHandler#characters
 659      */
 660     public void characters (char ch[], int start, int length)
 661         throws SAXException
 662     {
 663         if (contentHandler != null) {
 664             contentHandler.characters(ch, start, length);
 665         }
 666     }
 667 
 668 
 669     /**
 670      * Adapter implementation method; do not call.
 671      * Adapt a SAX1 ignorable whitespace event.
 672      *
 673      * @param ch An array of characters.
 674      * @param start The starting position in the array.
 675      * @param length The number of characters to use.
 676      * @exception SAXException The client may raise a
 677      *            processing exception.
 678      * @see org.xml.sax.DocumentHandler#ignorableWhitespace
 679      */
 680     public void ignorableWhitespace (char ch[], int start, int length)
 681         throws SAXException
 682     {
 683         if (contentHandler != null) {
 684             contentHandler.ignorableWhitespace(ch, start, length);
 685         }
 686     }
 687 
 688 
 689     /**
 690      * Adapter implementation method; do not call.
 691      * Adapt a SAX1 processing instruction event.
 692      *
 693      * @param target The processing instruction target.
 694      * @param data The remainder of the processing instruction
 695      * @exception SAXException The client may raise a
 696      *            processing exception.
 697      * @see org.xml.sax.DocumentHandler#processingInstruction
 698      */
 699     public void processingInstruction (String target, String data)
 700         throws SAXException
 701     {
 702         if (contentHandler != null) {
 703             contentHandler.processingInstruction(target, data);
 704         }
 705     }
 706 
 707 
 708 
 709     ////////////////////////////////////////////////////////////////////
 710     // Internal utility methods.
 711     ////////////////////////////////////////////////////////////////////
 712 
 713 
 714     /**
 715      * Initialize the parser before each run.


 731             parser.setDTDHandler(dtdHandler);
 732         }
 733         if (errorHandler != null) {
 734             parser.setErrorHandler(errorHandler);
 735         }
 736         parser.setDocumentHandler(this);
 737         locator = null;
 738     }
 739 
 740 
 741     /**
 742      * Process a qualified (prefixed) name.
 743      *
 744      * <p>If the name has an undeclared prefix, use only the qname
 745      * and make an ErrorHandler.error callback in case the app is
 746      * interested.</p>
 747      *
 748      * @param qName The qualified (prefixed) name.
 749      * @param isAttribute true if this is an attribute name.
 750      * @return The name split into three parts.
 751      * @exception SAXException The client may throw
 752      *            an exception if there is an error callback.
 753      */
 754     private String [] processName (String qName, boolean isAttribute,
 755                                    boolean useException)
 756         throws SAXException
 757     {
 758         String parts[] = nsSupport.processName(qName, nameParts,
 759                                                isAttribute);
 760         if (parts == null) {
 761             if (useException)
 762                 throw makeException("Undeclared prefix: " + qName);
 763             reportError("Undeclared prefix: " + qName);
 764             parts = new String[3];
 765             parts[0] = parts[1] = "";
 766             parts[2] = qName.intern();
 767         }
 768         return parts;
 769     }
 770 
 771 
 772     /**
 773      * Report a non-fatal error.
 774      *
 775      * @param message The error message.
 776      * @exception SAXException The client may throw
 777      *            an exception.
 778      */
 779     void reportError (String message)
 780         throws SAXException
 781     {
 782         if (errorHandler != null)
 783             errorHandler.error(makeException(message));
 784     }
 785 
 786 
 787     /**
 788      * Construct an exception for the current context.
 789      *
 790      * @param message The error message.
 791      */
 792     private SAXParseException makeException (String message)
 793     {
 794         if (locator != null) {
 795             return new SAXParseException(message, locator);
 796         } else {
 797             return new SAXParseException(message, null, null, -1, -1);
 798         }
 799     }
 800 
 801 
 802     /**
 803      * Throw an exception if we are parsing.
 804      *
 805      * <p>Use this method to detect illegal feature or
 806      * property changes.</p>
 807      *
 808      * @param type The type of thing (feature or property).
 809      * @param name The feature or property name.
 810      * @exception SAXNotSupportedException If a
 811      *            document is currently being parsed.
 812      */
 813     private void checkNotParsing (String type, String name)
 814         throws SAXNotSupportedException
 815     {
 816         if (parsing) {
 817             throw new SAXNotSupportedException("Cannot change " +
 818                                                type + ' ' +
 819                                                name + " while parsing");
 820 
 821         }
 822     }
 823 
 824 
 825 
 826     ////////////////////////////////////////////////////////////////////
 827     // Internal state.
 828     ////////////////////////////////////////////////////////////////////
 829 
 830     private NamespaceSupport nsSupport;


   1 /*
   2  * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  64  * @version 2.0.1 (sax2r2)
  65  * @see org.xml.sax.helpers.XMLReaderAdapter
  66  * @see org.xml.sax.XMLReader
  67  * @see org.xml.sax.Parser
  68  */
  69 @SuppressWarnings("deprecation")
  70 public class ParserAdapter implements XMLReader, DocumentHandler
  71 {
  72 
  73     ////////////////////////////////////////////////////////////////////
  74     // Constructors.
  75     ////////////////////////////////////////////////////////////////////
  76 
  77 
  78     /**
  79      * Construct a new parser adapter.
  80      *
  81      * <p>Use the "org.xml.sax.parser" property to locate the
  82      * embedded SAX1 driver.</p>
  83      *
  84      * @throws SAXException If the embedded driver
  85      *            cannot be instantiated or if the
  86      *            org.xml.sax.parser property is not specified.
  87      */
  88     public ParserAdapter ()
  89       throws SAXException
  90     {
  91         super();
  92 
  93         String driver = SecuritySupport.getSystemProperty("org.xml.sax.parser");
  94 
  95         try {
  96             setup(ParserFactory.makeParser());
  97         } catch (ClassNotFoundException e1) {
  98             throw new
  99                 SAXException("Cannot find SAX1 driver class " +
 100                              driver, e1);
 101         } catch (IllegalAccessException e2) {
 102             throw new
 103                 SAXException("SAX1 driver class " +
 104                              driver +


 111         } catch (ClassCastException e4) {
 112             throw new
 113                 SAXException("SAX1 driver class " +
 114                              driver +
 115                              " does not implement org.xml.sax.Parser");
 116         } catch (NullPointerException e5) {
 117             throw new
 118                 SAXException("System property org.xml.sax.parser not specified");
 119         }
 120     }
 121 
 122 
 123     /**
 124      * Construct a new parser adapter.
 125      *
 126      * <p>Note that the embedded parser cannot be changed once the
 127      * adapter is created; to embed a different parser, allocate
 128      * a new ParserAdapter.</p>
 129      *
 130      * @param parser The SAX1 parser to embed.
 131      * @throws java.lang.NullPointerException If the parser parameter
 132      *            is null.
 133      */
 134     public ParserAdapter (Parser parser)
 135     {
 136         super();
 137         setup(parser);
 138     }
 139 
 140 
 141     /**
 142      * Internal setup method.
 143      *
 144      * @param parser The embedded parser.
 145      * @throws java.lang.NullPointerException If the parser parameter
 146      *            is null.
 147      */
 148     private void setup (Parser parser)
 149     {
 150         if (parser == null) {
 151             throw new
 152                 NullPointerException("Parser argument must not be null");
 153         }
 154         this.parser = parser;
 155         atts = new AttributesImpl();
 156         nsSupport = new NamespaceSupport();
 157         attAdapter = new AttributeListAdapter();
 158     }
 159 
 160 
 161 
 162     ////////////////////////////////////////////////////////////////////
 163     // Implementation of org.xml.sax.XMLReader.
 164     ////////////////////////////////////////////////////////////////////
 165 
 166 
 167     //
 168     // Internal constants for the sake of convenience.
 169     //
 170     private final static String FEATURES = "http://xml.org/sax/features/";
 171     private final static String NAMESPACES = FEATURES + "namespaces";
 172     private final static String NAMESPACE_PREFIXES = FEATURES + "namespace-prefixes";
 173     private final static String XMLNS_URIs = FEATURES + "xmlns-uris";
 174 
 175 
 176     /**
 177      * Set a feature flag for the parser.
 178      *
 179      * <p>The only features recognized are namespaces and
 180      * namespace-prefixes.</p>
 181      *
 182      * @param name The feature name, as a complete URI.
 183      * @param value The requested feature value.
 184      * @throws SAXNotRecognizedException If the feature
 185      *            can't be assigned or retrieved.
 186      * @throws SAXNotSupportedException If the feature
 187      *            can't be assigned that value.
 188      * @see org.xml.sax.XMLReader#setFeature
 189      */
 190     public void setFeature (String name, boolean value)
 191         throws SAXNotRecognizedException, SAXNotSupportedException
 192     {
 193         if (name.equals(NAMESPACES)) {
 194             checkNotParsing("feature", name);
 195             namespaces = value;
 196             if (!namespaces && !prefixes) {
 197                 prefixes = true;
 198             }
 199         } else if (name.equals(NAMESPACE_PREFIXES)) {
 200             checkNotParsing("feature", name);
 201             prefixes = value;
 202             if (!prefixes && !namespaces) {
 203                 namespaces = true;
 204             }
 205         } else if (name.equals(XMLNS_URIs)) {
 206             checkNotParsing("feature", name);
 207             uris = value;
 208         } else {
 209             throw new SAXNotRecognizedException("Feature: " + name);
 210         }
 211     }
 212 
 213 
 214     /**
 215      * Check a parser feature flag.
 216      *
 217      * <p>The only features recognized are namespaces and
 218      * namespace-prefixes.</p>
 219      *
 220      * @param name The feature name, as a complete URI.
 221      * @return The current feature value.
 222      * @throws SAXNotRecognizedException If the feature
 223      *            value can't be assigned or retrieved.
 224      * @throws SAXNotSupportedException If the
 225      *            feature is not currently readable.
 226      * @see org.xml.sax.XMLReader#setFeature
 227      */
 228     public boolean getFeature (String name)
 229         throws SAXNotRecognizedException, SAXNotSupportedException
 230     {
 231         if (name.equals(NAMESPACES)) {
 232             return namespaces;
 233         } else if (name.equals(NAMESPACE_PREFIXES)) {
 234             return prefixes;
 235         } else if (name.equals(XMLNS_URIs)) {
 236             return uris;
 237         } else {
 238             throw new SAXNotRecognizedException("Feature: " + name);
 239         }
 240     }
 241 
 242 
 243     /**
 244      * Set a parser property.
 245      *
 246      * <p>No properties are currently recognized.</p>
 247      *
 248      * @param name The property name.
 249      * @param value The property value.
 250      * @throws SAXNotRecognizedException If the property
 251      *            value can't be assigned or retrieved.
 252      * @throws SAXNotSupportedException If the property
 253      *            can't be assigned that value.
 254      * @see org.xml.sax.XMLReader#setProperty
 255      */
 256     public void setProperty (String name, Object value)
 257         throws SAXNotRecognizedException, SAXNotSupportedException
 258     {
 259         throw new SAXNotRecognizedException("Property: " + name);
 260     }
 261 
 262 
 263     /**
 264      * Get a parser property.
 265      *
 266      * <p>No properties are currently recognized.</p>
 267      *
 268      * @param name The property name.
 269      * @return The property value.
 270      * @throws SAXNotRecognizedException If the property
 271      *            value can't be assigned or retrieved.
 272      * @throws SAXNotSupportedException If the property
 273      *            value is not currently readable.
 274      * @see org.xml.sax.XMLReader#getProperty
 275      */
 276     public Object getProperty (String name)
 277         throws SAXNotRecognizedException, SAXNotSupportedException
 278     {
 279         throw new SAXNotRecognizedException("Property: " + name);
 280     }
 281 
 282 
 283     /**
 284      * Set the entity resolver.
 285      *
 286      * @param resolver The new entity resolver.
 287      * @see org.xml.sax.XMLReader#setEntityResolver
 288      */
 289     public void setEntityResolver (EntityResolver resolver)
 290     {
 291         entityResolver = resolver;
 292     }


 363         errorHandler = handler;
 364     }
 365 
 366 
 367     /**
 368      * Return the current error handler.
 369      *
 370      * @return The current error handler, or null if none was supplied.
 371      * @see org.xml.sax.XMLReader#getEntityResolver
 372      */
 373     public ErrorHandler getErrorHandler ()
 374     {
 375         return errorHandler;
 376     }
 377 
 378 
 379     /**
 380      * Parse an XML document.
 381      *
 382      * @param systemId The absolute URL of the document.
 383      * @throws java.io.IOException If there is a problem reading
 384      *            the raw content of the document.
 385      * @throws SAXException If there is a problem
 386      *            processing the document.
 387      * @see #parse(org.xml.sax.InputSource)
 388      * @see org.xml.sax.Parser#parse(java.lang.String)
 389      */
 390     public void parse (String systemId)
 391         throws IOException, SAXException
 392     {
 393         parse(new InputSource(systemId));
 394     }
 395 
 396 
 397     /**
 398      * Parse an XML document.
 399      *
 400      * @param input An input source for the document.
 401      * @throws java.io.IOException If there is a problem reading
 402      *            the raw content of the document.
 403      * @throws SAXException If there is a problem
 404      *            processing the document.
 405      * @see #parse(java.lang.String)
 406      * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
 407      */
 408     public void parse (InputSource input)
 409         throws IOException, SAXException
 410     {
 411         if (parsing) {
 412             throw new SAXException("Parser is already in use");
 413         }
 414         setupParser();
 415         parsing = true;
 416         try {
 417             parser.parse(input);
 418         } finally {
 419             parsing = false;
 420         }
 421         parsing = false;
 422     }
 423 


 431     /**
 432      * Adapter implementation method; do not call.
 433      * Adapt a SAX1 document locator event.
 434      *
 435      * @param locator A document locator.
 436      * @see org.xml.sax.ContentHandler#setDocumentLocator
 437      */
 438     public void setDocumentLocator (Locator locator)
 439     {
 440         this.locator = locator;
 441         if (contentHandler != null) {
 442             contentHandler.setDocumentLocator(locator);
 443         }
 444     }
 445 
 446 
 447     /**
 448      * Adapter implementation method; do not call.
 449      * Adapt a SAX1 start document event.
 450      *
 451      * @throws SAXException The client may raise a
 452      *            processing exception.
 453      * @see org.xml.sax.DocumentHandler#startDocument
 454      */
 455     public void startDocument ()
 456         throws SAXException
 457     {
 458         if (contentHandler != null) {
 459             contentHandler.startDocument();
 460         }
 461     }
 462 
 463 
 464     /**
 465      * Adapter implementation method; do not call.
 466      * Adapt a SAX1 end document event.
 467      *
 468      * @throws SAXException The client may raise a
 469      *            processing exception.
 470      * @see org.xml.sax.DocumentHandler#endDocument
 471      */
 472     public void endDocument ()
 473         throws SAXException
 474     {
 475         if (contentHandler != null) {
 476             contentHandler.endDocument();
 477         }
 478     }
 479 
 480 
 481     /**
 482      * Adapter implementation method; do not call.
 483      * Adapt a SAX1 startElement event.
 484      *
 485      * <p>If necessary, perform Namespace processing.</p>
 486      *
 487      * @param qName The qualified (prefixed) name.
 488      * @param qAtts The XML attribute list (with qnames).
 489      * @throws SAXException The client may raise a
 490      *            processing exception.
 491      */
 492     public void startElement (String qName, AttributeList qAtts)
 493         throws SAXException
 494     {
 495                                 // These are exceptions from the
 496                                 // first pass; they should be
 497                                 // ignored if there's a second pass,
 498                                 // but reported otherwise.
 499         List<SAXException> exceptions = null;
 500 
 501                                 // If we're not doing Namespace
 502                                 // processing, dispatch this quickly.
 503         if (!namespaces) {
 504             if (contentHandler != null) {
 505                 attAdapter.setAttributeList(qAtts);
 506                 contentHandler.startElement("", "", qName.intern(),
 507                                             attAdapter);
 508             }
 509             return;


 599         // now handle the deferred exception reports
 600         if (exceptions != null && errorHandler != null) {
 601             for (int i = 0; i < exceptions.size(); i++)
 602                 errorHandler.error((SAXParseException)
 603                                 (exceptions.get(i)));
 604         }
 605 
 606                                 // OK, finally report the event.
 607         if (contentHandler != null) {
 608             String name[] = processName(qName, false, false);
 609             contentHandler.startElement(name[0], name[1], name[2], atts);
 610         }
 611     }
 612 
 613 
 614     /**
 615      * Adapter implementation method; do not call.
 616      * Adapt a SAX1 end element event.
 617      *
 618      * @param qName The qualified (prefixed) name.
 619      * @throws SAXException The client may raise a
 620      *            processing exception.
 621      * @see org.xml.sax.DocumentHandler#endElement
 622      */
 623     public void endElement (String qName)
 624         throws SAXException
 625     {
 626                                 // If we're not doing Namespace
 627                                 // processing, dispatch this quickly.
 628         if (!namespaces) {
 629             if (contentHandler != null) {
 630                 contentHandler.endElement("", "", qName.intern());
 631             }
 632             return;
 633         }
 634 
 635                                 // Split the name.
 636         String names[] = processName(qName, false, false);
 637         if (contentHandler != null) {
 638             contentHandler.endElement(names[0], names[1], names[2]);
 639             Enumeration<String> ePrefixes = nsSupport.getDeclaredPrefixes();
 640             while (ePrefixes.hasMoreElements()) {
 641                 String prefix = ePrefixes.nextElement();
 642                 contentHandler.endPrefixMapping(prefix);
 643             }
 644         }
 645         nsSupport.popContext();
 646     }
 647 
 648 
 649     /**
 650      * Adapter implementation method; do not call.
 651      * Adapt a SAX1 characters event.
 652      *
 653      * @param ch An array of characters.
 654      * @param start The starting position in the array.
 655      * @param length The number of characters to use.
 656      * @throws SAXException The client may raise a
 657      *            processing exception.
 658      * @see org.xml.sax.DocumentHandler#characters
 659      */
 660     public void characters (char ch[], int start, int length)
 661         throws SAXException
 662     {
 663         if (contentHandler != null) {
 664             contentHandler.characters(ch, start, length);
 665         }
 666     }
 667 
 668 
 669     /**
 670      * Adapter implementation method; do not call.
 671      * Adapt a SAX1 ignorable whitespace event.
 672      *
 673      * @param ch An array of characters.
 674      * @param start The starting position in the array.
 675      * @param length The number of characters to use.
 676      * @throws SAXException The client may raise a
 677      *            processing exception.
 678      * @see org.xml.sax.DocumentHandler#ignorableWhitespace
 679      */
 680     public void ignorableWhitespace (char ch[], int start, int length)
 681         throws SAXException
 682     {
 683         if (contentHandler != null) {
 684             contentHandler.ignorableWhitespace(ch, start, length);
 685         }
 686     }
 687 
 688 
 689     /**
 690      * Adapter implementation method; do not call.
 691      * Adapt a SAX1 processing instruction event.
 692      *
 693      * @param target The processing instruction target.
 694      * @param data The remainder of the processing instruction
 695      * @throws SAXException The client may raise a
 696      *            processing exception.
 697      * @see org.xml.sax.DocumentHandler#processingInstruction
 698      */
 699     public void processingInstruction (String target, String data)
 700         throws SAXException
 701     {
 702         if (contentHandler != null) {
 703             contentHandler.processingInstruction(target, data);
 704         }
 705     }
 706 
 707 
 708 
 709     ////////////////////////////////////////////////////////////////////
 710     // Internal utility methods.
 711     ////////////////////////////////////////////////////////////////////
 712 
 713 
 714     /**
 715      * Initialize the parser before each run.


 731             parser.setDTDHandler(dtdHandler);
 732         }
 733         if (errorHandler != null) {
 734             parser.setErrorHandler(errorHandler);
 735         }
 736         parser.setDocumentHandler(this);
 737         locator = null;
 738     }
 739 
 740 
 741     /**
 742      * Process a qualified (prefixed) name.
 743      *
 744      * <p>If the name has an undeclared prefix, use only the qname
 745      * and make an ErrorHandler.error callback in case the app is
 746      * interested.</p>
 747      *
 748      * @param qName The qualified (prefixed) name.
 749      * @param isAttribute true if this is an attribute name.
 750      * @return The name split into three parts.
 751      * @throws SAXException The client may throw
 752      *            an exception if there is an error callback.
 753      */
 754     private String [] processName (String qName, boolean isAttribute,
 755                                    boolean useException)
 756         throws SAXException
 757     {
 758         String parts[] = nsSupport.processName(qName, nameParts,
 759                                                isAttribute);
 760         if (parts == null) {
 761             if (useException)
 762                 throw makeException("Undeclared prefix: " + qName);
 763             reportError("Undeclared prefix: " + qName);
 764             parts = new String[3];
 765             parts[0] = parts[1] = "";
 766             parts[2] = qName.intern();
 767         }
 768         return parts;
 769     }
 770 
 771 
 772     /**
 773      * Report a non-fatal error.
 774      *
 775      * @param message The error message.
 776      * @throws SAXException The client may throw
 777      *            an exception.
 778      */
 779     void reportError (String message)
 780         throws SAXException
 781     {
 782         if (errorHandler != null)
 783             errorHandler.error(makeException(message));
 784     }
 785 
 786 
 787     /**
 788      * Construct an exception for the current context.
 789      *
 790      * @param message The error message.
 791      */
 792     private SAXParseException makeException (String message)
 793     {
 794         if (locator != null) {
 795             return new SAXParseException(message, locator);
 796         } else {
 797             return new SAXParseException(message, null, null, -1, -1);
 798         }
 799     }
 800 
 801 
 802     /**
 803      * Throw an exception if we are parsing.
 804      *
 805      * <p>Use this method to detect illegal feature or
 806      * property changes.</p>
 807      *
 808      * @param type The type of thing (feature or property).
 809      * @param name The feature or property name.
 810      * @throws SAXNotSupportedException If a
 811      *            document is currently being parsed.
 812      */
 813     private void checkNotParsing (String type, String name)
 814         throws SAXNotSupportedException
 815     {
 816         if (parsing) {
 817             throw new SAXNotSupportedException("Cannot change " +
 818                                                type + ' ' +
 819                                                name + " while parsing");
 820 
 821         }
 822     }
 823 
 824 
 825 
 826     ////////////////////////////////////////////////////////////////////
 827     // Internal state.
 828     ////////////////////////////////////////////////////////////////////
 829 
 830     private NamespaceSupport nsSupport;


< prev index next >