OSDN Git Service

PR target/19680
[pf3gnuchains/gcc-fork.git] / libjava / org / xml / sax / helpers / ParserAdapter.java
1 // ParserAdapter.java - adapt a SAX1 Parser to a SAX2 XMLReader.
2 // http://www.saxproject.org
3 // Written by David Megginson
4 // NO WARRANTY!  This class is in the public domain.
5
6 // $Id: ParserAdapter.java,v 1.8.2.4 2002/01/29 21:34:14 dbrownell Exp $
7
8 package org.xml.sax.helpers;
9
10 import java.io.IOException;
11 import java.util.Enumeration;
12 import java.util.Vector;
13
14 import org.xml.sax.Parser;      // deprecated
15 import org.xml.sax.InputSource;
16 import org.xml.sax.Locator;
17 import org.xml.sax.AttributeList; // deprecated
18 import org.xml.sax.EntityResolver;
19 import org.xml.sax.DTDHandler;
20 import org.xml.sax.DocumentHandler; // deprecated
21 import org.xml.sax.ErrorHandler;
22 import org.xml.sax.SAXException;
23 import org.xml.sax.SAXParseException;
24
25 import org.xml.sax.XMLReader;
26 import org.xml.sax.Attributes;
27 import org.xml.sax.ContentHandler;
28 import org.xml.sax.SAXNotRecognizedException;
29 import org.xml.sax.SAXNotSupportedException;
30
31
32 /**
33  * Adapt a SAX1 Parser as a SAX2 XMLReader.
34  *
35  * <blockquote>
36  * <em>This module, both source code and documentation, is in the
37  * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
38  * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
39  * for further information.
40  * </blockquote>
41  *
42  * <p>This class wraps a SAX1 {@link org.xml.sax.Parser Parser}
43  * and makes it act as a SAX2 {@link org.xml.sax.XMLReader XMLReader},
44  * with feature, property, and Namespace support.  Note
45  * that it is not possible to report {@link org.xml.sax.ContentHandler#skippedEntity
46  * skippedEntity} events, since SAX1 does not make that information available.</p>
47  *
48  * <p>This adapter does not test for duplicate Namespace-qualified
49  * attribute names.</p>
50  *
51  * @since SAX 2.0
52  * @author David Megginson
53  * @version 2.0.1 (sax2r2)
54  * @see org.xml.sax.helpers.XMLReaderAdapter
55  * @see org.xml.sax.XMLReader
56  * @see org.xml.sax.Parser
57  */
58 public class ParserAdapter implements XMLReader, DocumentHandler
59 {
60
61 \f
62     ////////////////////////////////////////////////////////////////////
63     // Constructors.
64     ////////////////////////////////////////////////////////////////////
65
66
67     /**
68      * Construct a new parser adapter.
69      *
70      * <p>Use the "org.xml.sax.parser" property to locate the
71      * embedded SAX1 driver.</p>
72      *
73      * @exception SAXException If the embedded driver
74      *            cannot be instantiated or if the
75      *            org.xml.sax.parser property is not specified.
76      */
77     public ParserAdapter ()
78       throws SAXException
79     {
80         super();
81
82         String driver = System.getProperty("org.xml.sax.parser");
83
84         try {
85             setup(ParserFactory.makeParser());
86         } catch (ClassNotFoundException e1) {
87             throw new
88                 SAXException("Cannot find SAX1 driver class " +
89                              driver, e1);
90         } catch (IllegalAccessException e2) {
91             throw new
92                 SAXException("SAX1 driver class " +
93                              driver +
94                              " found but cannot be loaded", e2);
95         } catch (InstantiationException e3) {
96             throw new
97                 SAXException("SAX1 driver class " +
98                              driver +
99                              " loaded but cannot be instantiated", e3);
100         } catch (ClassCastException e4) {
101             throw new
102                 SAXException("SAX1 driver class " +
103                              driver +
104                              " does not implement org.xml.sax.Parser");
105         } catch (NullPointerException e5) {
106             throw new 
107                 SAXException("System property org.xml.sax.parser not specified");
108         }
109     }
110
111
112     /**
113      * Construct a new parser adapter.
114      *
115      * <p>Note that the embedded parser cannot be changed once the
116      * adapter is created; to embed a different parser, allocate
117      * a new ParserAdapter.</p>
118      *
119      * @param parser The SAX1 parser to embed.
120      * @exception java.lang.NullPointerException If the parser parameter
121      *            is null.
122      */
123     public ParserAdapter (Parser parser)
124     {
125         super();
126         setup(parser);
127     }
128
129
130     /**
131      * Internal setup method.
132      *
133      * @param parser The embedded parser.
134      * @exception java.lang.NullPointerException If the parser parameter
135      *            is null.
136      */
137     private void setup (Parser parser)
138     {
139         if (parser == null) {
140             throw new
141                 NullPointerException("Parser argument must not be null");
142         }
143         this.parser = parser;
144         atts = new AttributesImpl();
145         nsSupport = new NamespaceSupport();
146         attAdapter = new AttributeListAdapter();
147     }
148
149
150 \f
151     ////////////////////////////////////////////////////////////////////
152     // Implementation of org.xml.sax.XMLReader.
153     ////////////////////////////////////////////////////////////////////
154
155
156     //
157     // Internal constants for the sake of convenience.
158     //
159     private final static String FEATURES = "http://xml.org/sax/features/";
160     private final static String NAMESPACES = FEATURES + "namespaces";
161     private final static String NAMESPACE_PREFIXES = FEATURES + "namespace-prefixes";
162
163
164     /**
165      * Set a feature flag for the parser.
166      *
167      * <p>The only features recognized are namespaces and 
168      * namespace-prefixes.</p>
169      *
170      * @param name The feature name, as a complete URI.
171      * @param value The requested feature value.
172      * @exception SAXNotRecognizedException If the feature
173      *            can't be assigned or retrieved.
174      * @exception SAXNotSupportedException If the feature
175      *            can't be assigned that value.
176      * @see org.xml.sax.XMLReader#setFeature
177      */
178     public void setFeature (String name, boolean value)
179         throws SAXNotRecognizedException, SAXNotSupportedException
180     {
181         if (name.equals(NAMESPACES)) {
182             checkNotParsing("feature", name);
183             namespaces = value;
184             if (!namespaces && !prefixes) {
185                 prefixes = true;
186             }
187         } else if (name.equals(NAMESPACE_PREFIXES)) {
188             checkNotParsing("feature", name);
189             prefixes = value;
190             if (!prefixes && !namespaces) {
191                 namespaces = true;
192             }
193         } else {
194             throw new SAXNotRecognizedException("Feature: " + name);
195         }
196     }
197
198
199     /**
200      * Check a parser feature flag.
201      *
202      * <p>The only features recognized are namespaces and 
203      * namespace-prefixes.</p>
204      *
205      * @param name The feature name, as a complete URI.
206      * @return The current feature value.
207      * @exception SAXNotRecognizedException If the feature
208      *            value can't be assigned or retrieved.
209      * @exception SAXNotSupportedException If the
210      *            feature is not currently readable.
211      * @see org.xml.sax.XMLReader#setFeature
212      */
213     public boolean getFeature (String name)
214         throws SAXNotRecognizedException, SAXNotSupportedException
215     {
216         if (name.equals(NAMESPACES)) {
217             return namespaces;
218         } else if (name.equals(NAMESPACE_PREFIXES)) {
219             return prefixes;
220         } else {
221             throw new SAXNotRecognizedException("Feature: " + name);
222         }
223     }
224
225
226     /**
227      * Set a parser property.
228      *
229      * <p>No properties are currently recognized.</p>
230      *
231      * @param name The property name.
232      * @param value The property value.
233      * @exception SAXNotRecognizedException If the property
234      *            value can't be assigned or retrieved.
235      * @exception SAXNotSupportedException If the property
236      *            can't be assigned that value.
237      * @see org.xml.sax.XMLReader#setProperty
238      */
239     public void setProperty (String name, Object value)
240         throws SAXNotRecognizedException, SAXNotSupportedException
241     {
242         throw new SAXNotRecognizedException("Property: " + name);
243     }
244
245
246     /**
247      * Get a parser property.
248      *
249      * <p>No properties are currently recognized.</p>
250      *
251      * @param name The property name.
252      * @return The property value.
253      * @exception SAXNotRecognizedException If the property
254      *            value can't be assigned or retrieved.
255      * @exception SAXNotSupportedException If the property
256      *            value is not currently readable.
257      * @see org.xml.sax.XMLReader#getProperty
258      */
259     public Object getProperty (String name)
260         throws SAXNotRecognizedException, SAXNotSupportedException
261     {
262         throw new SAXNotRecognizedException("Property: " + name);
263     }
264
265
266     /**
267      * Set the entity resolver.
268      *
269      * @param resolver The new entity resolver.
270      * @see org.xml.sax.XMLReader#setEntityResolver
271      */
272     public void setEntityResolver (EntityResolver resolver)
273     {
274         entityResolver = resolver;
275     }
276
277
278     /**
279      * Return the current entity resolver.
280      *
281      * @return The current entity resolver, or null if none was supplied.
282      * @see org.xml.sax.XMLReader#getEntityResolver
283      */
284     public EntityResolver getEntityResolver ()
285     {
286         return entityResolver;
287     }
288
289
290     /**
291      * Set the DTD handler.
292      *
293      * @param resolver The new DTD handler.
294      * @see org.xml.sax.XMLReader#setEntityResolver
295      */
296     public void setDTDHandler (DTDHandler handler)
297     {
298         dtdHandler = handler;
299     }
300
301
302     /**
303      * Return the current DTD handler.
304      *
305      * @return The current DTD handler, or null if none was supplied.
306      * @see org.xml.sax.XMLReader#getEntityResolver
307      */
308     public DTDHandler getDTDHandler ()
309     {
310         return dtdHandler;
311     }
312
313
314     /**
315      * Set the content handler.
316      *
317      * @param resolver The new content handler.
318      * @see org.xml.sax.XMLReader#setEntityResolver
319      */
320     public void setContentHandler (ContentHandler handler)
321     {
322         contentHandler = handler;
323     }
324
325
326     /**
327      * Return the current content handler.
328      *
329      * @return The current content handler, or null if none was supplied.
330      * @see org.xml.sax.XMLReader#getEntityResolver
331      */
332     public ContentHandler getContentHandler ()
333     {
334         return contentHandler;
335     }
336
337
338     /**
339      * Set the error handler.
340      *
341      * @param resolver The new error handler.
342      * @see org.xml.sax.XMLReader#setEntityResolver
343      */
344     public void setErrorHandler (ErrorHandler handler)
345     {
346         errorHandler = handler;
347     }
348
349
350     /**
351      * Return the current error handler.
352      *
353      * @return The current error handler, or null if none was supplied.
354      * @see org.xml.sax.XMLReader#getEntityResolver
355      */
356     public ErrorHandler getErrorHandler ()
357     {
358         return errorHandler;
359     }
360
361
362     /**
363      * Parse an XML document.
364      *
365      * @param systemId The absolute URL of the document.
366      * @exception java.io.IOException If there is a problem reading
367      *            the raw content of the document.
368      * @exception SAXException If there is a problem
369      *            processing the document.
370      * @see #parse(org.xml.sax.InputSource)
371      * @see org.xml.sax.Parser#parse(java.lang.String)
372      */
373     public void parse (String systemId)
374         throws IOException, SAXException
375     {
376         parse(new InputSource(systemId));
377     }
378
379
380     /**
381      * Parse an XML document.
382      *
383      * @param input An input source for the document.
384      * @exception java.io.IOException If there is a problem reading
385      *            the raw content of the document.
386      * @exception SAXException If there is a problem
387      *            processing the document.
388      * @see #parse(java.lang.String)
389      * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
390      */
391     public void parse (InputSource input)
392         throws IOException, SAXException
393     {
394         if (parsing) {
395             throw new SAXException("Parser is already in use");
396         }
397         setupParser();
398         parsing = true;
399         try {
400             parser.parse(input);
401         } finally {
402             parsing = false;
403         }
404         parsing = false;
405     }
406
407
408 \f
409     ////////////////////////////////////////////////////////////////////
410     // Implementation of org.xml.sax.DocumentHandler.
411     ////////////////////////////////////////////////////////////////////
412
413
414     /**
415      * Adapter implementation method; do not call.
416      * Adapt a SAX1 document locator event.
417      *
418      * @param locator A document locator.
419      * @see org.xml.sax.ContentHandler#setDocumentLocator
420      */
421     public void setDocumentLocator (Locator locator)
422     {
423         this.locator = locator;
424         if (contentHandler != null) {
425             contentHandler.setDocumentLocator(locator);
426         }
427     }
428
429
430     /**
431      * Adapter implementation method; do not call.
432      * Adapt a SAX1 start document event.
433      *
434      * @exception SAXException The client may raise a
435      *            processing exception.
436      * @see org.xml.sax.DocumentHandler#startDocument
437      */
438     public void startDocument ()
439         throws SAXException
440     {
441         if (contentHandler != null) {
442             contentHandler.startDocument();
443         }
444     }
445
446
447     /**
448      * Adapter implementation method; do not call.
449      * Adapt a SAX1 end document event.
450      *
451      * @exception SAXException The client may raise a
452      *            processing exception.
453      * @see org.xml.sax.DocumentHandler#endDocument
454      */
455     public void endDocument ()
456         throws SAXException
457     {
458         if (contentHandler != null) {
459             contentHandler.endDocument();
460         }
461     }
462
463
464     /**
465      * Adapter implementation method; do not call.
466      * Adapt a SAX1 startElement event.
467      *
468      * <p>If necessary, perform Namespace processing.</p>
469      *
470      * @param qName The qualified (prefixed) name.
471      * @param qAtts The XML 1.0 attribute list (with qnames).
472      * @exception SAXException The client may raise a
473      *            processing exception.
474      */
475     public void startElement (String qName, AttributeList qAtts)
476         throws SAXException
477     {
478                                 // These are exceptions from the
479                                 // first pass; they should be
480                                 // ignored if there's a second pass,
481                                 // but reported otherwise.
482         Vector exceptions = null;
483
484                                 // If we're not doing Namespace
485                                 // processing, dispatch this quickly.
486         if (!namespaces) {
487             if (contentHandler != null) {
488                 attAdapter.setAttributeList(qAtts);
489                 contentHandler.startElement("", "", qName.intern(),
490                                             attAdapter);
491             }
492             return;
493         }
494
495
496                                 // OK, we're doing Namespace processing.
497         nsSupport.pushContext();
498         int length = qAtts.getLength();
499         
500                                 // First pass:  handle NS decls
501         for (int i = 0; i < length; i++) {
502             String attQName = qAtts.getName(i);
503
504             if (!attQName.startsWith("xmlns"))
505                 continue;
506                                 // Could be a declaration...
507             String prefix;
508             int n = attQName.indexOf(':');
509
510                                 // xmlns=...
511             if (n == -1 && attQName.length () == 5) {
512                 prefix = "";
513             } else if (n != 5) {
514                 // XML namespaces spec doesn't discuss "xmlnsf:oo"
515                 // (and similarly named) attributes ... at most, warn
516                 continue;
517             } else              // xmlns:foo=...
518                 prefix = attQName.substring(n+1);
519
520             String value = qAtts.getValue(i);
521             if (!nsSupport.declarePrefix(prefix, value)) {
522                 reportError("Illegal Namespace prefix: " + prefix);
523                 continue;
524             }
525             if (contentHandler != null)
526                 contentHandler.startPrefixMapping(prefix, value);
527         }
528         
529                                 // Second pass: copy all relevant
530                                 // attributes into the SAX2 AttributeList
531                                 // using updated prefix bindings
532         atts.clear();
533         for (int i = 0; i < length; i++) {
534             String attQName = qAtts.getName(i);
535             String type = qAtts.getType(i);
536             String value = qAtts.getValue(i);
537
538                                 // Declaration?
539             if (attQName.startsWith("xmlns")) {
540                 String prefix;
541                 int n = attQName.indexOf(':');
542
543                 if (n == -1 && attQName.length () == 5) {
544                     prefix = "";
545                 } else if (n != 5) {
546                     // XML namespaces spec doesn't discuss "xmlnsf:oo"
547                     // (and similarly named) attributes ... ignore
548                     prefix = null;
549                 } else {
550                     prefix = attQName.substring(n+1);
551                 }
552                                 // Yes, decl:  report or prune
553                 if (prefix != null) {
554                     if (prefixes)
555                         atts.addAttribute("", "", attQName.intern(),
556                                       type, value);
557                     continue;
558                 }
559             } 
560
561                                 // Not a declaration -- report
562             try {
563                 String attName[] = processName(attQName, true, true);
564                 atts.addAttribute(attName[0], attName[1], attName[2],
565                                   type, value);
566             } catch (SAXException e) {
567                 if (exceptions == null)
568                     exceptions = new Vector();
569                 exceptions.addElement(e);
570                 atts.addAttribute("", attQName, attQName, type, value);
571             }
572         }
573         
574         // now handle the deferred exception reports
575         if (exceptions != null && errorHandler != null) {
576             for (int i = 0; i < exceptions.size(); i++)
577                 errorHandler.error((SAXParseException)
578                                 (exceptions.elementAt(i)));
579         }
580
581                                 // OK, finally report the event.
582         if (contentHandler != null) {
583             String name[] = processName(qName, false, false);
584             contentHandler.startElement(name[0], name[1], name[2], atts);
585         }
586     }
587
588
589     /**
590      * Adapter implementation method; do not call.
591      * Adapt a SAX1 end element event.
592      *
593      * @param qName The qualified (prefixed) name.
594      * @exception SAXException The client may raise a
595      *            processing exception.
596      * @see org.xml.sax.DocumentHandler#endElement
597      */
598     public void endElement (String qName)
599         throws SAXException
600     {
601                                 // If we're not doing Namespace
602                                 // processing, dispatch this quickly.
603         if (!namespaces) {
604             if (contentHandler != null) {
605                 contentHandler.endElement("", "", qName.intern());
606             }
607             return;
608         }
609
610                                 // Split the name.
611         String names[] = processName(qName, false, false);
612         if (contentHandler != null) {
613             contentHandler.endElement(names[0], names[1], names[2]);
614             Enumeration prefixes = nsSupport.getDeclaredPrefixes();
615             while (prefixes.hasMoreElements()) {
616                 String prefix = (String)prefixes.nextElement();
617                 contentHandler.endPrefixMapping(prefix);
618             }
619         }
620         nsSupport.popContext();
621     }
622
623
624     /**
625      * Adapter implementation method; do not call.
626      * Adapt a SAX1 characters event.
627      *
628      * @param ch An array of characters.
629      * @param start The starting position in the array.
630      * @param length The number of characters to use.
631      * @exception SAXException The client may raise a
632      *            processing exception.
633      * @see org.xml.sax.DocumentHandler#characters
634      */
635     public void characters (char ch[], int start, int length)
636         throws SAXException
637     {
638         if (contentHandler != null) {
639             contentHandler.characters(ch, start, length);
640         }
641     }
642
643
644     /**
645      * Adapter implementation method; do not call.
646      * Adapt a SAX1 ignorable whitespace event.
647      *
648      * @param ch An array of characters.
649      * @param start The starting position in the array.
650      * @param length The number of characters to use.
651      * @exception SAXException The client may raise a
652      *            processing exception.
653      * @see org.xml.sax.DocumentHandler#ignorableWhitespace
654      */
655     public void ignorableWhitespace (char ch[], int start, int length)
656         throws SAXException
657     {
658         if (contentHandler != null) {
659             contentHandler.ignorableWhitespace(ch, start, length);
660         }
661     }
662
663
664     /**
665      * Adapter implementation method; do not call.
666      * Adapt a SAX1 processing instruction event.
667      *
668      * @param target The processing instruction target.
669      * @param data The remainder of the processing instruction
670      * @exception SAXException The client may raise a
671      *            processing exception.
672      * @see org.xml.sax.DocumentHandler#processingInstruction
673      */
674     public void processingInstruction (String target, String data)
675         throws SAXException
676     {
677         if (contentHandler != null) {
678             contentHandler.processingInstruction(target, data);
679         }
680     }
681
682
683 \f
684     ////////////////////////////////////////////////////////////////////
685     // Internal utility methods.
686     ////////////////////////////////////////////////////////////////////
687
688
689     /**
690      * Initialize the parser before each run.
691      */
692     private void setupParser ()
693     {
694         nsSupport.reset();
695
696         if (entityResolver != null) {
697             parser.setEntityResolver(entityResolver);
698         }
699         if (dtdHandler != null) {
700             parser.setDTDHandler(dtdHandler);
701         }
702         if (errorHandler != null) {
703             parser.setErrorHandler(errorHandler);
704         }
705         parser.setDocumentHandler(this);
706         locator = null;
707     }
708
709
710     /**
711      * Process a qualified (prefixed) name.
712      *
713      * <p>If the name has an undeclared prefix, use only the qname
714      * and make an ErrorHandler.error callback in case the app is
715      * interested.</p>
716      *
717      * @param qName The qualified (prefixed) name.
718      * @param isAttribute true if this is an attribute name.
719      * @return The name split into three parts.
720      * @exception SAXException The client may throw
721      *            an exception if there is an error callback.
722      */
723     private String [] processName (String qName, boolean isAttribute,
724                                    boolean useException)
725         throws SAXException
726     {
727         String parts[] = nsSupport.processName(qName, nameParts,
728                                                isAttribute);
729         if (parts == null) {
730             if (useException)
731                 throw makeException("Undeclared prefix: " + qName);
732             reportError("Undeclared prefix: " + qName);
733             parts = new String[3];
734             parts[0] = parts[1] = "";
735             parts[2] = qName.intern();
736         }
737         return parts;
738     }
739
740
741     /**
742      * Report a non-fatal error.
743      *
744      * @param message The error message.
745      * @exception SAXException The client may throw
746      *            an exception.
747      */
748     void reportError (String message)
749         throws SAXException
750     {
751         if (errorHandler != null)
752             errorHandler.error(makeException(message));
753     }
754
755     
756     /**
757      * Construct an exception for the current context.
758      *
759      * @param message The error message.
760      */
761     private SAXParseException makeException (String message)
762     {
763         if (locator != null) {
764             return new SAXParseException(message, locator);
765         } else {
766             return new SAXParseException(message, null, null, -1, -1);
767         }
768     }
769
770
771     /**
772      * Throw an exception if we are parsing.
773      *
774      * <p>Use this method to detect illegal feature or
775      * property changes.</p>
776      *
777      * @param type The type of thing (feature or property).
778      * @param name The feature or property name.
779      * @exception SAXNotSupportedException If a
780      *            document is currently being parsed.
781      */
782     private void checkNotParsing (String type, String name)
783         throws SAXNotSupportedException
784     {
785         if (parsing) {
786             throw new SAXNotSupportedException("Cannot change " +
787                                                type + ' ' +
788                                                name + " while parsing");
789                                                
790         }
791     }
792
793
794 \f
795     ////////////////////////////////////////////////////////////////////
796     // Internal state.
797     ////////////////////////////////////////////////////////////////////
798
799     private NamespaceSupport nsSupport;
800     private AttributeListAdapter attAdapter;
801
802     private boolean parsing = false;
803     private String nameParts[] = new String[3];
804
805     private Parser parser = null;
806
807     private AttributesImpl atts = null;
808
809                                 // Features
810     private boolean namespaces = true;
811     private boolean prefixes = false;
812
813                                 // Properties
814
815                                 // Handlers
816     Locator locator;
817
818     EntityResolver entityResolver = null;
819     DTDHandler dtdHandler = null;
820     ContentHandler contentHandler = null;
821     ErrorHandler errorHandler = null;
822
823
824 \f
825     ////////////////////////////////////////////////////////////////////
826     // Inner class to wrap an AttributeList when not doing NS proc.
827     ////////////////////////////////////////////////////////////////////
828
829
830     /**
831      * Adapt a SAX1 AttributeList as a SAX2 Attributes object.
832      *
833      * <p>This class is in the Public Domain, and comes with NO
834      * WARRANTY of any kind.</p>
835      *
836      * <p>This wrapper class is used only when Namespace support
837      * is disabled -- it provides pretty much a direct mapping
838      * from SAX1 to SAX2, except that names and types are 
839      * interned whenever requested.</p>
840      */
841     final class AttributeListAdapter implements Attributes
842     {
843
844         /**
845          * Construct a new adapter.
846          */
847         AttributeListAdapter ()
848         {
849         }
850
851
852         /**
853          * Set the embedded AttributeList.
854          *
855          * <p>This method must be invoked before any of the others
856          * can be used.</p>
857          *
858          * @param The SAX1 attribute list (with qnames).
859          */
860         void setAttributeList (AttributeList qAtts)
861         {
862             this.qAtts = qAtts;
863         }
864
865
866         /**
867          * Return the length of the attribute list.
868          *
869          * @return The number of attributes in the list.
870          * @see org.xml.sax.Attributes#getLength
871          */
872         public int getLength ()
873         {
874             return qAtts.getLength();
875         }
876
877
878         /**
879          * Return the Namespace URI of the specified attribute.
880          *
881          * @param The attribute's index.
882          * @return Always the empty string.
883          * @see org.xml.sax.Attributes#getURI
884          */
885         public String getURI (int i)
886         {
887             return "";
888         }
889
890
891         /**
892          * Return the local name of the specified attribute.
893          *
894          * @param The attribute's index.
895          * @return Always the empty string.
896          * @see org.xml.sax.Attributes#getLocalName
897          */
898         public String getLocalName (int i)
899         {
900             return "";
901         }
902
903
904         /**
905          * Return the qualified (prefixed) name of the specified attribute.
906          *
907          * @param The attribute's index.
908          * @return The attribute's qualified name, internalized.
909          */
910         public String getQName (int i)
911         {
912             return qAtts.getName(i).intern();
913         }
914
915
916         /**
917          * Return the type of the specified attribute.
918          *
919          * @param The attribute's index.
920          * @return The attribute's type as an internalized string.
921          */
922         public String getType (int i)
923         {
924             return qAtts.getType(i).intern();
925         }
926
927
928         /**
929          * Return the value of the specified attribute.
930          *
931          * @param The attribute's index.
932          * @return The attribute's value.
933          */
934         public String getValue (int i)
935         {
936             return qAtts.getValue(i);
937         }
938
939
940         /**
941          * Look up an attribute index by Namespace name.
942          *
943          * @param uri The Namespace URI or the empty string.
944          * @param localName The local name.
945          * @return The attributes index, or -1 if none was found.
946          * @see org.xml.sax.Attributes#getIndex(java.lang.String,java.lang.String)
947          */
948         public int getIndex (String uri, String localName)
949         {
950             return -1;
951         }
952
953
954         /**
955          * Look up an attribute index by qualified (prefixed) name.
956          *
957          * @param qName The qualified name.
958          * @return The attributes index, or -1 if none was found.
959          * @see org.xml.sax.Attributes#getIndex(java.lang.String)
960          */
961         public int getIndex (String qName)
962         {
963             int max = atts.getLength();
964             for (int i = 0; i < max; i++) {
965                 if (qAtts.getName(i).equals(qName)) {
966                     return i;
967                 }
968             }
969             return -1;
970         }
971
972
973         /**
974          * Look up the type of an attribute by Namespace name.
975          *
976          * @param uri The Namespace URI
977          * @param localName The local name.
978          * @return The attribute's type as an internalized string.
979          */
980         public String getType (String uri, String localName)
981         {
982             return null;
983         }
984
985
986         /**
987          * Look up the type of an attribute by qualified (prefixed) name.
988          *
989          * @param qName The qualified name.
990          * @return The attribute's type as an internalized string.
991          */
992         public String getType (String qName)
993         {
994             return qAtts.getType(qName).intern();
995         }
996
997
998         /**
999          * Look up the value of an attribute by Namespace name.
1000          *
1001          * @param uri The Namespace URI
1002          * @param localName The local name.
1003          * @return The attribute's value.
1004          */
1005         public String getValue (String uri, String localName)
1006         {
1007             return null;
1008         }
1009
1010
1011         /**
1012          * Look up the value of an attribute by qualified (prefixed) name.
1013          *
1014          * @param qName The qualified name.
1015          * @return The attribute's value.
1016          */
1017         public String getValue (String qName)
1018         {
1019             return qAtts.getValue(qName);
1020         }
1021
1022         private AttributeList qAtts;
1023     }
1024 }
1025
1026 // end of ParserAdapter.java