1 // XMLReaderAdapter.java - adapt an SAX2 XMLReader to a SAX1 Parser
2 // http://www.saxproject.org
3 // Written by David Megginson
4 // NO WARRANTY! This class is in the public domain.
5 // $Id: XMLReaderAdapter.java,v 1.9 2004/04/26 17:34:35 dmegginson Exp $
7 package org.xml.sax.helpers;
9 import java.io.IOException;
10 import java.util.Locale;
12 import org.xml.sax.Parser; // deprecated
13 import org.xml.sax.Locator;
14 import org.xml.sax.InputSource;
15 import org.xml.sax.AttributeList; // deprecated
16 import org.xml.sax.EntityResolver;
17 import org.xml.sax.DTDHandler;
18 import org.xml.sax.DocumentHandler; // deprecated
19 import org.xml.sax.ErrorHandler;
20 import org.xml.sax.SAXException;
22 import org.xml.sax.XMLReader;
23 import org.xml.sax.Attributes;
24 import org.xml.sax.ContentHandler;
25 import org.xml.sax.SAXNotSupportedException;
29 * Adapt a SAX2 XMLReader as a SAX1 Parser.
32 * <em>This module, both source code and documentation, is in the
33 * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
34 * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
35 * for further information.
38 * <p>This class wraps a SAX2 {@link org.xml.sax.XMLReader XMLReader}
39 * and makes it act as a SAX1 {@link org.xml.sax.Parser Parser}. The XMLReader
40 * must support a true value for the
41 * http://xml.org/sax/features/namespace-prefixes property or parsing will fail
42 * with a {@link org.xml.sax.SAXException SAXException}; if the XMLReader
43 * supports a false value for the http://xml.org/sax/features/namespaces
44 * property, that will also be used to improve efficiency.</p>
47 * @author David Megginson
48 * @version 2.0.1 (sax2r2)
49 * @see org.xml.sax.Parser
50 * @see org.xml.sax.XMLReader
52 public class XMLReaderAdapter implements Parser, ContentHandler
56 ////////////////////////////////////////////////////////////////////
58 ////////////////////////////////////////////////////////////////////
62 * Create a new adapter.
64 * <p>Use the "org.xml.sax.driver" property to locate the SAX2
65 * driver to embed.</p>
67 * @exception org.xml.sax.SAXException If the embedded driver
68 * cannot be instantiated or if the
69 * org.xml.sax.driver property is not specified.
71 public XMLReaderAdapter ()
74 setup(XMLReaderFactory.createXMLReader());
79 * Create a new adapter.
81 * <p>Create a new adapter, wrapped around a SAX2 XMLReader.
82 * The adapter will make the XMLReader act like a SAX1
85 * @param xmlReader The SAX2 XMLReader to wrap.
86 * @exception java.lang.NullPointerException If the argument is null.
88 public XMLReaderAdapter (XMLReader xmlReader)
98 * @param xmlReader The embedded XMLReader.
100 private void setup (XMLReader xmlReader)
102 if (xmlReader == null) {
103 throw new NullPointerException("XMLReader must not be null");
105 this.xmlReader = xmlReader;
106 qAtts = new AttributesAdapter();
111 ////////////////////////////////////////////////////////////////////
112 // Implementation of org.xml.sax.Parser.
113 ////////////////////////////////////////////////////////////////////
117 * Set the locale for error reporting.
119 * <p>This is not supported in SAX2, and will always throw
122 * @param locale the locale for error reporting.
123 * @see org.xml.sax.Parser#setLocale
124 * @exception org.xml.sax.SAXException Thrown unless overridden.
127 public void setLocale (Locale locale)
130 throw new SAXNotSupportedException("setLocale not supported");
135 * Register the entity resolver.
137 * @param resolver The new resolver.
138 * @see org.xml.sax.Parser#setEntityResolver
141 public void setEntityResolver (EntityResolver resolver)
143 xmlReader.setEntityResolver(resolver);
148 * Register the DTD event handler.
150 * @param handler The new DTD event handler.
151 * @see org.xml.sax.Parser#setDTDHandler
154 public void setDTDHandler (DTDHandler handler)
156 xmlReader.setDTDHandler(handler);
161 * Register the SAX1 document event handler.
163 * <p>Note that the SAX1 document handler has no Namespace
166 * @param handler The new SAX1 document event handler.
167 * @see org.xml.sax.Parser#setDocumentHandler
170 public void setDocumentHandler (DocumentHandler handler)
172 documentHandler = handler;
177 * Register the error event handler.
179 * @param handler The new error event handler.
180 * @see org.xml.sax.Parser#setErrorHandler
183 public void setErrorHandler (ErrorHandler handler)
185 xmlReader.setErrorHandler(handler);
190 * Parse the document.
192 * <p>This method will throw an exception if the embedded
193 * XMLReader does not support the
194 * http://xml.org/sax/features/namespace-prefixes property.</p>
196 * @param systemId The absolute URL of the document.
197 * @exception java.io.IOException If there is a problem reading
198 * the raw content of the document.
199 * @exception org.xml.sax.SAXException If there is a problem
200 * processing the document.
201 * @see #parse(org.xml.sax.InputSource)
202 * @see org.xml.sax.Parser#parse(java.lang.String)
205 public void parse (String systemId)
206 throws IOException, SAXException
208 parse(new InputSource(systemId));
213 * Parse the document.
215 * <p>This method will throw an exception if the embedded
216 * XMLReader does not support the
217 * http://xml.org/sax/features/namespace-prefixes property.</p>
219 * @param input An input source for the document.
220 * @exception java.io.IOException If there is a problem reading
221 * the raw content of the document.
222 * @exception org.xml.sax.SAXException If there is a problem
223 * processing the document.
224 * @see #parse(java.lang.String)
225 * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
228 public void parse (InputSource input)
229 throws IOException, SAXException
232 xmlReader.parse(input);
237 * Set up the XML reader.
239 private void setupXMLReader ()
242 xmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
244 xmlReader.setFeature("http://xml.org/sax/features/namespaces",
246 } catch (SAXException e) {
247 // NO OP: it's just extra information, and we can ignore it
249 xmlReader.setContentHandler(this);
254 ////////////////////////////////////////////////////////////////////
255 // Implementation of org.xml.sax.ContentHandler.
256 ////////////////////////////////////////////////////////////////////
260 * Set a document locator.
262 * @param locator The document locator.
263 * @see org.xml.sax.ContentHandler#setDocumentLocator
266 public void setDocumentLocator (Locator locator)
268 if (documentHandler != null)
269 documentHandler.setDocumentLocator(locator);
274 * Start document event.
276 * @exception org.xml.sax.SAXException The client may raise a
277 * processing exception.
278 * @see org.xml.sax.ContentHandler#startDocument
281 public void startDocument ()
284 if (documentHandler != null)
285 documentHandler.startDocument();
290 * End document event.
292 * @exception org.xml.sax.SAXException The client may raise a
293 * processing exception.
294 * @see org.xml.sax.ContentHandler#endDocument
297 public void endDocument ()
300 if (documentHandler != null)
301 documentHandler.endDocument();
306 * Adapt a SAX2 start prefix mapping event.
308 * @param prefix The prefix being mapped.
309 * @param uri The Namespace URI being mapped to.
310 * @see org.xml.sax.ContentHandler#startPrefixMapping
313 public void startPrefixMapping (String prefix, String uri)
319 * Adapt a SAX2 end prefix mapping event.
321 * @param prefix The prefix being mapped.
322 * @see org.xml.sax.ContentHandler#endPrefixMapping
325 public void endPrefixMapping (String prefix)
331 * Adapt a SAX2 start element event.
333 * @param uri The Namespace URI.
334 * @param localName The Namespace local name.
335 * @param qName The qualified (prefixed) name.
336 * @param atts The SAX2 attributes.
337 * @exception org.xml.sax.SAXException The client may raise a
338 * processing exception.
339 * @see org.xml.sax.ContentHandler#endDocument
342 public void startElement (String uri, String localName,
343 String qName, Attributes atts)
346 if (documentHandler != null) {
347 qAtts.setAttributes(atts);
348 documentHandler.startElement(qName, qAtts);
354 * Adapt a SAX2 end element event.
356 * @param uri The Namespace URI.
357 * @param localName The Namespace local name.
358 * @param qName The qualified (prefixed) name.
359 * @exception org.xml.sax.SAXException The client may raise a
360 * processing exception.
361 * @see org.xml.sax.ContentHandler#endElement
364 public void endElement (String uri, String localName,
368 if (documentHandler != null)
369 documentHandler.endElement(qName);
374 * Adapt a SAX2 characters event.
376 * @param ch An array of characters.
377 * @param start The starting position in the array.
378 * @param length The number of characters to use.
379 * @exception org.xml.sax.SAXException The client may raise a
380 * processing exception.
381 * @see org.xml.sax.ContentHandler#characters
384 public void characters (char ch[], int start, int length)
387 if (documentHandler != null)
388 documentHandler.characters(ch, start, length);
393 * Adapt a SAX2 ignorable whitespace event.
395 * @param ch An array of characters.
396 * @param start The starting position in the array.
397 * @param length The number of characters to use.
398 * @exception org.xml.sax.SAXException The client may raise a
399 * processing exception.
400 * @see org.xml.sax.ContentHandler#ignorableWhitespace
403 public void ignorableWhitespace (char ch[], int start, int length)
406 if (documentHandler != null)
407 documentHandler.ignorableWhitespace(ch, start, length);
412 * Adapt a SAX2 processing instruction event.
414 * @param target The processing instruction target.
415 * @param data The remainder of the processing instruction
416 * @exception org.xml.sax.SAXException The client may raise a
417 * processing exception.
418 * @see org.xml.sax.ContentHandler#processingInstruction
421 public void processingInstruction (String target, String data)
424 if (documentHandler != null)
425 documentHandler.processingInstruction(target, data);
430 * Adapt a SAX2 skipped entity event.
432 * @param name The name of the skipped entity.
433 * @see org.xml.sax.ContentHandler#skippedEntity
434 * @exception org.xml.sax.SAXException Throwable by subclasses.
437 public void skippedEntity (String name)
444 ////////////////////////////////////////////////////////////////////
446 ////////////////////////////////////////////////////////////////////
449 DocumentHandler documentHandler;
450 AttributesAdapter qAtts;
454 ////////////////////////////////////////////////////////////////////
456 ////////////////////////////////////////////////////////////////////
460 * Internal class to wrap a SAX2 Attributes object for SAX1.
462 final class AttributesAdapter implements AttributeList
470 * Set the embedded Attributes object.
472 * @param The embedded SAX2 Attributes.
474 void setAttributes (Attributes attributes)
476 this.attributes = attributes;
481 * Return the number of attributes.
483 * @return The length of the attribute list.
484 * @see org.xml.sax.AttributeList#getLength
487 public int getLength ()
489 return attributes.getLength();
494 * Return the qualified (prefixed) name of an attribute by position.
496 * @return The qualified name.
497 * @see org.xml.sax.AttributeList#getName
500 public String getName (int i)
502 return attributes.getQName(i);
507 * Return the type of an attribute by position.
510 * @see org.xml.sax.AttributeList#getType(int)
513 public String getType (int i)
515 return attributes.getType(i);
520 * Return the value of an attribute by position.
523 * @see org.xml.sax.AttributeList#getValue(int)
526 public String getValue (int i)
528 return attributes.getValue(i);
533 * Return the type of an attribute by qualified (prefixed) name.
536 * @see org.xml.sax.AttributeList#getType(java.lang.String)
539 public String getType (String qName)
541 return attributes.getType(qName);
546 * Return the value of an attribute by qualified (prefixed) name.
549 * @see org.xml.sax.AttributeList#getValue(java.lang.String)
552 public String getValue (String qName)
554 return attributes.getValue(qName);
557 private Attributes attributes;
562 // end of XMLReaderAdapter.java