OSDN Git Service

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