Save This Page
Home » Xerces-J-src.2.9.1 » org.apache.xerces » parsers » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    * 
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    * 
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   
   18   package org.apache.xerces.parsers;
   19   
   20   import java.io.CharConversionException;
   21   import java.io.IOException;
   22   import java.util.Locale;
   23   
   24   import org.apache.xerces.impl.Constants;
   25   import org.apache.xerces.util.EntityResolver2Wrapper;
   26   import org.apache.xerces.util.EntityResolverWrapper;
   27   import org.apache.xerces.util.ErrorHandlerWrapper;
   28   import org.apache.xerces.util.SAXMessageFormatter;
   29   import org.apache.xerces.util.SymbolHash;
   30   import org.apache.xerces.util.XMLSymbols;
   31   import org.apache.xerces.xni.Augmentations;
   32   import org.apache.xerces.xni.NamespaceContext;
   33   import org.apache.xerces.xni.QName;
   34   import org.apache.xerces.xni.XMLAttributes;
   35   import org.apache.xerces.xni.XMLLocator;
   36   import org.apache.xerces.xni.XMLResourceIdentifier;
   37   import org.apache.xerces.xni.XMLString;
   38   import org.apache.xerces.xni.XNIException;
   39   import org.apache.xerces.xni.parser.XMLConfigurationException;
   40   import org.apache.xerces.xni.parser.XMLEntityResolver;
   41   import org.apache.xerces.xni.parser.XMLErrorHandler;
   42   import org.apache.xerces.xni.parser.XMLInputSource;
   43   import org.apache.xerces.xni.parser.XMLParseException;
   44   import org.apache.xerces.xni.parser.XMLParserConfiguration;
   45   import org.apache.xerces.xs.AttributePSVI;
   46   import org.apache.xerces.xs.ElementPSVI;
   47   import org.apache.xerces.xs.PSVIProvider;
   48   import org.xml.sax.AttributeList;
   49   import org.xml.sax.ContentHandler;
   50   import org.xml.sax.DTDHandler;
   51   import org.xml.sax.DocumentHandler;
   52   import org.xml.sax.EntityResolver;
   53   import org.xml.sax.ErrorHandler;
   54   import org.xml.sax.InputSource;
   55   import org.xml.sax.Parser;
   56   import org.xml.sax.SAXException;
   57   import org.xml.sax.SAXNotRecognizedException;
   58   import org.xml.sax.SAXNotSupportedException;
   59   import org.xml.sax.SAXParseException;
   60   import org.xml.sax.XMLReader;
   61   import org.xml.sax.ext.Attributes2;
   62   import org.xml.sax.ext.DeclHandler;
   63   import org.xml.sax.ext.EntityResolver2;
   64   import org.xml.sax.ext.LexicalHandler;
   65   import org.xml.sax.ext.Locator2;
   66   import org.xml.sax.ext.Locator2Impl;
   67   
   68   /**
   69    * This is the base class of all SAX parsers. It implements both the
   70    * SAX1 and SAX2 parser functionality, while the actual pipeline is
   71    * defined in the parser configuration.
   72    *
   73    * @author Arnaud Le Hors, IBM
   74    * @author Andy Clark, IBM
   75    *
   76    * @version $Id: AbstractSAXParser.java 548086 2007-06-17 18:17:43Z mrglavas $
   77    */
   78   public abstract class AbstractSAXParser
   79       extends AbstractXMLDocumentParser
   80       implements PSVIProvider, // PSVI 
   81                 Parser, XMLReader // SAX1, SAX2
   82   {
   83   
   84       //
   85       // Constants
   86       //
   87   
   88       // features
   89   
   90       /** Feature identifier: namespaces. */
   91       protected static final String NAMESPACES =
   92           Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
   93   
   94       /** Feature id: string interning. */
   95       protected static final String STRING_INTERNING =
   96           Constants.SAX_FEATURE_PREFIX + Constants.STRING_INTERNING_FEATURE;
   97       
   98       /** Feature identifier: allow notation and unparsed entity events to be sent out of order. */
   99       // this is not meant to be a recognized feature, but we need it here to use
  100       // if it is already a recognized feature for the pipeline
  101       protected static final String ALLOW_UE_AND_NOTATION_EVENTS =
  102           Constants.SAX_FEATURE_PREFIX + Constants.ALLOW_DTD_EVENTS_AFTER_ENDDTD_FEATURE;
  103   
  104       /** Recognized features. */
  105       private static final String[] RECOGNIZED_FEATURES = {
  106           NAMESPACES,
  107           STRING_INTERNING,
  108       };
  109   
  110       // properties
  111   
  112       /** Property id: lexical handler. */
  113       protected static final String LEXICAL_HANDLER = 
  114           Constants.SAX_PROPERTY_PREFIX + Constants.LEXICAL_HANDLER_PROPERTY;
  115   
  116       /** Property id: declaration handler. */
  117       protected static final String DECLARATION_HANDLER =
  118           Constants.SAX_PROPERTY_PREFIX + Constants.DECLARATION_HANDLER_PROPERTY;
  119   
  120       /** Property id: DOM node. */
  121       protected static final String DOM_NODE = 
  122           Constants.SAX_PROPERTY_PREFIX + Constants.DOM_NODE_PROPERTY;
  123   
  124       /** Recognized properties. */
  125       private static final String[] RECOGNIZED_PROPERTIES = {
  126           LEXICAL_HANDLER,
  127           DECLARATION_HANDLER,
  128           DOM_NODE,
  129       };
  130   
  131       //
  132       // Data
  133       //
  134   
  135       // features
  136   
  137       /** Namespaces. */
  138       protected boolean fNamespaces;
  139   
  140       /** Namespace prefixes. */
  141       protected boolean fNamespacePrefixes = false;
  142       
  143       /** Lexical handler parameter entities. */
  144       protected boolean fLexicalHandlerParameterEntities = true;
  145       
  146       /** Standalone document declaration. */
  147       protected boolean fStandalone;
  148       
  149       /** Resolve DTD URIs. */
  150       protected boolean fResolveDTDURIs = true;
  151       
  152       /** Use EntityResolver2. */
  153       protected boolean fUseEntityResolver2 = true;
  154       
  155       /** 
  156        * XMLNS URIs: Namespace declarations in the 
  157        * http://www.w3.org/2000/xmlns/ namespace.
  158        */
  159       protected boolean fXMLNSURIs = false;
  160   
  161       // parser handlers
  162   
  163       /** Content handler. */
  164       protected ContentHandler fContentHandler;
  165   
  166       /** Document handler. */
  167       protected DocumentHandler fDocumentHandler;
  168       
  169       /** Namespace context */
  170       protected NamespaceContext fNamespaceContext;
  171   
  172       /** DTD handler. */
  173       protected org.xml.sax.DTDHandler fDTDHandler;
  174   
  175       /** Decl handler. */
  176       protected DeclHandler fDeclHandler;
  177   
  178       /** Lexical handler. */
  179       protected LexicalHandler fLexicalHandler;
  180   
  181       protected QName fQName = new QName();
  182   
  183       // state
  184   
  185       /**
  186        * True if a parse is in progress. This state is needed because
  187        * some features/properties cannot be set while parsing (e.g.
  188        * validation and namespaces).
  189        */
  190       protected boolean fParseInProgress = false;
  191   
  192       // track the version of the document being parsed
  193       protected String fVersion;
  194   
  195       // temp vars
  196       private final AttributesProxy fAttributesProxy = new AttributesProxy();
  197       private Augmentations fAugmentations = null;
  198   
  199   
  200       // temporary buffer for sending normalized values
  201       // REVISIT: what should be the size of the buffer?
  202       private static final int BUFFER_SIZE = 20;
  203       private char[] fCharBuffer =  new char[BUFFER_SIZE];
  204   
  205       // allows us to keep track of whether an attribute has
  206       // been declared twice, so that we can avoid exposing the
  207       // second declaration to any registered DeclHandler
  208       protected SymbolHash fDeclaredAttrs = null;
  209   
  210       //
  211       // Constructors
  212       //
  213   
  214       /** Default constructor. */
  215       protected AbstractSAXParser(XMLParserConfiguration config) {
  216           super(config);
  217   
  218           config.addRecognizedFeatures(RECOGNIZED_FEATURES);
  219           config.addRecognizedProperties(RECOGNIZED_PROPERTIES);
  220   
  221           try {
  222               config.setFeature(ALLOW_UE_AND_NOTATION_EVENTS, false);
  223           }
  224           catch (XMLConfigurationException e) {
  225               // it wasn't a recognized feature, so we don't worry about it
  226           }
  227       } // <init>(XMLParserConfiguration)
  228   
  229       //
  230       // XMLDocumentHandler methods
  231       //
  232   
  233       /**
  234        * The start of the document.
  235        *
  236        * @param locator The document locator, or null if the document
  237        *                 location cannot be reported during the parsing
  238        *                 of this document. However, it is <em>strongly</em>
  239        *                 recommended that a locator be supplied that can
  240        *                 at least report the system identifier of the
  241        *                 document.
  242        * @param encoding The auto-detected IANA encoding name of the entity
  243        *                 stream. This value will be null in those situations
  244        *                 where the entity encoding is not auto-detected (e.g.
  245        *                 internal entities or a document entity that is
  246        *                 parsed from a java.io.Reader).
  247        * @param namespaceContext
  248        *                 The namespace context in effect at the
  249        *                 start of this document.
  250        *                 This object represents the current context.
  251        *                 Implementors of this class are responsible
  252        *                 for copying the namespace bindings from the
  253        *                 the current context (and its parent contexts)
  254        *                 if that information is important.
  255        * @param augs     Additional information that may include infoset augmentations
  256        *
  257        * @throws XNIException Thrown by handler to signal an error.
  258        */
  259       public void startDocument(XMLLocator locator, String encoding, 
  260                                 NamespaceContext namespaceContext, Augmentations augs)
  261           throws XNIException {
  262           
  263           fNamespaceContext = namespaceContext;
  264   
  265           try {
  266               // SAX1
  267               if (fDocumentHandler != null) {
  268                   if (locator != null) {
  269                       fDocumentHandler.setDocumentLocator(new LocatorProxy(locator));
  270                   }
  271                   fDocumentHandler.startDocument();
  272               }
  273   
  274               // SAX2
  275               if (fContentHandler != null) {
  276                   if (locator != null) {
  277                       fContentHandler.setDocumentLocator(new LocatorProxy(locator));
  278                   }
  279                   fContentHandler.startDocument();
  280               }
  281           }
  282           catch (SAXException e) {
  283               throw new XNIException(e);
  284           }
  285   
  286       } // startDocument(locator,encoding,augs)
  287   
  288       /**
  289        * Notifies of the presence of an XMLDecl line in the document. If
  290        * present, this method will be called immediately following the
  291        * startDocument call.
  292        * 
  293        * @param version    The XML version.
  294        * @param encoding   The IANA encoding name of the document, or null if
  295        *                   not specified.
  296        * @param standalone The standalone value, or null if not specified.
  297        * @param augs   Additional information that may include infoset augmentations
  298        *
  299        * @throws XNIException Thrown by handler to signal an error.
  300        */
  301       public void xmlDecl(String version, String encoding, String standalone, Augmentations augs)
  302           throws XNIException {
  303           // the version need only be set once; if
  304           // document's XML 1.0|1.1, that's how it'll stay
  305           fVersion = version;
  306           fStandalone = "yes".equals(standalone);
  307       } // xmlDecl(String,String,String)
  308   
  309       /**
  310        * Notifies of the presence of the DOCTYPE line in the document.
  311        *
  312        * @param rootElement The name of the root element.
  313        * @param publicId    The public identifier if an external DTD or null
  314        *                    if the external DTD is specified using SYSTEM.
  315        * @param systemId    The system identifier if an external DTD, null
  316        *                    otherwise.
  317        * @param augs     Additional information that may include infoset augmentations
  318        *
  319        * @throws XNIException Thrown by handler to signal an error.
  320        */
  321       public void doctypeDecl(String rootElement,
  322                               String publicId, String systemId, Augmentations augs)
  323           throws XNIException {
  324           fInDTD = true;
  325   
  326           try {
  327               // SAX2 extension
  328               if (fLexicalHandler != null) {
  329                   fLexicalHandler.startDTD(rootElement, publicId, systemId);
  330               }
  331           }
  332           catch (SAXException e) {
  333               throw new XNIException(e);
  334           }
  335   
  336           // is there a DeclHandler?
  337           if(fDeclHandler != null) {
  338               fDeclaredAttrs = new SymbolHash();
  339           }
  340   
  341       } // doctypeDecl(String,String,String)
  342   
  343           /**
  344        * This method notifies of the start of an entity. The DTD has the
  345        * pseudo-name of "[dtd]" parameter entity names start with '%'; and
  346        * general entity names are just the entity name.
  347        * <p>
  348        * <strong>Note:</strong> Since the document is an entity, the handler
  349        * will be notified of the start of the document entity by calling the
  350        * startEntity method with the entity name "[xml]" <em>before</em> calling
  351        * the startDocument method. When exposing entity boundaries through the
  352        * SAX API, the document entity is never reported, however.
  353        * <p>
  354        * <strong>Note:</strong> This method is not called for entity references
  355        * appearing as part of attribute values.
  356        *
  357        * @param name     The name of the entity.
  358        * @param identifier The resource identifier.
  359        * @param encoding The auto-detected IANA encoding name of the entity
  360        *                 stream. This value will be null in those situations
  361        *                 where the entity encoding is not auto-detected (e.g.
  362        *                 internal parameter entities).
  363        * @param augs     Additional information that may include infoset augmentations
  364        *
  365        * @throws XNIException Thrown by handler to signal an error.
  366        */
  367       public void startGeneralEntity(String name, XMLResourceIdentifier identifier, 
  368                                      String encoding, Augmentations augs)
  369           throws XNIException {
  370           
  371           try {
  372               // Only report startEntity if this entity was actually read.
  373               if (augs != null && Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
  374                   // report skipped entity to content handler
  375                   if (fContentHandler != null) {
  376                       fContentHandler.skippedEntity(name);
  377                   }
  378               }
  379               else {
  380                   // SAX2 extension
  381                   if (fLexicalHandler != null) {
  382                       fLexicalHandler.startEntity(name);
  383                   }
  384               }
  385           }
  386           catch (SAXException e) {
  387               throw new XNIException(e);
  388           }
  389   
  390       } // startGeneralEntity(String,String,String,String,String)
  391   
  392       /**
  393        * This method notifies the end of an entity. The DTD has the pseudo-name
  394        * of "[dtd]" parameter entity names start with '%'; and general entity
  395        * names are just the entity name.
  396        * <p>
  397        * <strong>Note:</strong> Since the document is an entity, the handler
  398        * will be notified of the end of the document entity by calling the
  399        * endEntity method with the entity name "[xml]" <em>after</em> calling
  400        * the endDocument method. When exposing entity boundaries through the
  401        * SAX API, the document entity is never reported, however.
  402        * <p>
  403        * <strong>Note:</strong> This method is not called for entity references
  404        * appearing as part of attribute values.
  405        *
  406        * @param name The name of the entity.
  407        * @param augs     Additional information that may include infoset augmentations
  408        *
  409        * @throws XNIException Thrown by handler to signal an error.
  410        */
  411       public void endGeneralEntity(String name, Augmentations augs) throws XNIException {
  412   
  413           try {
  414               // Only report endEntity if this entity was actually read.
  415               if (augs == null || !Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
  416                   // SAX2 extension
  417                   if (fLexicalHandler != null) {
  418                       fLexicalHandler.endEntity(name);
  419                   }
  420               }
  421           }
  422           catch (SAXException e) {
  423               throw new XNIException(e);
  424           }
  425   
  426       } // endEntity(String)
  427   
  428        /**
  429        * The start of an element. If the document specifies the start element
  430        * by using an empty tag, then the startElement method will immediately
  431        * be followed by the endElement method, with no intervening methods.
  432        *
  433        * @param element    The name of the element.
  434        * @param attributes The element attributes.
  435        * @param augs     Additional information that may include infoset augmentations
  436        *
  437        * @throws XNIException Thrown by handler to signal an error.
  438        */
  439       public void startElement(QName element, XMLAttributes attributes, Augmentations augs)
  440           throws XNIException {
  441   
  442           try {
  443               // SAX1
  444               if (fDocumentHandler != null) {
  445                   // REVISIT: should we support schema-normalized-value for SAX1 events
  446                   // 
  447                   fAttributesProxy.setAttributes(attributes);
  448                   fDocumentHandler.startElement(element.rawname, fAttributesProxy);
  449               }
  450   
  451               // SAX2
  452               if (fContentHandler != null) {                
  453                   
  454                   if (fNamespaces) {
  455                       // send prefix mapping events
  456                       startNamespaceMapping();
  457   
  458                       // REVISIT: It should not be necessary to iterate over the attribute
  459                       // list when the set of [namespace attributes] is empty for this
  460                       // element. This should be computable from the NamespaceContext, but
  461                       // since we currently don't report the mappings for the xml prefix
  462                       // we cannot use the declared prefix count for the current context
  463                       // to skip this section. -- mrglavas
  464                       int len = attributes.getLength();
  465                       if (!fNamespacePrefixes) {
  466                           for (int i = len - 1; i >= 0; --i) {
  467                               attributes.getName(i, fQName);    
  468                               if ((fQName.prefix == XMLSymbols.PREFIX_XMLNS) || 
  469                                  (fQName.rawname == XMLSymbols.PREFIX_XMLNS)) {
  470                                   // remove namespace declaration attributes
  471                                   attributes.removeAttributeAt(i);
  472                               }
  473                           }
  474                       }
  475                       else if (!fXMLNSURIs) {
  476                           for (int i = len - 1; i >= 0; --i) {
  477                               attributes.getName(i, fQName);    
  478                               if ((fQName.prefix == XMLSymbols.PREFIX_XMLNS) || 
  479                                  (fQName.rawname == XMLSymbols.PREFIX_XMLNS)) {
  480                                   // localpart should be empty string as per SAX documentation:
  481                                   // http://www.saxproject.org/?selected=namespaces
  482                                   fQName.prefix = "";
  483                                   fQName.uri = "";
  484                                   fQName.localpart = "";
  485                                   attributes.setName(i, fQName);
  486                               }
  487                           }
  488                       }
  489                   }
  490                   
  491                   fAugmentations = augs;
  492                   
  493                   String uri = element.uri != null ? element.uri : "";
  494                   String localpart = fNamespaces ? element.localpart : "";
  495                   fAttributesProxy.setAttributes(attributes);
  496                   fContentHandler.startElement(uri, localpart, element.rawname,
  497                                                fAttributesProxy);
  498               }
  499           }
  500           catch (SAXException e) {
  501               throw new XNIException(e);
  502           }
  503   
  504       } // startElement(QName,XMLAttributes)
  505   
  506       /**
  507        * Character content.
  508        *
  509        * @param text The content.
  510        * @param augs     Additional information that may include infoset augmentations
  511        *
  512        * @throws XNIException Thrown by handler to signal an error.
  513        */
  514       public void characters(XMLString text, Augmentations augs) throws XNIException {
  515           
  516           // if type is union (XML Schema) it is possible that we receive
  517           // character call with empty data
  518           if (text.length == 0) {
  519               return;
  520           }
  521   
  522   
  523           try {
  524               // SAX1
  525               if (fDocumentHandler != null) {
  526                   // REVISIT: should we support schema-normalized-value for SAX1 events
  527                   // 
  528                   fDocumentHandler.characters(text.ch, text.offset, text.length);
  529               }
  530   
  531               // SAX2
  532               if (fContentHandler != null) {
  533                   fContentHandler.characters(text.ch, text.offset, text.length);
  534               }
  535           }
  536           catch (SAXException e) {
  537               throw new XNIException(e);
  538           }
  539   
  540       } // characters(XMLString)
  541   
  542       /**
  543        * Ignorable whitespace. For this method to be called, the document
  544        * source must have some way of determining that the text containing
  545        * only whitespace characters should be considered ignorable. For
  546        * example, the validator can determine if a length of whitespace
  547        * characters in the document are ignorable based on the element
  548        * content model.
  549        *
  550        * @param text The ignorable whitespace.
  551        * @param augs     Additional information that may include infoset augmentations
  552        *
  553        * @throws XNIException Thrown by handler to signal an error.
  554        */
  555       public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException {
  556   
  557           try {
  558               // SAX1
  559               if (fDocumentHandler != null) {
  560                   fDocumentHandler.ignorableWhitespace(text.ch, text.offset, text.length);
  561               }
  562   
  563               // SAX2
  564               if (fContentHandler != null) {
  565                   fContentHandler.ignorableWhitespace(text.ch, text.offset, text.length);
  566               }
  567           }
  568           catch (SAXException e) {
  569               throw new XNIException(e);
  570           }
  571   
  572       } // ignorableWhitespace(XMLString)
  573   
  574       /**
  575        * The end of an element.
  576        *
  577        * @param element The name of the element.
  578        * @param augs     Additional information that may include infoset augmentations
  579        *
  580        * @throws XNIException Thrown by handler to signal an error.
  581        */
  582       public void endElement(QName element, Augmentations augs) throws XNIException {
  583           
  584   
  585           try {
  586               // SAX1
  587               if (fDocumentHandler != null) {
  588                   fDocumentHandler.endElement(element.rawname);
  589               }
  590   
  591               // SAX2
  592               if (fContentHandler != null) {
  593                   fAugmentations = augs;
  594                   String uri = element.uri != null ? element.uri : "";
  595                   String localpart = fNamespaces ? element.localpart : "";
  596                   fContentHandler.endElement(uri, localpart,
  597                                              element.rawname);
  598                   if (fNamespaces) {
  599                       endNamespaceMapping();
  600                   } 
  601               }
  602           }
  603           catch (SAXException e) {
  604               throw new XNIException(e);
  605           }
  606   
  607       } // endElement(QName)
  608   
  609           /**
  610        * The start of a CDATA section.
  611        * @param augs     Additional information that may include infoset augmentations
  612        *
  613        * @throws XNIException Thrown by handler to signal an error.
  614        */
  615       public void startCDATA(Augmentations augs) throws XNIException {
  616   
  617           try {
  618               // SAX2 extension
  619               if (fLexicalHandler != null) {
  620                   fLexicalHandler.startCDATA();
  621               }
  622           }
  623           catch (SAXException e) {
  624               throw new XNIException(e);
  625           }
  626   
  627       } // startCDATA()
  628   
  629       /**
  630        * The end of a CDATA section.
  631        * @param augs     Additional information that may include infoset augmentations
  632        *
  633        * @throws XNIException Thrown by handler to signal an error.
  634        */
  635       public void endCDATA(Augmentations augs) throws XNIException {
  636   
  637           try {
  638               // SAX2 extension
  639               if (fLexicalHandler != null) {
  640                   fLexicalHandler.endCDATA();
  641               }
  642           }
  643           catch (SAXException e) {
  644               throw new XNIException(e);
  645           }
  646   
  647       } // endCDATA()
  648   
  649       /**
  650        * A comment.
  651        *
  652        * @param text The text in the comment.
  653        * @param augs     Additional information that may include infoset augmentations
  654        *
  655        * @throws XNIException Thrown by application to signal an error.
  656        */
  657       public void comment(XMLString text, Augmentations augs) throws XNIException {
  658   
  659           try {
  660               // SAX2 extension
  661               if (fLexicalHandler != null) {
  662                   fLexicalHandler.comment(text.ch, 0, text.length);
  663               }
  664           }
  665           catch (SAXException e) {
  666               throw new XNIException(e);
  667           }
  668   
  669       } // comment(XMLString)
  670   
  671       /**
  672        * A processing instruction. Processing instructions consist of a
  673        * target name and, optionally, text data. The data is only meaningful
  674        * to the application.
  675        * <p>
  676        * Typically, a processing instruction's data will contain a series
  677        * of pseudo-attributes. These pseudo-attributes follow the form of
  678        * element attributes but are <strong>not</strong> parsed or presented
  679        * to the application as anything other than text. The application is
  680        * responsible for parsing the data.
  681        *
  682        * @param target The target.
  683        * @param data   The data or null if none specified.
  684        * @param augs     Additional information that may include infoset augmentations
  685        *
  686        * @throws XNIException Thrown by handler to signal an error.
  687        */
  688       public void processingInstruction(String target, XMLString data, Augmentations augs)
  689           throws XNIException {
  690   
  691           //
  692           // REVISIT - I keep running into SAX apps that expect
  693           //   null data to be an empty string, which is contrary
  694           //   to the comment for this method in the SAX API.
  695           //
  696   
  697           try {
  698               // SAX1
  699               if (fDocumentHandler != null) {
  700                   fDocumentHandler.processingInstruction(target,
  701                                                          data.toString());
  702               }
  703   
  704               // SAX2
  705               if (fContentHandler != null) {
  706                   fContentHandler.processingInstruction(target, data.toString());
  707               }
  708           }
  709           catch (SAXException e) {
  710               throw new XNIException(e);
  711           }
  712   
  713       } // processingInstruction(String,XMLString)
  714   
  715   
  716       /**
  717        * The end of the document.
  718        * @param augs     Additional information that may include infoset augmentations
  719        *
  720        * @throws XNIException Thrown by handler to signal an error.
  721        */
  722       public void endDocument(Augmentations augs) throws XNIException {
  723   
  724           try {
  725               // SAX1
  726               if (fDocumentHandler != null) {
  727                   fDocumentHandler.endDocument();
  728               }
  729   
  730               // SAX2
  731               if (fContentHandler != null) {
  732                   fContentHandler.endDocument();
  733               }
  734           }
  735           catch (SAXException e) {
  736               throw new XNIException(e);
  737           }
  738   
  739       } // endDocument()
  740   
  741       //
  742       // XMLDTDHandler methods
  743       //
  744   
  745       /**
  746        * The start of the DTD external subset.
  747        *
  748        * @param augs Additional information that may include infoset
  749        *                      augmentations.
  750        *
  751        * @throws XNIException Thrown by handler to signal an error.
  752        */
  753       public void startExternalSubset(XMLResourceIdentifier identifier, 
  754                                       Augmentations augs) throws XNIException {
  755           startParameterEntity("[dtd]", null, null, augs);
  756       }
  757   
  758       /**
  759        * The end of the DTD external subset.
  760        *
  761        * @param augs Additional information that may include infoset
  762        *                      augmentations.
  763        *
  764        * @throws XNIException Thrown by handler to signal an error.
  765        */
  766       public void endExternalSubset(Augmentations augs) throws XNIException {
  767           endParameterEntity("[dtd]", augs);
  768       }
  769   
  770       /**
  771        * This method notifies of the start of parameter entity. The DTD has the
  772        * pseudo-name of "[dtd]" parameter entity names start with '%'; and
  773        * general entity names are just the entity name.
  774        * <p>
  775        * <strong>Note:</strong> Since the document is an entity, the handler
  776        * will be notified of the start of the document entity by calling the
  777        * startEntity method with the entity name "[xml]" <em>before</em> calling
  778        * the startDocument method. When exposing entity boundaries through the
  779        * SAX API, the document entity is never reported, however.
  780        * <p>
  781        * <strong>Note:</strong> This method is not called for entity references
  782        * appearing as part of attribute values.
  783        *
  784        * @param name     The name of the parameter entity.
  785        * @param identifier The resource identifier.
  786        * @param encoding The auto-detected IANA encoding name of the entity
  787        *                 stream. This value will be null in those situations
  788        *                 where the entity encoding is not auto-detected (e.g.
  789        *                 internal parameter entities).
  790        * @param augs Additional information that may include infoset
  791        *                      augmentations.
  792        *
  793        * @throws XNIException Thrown by handler to signal an error.
  794        */
  795       public void startParameterEntity(String name, 
  796                                        XMLResourceIdentifier identifier,
  797                                        String encoding, Augmentations augs)
  798           throws XNIException {
  799   
  800           try {
  801               // Only report startEntity if this entity was actually read.
  802               if (augs != null && Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
  803                   // report skipped entity to content handler
  804                   if (fContentHandler != null) {
  805                       fContentHandler.skippedEntity(name);
  806                   }
  807               }
  808               else {
  809                   // SAX2 extension
  810                   if (fLexicalHandler != null && fLexicalHandlerParameterEntities) {
  811                       fLexicalHandler.startEntity(name);
  812                   }
  813               }
  814           }
  815           catch (SAXException e) {
  816               throw new XNIException(e);
  817           }
  818   
  819       } // startParameterEntity(String,identifier,String,Augmentation)
  820   
  821       /**
  822        * This method notifies the end of an entity. The DTD has the pseudo-name
  823        * of "[dtd]" parameter entity names start with '%'; and general entity
  824        * names are just the entity name.
  825        * <p>
  826        * <strong>Note:</strong> Since the document is an entity, the handler
  827        * will be notified of the end of the document entity by calling the
  828        * endEntity method with the entity name "[xml]" <em>after</em> calling
  829        * the endDocument method. When exposing entity boundaries through the
  830        * SAX API, the document entity is never reported, however.
  831        * <p>
  832        * <strong>Note:</strong> This method is not called for entity references
  833        * appearing as part of attribute values.
  834        *
  835        * @param name The name of the parameter entity.
  836        * @param augs Additional information that may include infoset
  837        *                      augmentations.
  838        *
  839        * @throws XNIException Thrown by handler to signal an error.
  840        */
  841       public void endParameterEntity(String name, Augmentations augs) throws XNIException {
  842   
  843           try {
  844               // Only report endEntity if this entity was actually read.
  845               if (augs == null || !Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
  846                   // SAX2 extension
  847                   if (fLexicalHandler != null && fLexicalHandlerParameterEntities) {
  848                       fLexicalHandler.endEntity(name);
  849                   }
  850               }
  851           }
  852           catch (SAXException e) {
  853               throw new XNIException(e);
  854           }
  855   
  856       } // endEntity(String)
  857   
  858       /**
  859        * An element declaration.
  860        *
  861        * @param name         The name of the element.
  862        * @param contentModel The element content model.
  863        *
  864        * @param augs Additional information that may include infoset
  865        *                      augmentations.
  866        *
  867        * @throws XNIException Thrown by handler to signal an error.
  868        */
  869       public void elementDecl(String name, String contentModel, Augmentations augs)
  870           throws XNIException {
  871   
  872           try {
  873               // SAX2 extension
  874               if (fDeclHandler != null) {
  875                   fDeclHandler.elementDecl(name, contentModel);
  876               }
  877           }
  878           catch (SAXException e) {
  879               throw new XNIException(e);
  880           }
  881   
  882       } // elementDecl(String,String, Augmentations)
  883   
  884       /**
  885        * An attribute declaration.
  886        *
  887        * @param elementName   The name of the element that this attribute
  888        *                      is associated with.
  889        * @param attributeName The name of the attribute.
  890        * @param type          The attribute type. This value will be one of
  891        *                      the following: "CDATA", "ENTITY", "ENTITIES",
  892        *                      "ENUMERATION", "ID", "IDREF", "IDREFS",
  893        *                      "NMTOKEN", "NMTOKENS", or "NOTATION".
  894        * @param enumeration   If the type has the value "ENUMERATION" or
  895        *                      "NOTATION", this array holds the allowed attribute
  896        *                      values; otherwise, this array is null.
  897        * @param defaultType   The attribute default type. This value will be
  898        *                      one of the following: "#FIXED", "#IMPLIED",
  899        *                      "#REQUIRED", or null.
  900        * @param defaultValue  The attribute default value, or null if no
  901        *                      default value is specified.
  902        *
  903        * @param nonNormalizedDefaultValue  The attribute default value with no normalization 
  904        *                      performed, or null if no default value is specified.
  905        * @param augs Additional information that may include infoset
  906        *                      augmentations.
  907        *
  908        * @throws XNIException Thrown by handler to signal an error.
  909        */
  910       public void attributeDecl(String elementName, String attributeName,
  911                                 String type, String[] enumeration,
  912                                 String defaultType, XMLString defaultValue,
  913                                 XMLString nonNormalizedDefaultValue, Augmentations augs) throws XNIException {
  914   
  915           try {
  916               // SAX2 extension
  917               if (fDeclHandler != null) {
  918                   // used as a key to detect duplicate attribute definitions.
  919                   String elemAttr = new StringBuffer(elementName).append("<").append(attributeName).toString();
  920                   if(fDeclaredAttrs.get(elemAttr) != null) {
  921                       // we aren't permitted to return duplicate attribute definitions
  922                       return;
  923                   }
  924                   fDeclaredAttrs.put(elemAttr, Boolean.TRUE);
  925                   if (type.equals("NOTATION") || 
  926                       type.equals("ENUMERATION")) {
  927   
  928                       StringBuffer str = new StringBuffer();
  929                       if (type.equals("NOTATION")) {
  930                         str.append(type);
  931                         str.append(" (");
  932                       }
  933                       else {
  934                         str.append("(");
  935                       }
  936                       for (int i = 0; i < enumeration.length; i++) {
  937                           str.append(enumeration[i]);
  938                           if (i < enumeration.length - 1) {
  939                               str.append('|');
  940                           }
  941                       }
  942                       str.append(')');
  943                       type = str.toString();
  944                   }
  945                   String value = (defaultValue==null) ? null : defaultValue.toString();
  946                   fDeclHandler.attributeDecl(elementName, attributeName,
  947                                              type, defaultType, value);
  948               }
  949           }
  950           catch (SAXException e) {
  951               throw new XNIException(e);
  952           }
  953   
  954       } // attributeDecl(String,String,String,String[],String,XMLString, XMLString, Augmentations)
  955   
  956       /**
  957        * An internal entity declaration.
  958        *
  959        * @param name The name of the entity. Parameter entity names start with
  960        *             '%', whereas the name of a general entity is just the
  961        *             entity name.
  962        * @param text The value of the entity.
  963        * @param nonNormalizedText The non-normalized value of the entity. This
  964        *             value contains the same sequence of characters that was in
  965        *             the internal entity declaration, without any entity
  966        *             references expanded.
  967        *
  968        * @param augs Additional information that may include infoset
  969        *                      augmentations.
  970        *
  971        * @throws XNIException Thrown by handler to signal an error.
  972        */
  973       public void internalEntityDecl(String name, XMLString text,
  974                                      XMLString nonNormalizedText,
  975                                      Augmentations augs) throws XNIException {
  976   
  977           try {
  978               // SAX2 extensions
  979               if (fDeclHandler != null) {
  980                   fDeclHandler.internalEntityDecl(name, text.toString());
  981               }
  982           }
  983           catch (SAXException e) {
  984               throw new XNIException(e);
  985           }
  986   
  987       } // internalEntityDecl(String,XMLString,XMLString)
  988   
  989       /**
  990        * An external entity declaration.
  991        *
  992        * @param name     The name of the entity. Parameter entity names start
  993        *                 with '%', whereas the name of a general entity is just
  994        *                 the entity name.
  995        * @param identifier    An object containing all location information 
  996        *                      pertinent to this entity.
  997        * @param augs Additional information that may include infoset
  998        *                      augmentations.
  999        *
 1000        * @throws XNIException Thrown by handler to signal an error.
 1001        */
 1002       public void externalEntityDecl(String name, XMLResourceIdentifier identifier,
 1003                                      Augmentations augs) throws XNIException {
 1004           try {
 1005               // SAX2 extension
 1006               if (fDeclHandler != null) {
 1007                   String publicId = identifier.getPublicId();
 1008                   String systemId = fResolveDTDURIs ? 
 1009                       identifier.getExpandedSystemId() : identifier.getLiteralSystemId();
 1010                   fDeclHandler.externalEntityDecl(name, publicId, systemId);
 1011               }
 1012           }
 1013           catch (SAXException e) {
 1014               throw new XNIException(e);
 1015           }
 1016   
 1017       } // externalEntityDecl(String,,XMLResourceIdentifier, Augmentations)
 1018   
 1019       /**
 1020        * An unparsed entity declaration.
 1021        *
 1022        * @param name     The name of the entity.
 1023        * @param identifier    An object containing all location information 
 1024        *                      pertinent to this entity.
 1025        * @param notation The name of the notation.
 1026        *
 1027        * @param augs Additional information that may include infoset
 1028        *                      augmentations.
 1029        *
 1030        * @throws XNIException Thrown by handler to signal an error.
 1031        */
 1032       public void unparsedEntityDecl(String name, XMLResourceIdentifier identifier, 
 1033                                      String notation,
 1034                                      Augmentations augs) throws XNIException {
 1035           try {
 1036               // SAX2 extension
 1037               if (fDTDHandler != null) {
 1038                   String publicId = identifier.getPublicId();
 1039                   String systemId = fResolveDTDURIs ? 
 1040                       identifier.getExpandedSystemId() : identifier.getLiteralSystemId();
 1041                   fDTDHandler.unparsedEntityDecl(name, publicId, systemId, notation);
 1042               }
 1043           }
 1044           catch (SAXException e) {
 1045               throw new XNIException(e);
 1046           }
 1047   
 1048       } // unparsedEntityDecl(String,XMLResourceIdentifier, String, Augmentations)
 1049   
 1050       /**
 1051        * A notation declaration
 1052        *
 1053        * @param name     The name of the notation.
 1054        * @param identifier    An object containing all location information 
 1055        *                      pertinent to this notation.
 1056        * @param augs Additional information that may include infoset
 1057        *                      augmentations.
 1058        *
 1059        * @throws XNIException Thrown by handler to signal an error.
 1060        */
 1061       public void notationDecl(String name, XMLResourceIdentifier identifier,
 1062                                Augmentations augs) throws XNIException {
 1063           try {
 1064               // SAX1 and SAX2
 1065               if (fDTDHandler != null) {
 1066                   String publicId = identifier.getPublicId();
 1067                   String systemId = fResolveDTDURIs ? 
 1068                       identifier.getExpandedSystemId() : identifier.getLiteralSystemId();
 1069                   fDTDHandler.notationDecl(name, publicId, systemId);
 1070               }
 1071           }
 1072           catch (SAXException e) {
 1073               throw new XNIException(e);
 1074           }
 1075   
 1076       } // notationDecl(String,XMLResourceIdentifier, Augmentations)
 1077   
 1078       /**
 1079        * The end of the DTD.
 1080        *
 1081        * @param augs Additional information that may include infoset
 1082        *                      augmentations.
 1083        *
 1084        * @throws XNIException Thrown by handler to signal an error.
 1085        */
 1086       public void endDTD(Augmentations augs) throws XNIException {
 1087           fInDTD = false;
 1088   
 1089           try {
 1090               // SAX2 extension
 1091               if (fLexicalHandler != null) {
 1092                   fLexicalHandler.endDTD();
 1093               }
 1094           }
 1095           catch (SAXException e) {
 1096               throw new XNIException(e);
 1097           }
 1098           if(fDeclaredAttrs != null) {
 1099               // help out the GC
 1100               fDeclaredAttrs.clear();
 1101           }
 1102   
 1103       } // endDTD()
 1104   
 1105       //
 1106       // Parser and XMLReader methods
 1107       //
 1108   
 1109       /**
 1110        * Parses the input source specified by the given system identifier.
 1111        * <p>
 1112        * This method is equivalent to the following:
 1113        * <pre>
 1114        *     parse(new InputSource(systemId));
 1115        * </pre>
 1116        *
 1117        * @param systemId The system identifier (URI).
 1118        *
 1119        * @exception org.xml.sax.SAXException Throws exception on SAX error.
 1120        * @exception java.io.IOException Throws exception on i/o error.
 1121        */
 1122       public void parse(String systemId) throws SAXException, IOException {
 1123   
 1124           // parse document
 1125           XMLInputSource source = new XMLInputSource(null, systemId, null);
 1126           try {
 1127               parse(source);
 1128           }
 1129   
 1130           // wrap XNI exceptions as SAX exceptions
 1131           catch (XMLParseException e) {
 1132               Exception ex = e.getException();
 1133               if (ex == null || ex instanceof CharConversionException) {
 1134                   // must be a parser exception; mine it for locator info 
 1135                   // and throw a SAXParseException
 1136                   Locator2Impl locatorImpl = new Locator2Impl();
 1137                   // since XMLParseExceptions know nothing about encoding,
 1138                   // we cannot return anything meaningful in this context.
 1139                   // We *could* consult the LocatorProxy, but the
 1140                   // application can do this itself if it wishes to possibly
 1141                   // be mislead.
 1142                   locatorImpl.setXMLVersion(fVersion);
 1143                   locatorImpl.setPublicId(e.getPublicId());
 1144                   locatorImpl.setSystemId(e.getExpandedSystemId());
 1145                   locatorImpl.setLineNumber(e.getLineNumber());
 1146                   locatorImpl.setColumnNumber(e.getColumnNumber());
 1147                   throw (ex == null) ? 
 1148                           new SAXParseException(e.getMessage(), locatorImpl) : 
 1149                           new SAXParseException(e.getMessage(), locatorImpl, ex);
 1150               }
 1151               if (ex instanceof SAXException) {
 1152                   // why did we create an XMLParseException?
 1153                   throw (SAXException)ex;
 1154               }
 1155               if (ex instanceof IOException) {
 1156                   throw (IOException)ex;
 1157               }
 1158               throw new SAXException(ex);
 1159           }
 1160           catch (XNIException e) {
 1161               Exception ex = e.getException();
 1162               if (ex == null) {
 1163                   throw new SAXException(e.getMessage());
 1164               }
 1165               if (ex instanceof SAXException) {
 1166                   throw (SAXException)ex;
 1167               }
 1168               if (ex instanceof IOException) {
 1169                   throw (IOException)ex;
 1170               }
 1171               throw new SAXException(ex);
 1172           }
 1173   
 1174       } // parse(String)
 1175   
 1176       /**
 1177        * parse
 1178        *
 1179        * @param inputSource
 1180        *
 1181        * @exception org.xml.sax.SAXException
 1182        * @exception java.io.IOException
 1183        */
 1184       public void parse(InputSource inputSource)
 1185           throws SAXException, IOException {
 1186   
 1187           // parse document
 1188           try {
 1189               XMLInputSource xmlInputSource =
 1190                   new XMLInputSource(inputSource.getPublicId(),
 1191                                      inputSource.getSystemId(),
 1192                                      null);
 1193               xmlInputSource.setByteStream(inputSource.getByteStream());
 1194               xmlInputSource.setCharacterStream(inputSource.getCharacterStream());
 1195               xmlInputSource.setEncoding(inputSource.getEncoding());
 1196               parse(xmlInputSource);
 1197           }
 1198   
 1199           // wrap XNI exceptions as SAX exceptions
 1200           catch (XMLParseException e) {
 1201               Exception ex = e.getException();
 1202               if (ex == null || ex instanceof CharConversionException) {
 1203                   // must be a parser exception; mine it for locator info 
 1204                   // and throw a SAXParseException
 1205                   Locator2Impl locatorImpl = new Locator2Impl();
 1206                   // since XMLParseExceptions know nothing about encoding,
 1207                   // we cannot return anything meaningful in this context.
 1208                   // We *could* consult the LocatorProxy, but the
 1209                   // application can do this itself if it wishes to possibly
 1210                   // be mislead.
 1211                   locatorImpl.setXMLVersion(fVersion);
 1212                   locatorImpl.setPublicId(e.getPublicId());
 1213                   locatorImpl.setSystemId(e.getExpandedSystemId());
 1214                   locatorImpl.setLineNumber(e.getLineNumber());
 1215                   locatorImpl.setColumnNumber(e.getColumnNumber());
 1216                   throw (ex == null) ? 
 1217                           new SAXParseException(e.getMessage(), locatorImpl) : 
 1218                           new SAXParseException(e.getMessage(), locatorImpl, ex);
 1219               }
 1220               if (ex instanceof SAXException) {
 1221                   // why did we create an XMLParseException?
 1222                   throw (SAXException)ex;
 1223               }
 1224               if (ex instanceof IOException) {
 1225                   throw (IOException)ex;
 1226               }
 1227               throw new SAXException(ex);
 1228           }
 1229           catch (XNIException e) {
 1230               Exception ex = e.getException();
 1231               if (ex == null) {
 1232                   throw new SAXException(e.getMessage());
 1233               }
 1234               if (ex instanceof SAXException) {
 1235                   throw (SAXException)ex;
 1236               }
 1237               if (ex instanceof IOException) {
 1238                   throw (IOException)ex;
 1239               }
 1240               throw new SAXException(ex);
 1241           }
 1242   
 1243       } // parse(InputSource)
 1244   
 1245       /**
 1246        * Sets the resolver used to resolve external entities. The EntityResolver
 1247        * interface supports resolution of public and system identifiers.
 1248        *
 1249        * @param resolver The new entity resolver. Passing a null value will
 1250        *                 uninstall the currently installed resolver.
 1251        */
 1252       public void setEntityResolver(EntityResolver resolver) {
 1253   
 1254           try {
 1255               XMLEntityResolver xer = (XMLEntityResolver) fConfiguration.getProperty(ENTITY_RESOLVER);
 1256               if (fUseEntityResolver2 && resolver instanceof EntityResolver2) {
 1257                   if (xer instanceof EntityResolver2Wrapper) {
 1258                       EntityResolver2Wrapper er2w = (EntityResolver2Wrapper) xer;
 1259                       er2w.setEntityResolver((EntityResolver2) resolver);
 1260                   }
 1261                   else {
 1262                       fConfiguration.setProperty(ENTITY_RESOLVER,
 1263                               new EntityResolver2Wrapper((EntityResolver2) resolver));
 1264                   }
 1265               }
 1266               else {
 1267                   if (xer instanceof EntityResolverWrapper) {
 1268                       EntityResolverWrapper erw = (EntityResolverWrapper) xer;
 1269                       erw.setEntityResolver(resolver);
 1270                   }
 1271                   else {
 1272                       fConfiguration.setProperty(ENTITY_RESOLVER,
 1273                               new EntityResolverWrapper(resolver));
 1274                   }
 1275               }
 1276           }
 1277           catch (XMLConfigurationException e) {
 1278               // do nothing
 1279           }
 1280   
 1281       } // setEntityResolver(EntityResolver)
 1282   
 1283       /**
 1284        * Return the current entity resolver.
 1285        *
 1286        * @return The current entity resolver, or null if none
 1287        *         has been registered.
 1288        * @see #setEntityResolver
 1289        */
 1290       public EntityResolver getEntityResolver() {
 1291   
 1292           EntityResolver entityResolver = null;
 1293           try {
 1294               XMLEntityResolver xmlEntityResolver =
 1295                   (XMLEntityResolver)fConfiguration.getProperty(ENTITY_RESOLVER);
 1296               if (xmlEntityResolver != null) {
 1297                   if (xmlEntityResolver instanceof EntityResolverWrapper) {
 1298                       entityResolver =
 1299                           ((EntityResolverWrapper) xmlEntityResolver).getEntityResolver();
 1300                   }
 1301                   else if (xmlEntityResolver instanceof EntityResolver2Wrapper) {
 1302                       entityResolver = 
 1303                           ((EntityResolver2Wrapper) xmlEntityResolver).getEntityResolver();
 1304                   }
 1305               }
 1306           }
 1307           catch (XMLConfigurationException e) {
 1308               // do nothing
 1309           }
 1310           return entityResolver;
 1311   
 1312       } // getEntityResolver():EntityResolver
 1313   
 1314       /**
 1315        * Allow an application to register an error event handler.
 1316        *
 1317        * <p>If the application does not register an error handler, all
 1318        * error events reported by the SAX parser will be silently
 1319        * ignored; however, normal processing may not continue.  It is
 1320        * highly recommended that all SAX applications implement an
 1321        * error handler to avoid unexpected bugs.</p>
 1322        *
 1323        * <p>Applications may register a new or different handler in the
 1324        * middle of a parse, and the SAX parser must begin using the new
 1325        * handler immediately.</p>
 1326        *
 1327        * @param errorHandler The error handler.
 1328        * @see #getErrorHandler
 1329        */
 1330       public void setErrorHandler(ErrorHandler errorHandler) {
 1331   
 1332           try {
 1333               XMLErrorHandler xeh = (XMLErrorHandler) fConfiguration.getProperty(ERROR_HANDLER);
 1334               if (xeh instanceof ErrorHandlerWrapper) {
 1335                   ErrorHandlerWrapper ehw = (ErrorHandlerWrapper) xeh;
 1336                   ehw.setErrorHandler(errorHandler);
 1337               }
 1338               else {
 1339                   fConfiguration.setProperty(ERROR_HANDLER,
 1340                           new ErrorHandlerWrapper(errorHandler));
 1341               }
 1342           }
 1343           catch (XMLConfigurationException e) {
 1344               // do nothing
 1345           }
 1346   
 1347       } // setErrorHandler(ErrorHandler)
 1348   
 1349       /**
 1350        * Return the current error handler.
 1351        *
 1352        * @return The current error handler, or null if none
 1353        *         has been registered.
 1354        * @see #setErrorHandler
 1355        */
 1356       public ErrorHandler getErrorHandler() {
 1357   
 1358           ErrorHandler errorHandler = null;
 1359           try {
 1360               XMLErrorHandler xmlErrorHandler =
 1361                   (XMLErrorHandler)fConfiguration.getProperty(ERROR_HANDLER);
 1362               if (xmlErrorHandler != null &&
 1363                   xmlErrorHandler instanceof ErrorHandlerWrapper) {
 1364                   errorHandler = ((ErrorHandlerWrapper)xmlErrorHandler).getErrorHandler();
 1365               }
 1366           }
 1367           catch (XMLConfigurationException e) {
 1368               // do nothing
 1369           }
 1370           return errorHandler;
 1371   
 1372       } // getErrorHandler():ErrorHandler
 1373   
 1374       /**
 1375        * Set the locale to use for messages.
 1376        *
 1377        * @param locale The locale object to use for localization of messages.
 1378        *
 1379        * @exception SAXException An exception thrown if the parser does not
 1380        *                         support the specified locale.
 1381        *
 1382        * @see org.xml.sax.Parser
 1383        */
 1384       public void setLocale(Locale locale) throws SAXException {
 1385           //REVISIT:this methods is not part of SAX2 interfaces, we should throw exception
 1386           //if any application uses SAX2 and sets locale also. -nb
 1387           fConfiguration.setLocale(locale);
 1388   
 1389       } // setLocale(Locale)
 1390   
 1391       /**
 1392        * Allow an application to register a DTD event handler.
 1393        * <p>
 1394        * If the application does not register a DTD handler, all DTD
 1395        * events reported by the SAX parser will be silently ignored.
 1396        * <p>
 1397        * Applications may register a new or different handler in the
 1398        * middle of a parse, and the SAX parser must begin using the new
 1399        * handler immediately.
 1400        *
 1401        * @param dtdHandler The DTD handler.
 1402        *
 1403   
 1404        * @see #getDTDHandler
 1405        */
 1406       public void setDTDHandler(DTDHandler dtdHandler) {
 1407           fDTDHandler = dtdHandler;
 1408       } // setDTDHandler(DTDHandler)
 1409   
 1410       //
 1411       // Parser methods
 1412       //
 1413   
 1414       /**
 1415        * Allow an application to register a document event handler.
 1416        * <p>
 1417        * If the application does not register a document handler, all
 1418        * document events reported by the SAX parser will be silently
 1419        * ignored (this is the default behaviour implemented by
 1420        * HandlerBase).
 1421        * <p>
 1422        * Applications may register a new or different handler in the
 1423        * middle of a parse, and the SAX parser must begin using the new
 1424        * handler immediately.
 1425        *
 1426        * @param documentHandler The document handler.
 1427        */
 1428       public void setDocumentHandler(DocumentHandler documentHandler) {
 1429           fDocumentHandler = documentHandler;
 1430       } // setDocumentHandler(DocumentHandler)
 1431   
 1432       //
 1433       // XMLReader methods
 1434       //
 1435   
 1436       /**
 1437        * Allow an application to register a content event handler.
 1438        * <p>
 1439        * If the application does not register a content handler, all
 1440        * content events reported by the SAX parser will be silently
 1441        * ignored.
 1442        * <p>
 1443        * Applications may register a new or different handler in the
 1444        * middle of a parse, and the SAX parser must begin using the new
 1445        * handler immediately.
 1446        *
 1447        * @param contentHandler The content handler.
 1448        *
 1449        * @see #getContentHandler
 1450        */
 1451       public void setContentHandler(ContentHandler contentHandler) {
 1452           fContentHandler = contentHandler;
 1453       } // setContentHandler(ContentHandler)
 1454   
 1455       /**
 1456        * Return the current content handler.
 1457        *
 1458        * @return The current content handler, or null if none
 1459        *         has been registered.
 1460        *
 1461        * @see #setContentHandler
 1462        */
 1463       public ContentHandler getContentHandler() {
 1464           return fContentHandler;
 1465       } // getContentHandler():ContentHandler
 1466   
 1467       /**
 1468        * Return the current DTD handler.
 1469        *
 1470        * @return The current DTD handler, or null if none
 1471        *         has been registered.
 1472        * @see #setDTDHandler
 1473        */
 1474       public DTDHandler getDTDHandler() {
 1475           return fDTDHandler;
 1476       } // getDTDHandler():DTDHandler
 1477   
 1478       /**
 1479        * Set the state of any feature in a SAX2 parser.  The parser
 1480        * might not recognize the feature, and if it does recognize
 1481        * it, it might not be able to fulfill the request.
 1482        *
 1483        * @param featureId The unique identifier (URI) of the feature.
 1484        * @param state The requested state of the feature (true or false).
 1485        *
 1486        * @exception SAXNotRecognizedException If the
 1487        *            requested feature is not known.
 1488        * @exception SAXNotSupportedException If the
 1489        *            requested feature is known, but the requested
 1490        *            state is not supported.
 1491        */
 1492       public void setFeature(String featureId, boolean state)
 1493           throws SAXNotRecognizedException, SAXNotSupportedException {
 1494   
 1495           try {
 1496               //
 1497               // SAX2 Features
 1498               //
 1499   
 1500               if (featureId.startsWith(Constants.SAX_FEATURE_PREFIX)) {
 1501                   final int suffixLength = featureId.length() - Constants.SAX_FEATURE_PREFIX.length();
 1502   
 1503                   // http://xml.org/sax/features/namespaces
 1504                   if (suffixLength == Constants.NAMESPACES_FEATURE.length() && 
 1505                       featureId.endsWith(Constants.NAMESPACES_FEATURE)) {
 1506                       fConfiguration.setFeature(featureId, state);
 1507                       fNamespaces = state;
 1508                       return;
 1509                   }
 1510                   
 1511                   // http://xml.org/sax/features/namespace-prefixes
 1512                   //   controls the reporting of raw prefixed names and Namespace
 1513                   //   declarations (xmlns* attributes): when this feature is false
 1514                   //   (the default), raw prefixed names may optionally be reported,
 1515                   //   and xmlns* attributes must not be reported.
 1516                   //
 1517                   if (suffixLength == Constants.NAMESPACE_PREFIXES_FEATURE.length() && 
 1518                       featureId.endsWith(Constants.NAMESPACE_PREFIXES_FEATURE)) {
 1519                       fNamespacePrefixes = state;
 1520                       return;
 1521                   }
 1522                   
 1523                   // http://xml.org/sax/features/string-interning
 1524                   //   controls the use of java.lang.String#intern() for strings
 1525                   //   passed to SAX handlers.
 1526                   //
 1527                   if (suffixLength == Constants.STRING_INTERNING_FEATURE.length() && 
 1528                       featureId.endsWith(Constants.STRING_INTERNING_FEATURE)) {
 1529                       if (!state) {
 1530                           throw new SAXNotSupportedException(
 1531                               SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 1532                               "false-not-supported", new Object [] {featureId}));
 1533                       }
 1534                       return;
 1535                   }
 1536                   
 1537                   // http://xml.org/sax/features/lexical-handler/parameter-entities
 1538                   //   controls whether the beginning and end of parameter entities
 1539                   //   will be reported to the LexicalHandler.
 1540                   //
 1541                   if (suffixLength == Constants.LEXICAL_HANDLER_PARAMETER_ENTITIES_FEATURE.length() &&
 1542                       featureId.endsWith(Constants.LEXICAL_HANDLER_PARAMETER_ENTITIES_FEATURE)) {
 1543                       fLexicalHandlerParameterEntities = state;
 1544                       return;
 1545                   }
 1546                   
 1547                   // http://xml.org/sax/features/resolve-dtd-uris
 1548                   //   controls whether system identifiers will be absolutized relative to
 1549                   //   their base URIs before reporting.
 1550                   //
 1551                   if (suffixLength == Constants.RESOLVE_DTD_URIS_FEATURE.length() && 
 1552                       featureId.endsWith(Constants.RESOLVE_DTD_URIS_FEATURE)) {
 1553                       fResolveDTDURIs = state;
 1554                       return;
 1555                   }
 1556                   
 1557                   // http://xml.org/sax/features/unicode-normalization-checking
 1558                   //   controls whether Unicode normalization checking is performed
 1559                   //   as per Appendix B of the XML 1.1 specification
 1560                   //
 1561                   if (suffixLength == Constants.UNICODE_NORMALIZATION_CHECKING_FEATURE.length() &&
 1562                       featureId.endsWith(Constants.UNICODE_NORMALIZATION_CHECKING_FEATURE)) {
 1563                       // REVISIT: Allow this feature to be set once Unicode normalization
 1564                       // checking is supported -- mrglavas.
 1565                       if (state) {
 1566                           throw new SAXNotSupportedException(
 1567                               SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 1568                               "true-not-supported", new Object [] {featureId}));  
 1569                       }
 1570                       return;
 1571                   }
 1572                   
 1573                   // http://xml.org/sax/features/xmlns-uris
 1574                   //   controls whether the parser reports that namespace declaration
 1575                   //   attributes as being in the namespace: http://www.w3.org/2000/xmlns/
 1576                   //
 1577                   if (suffixLength == Constants.XMLNS_URIS_FEATURE.length() &&
 1578                       featureId.endsWith(Constants.XMLNS_URIS_FEATURE)) {
 1579                       fXMLNSURIs = state;
 1580                       return;
 1581                   }
 1582                   
 1583                   // http://xml.org/sax/features/use-entity-resolver2
 1584                   //   controls whether the methods of an object implementing
 1585                   //   org.xml.sax.ext.EntityResolver2 will be used by the parser.
 1586                   //
 1587                   if (suffixLength == Constants.USE_ENTITY_RESOLVER2_FEATURE.length() &&
 1588                       featureId.endsWith(Constants.USE_ENTITY_RESOLVER2_FEATURE)) {
 1589                       if (state != fUseEntityResolver2) {
 1590                           fUseEntityResolver2 = state;
 1591                           // Refresh EntityResolver wrapper.
 1592                           setEntityResolver(getEntityResolver());
 1593                       }
 1594                       return;
 1595                   }
 1596                   
 1597                   //
 1598                   // Read only features.
 1599                   //
 1600                   
 1601                   // http://xml.org/sax/features/is-standalone
 1602                   //   reports whether the document specified a standalone document declaration.
 1603                   // http://xml.org/sax/features/use-attributes2
 1604                   //   reports whether Attributes objects passed to startElement also implement
 1605                   //   the org.xml.sax.ext.Attributes2 interface.
 1606                   // http://xml.org/sax/features/use-locator2
 1607                   //   reports whether Locator objects passed to setDocumentLocator also implement
 1608                   //   the org.xml.sax.ext.Locator2 interface.
 1609                   // http://xml.org/sax/features/xml-1.1
 1610                   //   reports whether the parser supports both XML 1.1 and XML 1.0.
 1611                   if ((suffixLength == Constants.IS_STANDALONE_FEATURE.length() &&
 1612                       featureId.endsWith(Constants.IS_STANDALONE_FEATURE)) ||
 1613                       (suffixLength == Constants.USE_ATTRIBUTES2_FEATURE.length() &&
 1614                       featureId.endsWith(Constants.USE_ATTRIBUTES2_FEATURE)) ||
 1615                       (suffixLength == Constants.USE_LOCATOR2_FEATURE.length() &&
 1616                       featureId.endsWith(Constants.USE_LOCATOR2_FEATURE)) ||
 1617                       (suffixLength == Constants.XML_11_FEATURE.length() &&
 1618                       featureId.endsWith(Constants.XML_11_FEATURE))) {
 1619                       throw new SAXNotSupportedException(
 1620                           SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 1621                           "feature-read-only", new Object [] {featureId}));
 1622                   }
 1623                   
 1624   
 1625                   //
 1626                   // Drop through and perform default processing
 1627                   //
 1628               }
 1629   
 1630               //
 1631               // Xerces Features
 1632               //
 1633   
 1634               /*
 1635               else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) {
 1636                   String feature = featureId.substring(XERCES_FEATURES_PREFIX.length());
 1637                   //
 1638                   // Drop through and perform default processing
 1639                   //
 1640               }
 1641               */
 1642   
 1643               //
 1644               // Default handling
 1645               //
 1646   
 1647               fConfiguration.setFeature(featureId, state);
 1648           }
 1649           catch (XMLConfigurationException e) {
 1650               String identifier = e.getIdentifier();
 1651               if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
 1652                   throw new SAXNotRecognizedException(
 1653                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 1654                       "feature-not-recognized", new Object [] {identifier}));
 1655               }
 1656               else {
 1657                   throw new SAXNotSupportedException(
 1658                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 1659                       "feature-not-supported", new Object [] {identifier}));
 1660               }
 1661           }
 1662   
 1663       } // setFeature(String,boolean)
 1664   
 1665       /**
 1666        * Query the state of a feature.
 1667        *
 1668        * Query the current state of any feature in a SAX2 parser.  The
 1669        * parser might not recognize the feature.
 1670        *
 1671        * @param featureId The unique identifier (URI) of the feature
 1672        *                  being set.
 1673        * @return The current state of the feature.
 1674        * @exception org.xml.sax.SAXNotRecognizedException If the
 1675        *            requested feature is not known.
 1676        * @exception SAXNotSupportedException If the
 1677        *            requested feature is known but not supported.
 1678        */
 1679       public boolean getFeature(String featureId)
 1680           throws SAXNotRecognizedException, SAXNotSupportedException {
 1681   
 1682           try {
 1683               //
 1684               // SAX2 Features
 1685               //
 1686   
 1687               if (featureId.startsWith(Constants.SAX_FEATURE_PREFIX)) {
 1688                   final int suffixLength = featureId.length() - Constants.SAX_FEATURE_PREFIX.length();
 1689   
 1690                   // http://xml.org/sax/features/namespace-prefixes
 1691                   //   controls the reporting of raw prefixed names and Namespace
 1692                   //   declarations (xmlns* attributes): when this feature is false
 1693                   //   (the default), raw prefixed names may optionally be reported,
 1694                   //   and xmlns* attributes must not be reported.
 1695                   //
 1696                   if (suffixLength == Constants.NAMESPACE_PREFIXES_FEATURE.length() && 
 1697                       featureId.endsWith(Constants.NAMESPACE_PREFIXES_FEATURE)) {
 1698                       return fNamespacePrefixes;
 1699                   }
 1700                   // http://xml.org/sax/features/string-interning
 1701                   //   controls the use of java.lang.String#intern() for strings
 1702                   //   passed to SAX handlers.
 1703                   //
 1704                   if (suffixLength == Constants.STRING_INTERNING_FEATURE.length() && 
 1705                       featureId.endsWith(Constants.STRING_INTERNING_FEATURE)) {
 1706                       return true;
 1707                   }
 1708                   
 1709                   // http://xml.org/sax/features/is-standalone
 1710                   //   reports whether the document specified a standalone document declaration.
 1711                   //
 1712                   if (suffixLength == Constants.IS_STANDALONE_FEATURE.length() &&
 1713                       featureId.endsWith(Constants.IS_STANDALONE_FEATURE)) {
 1714                       return fStandalone;
 1715                   }
 1716                   
 1717                   // http://xml.org/sax/features/xml-1.1
 1718                   //   reports whether the parser supports both XML 1.1 and XML 1.0.
 1719                   //
 1720                   if (suffixLength == Constants.XML_11_FEATURE.length() &&
 1721                       featureId.endsWith(Constants.XML_11_FEATURE)) {
 1722                       return (fConfiguration instanceof XML11Configurable);
 1723                   }
 1724                   
 1725                   // http://xml.org/sax/features/lexical-handler/parameter-entities
 1726                   //   controls whether the beginning and end of parameter entities
 1727                   //   will be reported to the LexicalHandler.
 1728                   //
 1729                   if (suffixLength == Constants.LEXICAL_HANDLER_PARAMETER_ENTITIES_FEATURE.length() &&
 1730                       featureId.endsWith(Constants.LEXICAL_HANDLER_PARAMETER_ENTITIES_FEATURE)) {
 1731                       return fLexicalHandlerParameterEntities;
 1732                   }
 1733                   
 1734                   // http://xml.org/sax/features/resolve-dtd-uris
 1735                   //   controls whether system identifiers will be absolutized relative to
 1736                   //   their base URIs before reporting.
 1737                   if (suffixLength == Constants.RESOLVE_DTD_URIS_FEATURE.length() && 
 1738                       featureId.endsWith(Constants.RESOLVE_DTD_URIS_FEATURE)) {
 1739                       return fResolveDTDURIs;
 1740                   }
 1741                   
 1742                   // http://xml.org/sax/features/xmlns-uris
 1743                   //   controls whether the parser reports that namespace declaration
 1744                   //   attributes as being in the namespace: http://www.w3.org/2000/xmlns/
 1745                   //
 1746                   if (suffixLength == Constants.XMLNS_URIS_FEATURE.length() &&
 1747                       featureId.endsWith(Constants.XMLNS_URIS_FEATURE)) {
 1748                       return fXMLNSURIs;
 1749                   }
 1750                   
 1751                   // http://xml.org/sax/features/unicode-normalization-checking
 1752                   //   controls whether Unicode normalization checking is performed
 1753                   //   as per Appendix B of the XML 1.1 specification
 1754                   //
 1755                   if (suffixLength == Constants.UNICODE_NORMALIZATION_CHECKING_FEATURE.length() &&
 1756                       featureId.endsWith(Constants.UNICODE_NORMALIZATION_CHECKING_FEATURE)) {
 1757                       // REVISIT: Allow this feature to be set once Unicode normalization
 1758                       // checking is supported -- mrglavas.
 1759                       return false;
 1760                   }
 1761                   
 1762                   // http://xml.org/sax/features/use-entity-resolver2
 1763                   //   controls whether the methods of an object implementing
 1764                   //   org.xml.sax.ext.EntityResolver2 will be used by the parser.
 1765                   //
 1766                   if (suffixLength == Constants.USE_ENTITY_RESOLVER2_FEATURE.length() &&
 1767                       featureId.endsWith(Constants.USE_ENTITY_RESOLVER2_FEATURE)) {
 1768                       return fUseEntityResolver2;
 1769                   }
 1770                   
 1771                   // http://xml.org/sax/features/use-attributes2
 1772                   //   reports whether Attributes objects passed to startElement also implement
 1773                   //   the org.xml.sax.ext.Attributes2 interface.
 1774                   // http://xml.org/sax/features/use-locator2
 1775                   //   reports whether Locator objects passed to setDocumentLocator also implement
 1776                   //   the org.xml.sax.ext.Locator2 interface.
 1777                   //
 1778                   if ((suffixLength == Constants.USE_ATTRIBUTES2_FEATURE.length() &&
 1779                       featureId.endsWith(Constants.USE_ATTRIBUTES2_FEATURE)) ||
 1780                       (suffixLength == Constants.USE_LOCATOR2_FEATURE.length() &&
 1781                       featureId.endsWith(Constants.USE_LOCATOR2_FEATURE))) {
 1782                       return true;
 1783                   }                
 1784                   
 1785   
 1786                   //
 1787                   // Drop through and perform default processing
 1788                   //
 1789               }
 1790   
 1791               //
 1792               // Xerces Features
 1793               //
 1794   
 1795               /*
 1796               else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) {
 1797                   //
 1798                   // Drop through and perform default processing
 1799                   //
 1800               }
 1801               */
 1802   
 1803               return fConfiguration.getFeature(featureId);
 1804           }
 1805           catch (XMLConfigurationException e) {
 1806               String identifier = e.getIdentifier();
 1807               if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
 1808                   throw new SAXNotRecognizedException(
 1809                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 1810                       "feature-not-recognized", new Object [] {identifier}));
 1811               }
 1812               else {
 1813                   throw new SAXNotSupportedException(
 1814                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 1815                       "feature-not-supported", new Object [] {identifier}));
 1816               }
 1817           }
 1818   
 1819       } // getFeature(String):boolean
 1820   
 1821       /**
 1822        * Set the value of any property in a SAX2 parser.  The parser
 1823        * might not recognize the property, and if it does recognize
 1824        * it, it might not support the requested value.
 1825        *
 1826        * @param propertyId The unique identifier (URI) of the property
 1827        *                   being set.
 1828        * @param value The value to which the property is being set.
 1829        *
 1830        * @exception SAXNotRecognizedException If the
 1831        *            requested property is not known.
 1832        * @exception SAXNotSupportedException If the
 1833        *            requested property is known, but the requested
 1834        *            value is not supported.
 1835        */
 1836       public void setProperty(String propertyId, Object value)
 1837           throws SAXNotRecognizedException, SAXNotSupportedException {
 1838   
 1839           try {
 1840               //
 1841               // SAX2 core properties
 1842               //
 1843   
 1844               if (propertyId.startsWith(Constants.SAX_PROPERTY_PREFIX)) {
 1845                   final int suffixLength = propertyId.length() - Constants.SAX_PROPERTY_PREFIX.length();
 1846   
 1847                   //
 1848                   // http://xml.org/sax/properties/lexical-handler
 1849                   // Value type: org.xml.sax.ext.LexicalHandler
 1850                   // Access: read/write, pre-parse only
 1851                   //   Set the lexical event handler.
 1852                   //
 1853                   if (suffixLength == Constants.LEXICAL_HANDLER_PROPERTY.length() && 
 1854                       propertyId.endsWith(Constants.LEXICAL_HANDLER_PROPERTY)) {
 1855                       try {
 1856                           setLexicalHandler((LexicalHandler)value);
 1857                       }
 1858                       catch (ClassCastException e) {
 1859                           throw new SAXNotSupportedException(
 1860                               SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 1861                               "incompatible-class", new Object [] {propertyId, "org.xml.sax.ext.LexicalHandler"}));
 1862                       }
 1863                       return;
 1864                   }
 1865                   //
 1866                   // http://xml.org/sax/properties/declaration-handler
 1867                   // Value type: org.xml.sax.ext.DeclHandler
 1868                   // Access: read/write, pre-parse only
 1869                   //   Set the DTD declaration event handler.
 1870                   //
 1871                   if (suffixLength == Constants.DECLARATION_HANDLER_PROPERTY.length() && 
 1872                       propertyId.endsWith(Constants.DECLARATION_HANDLER_PROPERTY)) {
 1873                       try {
 1874                           setDeclHandler((DeclHandler)value);
 1875                       }
 1876                       catch (ClassCastException e) {
 1877                           throw new SAXNotSupportedException(
 1878                               SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 1879                               "incompatible-class", new Object [] {propertyId, "org.xml.sax.ext.DeclHandler"}));
 1880                       }
 1881                       return;
 1882                   }
 1883                   //
 1884                   // http://xml.org/sax/properties/dom-node
 1885                   // Value type: DOM Node
 1886                   // Access: read-only
 1887                   //   Get the DOM node currently being visited, if the SAX parser is
 1888                   //   iterating over a DOM tree.  If the parser recognises and
 1889                   //   supports this property but is not currently visiting a DOM
 1890                   //   node, it should return null (this is a good way to check for
 1891                   //   availability before the parse begins).
 1892                   // http://xml.org/sax/properties/document-xml-version
 1893                   // Value type: java.lang.String
 1894                   // Access: read-only
 1895                   //   The literal string describing the actual XML version of the document. 
 1896                   //
 1897                   if ((suffixLength == Constants.DOM_NODE_PROPERTY.length() && 
 1898                       propertyId.endsWith(Constants.DOM_NODE_PROPERTY)) ||
 1899                       (suffixLength == Constants.DOCUMENT_XML_VERSION_PROPERTY.length() &&
 1900                       propertyId.endsWith(Constants.DOCUMENT_XML_VERSION_PROPERTY))) {
 1901                       throw new SAXNotSupportedException(
 1902                           SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 1903                           "property-read-only", new Object [] {propertyId}));
 1904                   }
 1905                   //
 1906                   // Drop through and perform default processing
 1907                   //
 1908               }
 1909   
 1910               //
 1911               // Xerces Properties
 1912               //
 1913   
 1914               /*
 1915               else if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) {
 1916                   //
 1917                   // Drop through and perform default processing
 1918                   //
 1919               }
 1920               */
 1921   
 1922               //
 1923               // Perform default processing
 1924               //
 1925   
 1926               fConfiguration.setProperty(propertyId, value);
 1927           }
 1928           catch (XMLConfigurationException e) {
 1929               String identifier = e.getIdentifier();
 1930               if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
 1931                   throw new SAXNotRecognizedException(
 1932                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 1933                       "property-not-recognized", new Object [] {identifier}));
 1934               }
 1935               else {
 1936                   throw new SAXNotSupportedException(
 1937                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 1938                       "property-not-supported", new Object [] {identifier}));
 1939               }
 1940           }
 1941   
 1942       } // setProperty(String,Object)
 1943   
 1944       /**
 1945        * Query the value of a property.
 1946        *
 1947        * Return the current value of a property in a SAX2 parser.
 1948        * The parser might not recognize the property.
 1949        *
 1950        * @param propertyId The unique identifier (URI) of the property
 1951        *                   being set.
 1952        * @return The current value of the property.
 1953        * @exception org.xml.sax.SAXNotRecognizedException If the
 1954        *            requested property is not known.
 1955        * @exception SAXNotSupportedException If the
 1956        *            requested property is known but not supported.
 1957        */
 1958       public Object getProperty(String propertyId)
 1959           throws SAXNotRecognizedException, SAXNotSupportedException {
 1960   
 1961           try {
 1962               //
 1963               // SAX2 core properties
 1964               //
 1965   
 1966               if (propertyId.startsWith(Constants.SAX_PROPERTY_PREFIX)) {
 1967                   final int suffixLength = propertyId.length() - Constants.SAX_PROPERTY_PREFIX.length();
 1968   
 1969                   //
 1970                   // http://xml.org/sax/properties/document-xml-version
 1971                   // Value type: java.lang.String
 1972                   // Access: read-only
 1973                   //   The literal string describing the actual XML version of the document. 
 1974                   //
 1975                   if (suffixLength == Constants.DOCUMENT_XML_VERSION_PROPERTY.length() &&
 1976                       propertyId.endsWith(Constants.DOCUMENT_XML_VERSION_PROPERTY)) {
 1977                       return fVersion;
 1978                   }
 1979                   
 1980                   //
 1981                   // http://xml.org/sax/properties/lexical-handler
 1982                   // Value type: org.xml.sax.ext.LexicalHandler
 1983                   // Access: read/write, pre-parse only
 1984                   //   Set the lexical event handler.
 1985                   //
 1986                   if (suffixLength == Constants.LEXICAL_HANDLER_PROPERTY.length() && 
 1987                       propertyId.endsWith(Constants.LEXICAL_HANDLER_PROPERTY)) {
 1988                       return getLexicalHandler();
 1989                   }
 1990                   //
 1991                   // http://xml.org/sax/properties/declaration-handler
 1992                   // Value type: org.xml.sax.ext.DeclHandler
 1993                   // Access: read/write, pre-parse only
 1994                   //   Set the DTD declaration event handler.
 1995                   //
 1996                   if (suffixLength == Constants.DECLARATION_HANDLER_PROPERTY.length() && 
 1997                       propertyId.endsWith(Constants.DECLARATION_HANDLER_PROPERTY)) {
 1998                       return getDeclHandler();
 1999                   }
 2000                   
 2001                   //
 2002                   // http://xml.org/sax/properties/dom-node
 2003                   // Value type: DOM Node
 2004                   // Access: read-only
 2005                   //   Get the DOM node currently being visited, if the SAX parser is
 2006                   //   iterating over a DOM tree.  If the parser recognises and
 2007                   //   supports this property but is not currently visiting a DOM
 2008                   //   node, it should return null (this is a good way to check for
 2009                   //   availability before the parse begins).
 2010                   //
 2011                   if (suffixLength == Constants.DOM_NODE_PROPERTY.length() && 
 2012                       propertyId.endsWith(Constants.DOM_NODE_PROPERTY)) {
 2013                       // we are not iterating a DOM tree
 2014                       throw new SAXNotSupportedException(
 2015                           SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 2016                           "dom-node-read-not-supported", null));
 2017                   }
 2018                   
 2019                   //
 2020                   // Drop through and perform default processing
 2021                   //
 2022               }
 2023   
 2024               //
 2025               // Xerces properties
 2026               //
 2027   
 2028               /*
 2029               else if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) {
 2030                   //
 2031                   // Drop through and perform default processing
 2032                   //
 2033               }
 2034               */
 2035   
 2036               //
 2037               // Perform default processing
 2038               //
 2039   
 2040               return fConfiguration.getProperty(propertyId);
 2041           }
 2042           catch (XMLConfigurationException e) {
 2043               String identifier = e.getIdentifier();
 2044               if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
 2045                   throw new SAXNotRecognizedException(
 2046                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 2047                       "property-not-recognized", new Object [] {identifier}));
 2048               }
 2049               else {
 2050                   throw new SAXNotSupportedException(
 2051                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 2052                       "property-not-supported", new Object [] {identifier}));
 2053               }
 2054           }
 2055   
 2056       } // getProperty(String):Object
 2057   
 2058       //
 2059       // Protected methods
 2060       //
 2061   
 2062       // SAX2 core properties
 2063   
 2064       /**
 2065        * Set the DTD declaration event handler.
 2066        * <p>
 2067        * This method is the equivalent to the property:
 2068        * <pre>
 2069        * http://xml.org/sax/properties/declaration-handler
 2070        * </pre>
 2071        *
 2072        * @param handler The new handler.
 2073        *
 2074        * @see #getDeclHandler
 2075        * @see #setProperty
 2076        */
 2077       protected void setDeclHandler(DeclHandler handler)
 2078           throws SAXNotRecognizedException, SAXNotSupportedException {
 2079   
 2080           if (fParseInProgress) {
 2081               throw new SAXNotSupportedException(
 2082                   SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 2083                   "property-not-parsing-supported",
 2084                   new Object [] {"http://xml.org/sax/properties/declaration-handler"}));
 2085           }
 2086           fDeclHandler = handler;
 2087   
 2088       } // setDeclHandler(DeclHandler)
 2089   
 2090       /**
 2091        * Returns the DTD declaration event handler.
 2092        *
 2093        * @see #setDeclHandler
 2094        */
 2095       protected DeclHandler getDeclHandler()
 2096           throws SAXNotRecognizedException, SAXNotSupportedException {
 2097           return fDeclHandler;
 2098       } // getDeclHandler():DeclHandler
 2099   
 2100       /**
 2101        * Set the lexical event handler.
 2102        * <p>
 2103        * This method is the equivalent to the property:
 2104        * <pre>
 2105        * http://xml.org/sax/properties/lexical-handler
 2106        * </pre>
 2107        *
 2108        * @param handler lexical event handler
 2109        *
 2110        * @see #getLexicalHandler
 2111        * @see #setProperty
 2112        */
 2113       protected void setLexicalHandler(LexicalHandler handler)
 2114           throws SAXNotRecognizedException, SAXNotSupportedException {
 2115   
 2116           if (fParseInProgress) {
 2117               throw new SAXNotSupportedException(
 2118                   SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
 2119                   "property-not-parsing-supported",
 2120                   new Object [] {"http://xml.org/sax/properties/lexical-handler"}));
 2121           }
 2122           fLexicalHandler = handler;
 2123   
 2124       } // setLexicalHandler(LexicalHandler)
 2125   
 2126       /**
 2127        * Returns the lexical handler.
 2128        *
 2129        * @see #setLexicalHandler
 2130        */
 2131       protected LexicalHandler getLexicalHandler()
 2132           throws SAXNotRecognizedException, SAXNotSupportedException {
 2133           return fLexicalHandler;
 2134       } // getLexicalHandler():LexicalHandler
 2135   
 2136       /**
 2137        * Send startPrefixMapping events
 2138        */
 2139       protected final void startNamespaceMapping() throws SAXException{
 2140           int count = fNamespaceContext.getDeclaredPrefixCount();
 2141           if (count > 0) {
 2142               String prefix = null;
 2143               String uri = null;
 2144               for (int i = 0; i < count; i++) {
 2145                   prefix = fNamespaceContext.getDeclaredPrefixAt(i);
 2146                   uri = fNamespaceContext.getURI(prefix);
 2147                   fContentHandler.startPrefixMapping(prefix, 
 2148                       (uri == null) ? "" : uri);
 2149               }
 2150           }
 2151       }
 2152       
 2153       /**
 2154        * Send endPrefixMapping events
 2155        */
 2156       protected final void endNamespaceMapping() throws SAXException {
 2157           int count = fNamespaceContext.getDeclaredPrefixCount();
 2158           if (count > 0) {
 2159               for (int i = 0; i < count; i++) {
 2160                   fContentHandler.endPrefixMapping(fNamespaceContext.getDeclaredPrefixAt(i));
 2161               }
 2162           }
 2163       }
 2164   	
 2165       //
 2166       // XMLDocumentParser methods
 2167       //
 2168   
 2169       /**
 2170        * Reset all components before parsing.
 2171        *
 2172        * @throws XNIException Thrown if an error occurs during initialization.
 2173        */
 2174       public void reset() throws XNIException {
 2175           super.reset();
 2176   
 2177           // reset state
 2178           fInDTD = false;
 2179           fVersion = "1.0";
 2180           fStandalone = false;
 2181   
 2182           // features
 2183           fNamespaces = fConfiguration.getFeature(NAMESPACES);
 2184           fAugmentations = null;
 2185           fDeclaredAttrs = null;
 2186           
 2187       } // reset()
 2188   
 2189       //
 2190       // Classes
 2191       //
 2192   
 2193       protected static final class LocatorProxy
 2194           implements Locator2 {
 2195   
 2196           //
 2197           // Data
 2198           //
 2199   
 2200           /** XML locator. */
 2201           protected XMLLocator fLocator;
 2202   
 2203           //
 2204           // Constructors
 2205           //
 2206   
 2207           /** Constructs an XML locator proxy. */
 2208           public LocatorProxy(XMLLocator locator) {
 2209               fLocator = locator;
 2210           }
 2211   
 2212           //
 2213           // Locator methods
 2214           //
 2215   
 2216           /** Public identifier. */
 2217           public String getPublicId() {
 2218               return fLocator.getPublicId();
 2219           }
 2220   
 2221           /** System identifier. */
 2222           public String getSystemId() {
 2223               return fLocator.getExpandedSystemId();
 2224           }
 2225           /** Line number. */
 2226           public int getLineNumber() {
 2227               return fLocator.getLineNumber();
 2228           }
 2229   
 2230           /** Column number. */
 2231           public int getColumnNumber() {
 2232               return fLocator.getColumnNumber();
 2233           }
 2234   
 2235           // Locator2 methods
 2236           public String getXMLVersion() {
 2237               return fLocator.getXMLVersion();
 2238           }
 2239   
 2240           public String getEncoding() {
 2241               return fLocator.getEncoding();
 2242           }
 2243   
 2244       } // class LocatorProxy
 2245   
 2246       protected static final class AttributesProxy
 2247           implements AttributeList, Attributes2 {
 2248   
 2249           //
 2250           // Data
 2251           //
 2252   
 2253           /** XML attributes. */
 2254           protected XMLAttributes fAttributes;
 2255   
 2256           //
 2257           // Public methods
 2258           //
 2259   
 2260           /** Sets the XML attributes. */
 2261           public void setAttributes(XMLAttributes attributes) {
 2262               fAttributes = attributes;
 2263           } // setAttributes(XMLAttributes)
 2264   
 2265           public int getLength() {
 2266               return fAttributes.getLength();
 2267           }
 2268   
 2269           public String getName(int i) {
 2270               return fAttributes.getQName(i);
 2271           }
 2272   
 2273           public String getQName(int index) {
 2274               return fAttributes.getQName(index);
 2275           }
 2276   
 2277           public String getURI(int index) {
 2278               // REVISIT: this hides the fact that internally we use
 2279               //          null instead of empty string
 2280               //          SAX requires URI to be a string or an empty string
 2281               String uri= fAttributes.getURI(index);
 2282               return uri != null ? uri : "";
 2283           }
 2284   
 2285           public String getLocalName(int index) {
 2286               return fAttributes.getLocalName(index);
 2287           }
 2288   
 2289           public String getType(int i) {
 2290               return fAttributes.getType(i);
 2291           }
 2292   
 2293           public String getType(String name) {
 2294               return fAttributes.getType(name);
 2295           }
 2296   
 2297           public String getType(String uri, String localName) {
 2298               return uri.equals("") ? fAttributes.getType(null, localName) :
 2299                                       fAttributes.getType(uri, localName);
 2300           }
 2301   
 2302           public String getValue(int i) {
 2303               return fAttributes.getValue(i);
 2304           }
 2305   
 2306           public String getValue(String name) {
 2307               return fAttributes.getValue(name);
 2308           }
 2309   
 2310           public String getValue(String uri, String localName) {
 2311               return uri.equals("") ? fAttributes.getValue(null, localName) :
 2312                                       fAttributes.getValue(uri, localName);
 2313           }
 2314   
 2315           public int getIndex(String qName) {
 2316               return fAttributes.getIndex(qName);
 2317           }
 2318   
 2319           public int getIndex(String uri, String localPart) {
 2320               return uri.equals("") ? fAttributes.getIndex(null, localPart) :
 2321                                       fAttributes.getIndex(uri, localPart);
 2322           }
 2323           
 2324           // Attributes2 methods
 2325           // REVISIT: Localize exception messages. -- mrglavas
 2326           public boolean isDeclared(int index) {
 2327               if (index < 0 || index >= fAttributes.getLength()) {
 2328                   throw new ArrayIndexOutOfBoundsException(index);
 2329               }
 2330               return Boolean.TRUE.equals(
 2331                   fAttributes.getAugmentations(index).getItem(
 2332                   Constants.ATTRIBUTE_DECLARED));
 2333           }
 2334           
 2335           public boolean isDeclared(String qName) {
 2336               int index = getIndex(qName);
 2337               if (index == -1) {
 2338                   throw new IllegalArgumentException(qName);
 2339               }
 2340               return Boolean.TRUE.equals(
 2341                   fAttributes.getAugmentations(index).getItem(
 2342                   Constants.ATTRIBUTE_DECLARED));
 2343           }
 2344   		
 2345           public boolean isDeclared(String uri, String localName) {
 2346               int index = getIndex(uri, localName);
 2347               if (index == -1) {
 2348                   throw new IllegalArgumentException(localName);
 2349               }
 2350               return Boolean.TRUE.equals(
 2351                   fAttributes.getAugmentations(index).getItem(
 2352                   Constants.ATTRIBUTE_DECLARED));
 2353           }
 2354                   
 2355           public boolean isSpecified(int index) {
 2356               if (index < 0 || index >= fAttributes.getLength()) {
 2357                   throw new ArrayIndexOutOfBoundsException(index);
 2358               }
 2359               return fAttributes.isSpecified(index);
 2360           }
 2361           
 2362           public boolean isSpecified(String qName) {
 2363               int index = getIndex(qName);
 2364               if (index == -1) {
 2365                   throw new IllegalArgumentException(qName);
 2366               }
 2367               return fAttributes.isSpecified(index);
 2368           }
 2369           
 2370           public boolean isSpecified(String uri, String localName) {
 2371               int index = getIndex(uri, localName);
 2372               if (index == -1) {
 2373                   throw new IllegalArgumentException(localName);
 2374               }
 2375               return fAttributes.isSpecified(index);
 2376           }
 2377   
 2378       } // class AttributesProxy
 2379   
 2380   
 2381       // PSVIProvider methods
 2382   
 2383       public ElementPSVI getElementPSVI(){
 2384           return (fAugmentations != null)?(ElementPSVI)fAugmentations.getItem(Constants.ELEMENT_PSVI):null;
 2385       }
 2386   
 2387   
 2388       public AttributePSVI getAttributePSVI(int index){
 2389   
 2390           return (AttributePSVI)fAttributesProxy.fAttributes.getAugmentations(index).getItem(Constants.ATTRIBUTE_PSVI);
 2391       }
 2392   
 2393   
 2394       public AttributePSVI getAttributePSVIByName(String uri, 
 2395                                                   String localname){
 2396           return (AttributePSVI)fAttributesProxy.fAttributes.getAugmentations(uri, localname).getItem(Constants.ATTRIBUTE_PSVI);
 2397       }
 2398   
 2399   } // class AbstractSAXParser

Save This Page
Home » Xerces-J-src.2.9.1 » org.apache.xerces » parsers » [javadoc | source]