/[classpath]/classpath/gnu/xml/aelfred2/SAXDriver.java
ViewVC logotype

Diff of /classpath/gnu/xml/aelfred2/SAXDriver.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by dog, Sun Feb 13 10:14:13 2005 UTC revision 1.5 by dog, Sun Feb 27 14:32:29 2005 UTC
# Line 60  import java.net.URL; Line 60  import java.net.URL;
60  import java.util.Locale;  import java.util.Locale;
61  import java.util.Stack;  import java.util.Stack;
62    
 // maintaining 1.1 compatibility for now ... more portable, PJava, etc  
 // Iterator, Hashmap and ArrayList ought to be faster  
63  import java.util.ArrayList;  import java.util.ArrayList;
64  import java.util.Collections;  import java.util.Collections;
65  import java.util.Enumeration;  import java.util.Enumeration;
# Line 131  import org.xml.sax.helpers.NamespaceSupp Line 129  import org.xml.sax.helpers.NamespaceSupp
129   * @see org.xml.sax.Parser   * @see org.xml.sax.Parser
130   */   */
131  final public class SAXDriver  final public class SAXDriver
132      implements Locator, Attributes2, XMLReader, Parser, AttributeList    implements Locator, Attributes2, XMLReader, Parser, AttributeList
133  {  {
134      private final DefaultHandler2       base = new DefaultHandler2 ();    
135      private XmlParser                   parser;    private final DefaultHandler2 base = new DefaultHandler2();
136      private XmlParser parser;
137      private EntityResolver              entityResolver = base;    
138      private EntityResolver2             resolver2 = null;    private EntityResolver entityResolver = base;
139      private ContentHandler              contentHandler = base;    private EntityResolver2 resolver2 = null;
140      private DTDHandler                  dtdHandler = base;    private ContentHandler contentHandler = base;
141      private ErrorHandler                errorHandler = base;    private DTDHandler dtdHandler = base;
142      private DeclHandler                 declHandler = base;    private ErrorHandler errorHandler = base;
143      private LexicalHandler              lexicalHandler = base;    private DeclHandler declHandler = base;
144      private LexicalHandler lexicalHandler = base;
145      private String                      elementName;    
146      private Stack                       entityStack;    private String elementName;
147      private Stack entityStack;
148      // one vector (of object/struct): faster, smaller    
149      private List                        attributesList;    // one vector (of object/struct): faster, smaller
150      private List attributesList;
151      private boolean                     namespaces = true;    
152      private boolean                     xmlNames = false;    private boolean namespaces = true;
153      private boolean                     extGE = true;    private boolean xmlNames = false;
154      private boolean                     extPE = true;    private boolean extGE = true;
155      private boolean                     resolveAll = true;    private boolean extPE = true;
156      private boolean                     useResolver2 = true;    private boolean resolveAll = true;
157      private boolean                     stringInterning = true;    private boolean useResolver2 = true;
158      
159      private int                         attributeCount;    // package private to allow (read-only) access in XmlParser
160      private boolean                     attributes;    boolean stringInterning = true;
161      private String                      nsTemp [];    
162      private NamespaceSupport            prefixStack;    private int attributeCount;
163      private boolean attributes;
164      //    private String[] nsTemp;
165      // Constructor.    private NamespaceSupport prefixStack;
166      //    
167      //
168      /** Constructs a SAX Parser.  */    // Constructor.
169      public SAXDriver ()    //
170      {  
171        reset ();    /**
172      }     * Constructs a SAX Parser.
173       */
174      private void reset ()    public SAXDriver()
175      {    {
176        elementName = null;      reset();
177        entityStack = new Stack ();    }
       attributesList = Collections.synchronizedList(new ArrayList());  
       attributeCount = 0;  
       attributes = false;  
       nsTemp = new String[3];  
       prefixStack = null;  
     }  
178    
179      private void reset()
180      {
181        elementName = null;
182        entityStack = new Stack();
183        attributesList = Collections.synchronizedList(new ArrayList());
184        attributeCount = 0;
185        attributes = false;
186        nsTemp = new String[3];
187        prefixStack = null;
188      }
189    
     //  
     // Implementation of org.xml.sax.Parser.  
     //  
190    
191      /**    //
192       * <b>SAX1</b>: Sets the locale used for diagnostics; currently,    // Implementation of org.xml.sax.Parser.
193       * only locales using the English language are supported.    //
194       * @param locale The locale for which diagnostics will be generated  
195       */    /**
196      public void setLocale (Locale locale)     * <b>SAX1</b>: Sets the locale used for diagnostics; currently,
197      throws SAXException     * only locales using the English language are supported.
198      {     * @param locale The locale for which diagnostics will be generated
199          if ("en".equals (locale.getLanguage ()))     */
200              return ;    public void setLocale(Locale locale)
201        throws SAXException
202          throw new SAXException ("AElfred2 only supports English locales.");    {
203      }      if ("en".equals(locale.getLanguage()))
204          {
205            return;
206          }
207        throw new SAXException ("AElfred2 only supports English locales.");
208      }
209    
210      /**
211       * <b>SAX2</b>: Returns the object used when resolving external
212       * entities during parsing (both general and parameter entities).
213       */
214      public EntityResolver getEntityResolver()
215      {
216        return (entityResolver == base) ? null : entityResolver;
217      }
218    
219      /**    /**
220       * <b>SAX2</b>: Returns the object used when resolving external     * <b>SAX1, SAX2</b>: Set the entity resolver for this parser.
221       * entities during parsing (both general and parameter entities).     * @param handler The object to receive entity events.
222       */     */
223      public EntityResolver getEntityResolver ()    public void setEntityResolver(EntityResolver resolver)
224      {    {
225          return (entityResolver == base) ? null : entityResolver;      if (resolver instanceof EntityResolver2)
226      }        {
227            resolver2 = (EntityResolver2) resolver;
228          }
229        else
230          {
231            resolver2 = null;
232          }
233        if (resolver == null)
234          {
235            resolver = base;
236          }
237        entityResolver = resolver;
238      }
239    
240      /**    /**
241       * <b>SAX1, SAX2</b>: Set the entity resolver for this parser.     * <b>SAX2</b>: Returns the object used to process declarations related
242       * @param handler The object to receive entity events.     * to notations and unparsed entities.
243       */     */
244      public void setEntityResolver (EntityResolver resolver)    public DTDHandler getDTDHandler()
245      {    {
246          if (resolver instanceof EntityResolver2)      return (dtdHandler == base) ? null : dtdHandler;
247              resolver2 = (EntityResolver2) resolver;    }
         else  
             resolver2 = null;  
         if (resolver == null)  
             resolver = base;  
         entityResolver = resolver;  
     }  
248    
249      /**
250       * <b>SAX1, SAX2</b>: Set the DTD handler for this parser.
251       * @param handler The object to receive DTD events.
252       */
253      public void setDTDHandler(DTDHandler handler)
254      {
255        if (handler == null)
256          {
257            handler = base;
258          }
259        this.dtdHandler = handler;
260      }
261    
     /**  
      * <b>SAX2</b>: Returns the object used to process declarations related  
      * to notations and unparsed entities.  
      */  
     public DTDHandler getDTDHandler ()  
     {  
         return (dtdHandler == base) ? null : dtdHandler;  
     }  
262    
263      /**    /**
264       * <b>SAX1, SAX2</b>: Set the DTD handler for this parser.     * <b>SAX1</b>: Set the document handler for this parser.  If a
265       * @param handler The object to receive DTD events.     * content handler was set, this document handler will supplant it.
266       */     * The parser is set to report all XML 1.0 names rather than to
267      public void setDTDHandler (DTDHandler handler)     * filter out "xmlns" attributes (the "namespace-prefixes" feature
268      {     * is set to true).
269          if (handler == null)     *
270              handler = base;     * @deprecated SAX2 programs should use the XMLReader interface
271          this.dtdHandler = handler;     *  and a ContentHandler.
272      }     *
273       * @param handler The object to receive document events.
274       */
275      public void setDocumentHandler(DocumentHandler handler)
276      {
277        contentHandler = new Adapter(handler);
278        xmlNames = true;
279      }
280    
281      /**
282       * <b>SAX2</b>: Returns the object used to report the logical
283       * content of an XML document.
284       */
285      public ContentHandler getContentHandler()
286      {
287        return (contentHandler == base) ? null : contentHandler;
288      }
289    
290      /**    /**
291       * <b>SAX1</b>: Set the document handler for this parser.  If a     * <b>SAX2</b>: Assigns the object used to report the logical
292       * content handler was set, this document handler will supplant it.     * content of an XML document.  If a document handler was set,
293       * The parser is set to report all XML 1.0 names rather than to     * this content handler will supplant it (but XML 1.0 style name
294       * filter out "xmlns" attributes (the "namespace-prefixes" feature     * reporting may remain enabled).
295       * is set to true).     */
296       *    public void setContentHandler(ContentHandler handler)
297       * @deprecated SAX2 programs should use the XMLReader interface    {
298       *  and a ContentHandler.      if (handler == null)
299       *        {
300       * @param handler The object to receive document events.          handler = base;
301       */        }
302      public void setDocumentHandler (DocumentHandler handler)      contentHandler = handler;
303      {    }
         contentHandler = new Adapter (handler);  
         xmlNames = true;  
     }  
304    
305      /**    /**
306       * <b>SAX2</b>: Returns the object used to report the logical     * <b>SAX1, SAX2</b>: Set the error handler for this parser.
307       * content of an XML document.     * @param handler The object to receive error events.
308       */     */
309      public ContentHandler getContentHandler ()    public void setErrorHandler(ErrorHandler handler)
310      {    {
311          return contentHandler == base ? null : contentHandler;      if (handler == null)
312      }        {
313            handler = base;
314          }
315        this.errorHandler = handler;
316      }
317    
318      /**    /**
319       * <b>SAX2</b>: Assigns the object used to report the logical     * <b>SAX2</b>: Returns the object used to receive callbacks for XML
320       * content of an XML document.  If a document handler was set,     * errors of all levels (fatal, nonfatal, warning); this is never null;
321       * this content handler will supplant it (but XML 1.0 style name     */
322       * reporting may remain enabled).    public ErrorHandler getErrorHandler()
323       */    {
324      public void setContentHandler (ContentHandler handler)      return (errorHandler == base) ? null : errorHandler;
325      {    }
         if (handler == null)  
             handler = base;  
         contentHandler = handler;  
     }  
326    
327      /**    /**
328       * <b>SAX1, SAX2</b>: Set the error handler for this parser.     * <b>SAX1, SAX2</b>: Auxiliary API to parse an XML document, used mostly
329       * @param handler The object to receive error events.     * when no URI is available.
330       */     * If you want anything useful to happen, you should set
331      public void setErrorHandler (ErrorHandler handler)     * at least one type of handler.
332      {     * @param source The XML input source.  Don't set 'encoding' unless
333          if (handler == null)     *  you know for a fact that it's correct.
334              handler = base;     * @see #setEntityResolver
335          this.errorHandler = handler;     * @see #setDTDHandler
336      }     * @see #setContentHandler
337       * @see #setErrorHandler
338       * @exception SAXException The handlers may throw any SAXException,
339       *  and the parser normally throws SAXParseException objects.
340       * @exception IOException IOExceptions are normally through through
341       *  the parser if there are problems reading the source document.
342       */
343      public void parse(InputSource source)
344        throws SAXException, IOException
345      {
346        synchronized (base)
347          {
348            parser = new XmlParser();
349            if (namespaces)
350              {
351                prefixStack = new NamespaceSupport();
352              }
353            else if (!xmlNames)
354              {
355                throw new IllegalStateException();
356              }
357            parser.setHandler(this);
358            
359            try
360              {
361                Reader r = source.getCharacterStream();
362                InputStream in = source.getByteStream();
363                            
364                parser.doParse(source.getSystemId(),
365                               source.getPublicId(),
366                               r,
367                               in,
368                               source.getEncoding());
369              }
370            catch (SAXException e)
371              {
372                throw e;
373              }
374            catch (IOException e)
375              {
376                throw e;
377              }
378            catch (RuntimeException e)
379              {
380                throw e;
381              }
382            catch (Exception e)
383              {
384                throw new SAXParseException(e.getMessage(), this, e);
385              }
386            finally
387              {
388                contentHandler.endDocument();
389                reset();
390              }
391          }
392      }
393    
394      /**    /**
395       * <b>SAX2</b>: Returns the object used to receive callbacks for XML     * <b>SAX1, SAX2</b>: Preferred API to parse an XML document, using a
396       * errors of all levels (fatal, nonfatal, warning); this is never null;     * system identifier (URI).
397       */     */
398      public ErrorHandler getErrorHandler ()    public void parse(String systemId)
399          { return errorHandler == base ? null : errorHandler; }      throws SAXException, IOException
400      {
401        parse(new InputSource(systemId));
402      }
403    
404      //
405      // Implementation of SAX2 "XMLReader" interface
406      //
407      static final String FEATURE = "http://xml.org/sax/features/";
408      static final String PROPERTY = "http://xml.org/sax/properties/";
409    
410      /**
411       * <b>SAX2</b>: Tells the value of the specified feature flag.
412       *
413       * @exception SAXNotRecognizedException thrown if the feature flag
414       *  is neither built in, nor yet assigned.
415       */
416      public boolean getFeature(String featureId)
417        throws SAXNotRecognizedException, SAXNotSupportedException
418      {
419        if ((FEATURE + "validation").equals(featureId))
420          {
421            return false;
422          }
423    
424      /**      // external entities (both types) are optionally included
425       * <b>SAX1, SAX2</b>: Auxiliary API to parse an XML document, used mostly      if ((FEATURE + "external-general-entities").equals(featureId))
426       * when no URI is available.        {
427       * If you want anything useful to happen, you should set          return extGE;
428       * at least one type of handler.        }
429       * @param source The XML input source.  Don't set 'encoding' unless      if ((FEATURE + "external-parameter-entities").equals(featureId))
430       *  you know for a fact that it's correct.        {
431       * @see #setEntityResolver          return extPE;
432       * @see #setDTDHandler        }
433       * @see #setContentHandler      
434       * @see #setErrorHandler      // element/attribute names are as written in document; no mangling
435       * @exception SAXException The handlers may throw any SAXException,      if ((FEATURE + "namespace-prefixes").equals(featureId))
436       *  and the parser normally throws SAXParseException objects.        {
437       * @exception IOException IOExceptions are normally through through          return xmlNames;
438       *  the parser if there are problems reading the source document.        }
      */  
     public void parse (InputSource source)  
     throws SAXException, IOException  
     {  
         synchronized (base) {  
             parser = new XmlParser ();  
             if (namespaces)  
                 prefixStack = new NamespaceSupport ();  
             else if (!xmlNames)  
                 throw new IllegalStateException ();  
             parser.setHandler (this);  
   
             try {  
   
               Reader r = source.getCharacterStream();  
               InputStream in = source.getByteStream();  
   
                 
                 parser.doParse (source.getSystemId (),  
                               source.getPublicId (),  
                               r,  
                               in,  
                               source.getEncoding ());  
             } catch (SAXException e) {  
                 throw e;  
             } catch (IOException e) {  
                 throw e;  
             } catch (RuntimeException e) {  
                 throw e;  
             } catch (Exception e) {  
                 throw new SAXParseException (e.getMessage (), this, e);  
             } finally {  
                 contentHandler.endDocument ();  
                 reset();  
             }  
         }  
     }  
439    
440        // report element/attribute namespaces?
441        if ((FEATURE + "namespaces").equals(featureId))
442          {
443            return namespaces;
444          }
445    
446      /**      // all PEs and GEs are reported
447       * <b>SAX1, SAX2</b>: Preferred API to parse an XML document, using a      if ((FEATURE + "lexical-handler/parameter-entities").equals(featureId))
448       * system identifier (URI).        {
449       */          return true;
450      public void parse (String systemId)        }
     throws SAXException, IOException  
     {  
         parse (new InputSource (systemId));  
     }  
451    
452      //      // default is true
453      // Implementation of SAX2 "XMLReader" interface      if ((FEATURE + "string-interning").equals(featureId))
454      //        {
455      static final String FEATURE = "http://xml.org/sax/features/";          return stringInterning;
456      static final String PROPERTY = "http://xml.org/sax/properties/";        }
457      
458        // EXTENSIONS 1.1
459        
460        // always returns isSpecified info
461        if ((FEATURE + "use-attributes2").equals(featureId))
462          {
463            return true;
464          }
465      
466        // meaningful between startDocument/endDocument
467        if ((FEATURE + "is-standalone").equals(featureId))
468          {
469            if (parser == null)
470              {
471                throw new SAXNotSupportedException(featureId);
472              }
473            return parser.isStandalone();
474          }
475    
476      /**      // optionally don't absolutize URIs in declarations
477       * <b>SAX2</b>: Tells the value of the specified feature flag.      if ((FEATURE + "resolve-dtd-uris").equals(featureId))
478       *        {
479       * @exception SAXNotRecognizedException thrown if the feature flag          return resolveAll;
480       *  is neither built in, nor yet assigned.        }
      */  
     public boolean getFeature (String featureId)  
     throws SAXNotRecognizedException, SAXNotSupportedException  
     {  
         if ((FEATURE + "validation").equals (featureId))  
             return false;  
481    
482          // external entities (both types) are optionally included      // optionally use resolver2 interface methods, if possible
483          if ((FEATURE + "external-general-entities").equals (featureId))      if ((FEATURE + "use-entity-resolver2").equals(featureId))
484              return extGE;        {
485          if ((FEATURE + "external-parameter-entities") .equals (featureId))          return useResolver2;
486              return extPE;        }
487      
488          // element/attribute names are as written in document; no mangling      throw new SAXNotRecognizedException(featureId);
489          if ((FEATURE + "namespace-prefixes").equals (featureId))    }
             return xmlNames;  
   
         // report element/attribute namespaces?  
         if ((FEATURE + "namespaces").equals (featureId))  
             return namespaces;  
   
         // all PEs and GEs are reported  
         if ((FEATURE + "lexical-handler/parameter-entities").equals (featureId))  
             return true;  
   
         // default is true  
         if ((FEATURE + "string-interning").equals (featureId))  
             return stringInterning;  
           
         // EXTENSIONS 1.1  
   
         // always returns isSpecified info  
         if ((FEATURE + "use-attributes2").equals (featureId))  
             return true;  
           
         // meaningful between startDocument/endDocument  
         if ((FEATURE + "is-standalone").equals (featureId)) {  
             if (parser == null)  
                 throw new SAXNotSupportedException (featureId);  
             return parser.isStandalone ();  
         }  
   
         // optionally don't absolutize URIs in declarations  
         if ((FEATURE + "resolve-dtd-uris").equals (featureId))  
             return resolveAll;  
   
         // optionally use resolver2 interface methods, if possible  
         if ((FEATURE + "use-entity-resolver2").equals (featureId))  
             return useResolver2;  
           
         throw new SAXNotRecognizedException (featureId);  
     }  
