1
2
3
4
5
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;
14 import org.xml.sax.InputSource;
15 import org.xml.sax.Locator;
16 import org.xml.sax.AttributeList;
17 import org.xml.sax.EntityResolver;
18 import org.xml.sax.DTDHandler;
19 import org.xml.sax.DocumentHandler;
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
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
152
153
154
155
156
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 resolver 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 resolver 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 resolver 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
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
484
485
486
487 Vector exceptions = null;
488
489
490
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
502 nsSupport.pushContext();
503 int length = qAtts.getLength();
504
505
506 for (int i = 0; i < length; i++) {
507 String attQName = qAtts.getName(i);
508
509 if (!attQName.startsWith("xmlns"))
510 continue;
511
512 String prefix;
513 int n = attQName.indexOf(':');
514
515
516 if (n == -1 && attQName.length () == 5) {
517 prefix = "";
518 } else if (n != 5) {
519
520
521 continue;
522 } else
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
535
536
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
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
552
553 prefix = null;
554 } else {
555 prefix = attQName.substring(6);
556 }
557
558 if (prefix != null) {
559 if (prefixes) {
560 if (uris)
561
562
563
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
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
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
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
615
616 if (!namespaces) {
617 if (contentHandler != null) {
618 contentHandler.endElement("", "", qName.intern());
619 }
620 return;
621 }
622
623
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
699
700
701
702 /***
703 * Initialize the parser before each run.
704 */
705 private void setupParser ()
706 {
707
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
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
829 private boolean namespaces = true;
830 private boolean prefixes = false;
831 private boolean uris = false;
832
833
834
835
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
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