001 /*
002 * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 // XMLReaderAdapter.java - adapt an SAX2 XMLReader to a SAX1 Parser
027 // http://www.saxproject.org
028 // Written by David Megginson
029 // NO WARRANTY! This class is in the public domain.
030 // $Id: XMLReaderAdapter.java,v 1.3 2004/11/03 22:53:09 jsuttor Exp $
031 package org.xml.sax.helpers;
032
033 import java.io.IOException;
034 import java.util.Locale;
035
036 import org.xml.sax.Parser; // deprecated
037 import org.xml.sax.Locator;
038 import org.xml.sax.InputSource;
039 import org.xml.sax.AttributeList; // deprecated
040 import org.xml.sax.EntityResolver;
041 import org.xml.sax.DTDHandler;
042 import org.xml.sax.DocumentHandler; // deprecated
043 import org.xml.sax.ErrorHandler;
044 import org.xml.sax.SAXException;
045
046 import org.xml.sax.XMLReader;
047 import org.xml.sax.Attributes;
048 import org.xml.sax.ContentHandler;
049 import org.xml.sax.SAXNotSupportedException;
050
051 /**
052 * Adapt a SAX2 XMLReader as a SAX1 Parser.
053 *
054 * <blockquote>
055 * <em>This module, both source code and documentation, is in the
056 * Public Domain, and comes with <strong>NO WARRANTY</strong>.</em>
057 * See <a href='http://www.saxproject.org'>http://www.saxproject.org</a>
058 * for further information.
059 * </blockquote>
060 *
061 * <p>This class wraps a SAX2 {@link org.xml.sax.XMLReader XMLReader}
062 * and makes it act as a SAX1 {@link org.xml.sax.Parser Parser}. The XMLReader
063 * must support a true value for the
064 * http://xml.org/sax/features/namespace-prefixes property or parsing will fail
065 * with a {@link org.xml.sax.SAXException SAXException}; if the XMLReader
066 * supports a false value for the http://xml.org/sax/features/namespaces
067 * property, that will also be used to improve efficiency.</p>
068 *
069 * @since SAX 2.0
070 * @author David Megginson
071 * @version 2.0.1 (sax2r2)
072 * @see org.xml.sax.Parser
073 * @see org.xml.sax.XMLReader
074 */
075 public class XMLReaderAdapter implements Parser, ContentHandler {
076
077 ////////////////////////////////////////////////////////////////////
078 // Constructor.
079 ////////////////////////////////////////////////////////////////////
080
081 /**
082 * Create a new adapter.
083 *
084 * <p>Use the "org.xml.sax.driver" property to locate the SAX2
085 * driver to embed.</p>
086 *
087 * @exception org.xml.sax.SAXException If the embedded driver
088 * cannot be instantiated or if the
089 * org.xml.sax.driver property is not specified.
090 */
091 public XMLReaderAdapter() throws SAXException {
092 setup(XMLReaderFactory.createXMLReader());
093 }
094
095 /**
096 * Create a new adapter.
097 *
098 * <p>Create a new adapter, wrapped around a SAX2 XMLReader.
099 * The adapter will make the XMLReader act like a SAX1
100 * Parser.</p>
101 *
102 * @param xmlReader The SAX2 XMLReader to wrap.
103 * @exception java.lang.NullPointerException If the argument is null.
104 */
105 public XMLReaderAdapter(XMLReader xmlReader) {
106 setup(xmlReader);
107 }
108
109 /**
110 * Internal setup.
111 *
112 * @param xmlReader The embedded XMLReader.
113 */
114 private void setup(XMLReader xmlReader) {
115 if (xmlReader == null) {
116 throw new NullPointerException("XMLReader must not be null");
117 }
118 this .xmlReader = xmlReader;
119 qAtts = new AttributesAdapter();
120 }
121
122 ////////////////////////////////////////////////////////////////////
123 // Implementation of org.xml.sax.Parser.
124 ////////////////////////////////////////////////////////////////////
125
126 /**
127 * Set the locale for error reporting.
128 *
129 * <p>This is not supported in SAX2, and will always throw
130 * an exception.</p>
131 *
132 * @param locale the locale for error reporting.
133 * @see org.xml.sax.Parser#setLocale
134 * @exception org.xml.sax.SAXException Thrown unless overridden.
135 */
136 public void setLocale(Locale locale) throws SAXException {
137 throw new SAXNotSupportedException("setLocale not supported");
138 }
139
140 /**
141 * Register the entity resolver.
142 *
143 * @param resolver The new resolver.
144 * @see org.xml.sax.Parser#setEntityResolver
145 */
146 public void setEntityResolver(EntityResolver resolver) {
147 xmlReader.setEntityResolver(resolver);
148 }
149
150 /**
151 * Register the DTD event handler.
152 *
153 * @param handler The new DTD event handler.
154 * @see org.xml.sax.Parser#setDTDHandler
155 */
156 public void setDTDHandler(DTDHandler handler) {
157 xmlReader.setDTDHandler(handler);
158 }
159
160 /**
161 * Register the SAX1 document event handler.
162 *
163 * <p>Note that the SAX1 document handler has no Namespace
164 * support.</p>
165 *
166 * @param handler The new SAX1 document event handler.
167 * @see org.xml.sax.Parser#setDocumentHandler
168 */
169 public void setDocumentHandler(DocumentHandler handler) {
170 documentHandler = handler;
171 }
172
173 /**
174 * Register the error event handler.
175 *
176 * @param handler The new error event handler.
177 * @see org.xml.sax.Parser#setErrorHandler
178 */
179 public void setErrorHandler(ErrorHandler handler) {
180 xmlReader.setErrorHandler(handler);
181 }
182
183 /**
184 * Parse the document.
185 *
186 * <p>This method will throw an exception if the embedded
187 * XMLReader does not support the
188 * http://xml.org/sax/features/namespace-prefixes property.</p>
189 *
190 * @param systemId The absolute URL of the document.
191 * @exception java.io.IOException If there is a problem reading
192 * the raw content of the document.
193 * @exception org.xml.sax.SAXException If there is a problem
194 * processing the document.
195 * @see #parse(org.xml.sax.InputSource)
196 * @see org.xml.sax.Parser#parse(java.lang.String)
197 */
198 public void parse(String systemId) throws IOException, SAXException {
199 parse(new InputSource(systemId));
200 }
201
202 /**
203 * Parse the document.
204 *
205 * <p>This method will throw an exception if the embedded
206 * XMLReader does not support the
207 * http://xml.org/sax/features/namespace-prefixes property.</p>
208 *
209 * @param input An input source for the document.
210 * @exception java.io.IOException If there is a problem reading
211 * the raw content of the document.
212 * @exception org.xml.sax.SAXException If there is a problem
213 * processing the document.
214 * @see #parse(java.lang.String)
215 * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
216 */
217 public void parse(InputSource input) throws IOException,
218 SAXException {
219 setupXMLReader();
220 xmlReader.parse(input);
221 }
222
223 /**
224 * Set up the XML reader.
225 */
226 private void setupXMLReader() throws SAXException {
227 xmlReader.setFeature(
228 "http://xml.org/sax/features/namespace-prefixes", true);
229 try {
230 xmlReader.setFeature(
231 "http://xml.org/sax/features/namespaces", false);
232 } catch (SAXException e) {
233 // NO OP: it's just extra information, and we can ignore it
234 }
235 xmlReader.setContentHandler(this );
236 }
237
238 ////////////////////////////////////////////////////////////////////
239 // Implementation of org.xml.sax.ContentHandler.
240 ////////////////////////////////////////////////////////////////////
241
242 /**
243 * Set a document locator.
244 *
245 * @param locator The document locator.
246 * @see org.xml.sax.ContentHandler#setDocumentLocator
247 */
248 public void setDocumentLocator(Locator locator) {
249 if (documentHandler != null)
250 documentHandler.setDocumentLocator(locator);
251 }
252
253 /**
254 * Start document event.
255 *
256 * @exception org.xml.sax.SAXException The client may raise a
257 * processing exception.
258 * @see org.xml.sax.ContentHandler#startDocument
259 */
260 public void startDocument() throws SAXException {
261 if (documentHandler != null)
262 documentHandler.startDocument();
263 }
264
265 /**
266 * End document event.
267 *
268 * @exception org.xml.sax.SAXException The client may raise a
269 * processing exception.
270 * @see org.xml.sax.ContentHandler#endDocument
271 */
272 public void endDocument() throws SAXException {
273 if (documentHandler != null)
274 documentHandler.endDocument();
275 }
276
277 /**
278 * Adapt a SAX2 start prefix mapping event.
279 *
280 * @param prefix The prefix being mapped.
281 * @param uri The Namespace URI being mapped to.
282 * @see org.xml.sax.ContentHandler#startPrefixMapping
283 */
284 public void startPrefixMapping(String prefix, String uri) {
285 }
286
287 /**
288 * Adapt a SAX2 end prefix mapping event.
289 *
290 * @param prefix The prefix being mapped.
291 * @see org.xml.sax.ContentHandler#endPrefixMapping
292 */
293 public void endPrefixMapping(String prefix) {
294 }
295
296 /**
297 * Adapt a SAX2 start element event.
298 *
299 * @param uri The Namespace URI.
300 * @param localName The Namespace local name.
301 * @param qName The qualified (prefixed) name.
302 * @param atts The SAX2 attributes.
303 * @exception org.xml.sax.SAXException The client may raise a
304 * processing exception.
305 * @see org.xml.sax.ContentHandler#endDocument
306 */
307 public void startElement(String uri, String localName,
308 String qName, Attributes atts) throws SAXException {
309 if (documentHandler != null) {
310 qAtts.setAttributes(atts);
311 documentHandler.startElement(qName, qAtts);
312 }
313 }
314
315 /**
316 * Adapt a SAX2 end element event.
317 *
318 * @param uri The Namespace URI.
319 * @param localName The Namespace local name.
320 * @param qName The qualified (prefixed) name.
321 * @exception org.xml.sax.SAXException The client may raise a
322 * processing exception.
323 * @see org.xml.sax.ContentHandler#endElement
324 */
325 public void endElement(String uri, String localName, String qName)
326 throws SAXException {
327 if (documentHandler != null)
328 documentHandler.endElement(qName);
329 }
330
331 /**
332 * Adapt a SAX2 characters event.
333 *
334 * @param ch An array of characters.
335 * @param start The starting position in the array.
336 * @param length The number of characters to use.
337 * @exception org.xml.sax.SAXException The client may raise a
338 * processing exception.
339 * @see org.xml.sax.ContentHandler#characters
340 */
341 public void characters(char ch[], int start, int length)
342 throws SAXException {
343 if (documentHandler != null)
344 documentHandler.characters(ch, start, length);
345 }
346
347 /**
348 * Adapt a SAX2 ignorable whitespace event.
349 *
350 * @param ch An array of characters.
351 * @param start The starting position in the array.
352 * @param length The number of characters to use.
353 * @exception org.xml.sax.SAXException The client may raise a
354 * processing exception.
355 * @see org.xml.sax.ContentHandler#ignorableWhitespace
356 */
357 public void ignorableWhitespace(char ch[], int start, int length)
358 throws SAXException {
359 if (documentHandler != null)
360 documentHandler.ignorableWhitespace(ch, start, length);
361 }
362
363 /**
364 * Adapt a SAX2 processing instruction event.
365 *
366 * @param target The processing instruction target.
367 * @param data The remainder of the processing instruction
368 * @exception org.xml.sax.SAXException The client may raise a
369 * processing exception.
370 * @see org.xml.sax.ContentHandler#processingInstruction
371 */
372 public void processingInstruction(String target, String data)
373 throws SAXException {
374 if (documentHandler != null)
375 documentHandler.processingInstruction(target, data);
376 }
377
378 /**
379 * Adapt a SAX2 skipped entity event.
380 *
381 * @param name The name of the skipped entity.
382 * @see org.xml.sax.ContentHandler#skippedEntity
383 * @exception org.xml.sax.SAXException Throwable by subclasses.
384 */
385 public void skippedEntity(String name) throws SAXException {
386 }
387
388 ////////////////////////////////////////////////////////////////////
389 // Internal state.
390 ////////////////////////////////////////////////////////////////////
391
392 XMLReader xmlReader;
393 DocumentHandler documentHandler;
394 AttributesAdapter qAtts;
395
396 ////////////////////////////////////////////////////////////////////
397 // Internal class.
398 ////////////////////////////////////////////////////////////////////
399
400 /**
401 * Internal class to wrap a SAX2 Attributes object for SAX1.
402 */
403 final class AttributesAdapter implements AttributeList {
404 AttributesAdapter() {
405 }
406
407 /**
408 * Set the embedded Attributes object.
409 *
410 * @param The embedded SAX2 Attributes.
411 */
412 void setAttributes(Attributes attributes) {
413 this .attributes = attributes;
414 }
415
416 /**
417 * Return the number of attributes.
418 *
419 * @return The length of the attribute list.
420 * @see org.xml.sax.AttributeList#getLength
421 */
422 public int getLength() {
423 return attributes.getLength();
424 }
425
426 /**
427 * Return the qualified (prefixed) name of an attribute by position.
428 *
429 * @return The qualified name.
430 * @see org.xml.sax.AttributeList#getName
431 */
432 public String getName(int i) {
433 return attributes.getQName(i);
434 }
435
436 /**
437 * Return the type of an attribute by position.
438 *
439 * @return The type.
440 * @see org.xml.sax.AttributeList#getType(int)
441 */
442 public String getType(int i) {
443 return attributes.getType(i);
444 }
445
446 /**
447 * Return the value of an attribute by position.
448 *
449 * @return The value.
450 * @see org.xml.sax.AttributeList#getValue(int)
451 */
452 public String getValue(int i) {
453 return attributes.getValue(i);
454 }
455
456 /**
457 * Return the type of an attribute by qualified (prefixed) name.
458 *
459 * @return The type.
460 * @see org.xml.sax.AttributeList#getType(java.lang.String)
461 */
462 public String getType(String qName) {
463 return attributes.getType(qName);
464 }
465
466 /**
467 * Return the value of an attribute by qualified (prefixed) name.
468 *
469 * @return The value.
470 * @see org.xml.sax.AttributeList#getValue(java.lang.String)
471 */
472 public String getValue(String qName) {
473 return attributes.getValue(qName);
474 }
475
476 private Attributes attributes;
477 }
478
479 }
480
481 // end of XMLReaderAdapter.java
|