490    
491      // package private    // package private
492      DeclHandler getDeclHandler () { return declHandler; }    DeclHandler getDeclHandler()
493      {
494        return declHandler;
495      }
496    
497      // package private    // package private
498      boolean resolveURIs () { return resolveAll; }    boolean resolveURIs()
499      {
500        return resolveAll;
501      }
502    
503      /**    /**
504       * <b>SAX2</b>:  Returns the specified property.     * <b>SAX2</b>:  Returns the specified property.
505       *     *
506       * @exception SAXNotRecognizedException thrown if the property value     * @exception SAXNotRecognizedException thrown if the property value
507       *  is neither built in, nor yet stored.     *  is neither built in, nor yet stored.
508       */     */
509      public Object getProperty (String propertyId)    public Object getProperty(String propertyId)
510      throws SAXNotRecognizedException      throws SAXNotRecognizedException
511      {    {
512          if ((PROPERTY + "declaration-handler").equals (propertyId))      if ((PROPERTY + "declaration-handler").equals(propertyId))
513              return declHandler == base ? null : declHandler;        {
514            return (declHandler == base) ? null : declHandler;
515          }
516    
517          if ((PROPERTY + "lexical-handler").equals (propertyId))      if ((PROPERTY + "lexical-handler").equals(propertyId))
518              return lexicalHandler == base ? null : lexicalHandler;        {
519                    return (lexicalHandler == base) ? null : lexicalHandler;
520          // unknown properties        }
521          throw new SAXNotRecognizedException (propertyId);      
522      }      // unknown properties
523        throw new SAXNotRecognizedException(propertyId);
524      }
525    
526      /**    /**
527       * <b>SAX2</b>:  Sets the state of feature flags in this parser.  Some     * <b>SAX2</b>:  Sets the state of feature flags in this parser.  Some
528       * built-in feature flags are mutable.     * built-in feature flags are mutable.
529       */     */
530      public void setFeature (String featureId, boolean value)    public void setFeature(String featureId, boolean value)
531      throws SAXNotRecognizedException, SAXNotSupportedException      throws SAXNotRecognizedException, SAXNotSupportedException
532      {    {
533          boolean state;      boolean state;
534              
535          // Features with a defined value, we just change it if we can.      // Features with a defined value, we just change it if we can.
536          state = getFeature (featureId);      state = getFeature (featureId);
537        
538          if (state == value)      if (state == value)
539              return;        {
540          if (parser != null)          return;
541              throw new SAXNotSupportedException ("not while parsing");        }
542        if (parser != null)
543          if ((FEATURE + "namespace-prefixes").equals (featureId)) {        {
544              // in this implementation, this only affects xmlns reporting          throw new SAXNotSupportedException("not while parsing");
545              xmlNames = value;        }
             // forcibly prevent illegal parser state  
             if (!xmlNames)  
                 namespaces = true;  
             return;  
         }  
   
         if ((FEATURE + "namespaces").equals (featureId)) {  
             namespaces = value;  
             // forcibly prevent illegal parser state  
             if (!namespaces)  
                 xmlNames = true;  
             return;  
         }  
   
         if ((FEATURE + "external-general-entities").equals (featureId)) {  
             extGE = value;  
             return;  
         }  
         if ((FEATURE + "external-parameter-entities") .equals (featureId)) {  
             extPE = value;  
             return;  
         }  
         if ((FEATURE + "resolve-dtd-uris").equals (featureId)) {  
             resolveAll = value;  
             return;  
         }  
   
         if ((FEATURE + "use-entity-resolver2").equals (featureId)) {  
             useResolver2 = value;  
             return;  
         }  
   
         throw new SAXNotRecognizedException (featureId);  
     }  
546    
547      /**      if ((FEATURE + "namespace-prefixes").equals(featureId))
548       * <b>SAX2</b>:  Assigns the specified property.  Like SAX1 handlers,        {
549       * these may be changed at any time.          // in this implementation, this only affects xmlns reporting
550       */          xmlNames = value;
551      public void setProperty (String propertyId, Object value)          // forcibly prevent illegal parser state
552      throws SAXNotRecognizedException, SAXNotSupportedException          if (!xmlNames)
553      {            {
554          // see if the property is recognized              namespaces = true;
555          getProperty (propertyId);            }
556            return;
557          }
558    
559          // Properties with a defined value, we just change it if we can.      if ((FEATURE + "namespaces").equals(featureId))
560          {
561            namespaces = value;
562            // forcibly prevent illegal parser state
563            if (!namespaces)
564              {
565                xmlNames = true;
566              }
567            return;
568          }
569    
570          if ((PROPERTY + "declaration-handler").equals (propertyId)) {      if ((FEATURE + "external-general-entities").equals(featureId))
571              if (value == null)        {
572                  declHandler = base;          extGE = value;
573              else if (! (value instanceof DeclHandler))          return;
574                  throw new SAXNotSupportedException (propertyId);        }
575              else      if ((FEATURE + "external-parameter-entities").equals(featureId))
576                  declHandler = (DeclHandler) value;        {
577              return ;          extPE = value;
578          }          return;
579          }
580          if ((PROPERTY + "lexical-handler").equals (propertyId)) {      if ((FEATURE + "resolve-dtd-uris").equals(featureId))
581              if (value == null)        {
582                  lexicalHandler = base;          resolveAll = value;
583              else if (! (value instanceof LexicalHandler))          return;
584                  throw new SAXNotSupportedException (propertyId);        }
             else  
                 lexicalHandler = (LexicalHandler) value;  
             return ;  
         }  
585    
586          throw new SAXNotSupportedException (propertyId);      if ((FEATURE + "use-entity-resolver2").equals(featureId))
587      }        {
588            useResolver2 = value;
589            return;
590          }
591    
592        throw new SAXNotRecognizedException(featureId);
593      }
594    
595      //    /**
596      // This is where the driver receives XmlParser callbacks and translates     * <b>SAX2</b>:  Assigns the specified property.  Like SAX1 handlers,
597      // them into SAX callbacks.  Some more callbacks have been added for     * these may be changed at any time.
598      // SAX2 support.     */
599      //    public void setProperty(String propertyId, Object value)
600        throws SAXNotRecognizedException, SAXNotSupportedException
601      {
602        // see if the property is recognized
603        getProperty(propertyId);
604        
605        // Properties with a defined value, we just change it if we can.
606        
607        if ((PROPERTY + "declaration-handler").equals(propertyId))
608          {
609            if (value == null)
610              {
611                declHandler = base;
612              }
613            else if (!(value instanceof DeclHandler))
614              {
615                throw new SAXNotSupportedException(propertyId);
616              }
617            else
618              {
619                declHandler = (DeclHandler) value;
620              }
621            return ;
622          }
623        
624        if ((PROPERTY + "lexical-handler").equals(propertyId))
625          {
626            if (value == null)
627              {
628                lexicalHandler = base;
629              }
630            else if (!(value instanceof LexicalHandler))
631              {
632                throw new SAXNotSupportedException(propertyId);
633              }
634            else
635              {
636                lexicalHandler = (LexicalHandler) value;
637              }
638            return;
639          }
640        
641        throw new SAXNotSupportedException(propertyId);
642      }
643    
644      void startDocument ()    //
645      throws SAXException    // This is where the driver receives XmlParser callbacks and translates
646      {    // them into SAX callbacks.  Some more callbacks have been added for
647          contentHandler.setDocumentLocator (this);    // SAX2 support.
648          contentHandler.startDocument ();    //
649          attributesList.clear ();  
650      }    void startDocument()
651        throws SAXException
652      {
653        contentHandler.setDocumentLocator(this);
654        contentHandler.startDocument();
655        attributesList.clear();
656      }
657    
658      void xmlDecl(String version,    void xmlDecl(String version,
659                   String encoding,                 String encoding,
660                   boolean standalone,                 boolean standalone,
661                   String inputEncoding)                 String inputEncoding)
662        throws SAXException      throws SAXException
663      {    {
664        if (contentHandler instanceof ContentHandler2)      if (contentHandler instanceof ContentHandler2)
665          {        {
666            ((ContentHandler2) contentHandler).xmlDecl(version,          ((ContentHandler2) contentHandler).xmlDecl(version,
667                                                       encoding,                                                     encoding,
668                                                       standalone,                                                     standalone,
669                                                       inputEncoding);                                                     inputEncoding);
670          }        }
671      }    }
672    
673      void skippedEntity (String name)    void skippedEntity(String name)
674      throws SAXException      throws SAXException
675          { contentHandler.skippedEntity (name); }    {
676        contentHandler.skippedEntity(name);
677      }
678    
679      InputSource getExternalSubset (String name, String baseURI)    InputSource getExternalSubset(String name, String baseURI)
680      throws SAXException, IOException      throws SAXException, IOException
681      {    {
682          if (resolver2 == null || !useResolver2 || !extPE)      if (resolver2 == null || !useResolver2 || !extPE)
683              return null;        {
684          return resolver2.getExternalSubset (name, baseURI);          return null;
685      }        }
686        return resolver2.getExternalSubset(name, baseURI);
687      }
688    
689      InputSource resolveEntity (boolean isPE, String name,    InputSource resolveEntity(boolean isPE, String name,
690          InputSource in, String baseURI)                              InputSource in, String baseURI)
691      throws SAXException, IOException      throws SAXException, IOException
692      {    {
693          InputSource     source;      InputSource  source;
694        
695        // external entities might be skipped
696        if (isPE && !extPE)
697          {
698            return null;
699          }
700        if (!isPE && !extGE)
701          {
702            return null;
703          }
704    
705          // external entities might be skipped      // ... or not
706          if (isPE && !extPE)      lexicalHandler.startEntity(name);
707              return null;      if (resolver2 != null && useResolver2)
708          if (!isPE && !extGE)        {
709              return null;          source = resolver2.resolveEntity(name, in.getPublicId(),
710                                             baseURI, in.getSystemId());
711          // ... or not          if (source == null)
712          lexicalHandler.startEntity (name);            {
713          if (resolver2 != null && useResolver2) {              in.setSystemId(absolutize(baseURI,
714              source = resolver2.resolveEntity (name, in.getPublicId (),                                        in.getSystemId(), false));
715                          baseURI, in.getSystemId ());              source = in;
716              if (source == null) {            }
717                  in.setSystemId (absolutize (baseURI,        }
718                                  in.getSystemId (), false));      else
719                  source = in;        {
720              }          in.setSystemId(absolutize(baseURI, in.getSystemId(), false));
721          } else {          source = entityResolver.resolveEntity(in.getPublicId(),
722              in.setSystemId (absolutize (baseURI, in.getSystemId (), false));                                                in.getSystemId());
723              source = entityResolver.resolveEntity (in.getPublicId (),          if (source == null)
724                          in.getSystemId ());            {
725              if (source == null)              source = in;
726                  source = in;            }
727          }        }
728          startExternalEntity (name, source.getSystemId (), true);      startExternalEntity(name, source.getSystemId(), true);
729          return source;      return source;
730      }    }
731    
732      // absolutize a system ID relative to the specified base URI    // absolutize a system ID relative to the specified base URI
733      // (temporarily) package-visible for external entity decls    // (temporarily) package-visible for external entity decls
734      String absolutize (String baseURI, String systemId, boolean nice)    String absolutize(String baseURI, String systemId, boolean nice)
735      throws MalformedURLException, SAXException      throws MalformedURLException, SAXException
736      {    {
737          // FIXME normalize system IDs -- when?      // FIXME normalize system IDs -- when?
738          // - Convert to UTF-8      // - Convert to UTF-8
739          // - Map reserved and non-ASCII characters to %HH      // - Map reserved and non-ASCII characters to %HH
740        
741          try {      try
742              if (baseURI == null) {        {
743                  warn ("No base URI; hope this SYSTEM id is absolute: "          if (baseURI == null && XmlParser.uriWarnings)
744                          + systemId);            {
745                  return new URL (systemId).toString ();              warn ("No base URI; hope this SYSTEM id is absolute: "
746              } else                    + systemId);
747                  return new URL (new URL (baseURI), systemId).toString ();              return new URL(systemId).toString();
748              }
749          } catch (MalformedURLException e) {          else
750              {
751              // Let unknown URI schemes pass through unless we need              return new URL(new URL(baseURI), systemId).toString();
752              // the JVM to map them to i/o streams for us...            }
753              if (!nice)        }
754                  throw e;      catch (MalformedURLException e)
755          {
756              // sometimes sysids for notations or unparsed entities          // Let unknown URI schemes pass through unless we need
757              // aren't really URIs...          // the JVM to map them to i/o streams for us...
758              warn ("Can't absolutize SYSTEM id: " + e.getMessage ());          if (!nice)
759              return systemId;            {
760          }              throw e;
761      }            }
762            
763            // sometimes sysids for notations or unparsed entities
764            // aren't really URIs...
765            warn("Can't absolutize SYSTEM id: " + e.getMessage());
766            return systemId;
767          }
768      }
769    
770      void startExternalEntity (String name, String systemId,    void startExternalEntity(String name, String systemId, boolean stackOnly)
         boolean stackOnly)  
771      throws SAXException      throws SAXException
772      {    {
773          // The following warning was deleted because the application has the      // The following warning was deleted because the application has the
774          // option of not setting systemId. Sun's JAXP or Xerces seems to      // option of not setting systemId. Sun's JAXP or Xerces seems to
775          // ignore this case.      // ignore this case.
776          /*      /*
777          if (systemId == null)         if (systemId == null)
778              warn ("URI was not reported to parser for entity " + name);         warn ("URI was not reported to parser for entity " + name);
779          */       */
780          if (!stackOnly)         // spliced [dtd] needs startEntity      if (!stackOnly)  // spliced [dtd] needs startEntity
781              lexicalHandler.startEntity (name);        {
782          entityStack.push (systemId);          lexicalHandler.startEntity(name);
783      }        }
784        entityStack.push(systemId);
785      }
786    
787      void endExternalEntity (String name)    void endExternalEntity(String name)
788      throws SAXException      throws SAXException
789      {    {
790          if (!"[document]".equals (name))      if (!"[document]".equals(name))
791              lexicalHandler.endEntity (name);        {
792          entityStack.pop ();          lexicalHandler.endEntity(name);
793      }        }
794        entityStack.pop();
795      }
796    
797      void startInternalEntity (String name)    void startInternalEntity(String name)
798      throws SAXException      throws SAXException
799      {    {
800          lexicalHandler.startEntity (name);      lexicalHandler.startEntity(name);
801      }    }
802    
803      void endInternalEntity (String name)    void endInternalEntity(String name)
804      throws SAXException      throws SAXException
805      {    {
806          lexicalHandler.endEntity (name);      lexicalHandler.endEntity(name);
807      }    }
808    
809      void doctypeDecl (String name, String publicId, String systemId)    void doctypeDecl(String name, String publicId, String systemId)
810      throws SAXException      throws SAXException
811      {    {
812          lexicalHandler.startDTD (name, publicId, systemId);      lexicalHandler.startDTD(name, publicId, systemId);
813              
814          // ... the "name" is a declaration and should be given      // ... the "name" is a declaration and should be given
815          // to the DeclHandler (but sax2 doesn't).      // to the DeclHandler (but sax2 doesn't).
816        
817          // the IDs for the external subset are lexical details,      // the IDs for the external subset are lexical details,
818          // as are the contents of the internal subset; but sax2      // as are the contents of the internal subset; but sax2
819          // doesn't provide the internal subset "pre-parse"      // doesn't provide the internal subset "pre-parse"
820      }    }
821      
822      void notationDecl(String name, String publicId, String systemId,
823                        String baseUri)
824        throws SAXException
825      {
826        try
827          {
828            dtdHandler.notationDecl(name, publicId,
829                                    (resolveAll && systemId != null)
830                                    ? absolutize(baseUri, systemId, true)
831                                    : systemId);
832          }
833        catch (IOException e)
834          {
835            // "can't happen"
836            throw new SAXParseException(e.getMessage(), this, e);
837          }
838      }
839    
840      void notationDecl (String name, String ids [])    void unparsedEntityDecl(String name, String publicId, String systemId,
841                              String baseUri, String notation)
842      throws SAXException      throws SAXException
843      {    {
844          try {      try
845              dtdHandler.notationDecl (name, ids [0],        {
846                  (resolveAll && ids [1] != null)          dtdHandler.unparsedEntityDecl(name, publicId,
847                          ? absolutize (ids [2], ids [1], true)                                        resolveAll
848                          : ids [1]);                                        ? absolutize(baseUri, systemId, true)
849          } catch (IOException e) {                                        : systemId,
850              // "can't happen"                                        notation);
851              throw new SAXParseException (e.getMessage (), this, e);        }
852          }      catch (IOException e)
853      }        {
854            // "can't happen"
855            throw new SAXParseException(e.getMessage(), this, e);
856          }
857      }
858    
859      void unparsedEntityDecl (String name, String ids [], String notation)    void endDoctype()
860      throws SAXException      throws SAXException
861      {    {
862          try {      lexicalHandler.endDTD();
863              dtdHandler.unparsedEntityDecl (name, ids [0],    }
                     resolveAll  
                         ? absolutize (ids [2], ids [1], true)  
                         : ids [1],  
                     notation);  
         } catch (IOException e) {  
             // "can't happen"  
             throw new SAXParseException (e.getMessage (), this, e);  
         }  
     }  
864    
865      void endDoctype ()    private void declarePrefix(String prefix, String uri)
866      throws SAXException      throws SAXException
867      {    {
868          lexicalHandler.endDTD ();      int index = uri.indexOf(':');
     }  
869    
870      private void declarePrefix (String prefix, String uri)      // many versions of nwalsh docbook stylesheets
871      throws SAXException      // have bogus URLs; so this can't be an error...
872      {      if (index < 1 && uri.length() != 0)
873          int index = uri.indexOf (':');        {
874            warn("relative URI for namespace: " + uri);
875          }
876    
877          // many versions of nwalsh docbook stylesheets      // FIXME:  char [0] must be ascii alpha; chars [1..index]
878          // have bogus URLs; so this can't be an error...      // must be ascii alphanumeric or in "+-." [RFC 2396]
879          if (index < 1 && uri.length () != 0)      
880              warn ("relative URI for namespace: " + uri);      //Namespace Constraints
881        //name for xml prefix must be http://www.w3.org/XML/1998/namespace
882          // FIXME:  char [0] must be ascii alpha; chars [1..index]      boolean prefixEquality = prefix.equals("xml");
883          // must be ascii alphanumeric or in "+-." [RFC 2396]      boolean uriEquality = uri.equals("http://www.w3.org/XML/1998/namespace");
884                if ((prefixEquality || uriEquality) && !(prefixEquality && uriEquality))
885          //Namespace Constraints        {
886          //name for xml prefix must be http://www.w3.org/XML/1998/namespace          fatal("xml is by definition bound to the namespace name " +
887          boolean prefixEquality = prefix.equals("xml");                "http://www.w3.org/XML/1998/namespace");
888          boolean uriEquality = uri.equals("http://www.w3.org/XML/1998/namespace");        }
889          if ((prefixEquality || uriEquality) && !(prefixEquality && uriEquality))    
890             fatal ("xml is by definition bound to the namespace name " +      //xmlns prefix declaration is illegal but xml prefix declaration is llegal...
891                          "http://www.w3.org/XML/1998/namespace");      if (prefixEquality && uriEquality)
892                  {
893          //xmlns prefix declaration is illegal but xml prefix declaration is llegal...          return;
894          if (prefixEquality && uriEquality)        }
895             return;    
896                //name for xmlns prefix must be http://www.w3.org/2000/xmlns/
897          //name for xmlns prefix must be http://www.w3.org/2000/xmlns/      prefixEquality = prefix.equals("xmlns");
898          prefixEquality = prefix.equals("xmlns");      uriEquality = uri.equals("http://www.w3.org/2000/xmlns/");
899          uriEquality = uri.equals("http://www.w3.org/2000/xmlns/");      if ((prefixEquality || uriEquality) && !(prefixEquality && uriEquality))
900          if ((prefixEquality || uriEquality) && !(prefixEquality && uriEquality))        {
901             fatal("http://www.w3.org/2000/xmlns/ is by definition bound" +          fatal("http://www.w3.org/2000/xmlns/ is by definition bound" +
902                          " to prefix xmlns");                " to prefix xmlns");
903                  }
904          //even if the uri is http://www.w3.org/2000/xmlns/ it is illegal to declare it    
905          if (prefixEquality && uriEquality)      //even if the uri is http://www.w3.org/2000/xmlns/
906             fatal ("declaring the xmlns prefix is illegal");      // it is illegal to declare it
907                        if (prefixEquality && uriEquality)
908          uri = uri.intern ();        {
909          prefixStack.declarePrefix (prefix, uri);          fatal ("declaring the xmlns prefix is illegal");
910          contentHandler.startPrefixMapping (prefix, uri);        }
911      }    
912        uri = uri.intern();
913        prefixStack.declarePrefix(prefix, uri);
914        contentHandler.startPrefixMapping(prefix, uri);
915      }
916    
917      void attribute (String qname, String value, boolean isSpecified)    void attribute(String qname, String value, boolean isSpecified)
918      throws SAXException      throws SAXException
919      {    {
920          if (!attributes) {      if (!attributes)
921              attributes = true;        {
922              if (namespaces)          attributes = true;
923                  prefixStack.pushContext ();          if (namespaces)
924          }            {
925                prefixStack.pushContext();
926          // process namespace decls immediately;            }
         // then maybe forget this as an attribute  
         if (namespaces) {  
             int index;  
   
       // default NS declaration?  
       if (getFeature (FEATURE + "string-interning")) {  
         if ("xmlns" == qname) {  
           declarePrefix ("", value);  
           if (!xmlNames)  
             return;  
         }  
         // NS prefix declaration?  
         else if ((index = qname.indexOf (':')) == 5  
                  && qname.startsWith ("xmlns")) {  
           String                prefix = qname.substring (6);  
             
           if (prefix.equals(""))  
                 fatal ("missing prefix in namespace declaration attribute");      
           if (value.length () == 0) {  
             verror ("missing URI in namespace declaration attribute: "  
                     + qname);  
           } else  
             declarePrefix (prefix, value);  
           if (!xmlNames)  
             return;  
         }  
       } else {  
         if ("xmlns".equals(qname)) {  
           declarePrefix ("", value);  
           if (!xmlNames)  
             return;  
         }  
         // NS prefix declaration?  
         else if ((index = qname.indexOf (':')) == 5  
                  && qname.startsWith ("xmlns")) {  
           String                prefix = qname.substring (6);  
             
           if (value.length () == 0) {  
             verror ("missing URI in namespace decl attribute: "  
                     + qname);  
           } else  
             declarePrefix (prefix, value);  
           if (!xmlNames)  
             return;  
         }  
927        }        }
928        
929        // process namespace decls immediately;
930        // then maybe forget this as an attribute
931        if (namespaces)
932          {
933            int index;
934            
935            // default NS declaration?
936            if (stringInterning)
937              {
938                if ("xmlns" == qname)
939                  {
940                    declarePrefix("", value);
941                    if (!xmlNames)
942                      {
943                        return;
944                      }
945                  }
946                // NS prefix declaration?
947                else if ((index = qname.indexOf(':')) == 5
948                         && qname.startsWith("xmlns"))
949                  {
950                    String prefix = qname.substring(6);
951                  
952                    if (prefix.equals(""))
953                      {
954                        fatal("missing prefix " +
955                              "in namespace declaration attribute");  
956                      }
957                    if (value.length() == 0)
958                      {
959                        verror("missing URI in namespace declaration attribute: "
960                               + qname);
961                      }
962                    else
963                      {
964                        declarePrefix(prefix, value);
965                      }
966                    if (!xmlNames)
967                      {
968                        return;
969                      }
970                  }
971              }
972            else
973              {
974                if ("xmlns".equals(qname))
975                  {
976                    declarePrefix("", value);
977                    if (!xmlNames)
978                      {
979                        return;
980                      }
981                  }
982                // NS prefix declaration?
983                else if ((index = qname.indexOf(':')) == 5
984                         && qname.startsWith("xmlns"))
985                  {
986                    String prefix = qname.substring(6);
987                    
988                    if (value.length() == 0)
989                      {
990                        verror("missing URI in namespace decl attribute: "
991                               + qname);
992                      }
993                    else
994                      {
995                        declarePrefix(prefix, value);
996                      }
997                    if (!xmlNames)
998                      {
999                        return;
1000                      }
1001                  }
1002              }
1003          }
1004        // remember this attribute ...
1005        attributeCount++;
1006        
1007        // attribute type comes from querying parser's DTD records
1008        attributesList.add(new Attribute(qname, value, isSpecified));
1009        
1010    }    }
1011          // remember this attribute ...    
1012      void startElement(String elname)
         attributeCount++;  
           
         // attribute type comes from querying parser's DTD records  
         attributesList.add(new Attribute(qname, value, isSpecified));  
   
     }  
   
     void startElement (String elname)  
1013      throws SAXException      throws SAXException
1014      {    {
1015          ContentHandler handler = contentHandler;      ContentHandler handler = contentHandler;
   
         //  
         // NOTE:  this implementation of namespace support adds something  
         // like six percent to parsing CPU time, in a large (~50 MB)  
         // document that doesn't use namespaces at all.  (Measured by PC  
         // sampling, with a bug where endElement processing was omitted.)  
         // [Measurement referred to older implementation, older JVM ...]  
         //  
         // It ought to become notably faster in such cases.  Most  
         // costs are the prefix stack calling Hashtable.get() (2%),  
         // String.hashCode() (1.5%) and about 1.3% each for pushing  
         // the context, and two chunks of name processing.  
         //  
   
         if (!attributes) {  
             if (namespaces)  
                 prefixStack.pushContext ();  
         } else if (namespaces) {  
   
             // now we can patch up namespace refs; we saw all the  
             // declarations, so now we'll do the Right Thing  
             Iterator itt = attributesList.iterator ();  
             while(itt.hasNext())  
             {  
                 Attribute attribute = (Attribute) itt.next();  
                 String  qname = attribute.name;  
                 int     index;  
   
     // default NS declaration?  
     if (getFeature (FEATURE + "string-interning")) {  
       if ("xmlns" == qname)  
                     continue;  
     } else {  
       if ("xmlns".equals(qname))  
                     continue;  
     }  
                //Illegal in the new Namespaces Draft  
                //should it be only in 1.1 docs??  
                if (qname.equals (":"))  
                    fatal ("namespace names consisting of a single colon " +  
                                 "character are invalid");  
                 index = qname.indexOf (':');  
   
                 // NS prefix declaration?  
                 if (index == 5 && qname.startsWith ("xmlns"))  
                     continue;  
   
                 // it's not a NS decl; patch namespace info items  
                 if (prefixStack.processName (qname, nsTemp, true) == null)  
                     fatal ("undeclared attribute prefix in: " + qname);  
                 else {  
                     attribute.nameSpace = nsTemp[0];  
                     attribute.localName = nsTemp[1];  
                 }  
             }  
         }  
   
         // save element name so attribute callbacks work  
         elementName = elname;  
         if (namespaces) {  
             if (prefixStack.processName (elname, nsTemp, false) == null) {  
                 fatal ("undeclared element prefix in: " + elname);  
                 nsTemp [0] = nsTemp [1] = "";  
             }  
             handler.startElement (nsTemp [0], nsTemp [1], elname, this);  
         } else  
             handler.startElement ("", "", elname, this);  
         // elementName = null;  
   
         // elements with no attributes are pretty common!  
         if (attributes) {  
             attributesList.clear();  
             attributeCount = 0;  
             attributes = false;  
         }  
     }  
1016    
1017      void endElement (String elname)      //
1018        // NOTE:  this implementation of namespace support adds something
1019        // like six percent to parsing CPU time, in a large (~50 MB)
1020        // document that doesn't use namespaces at all.  (Measured by PC
1021        // sampling, with a bug where endElement processing was omitted.)
1022        // [Measurement referred to older implementation, older JVM ...]
1023        //
1024        // It ought to become notably faster in such cases.  Most
1025        // costs are the prefix stack calling Hashtable.get() (2%),
1026        // String.hashCode() (1.5%) and about 1.3% each for pushing
1027        // the context, and two chunks of name processing.
1028        //
1029        
1030        if (!attributes)
1031          {
1032            if (namespaces)
1033              {
1034                prefixStack.pushContext();
1035              }
1036          }
1037        else if (namespaces)
1038          {
1039          
1040            // now we can patch up namespace refs; we saw all the
1041            // declarations, so now we'll do the Right Thing
1042            Iterator itt = attributesList.iterator();
1043            while (itt.hasNext())
1044              {
1045                Attribute attribute = (Attribute) itt.next();
1046                String qname = attribute.name;
1047                int index;
1048                
1049                // default NS declaration?
1050                if (stringInterning)
1051                  {
1052                    if ("xmlns" == qname)
1053                      {
1054                        continue;
1055                      }
1056                  }
1057                else
1058                  {
1059                    if ("xmlns".equals(qname))
1060                      {
1061                        continue;
1062                      }
1063                  }
1064                //Illegal in the new Namespaces Draft
1065                //should it be only in 1.1 docs??
1066                if (qname.equals (":"))
1067                  {
1068                    fatal("namespace names consisting of a single colon " +
1069                          "character are invalid");
1070                  }
1071                index = qname.indexOf(':');
1072                
1073                // NS prefix declaration?
1074                if (index == 5 && qname.startsWith("xmlns"))
1075                  {
1076                    continue;
1077                  }
1078                
1079                // it's not a NS decl; patch namespace info items
1080                if (prefixStack.processName(qname, nsTemp, true) == null)
1081                  {
1082                    fatal("undeclared attribute prefix in: " + qname);
1083                  }
1084                else
1085                  {
1086                    attribute.nameSpace = nsTemp[0];
1087                    attribute.localName = nsTemp[1];
1088                  }
1089              }
1090          }
1091        
1092        // save element name so attribute callbacks work
1093        elementName = elname;
1094        if (namespaces)
1095          {
1096            if (prefixStack.processName(elname, nsTemp, false) == null)
1097              {
1098                fatal("undeclared element prefix in: " + elname);
1099                nsTemp[0] = nsTemp[1] = "";
1100              }
1101            handler.startElement(nsTemp[0], nsTemp[1], elname, this);
1102          }
1103        else
1104          {
1105            handler.startElement("", "", elname, this);
1106          }
1107        // elementName = null;
1108        
1109        // elements with no attributes are pretty common!
1110        if (attributes)
1111          {
1112            attributesList.clear();
1113            attributeCount = 0;
1114            attributes = false;
1115          }
1116      }
1117      
1118      void endElement(String elname)
1119      throws SAXException      throws SAXException
1120      {    {
1121          ContentHandler  handler = contentHandler;      ContentHandler handler = contentHandler;
1122    
1123          if (!namespaces) {      if (!namespaces)
1124              handler.endElement ("", "", elname);        {
1125              return;          handler.endElement("", "", elname);
1126          }          return;
1127          prefixStack.processName (elname, nsTemp, false);        }
1128          handler.endElement (nsTemp [0], nsTemp [1], elname);      prefixStack.processName(elname, nsTemp, false);
1129        handler.endElement(nsTemp[0], nsTemp[1], elname);
1130          Enumeration     prefixes = prefixStack.getDeclaredPrefixes ();      
1131        Enumeration prefixes = prefixStack.getDeclaredPrefixes();
1132          while (prefixes.hasMoreElements ())      
1133              handler.endPrefixMapping ((String) prefixes.nextElement ());      while (prefixes.hasMoreElements())
1134          prefixStack.popContext ();        {
1135      }          handler.endPrefixMapping((String) prefixes.nextElement());
1136          }
1137        prefixStack.popContext();
1138      }
1139    
1140      void startCDATA ()    void startCDATA()
1141      throws SAXException      throws SAXException
1142      {    {
1143          lexicalHandler.startCDATA ();      lexicalHandler.startCDATA();
1144      }    }
1145    
1146      void charData (char ch[], int start, int length)    void charData(char[] ch, int start, int length)
1147      throws SAXException      throws SAXException
1148      {    {
1149          contentHandler.characters (ch, start, length);      contentHandler.characters(ch, start, length);
1150      }    }
1151    
1152      void endCDATA ()    void endCDATA()
1153      throws SAXException      throws SAXException
1154      {    {
1155          lexicalHandler.endCDATA ();      lexicalHandler.endCDATA();
1156      }    }
1157    
1158      void ignorableWhitespace (char ch[], int start, int length)    void ignorableWhitespace(char[] ch, int start, int length)
1159      throws SAXException      throws SAXException
1160      {    {
1161          contentHandler.ignorableWhitespace (ch, start, length);      contentHandler.ignorableWhitespace(ch, start, length);
1162      }    }
1163    
1164      void processingInstruction (String target, String data)    void processingInstruction(String target, String data)
1165      throws SAXException      throws SAXException
1166      {    {
1167          contentHandler.processingInstruction (target, data);      contentHandler.processingInstruction(target, data);
1168      }    }
1169    
1170      void comment (char ch[], int start, int length)    void comment(char[] ch, int start, int length)
1171      throws SAXException      throws SAXException
1172      {    {
1173          if (lexicalHandler != base)      if (lexicalHandler != base)
1174              lexicalHandler.comment (ch, start, length);        {
1175      }          lexicalHandler.comment(ch, start, length);
1176          }
1177      }
1178    
1179      void fatal (String message)    void fatal(String message)
1180      throws SAXException      throws SAXException
1181      {    {
1182          SAXParseException fatal;      SAXParseException fatal;
1183              
1184          fatal = new SAXParseException (message, this);      fatal = new SAXParseException(message, this);
1185          errorHandler.fatalError (fatal);      errorHandler.fatalError(fatal);
1186    
1187          // Even if the application can continue ... we can't!      // Even if the application can continue ... we can't!
1188          throw fatal;      throw fatal;
1189      }    }
   
     // We can safely report a few validity errors that  
     // make layered SAX2 DTD validation more conformant  
     void verror (String message)  
     throws SAXException  
     {  
         SAXParseException err;  
           
         err = new SAXParseException (message, this);  
         errorHandler.error (err);  
     }  
1190    
1191      void warn (String message)    // We can safely report a few validity errors that
1192      // make layered SAX2 DTD validation more conformant
1193      void verror(String message)
1194        throws SAXException
1195      {
1196        SAXParseException err;
1197        
1198        err = new SAXParseException(message, this);
1199        errorHandler.error(err);
1200      }
1201      
1202      void warn(String message)
1203      throws SAXException      throws SAXException
1204      {    {
1205          SAXParseException err;      SAXParseException err;
1206              
1207          err = new SAXParseException (message, this);      err = new SAXParseException(message, this);
1208          errorHandler.warning (err);      errorHandler.warning(err);
1209      }    }
   
1210    
1211      //    //
1212      // Implementation of org.xml.sax.Attributes.    // Implementation of org.xml.sax.Attributes.
1213      //    //
1214    
1215      /**
1216       * <b>SAX1 AttributeList, SAX2 Attributes</b> method
1217       * (don't invoke on parser);
1218       */
1219      public int getLength()
1220      {
1221        return attributesList.size();
1222      }
1223    
1224      /**    /**
1225       * <b>SAX1 AttributeList, SAX2 Attributes</b> method     * <b>SAX2 Attributes</b> method (don't invoke on parser);
1226       * (don't invoke on parser);     */
1227       */    public String getURI(int index)
1228      public int getLength ()    {
1229      {      if (index < 0 || index >= attributesList.size())
1230          return attributesList.size();        {
1231      }          return null;
1232          }
1233        return ((Attribute) attributesList.get(index)).nameSpace;
1234      }
1235    
1236      /**    /**
1237       * <b>SAX2 Attributes</b> method (don't invoke on parser);     * <b>SAX2 Attributes</b> method (don't invoke on parser);
1238       */     */
1239      public String getURI (int index)    public String getLocalName(int index)
1240      {    {
1241          if (index < 0 || index >= attributesList.size())      if (index < 0 || index >= attributesList.size())
1242            {        {
1243              return null;          return null;
1244            }        }
1245          return ((Attribute) attributesList.get(index)).nameSpace;      Attribute attr = (Attribute) attributesList.get(index);
1246      }      // FIXME attr.localName is sometimes null, why?
1247        if (namespaces && attr.localName == null)
1248          {
1249            // XXX fix this here for now
1250            int ci = attr.name.indexOf(':');
1251            attr.localName = (ci == -1) ? attr.name :
1252              attr.name.substring(ci + 1);
1253          }
1254        return (attr.localName == null) ? "" : attr.localName;
1255      }
1256    
1257      /**    /**
1258       * <b>SAX2 Attributes</b> method (don't invoke on parser);     * <b>SAX2 Attributes</b> method (don't invoke on parser);
1259       */     */
1260      public String getLocalName (int index)    public String getQName(int index)
1261      {    {
1262          if (index < 0 || index >= attributesList.size())      if (index < 0 || index >= attributesList.size())
1263            {        {
1264              return null;        return null;
1265            }        }
1266          Attribute attr = (Attribute) attributesList.get(index);      Attribute attr = (Attribute) attributesList.get(index);
1267          // FIXME attr.localName is sometimes null, why?      return (attr.name == null) ? "" : attr.name;
1268          if (namespaces && attr.localName == null)    }
           {  
             // XXX fix this here for now  
             int ci = attr.name.indexOf(':');  
             attr.localName = (ci == -1) ? attr.name :  
               attr.name.substring(ci + 1);  
           }  
         return (attr.localName == null) ? "" : attr.localName;  
     }  
1269    
1270      /**    /**
1271       * <b>SAX2 Attributes</b> method (don't invoke on parser);     * <b>SAX1 AttributeList</b> method (don't invoke on parser);
1272       */     */
1273      public String getQName (int index)    public String getName(int index)
1274      {    {
1275          if (index < 0 || index >= attributesList.size())      return getQName(index);
1276            {    }
             return null;  
           }  
         Attribute attr = (Attribute) attributesList.get(index);  
         return (attr.name == null) ? "" : attr.name;  
     }  
1277    
1278      /**    /**
1279       * <b>SAX1 AttributeList</b> method (don't invoke on parser);     * <b>SAX1 AttributeList, SAX2 Attributes</b> method
1280       */     * (don't invoke on parser);
1281      public String getName (int index)     */
1282      {    public String getType(int index)
1283          return getQName(index);    {
1284      }      if (index < 0 || index >= attributesList.size())
1285          {
1286            return null;
1287          }
1288        String type = parser.getAttributeType(elementName, getQName(index));
1289        if (type == null)
1290          {
1291            return "CDATA";
1292          }
1293        // ... use DeclHandler.attributeDecl to see enumerations
1294        if (type == "ENUMERATION")
1295          {
1296            return "NMTOKEN";
1297          }
1298        return type;
1299      }
1300    
1301      /**    /**
1302       * <b>SAX1 AttributeList, SAX2 Attributes</b> method     * <b>SAX1 AttributeList, SAX2 Attributes</b> method
1303       * (don't invoke on parser);     * (don't invoke on parser);
1304       */     */
1305      public String getType (int index)    public String getValue(int index)
1306      {    {
1307          if (index < 0 || index >= attributesList.size())      if (index < 0 || index >= attributesList.size())
1308            {        {
1309              return null;          return null;
1310            }        }
1311          String  type = parser.getAttributeType(elementName, getQName(index));      return ((Attribute) attributesList.get(index)).value;
1312          if (type == null)    }
           {  
             return "CDATA";  
           }  
         // ... use DeclHandler.attributeDecl to see enumerations  
         if (type == "ENUMERATION")  
           {  
             return "NMTOKEN";  
           }  
         return type;  
     }  
1313    
1314      /**
1315       * <b>SAX2 Attributes</b> method (don't invoke on parser);
1316       */
1317      public int getIndex(String uri, String local)
1318        {
1319          int length = getLength();
1320          
1321          for (int i = 0; i < length; i++)
1322            {
1323              if (!getURI(i).equals(uri))
1324                {
1325                  continue;
1326                }
1327              if (getLocalName(i).equals(local))
1328                {
1329                  return i;
1330                }
1331            }
1332          return -1;
1333      }
1334    
1335      /**    /**
1336       * <b>SAX1 AttributeList, SAX2 Attributes</b> method     * <b>SAX2 Attributes</b> method (don't invoke on parser);
1337       * (don't invoke on parser);     */
1338       */    public int getIndex(String xmlName)
1339      public String getValue (int index)    {
1340      {      int length = getLength();
1341          if (index < 0 || index >= attributesList.size())      
1342        for (int i = 0; i < length; i++)
1343          {
1344            if (getQName(i).equals(xmlName))
1345            {            {
1346              return null;              return i;
1347            }            }
1348          return ((Attribute) attributesList.get(index)).value;        }
1349      }      return -1;
1350      }
1351    
1352      /**    /**
1353       * <b>SAX2 Attributes</b> method (don't invoke on parser);     * <b>SAX2 Attributes</b> method (don't invoke on parser);
1354       */     */
1355      public int getIndex (String uri, String local)    public String getType(String uri, String local)
1356      {    {
1357          int length = getLength();      int index = getIndex(uri, local);
1358        
1359        if (index < 0)
1360          {
1361            return null;
1362          }
1363        return getType(index);
1364      }
1365    
1366          for (int i = 0; i < length; i++)    /**
1367            {     * <b>SAX1 AttributeList, SAX2 Attributes</b> method
1368              if (!getURI(i).equals(uri))     * (don't invoke on parser);
1369                {     */
1370                  continue;    public String getType(String xmlName)
1371                }    {
1372              if (getLocalName(i).equals(local))      int index = getIndex(xmlName);
1373                {      
1374                  return i;      if (index < 0)
1375                }        {
1376            }          return null;
1377          return -1;        }
1378      }      return getType(index);
1379      }
1380    
1381      /**
1382       * <b>SAX Attributes</b> method (don't invoke on parser);
1383       */
1384      public String getValue(String uri, String local)
1385      {
1386        int index = getIndex(uri, local);
1387        
1388        if (index < 0)
1389          {
1390            return null;
1391          }
1392        return getValue(index);
1393      }
1394    
1395      /**    /**
1396       * <b>SAX2 Attributes</b> method (don't invoke on parser);     * <b>SAX1 AttributeList, SAX2 Attributes</b> method
1397       */     * (don't invoke on parser);
1398      public int getIndex (String xmlName)     */
1399      {    public String getValue(String xmlName)
1400          int length = getLength();    {
1401        int index = getIndex(xmlName);
1402        
1403        if (index < 0)
1404          {
1405            return null;
1406          }
1407        return getValue(index);
1408      }
1409    
1410          for (int i = 0; i < length; i++)    //
1411            {    // Implementation of org.xml.sax.ext.Attributes2
1412              if (getQName(i).equals(xmlName))    //
1413                {  
1414                  return i;    /** @return false unless the attribute was declared in the DTD.
1415                }     * @throws java.lang.ArrayIndexOutOfBoundsException
1416            }     *   When the supplied index does not identify an attribute.
1417          return -1;     */  
1418      }    public boolean isDeclared(int index)
1419      {
1420        if (index < 0 || index >= attributeCount)
1421          {
1422            throw new ArrayIndexOutOfBoundsException();
1423          }
1424        String type = parser.getAttributeType(elementName, getQName(index));
1425        return (type != null);
1426      }
1427    
1428      /** @return false unless the attribute was declared in the DTD.
1429       * @throws java.lang.IllegalArgumentException
1430       *   When the supplied names do not identify an attribute.
1431       */
1432      public boolean isDeclared(String qName)
1433      {
1434        int index = getIndex(qName);
1435        if (index < 0)
1436          {
1437            throw new IllegalArgumentException();
1438          }
1439        String type = parser.getAttributeType(elementName, qName);
1440        return (type != null);
1441      }
1442    
1443      /**    /** @return false unless the attribute was declared in the DTD.
1444       * <b>SAX2 Attributes</b> method (don't invoke on parser);     * @throws java.lang.IllegalArgumentException
1445       */     *   When the supplied names do not identify an attribute.
1446      public String getType (String uri, String local)     */
1447      {    public boolean isDeclared(String uri, String localName)
1448          int index = getIndex(uri, local);    {
1449        int index = getIndex(uri, localName);
1450        return isDeclared(index);
1451      }
1452    
1453          if (index < 0)    /**
1454            {     * <b>SAX-ext Attributes2</b> method (don't invoke on parser);
1455              return null;     */
1456            }    public boolean isSpecified(int index)
1457          return getType(index);    {
1458      }      return ((Attribute) attributesList.get(index)).specified;
1459      }
1460    
1461      /**
1462       * <b>SAX-ext Attributes2</b> method (don't invoke on parser);
1463       */
1464      public boolean isSpecified(String uri, String local)
1465      {
1466        int index = getIndex (uri, local);
1467        return isSpecified(index);
1468      }
1469    
1470      /**    /**
1471       * <b>SAX1 AttributeList, SAX2 Attributes</b> method     * <b>SAX-ext Attributes2</b> method (don't invoke on parser);
1472       * (don't invoke on parser);     */
1473       */    public boolean isSpecified(String xmlName)
1474      public String getType (String xmlName)    {
1475      {      int index = getIndex (xmlName);
1476          int index = getIndex(xmlName);      return isSpecified(index);
1477      }
1478    
1479          if (index < 0)    //
1480            {    // Implementation of org.xml.sax.Locator.
1481              return null;    //
1482            }  
1483          return getType(index);    /**
1484      }     * <b>SAX Locator</b> method (don't invoke on parser);
1485       */
1486      public String getPublicId()
1487      {
1488        return null;   // FIXME track public IDs too
1489      }
1490    
1491      /**
1492       * <b>SAX Locator</b> method (don't invoke on parser);
1493       */
1494      public String getSystemId()
1495      {
1496        if (entityStack.empty())
1497          {
1498            return null;
1499          }
1500        else
1501          {
1502            return (String) entityStack.peek();
1503          }
1504      }
1505    
1506      /**    /**
1507       * <b>SAX Attributes</b> method (don't invoke on parser);     * <b>SAX Locator</b> method (don't invoke on parser);
1508       */     */
1509      public String getValue (String uri, String local)    public int getLineNumber()
1510      {    {
1511          int index = getIndex(uri, local);      return parser.getLineNumber();
1512      }
1513    
1514          if (index < 0)    /**
1515            {     * <b>SAX Locator</b> method (don't invoke on parser);
1516              return null;     */
1517            }    public int getColumnNumber()
1518          return getValue(index);    {
1519      }      return parser.getColumnNumber();
1520      }
1521    
1522      // adapter between SAX2 content handler and SAX1 document handler callbacks
1523      private static class Adapter
1524        implements ContentHandler
1525      {
1526        
1527        private DocumentHandler docHandler;
1528    
1529      /**      Adapter(DocumentHandler dh)
      * <b>SAX1 AttributeList, SAX2 Attributes</b> method  
      * (don't invoke on parser);  
      */  
     public String getValue (String xmlName)  
1530      {      {
1531          int index = getIndex(xmlName);        docHandler = dh;
   
         if (index < 0)  
           {  
             return null;  
           }  
         return getValue(index);  
1532      }      }
1533    
1534        public void setDocumentLocator(Locator l)
     //  
     // Implementation of org.xml.sax.ext.Attributes2  
     //  
   
   
     /** @return false unless the attribute was declared in the DTD.  
      * @throws java.lang.ArrayIndexOutOfBoundsException  
      *   When the supplied index does not identify an attribute.  
      */      
     public boolean isDeclared (int index)  
1535      {      {
1536          if (index < 0 || index >= attributeCount)        docHandler.setDocumentLocator(l);
             throw new ArrayIndexOutOfBoundsException ();  
         String type = parser.getAttributeType(elementName, getQName(index));  
         return (type != null);  
1537      }      }
1538      
1539      /** @return false unless the attribute was declared in the DTD.      public void startDocument()
1540       * @throws java.lang.IllegalArgumentException        throws SAXException
      *   When the supplied names do not identify an attribute.  
      */  
     public boolean isDeclared (String qName)  
1541      {      {
1542          int index = getIndex (qName);        docHandler.startDocument();
         if (index < 0)  
             throw new IllegalArgumentException ();  
         String type = parser.getAttributeType(elementName, qName);  
         return (type != null);  
1543      }      }
1544      
1545      /** @return false unless the attribute was declared in the DTD.      public void processingInstruction(String target, String data)
1546       * @throws java.lang.IllegalArgumentException        throws SAXException
      *   When the supplied names do not identify an attribute.  
      */  
     public boolean isDeclared (String uri, String localName)  
1547      {      {
1548          int index = getIndex (uri, localName);        docHandler.processingInstruction(target, data);
         return isDeclared(index);  
1549      }      }
1550      
1551        public void startPrefixMapping(String prefix, String uri)
     /**  
      * <b>SAX-ext Attributes2</b> method (don't invoke on parser);  
      */  
     public boolean isSpecified (int index)  
1552      {      {
1553          return ((Attribute) attributesList.get(index)).specified;        /* ignored */
1554      }      }
1555    
1556      /**      public void startElement(String namespace,
1557       * <b>SAX-ext Attributes2</b> method (don't invoke on parser);                               String local,
1558       */                               String name,
1559      public boolean isSpecified (String uri, String local)                               Attributes attrs)
1560          throws SAXException
1561      {      {
1562          int index = getIndex (uri, local);        docHandler.startElement(name, (AttributeList) attrs);
         return isSpecified(index);  
1563      }      }
1564    
1565      /**      public void characters(char[] buf, int offset, int len)
1566       * <b>SAX-ext Attributes2</b> method (don't invoke on parser);        throws SAXException
      */  
     public boolean isSpecified (String xmlName)  
1567      {      {
1568          int index = getIndex (xmlName);        docHandler.characters(buf, offset, len);
         return isSpecified(index);  
1569      }      }
1570    
1571        public void ignorableWhitespace(char[] buf, int offset, int len)
1572      //        throws SAXException
     // Implementation of org.xml.sax.Locator.  
     //  
   
     /**  
      * <b>SAX Locator</b> method (don't invoke on parser);  
      */  
     public String getPublicId ()  
1573      {      {
1574          return null;            // FIXME track public IDs too        docHandler.ignorableWhitespace(buf, offset, len);
1575      }      }
1576    
1577      /**      public void skippedEntity(String name)
      * <b>SAX Locator</b> method (don't invoke on parser);  
      */  
     public String getSystemId ()  
1578      {      {
1579          if (entityStack.empty ())        /* ignored */
             return null;  
         else  
             return (String) entityStack.peek ();  
1580      }      }
1581    
1582      /**      public void endElement(String u, String l, String name)
1583       * <b>SAX Locator</b> method (don't invoke on parser);        throws SAXException
      */  
     public int getLineNumber ()  
1584      {      {
1585          return parser.getLineNumber ();        docHandler.endElement(name);
1586      }      }
1587    
1588      /**      public void endPrefixMapping(String prefix)
      * <b>SAX Locator</b> method (don't invoke on parser);  
      */  
     public int getColumnNumber ()  
1589      {      {
1590          return parser.getColumnNumber ();        /* ignored */
1591      }      }
1592    
1593      // adapter between SAX2 content handler and SAX1 document handler callbacks      public void endDocument()
1594      private static class Adapter implements ContentHandler        throws SAXException
1595      {      {
1596          private DocumentHandler         docHandler;        docHandler.endDocument();
   
         Adapter (DocumentHandler dh)  
             { docHandler = dh; }  
   
   
         public void setDocumentLocator (Locator l)  
             { docHandler.setDocumentLocator (l); }  
           
         public void startDocument () throws SAXException  
             { docHandler.startDocument (); }  
           
         public void processingInstruction (String target, String data)  
         throws SAXException  
             { docHandler.processingInstruction (target, data); }  
           
         public void startPrefixMapping (String prefix, String uri)  
             { /* ignored */ }  
   
         public void startElement (  
             String      namespace,  
             String      local,  
             String      name,  
             Attributes  attrs  
         ) throws SAXException  
             { docHandler.startElement (name, (AttributeList) attrs); }  
   
         public void characters (char buf [], int offset, int len)  
         throws SAXException  
             { docHandler.characters (buf, offset, len); }  
   
         public void ignorableWhitespace (char buf [], int offset, int len)  
         throws SAXException  
             { docHandler.ignorableWhitespace (buf, offset, len); }  
   
         public void skippedEntity (String name)  
             { /* ignored */ }  
   
         public void endElement (String u, String l, String name)  
         throws SAXException  
             { docHandler.endElement (name); }  
   
         public void endPrefixMapping (String prefix)  
             { /* ignored */ }  
   
         public void endDocument () throws SAXException  
             { docHandler.endDocument (); }  
1597      }      }
1598  }    }
   
 class Attribute  
 {  
1599    
1600      private static class Attribute
1601      {
1602        
1603      String name;      String name;
1604      String value;      String value;
1605      String nameSpace;      String nameSpace;
1606      String localName;      String localName;
1607      boolean specified;      boolean specified;
1608        
1609      Attribute(String name, String value, boolean specified)      Attribute(String name, String value, boolean specified)
1610      {      {
1611          this.name = name;        this.name = name;
1612          this.value = value;        this.value = value;
1613          this.nameSpace = "";        this.nameSpace = "";
1614          this.specified = specified;        this.specified = specified;
1615      }      }
1616  }      
1617      }
1618    
1619    }

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26