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