1 /*
2 * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
64 * @version 2.0.1 (sax2r2)
65 * @see org.xml.sax.helpers.XMLReaderAdapter
66 * @see org.xml.sax.XMLReader
67 * @see org.xml.sax.Parser
68 */
69 @SuppressWarnings("deprecation")
70 public class ParserAdapter implements XMLReader, DocumentHandler
71 {
72
73 ////////////////////////////////////////////////////////////////////
74 // Constructors.
75 ////////////////////////////////////////////////////////////////////
76
77
78 /**
79 * Construct a new parser adapter.
80 *
81 * <p>Use the "org.xml.sax.parser" property to locate the
82 * embedded SAX1 driver.</p>
83 *
84 * @exception SAXException If the embedded driver
85 * cannot be instantiated or if the
86 * org.xml.sax.parser property is not specified.
87 */
88 public ParserAdapter ()
89 throws SAXException
90 {
91 super();
92
93 String driver = SecuritySupport.getSystemProperty("org.xml.sax.parser");
94
95 try {
96 setup(ParserFactory.makeParser());
97 } catch (ClassNotFoundException e1) {
98 throw new
99 SAXException("Cannot find SAX1 driver class " +
100 driver, e1);
101 } catch (IllegalAccessException e2) {
102 throw new
103 SAXException("SAX1 driver class " +
104 driver +
111 } catch (ClassCastException e4) {
112 throw new
113 SAXException("SAX1 driver class " +
114 driver +
115 " does not implement org.xml.sax.Parser");
116 } catch (NullPointerException e5) {
117 throw new
118 SAXException("System property org.xml.sax.parser not specified");
119 }
120 }
121
122
123 /**
124 * Construct a new parser adapter.
125 *
126 * <p>Note that the embedded parser cannot be changed once the
127 * adapter is created; to embed a different parser, allocate
128 * a new ParserAdapter.</p>
129 *
130 * @param parser The SAX1 parser to embed.
131 * @exception java.lang.NullPointerException If the parser parameter
132 * is null.
133 */
134 public ParserAdapter (Parser parser)
135 {
136 super();
137 setup(parser);
138 }
139
140
141 /**
142 * Internal setup method.
143 *
144 * @param parser The embedded parser.
145 * @exception java.lang.NullPointerException If the parser parameter
146 * is null.
147 */
148 private void setup (Parser parser)
149 {
150 if (parser == null) {
151 throw new
152 NullPointerException("Parser argument must not be null");
153 }
154 this.parser = parser;
155 atts = new AttributesImpl();
156 nsSupport = new NamespaceSupport();
157 attAdapter = new AttributeListAdapter();
158 }
159
160
161
162 ////////////////////////////////////////////////////////////////////
163 // Implementation of org.xml.sax.XMLReader.
164 ////////////////////////////////////////////////////////////////////
165
166
167 //
168 // Internal constants for the sake of convenience.
169 //
170 private final static String FEATURES = "http://xml.org/sax/features/";
171 private final static String NAMESPACES = FEATURES + "namespaces";
172 private final static String NAMESPACE_PREFIXES = FEATURES + "namespace-prefixes";
173 private final static String XMLNS_URIs = FEATURES + "xmlns-uris";
174
175
176 /**
177 * Set a feature flag for the parser.
178 *
179 * <p>The only features recognized are namespaces and
180 * namespace-prefixes.</p>
181 *
182 * @param name The feature name, as a complete URI.
183 * @param value The requested feature value.
184 * @exception SAXNotRecognizedException If the feature
185 * can't be assigned or retrieved.
186 * @exception SAXNotSupportedException If the feature
187 * can't be assigned that value.
188 * @see org.xml.sax.XMLReader#setFeature
189 */
190 public void setFeature (String name, boolean value)
191 throws SAXNotRecognizedException, SAXNotSupportedException
192 {
193 if (name.equals(NAMESPACES)) {
194 checkNotParsing("feature", name);
195 namespaces = value;
196 if (!namespaces && !prefixes) {
197 prefixes = true;
198 }
199 } else if (name.equals(NAMESPACE_PREFIXES)) {
200 checkNotParsing("feature", name);
201 prefixes = value;
202 if (!prefixes && !namespaces) {
203 namespaces = true;
204 }
205 } else if (name.equals(XMLNS_URIs)) {
206 checkNotParsing("feature", name);
207 uris = value;
208 } else {
209 throw new SAXNotRecognizedException("Feature: " + name);
210 }
211 }
212
213
214 /**
215 * Check a parser feature flag.
216 *
217 * <p>The only features recognized are namespaces and
218 * namespace-prefixes.</p>
219 *
220 * @param name The feature name, as a complete URI.
221 * @return The current feature value.
222 * @exception SAXNotRecognizedException If the feature
223 * value can't be assigned or retrieved.
224 * @exception SAXNotSupportedException If the
225 * feature is not currently readable.
226 * @see org.xml.sax.XMLReader#setFeature
227 */
228 public boolean getFeature (String name)
229 throws SAXNotRecognizedException, SAXNotSupportedException
230 {
231 if (name.equals(NAMESPACES)) {
232 return namespaces;
233 } else if (name.equals(NAMESPACE_PREFIXES)) {
234 return prefixes;
235 } else if (name.equals(XMLNS_URIs)) {
236 return uris;
237 } else {
238 throw new SAXNotRecognizedException("Feature: " + name);
239 }
240 }
241
242
243 /**
244 * Set a parser property.
245 *
246 * <p>No properties are currently recognized.</p>
247 *
248 * @param name The property name.
249 * @param value The property value.
250 * @exception SAXNotRecognizedException If the property
251 * value can't be assigned or retrieved.
252 * @exception SAXNotSupportedException If the property
253 * can't be assigned that value.
254 * @see org.xml.sax.XMLReader#setProperty
255 */
256 public void setProperty (String name, Object value)
257 throws SAXNotRecognizedException, SAXNotSupportedException
258 {
259 throw new SAXNotRecognizedException("Property: " + name);
260 }
261
262
263 /**
264 * Get a parser property.
265 *
266 * <p>No properties are currently recognized.</p>
267 *
268 * @param name The property name.
269 * @return The property value.
270 * @exception SAXNotRecognizedException If the property
271 * value can't be assigned or retrieved.
272 * @exception SAXNotSupportedException If the property
273 * value is not currently readable.
274 * @see org.xml.sax.XMLReader#getProperty
275 */
276 public Object getProperty (String name)
277 throws SAXNotRecognizedException, SAXNotSupportedException
278 {
279 throw new SAXNotRecognizedException("Property: " + name);
280 }
281
282
283 /**
284 * Set the entity resolver.
285 *
286 * @param resolver The new entity resolver.
287 * @see org.xml.sax.XMLReader#setEntityResolver
288 */
289 public void setEntityResolver (EntityResolver resolver)
290 {
291 entityResolver = resolver;
292 }
363 errorHandler = handler;
364 }
365
366
367 /**
368 * Return the current error handler.
369 *
370 * @return The current error handler, or null if none was supplied.
371 * @see org.xml.sax.XMLReader#getEntityResolver
372 */
373 public ErrorHandler getErrorHandler ()
374 {
375 return errorHandler;
376 }
377
378
379 /**
380 * Parse an XML document.
381 *
382 * @param systemId The absolute URL of the document.
383 * @exception java.io.IOException If there is a problem reading
384 * the raw content of the document.
385 * @exception SAXException If there is a problem
386 * processing the document.
387 * @see #parse(org.xml.sax.InputSource)
388 * @see org.xml.sax.Parser#parse(java.lang.String)
389 */
390 public void parse (String systemId)
391 throws IOException, SAXException
392 {
393 parse(new InputSource(systemId));
394 }
395
396
397 /**
398 * Parse an XML document.
399 *
400 * @param input An input source for the document.
401 * @exception java.io.IOException If there is a problem reading
402 * the raw content of the document.
403 * @exception SAXException If there is a problem
404 * processing the document.
405 * @see #parse(java.lang.String)
406 * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
407 */
408 public void parse (InputSource input)
409 throws IOException, SAXException
410 {
411 if (parsing) {
412 throw new SAXException("Parser is already in use");
413 }
414 setupParser();
415 parsing = true;
416 try {
417 parser.parse(input);
418 } finally {
419 parsing = false;
420 }
421 parsing = false;
422 }
423
431 /**
432 * Adapter implementation method; do not call.
433 * Adapt a SAX1 document locator event.
434 *
435 * @param locator A document locator.
436 * @see org.xml.sax.ContentHandler#setDocumentLocator
437 */
438 public void setDocumentLocator (Locator locator)
439 {
440 this.locator = locator;
441 if (contentHandler != null) {
442 contentHandler.setDocumentLocator(locator);
443 }
444 }
445
446
447 /**
448 * Adapter implementation method; do not call.
449 * Adapt a SAX1 start document event.
450 *
451 * @exception SAXException The client may raise a
452 * processing exception.
453 * @see org.xml.sax.DocumentHandler#startDocument
454 */
455 public void startDocument ()
456 throws SAXException
457 {
458 if (contentHandler != null) {
459 contentHandler.startDocument();
460 }
461 }
462
463
464 /**
465 * Adapter implementation method; do not call.
466 * Adapt a SAX1 end document event.
467 *
468 * @exception SAXException The client may raise a
469 * processing exception.
470 * @see org.xml.sax.DocumentHandler#endDocument
471 */
472 public void endDocument ()
473 throws SAXException
474 {
475 if (contentHandler != null) {
476 contentHandler.endDocument();
477 }
478 }
479
480
481 /**
482 * Adapter implementation method; do not call.
483 * Adapt a SAX1 startElement event.
484 *
485 * <p>If necessary, perform Namespace processing.</p>
486 *
487 * @param qName The qualified (prefixed) name.
488 * @param qAtts The XML attribute list (with qnames).
489 * @exception SAXException The client may raise a
490 * processing exception.
491 */
492 public void startElement (String qName, AttributeList qAtts)
493 throws SAXException
494 {
495 // These are exceptions from the
496 // first pass; they should be
497 // ignored if there's a second pass,
498 // but reported otherwise.
499 List<SAXException> exceptions = null;
500
501 // If we're not doing Namespace
502 // processing, dispatch this quickly.
503 if (!namespaces) {
504 if (contentHandler != null) {
505 attAdapter.setAttributeList(qAtts);
506 contentHandler.startElement("", "", qName.intern(),
507 attAdapter);
508 }
509 return;
599 // now handle the deferred exception reports
600 if (exceptions != null && errorHandler != null) {
601 for (int i = 0; i < exceptions.size(); i++)
602 errorHandler.error((SAXParseException)
603 (exceptions.get(i)));
604 }
605
606 // OK, finally report the event.
607 if (contentHandler != null) {
608 String name[] = processName(qName, false, false);
609 contentHandler.startElement(name[0], name[1], name[2], atts);
610 }
611 }
612
613
614 /**
615 * Adapter implementation method; do not call.
616 * Adapt a SAX1 end element event.
617 *
618 * @param qName The qualified (prefixed) name.
619 * @exception SAXException The client may raise a
620 * processing exception.
621 * @see org.xml.sax.DocumentHandler#endElement
622 */
623 public void endElement (String qName)
624 throws SAXException
625 {
626 // If we're not doing Namespace
627 // processing, dispatch this quickly.
628 if (!namespaces) {
629 if (contentHandler != null) {
630 contentHandler.endElement("", "", qName.intern());
631 }
632 return;
633 }
634
635 // Split the name.
636 String names[] = processName(qName, false, false);
637 if (contentHandler != null) {
638 contentHandler.endElement(names[0], names[1], names[2]);
639 Enumeration<String> ePrefixes = nsSupport.getDeclaredPrefixes();
640 while (ePrefixes.hasMoreElements()) {
641 String prefix = ePrefixes.nextElement();
642 contentHandler.endPrefixMapping(prefix);
643 }
644 }
645 nsSupport.popContext();
646 }
647
648
649 /**
650 * Adapter implementation method; do not call.
651 * Adapt a SAX1 characters event.
652 *
653 * @param ch An array of characters.
654 * @param start The starting position in the array.
655 * @param length The number of characters to use.
656 * @exception SAXException The client may raise a
657 * processing exception.
658 * @see org.xml.sax.DocumentHandler#characters
659 */
660 public void characters (char ch[], int start, int length)
661 throws SAXException
662 {
663 if (contentHandler != null) {
664 contentHandler.characters(ch, start, length);
665 }
666 }
667
668
669 /**
670 * Adapter implementation method; do not call.
671 * Adapt a SAX1 ignorable whitespace event.
672 *
673 * @param ch An array of characters.
674 * @param start The starting position in the array.
675 * @param length The number of characters to use.
676 * @exception SAXException The client may raise a
677 * processing exception.
678 * @see org.xml.sax.DocumentHandler#ignorableWhitespace
679 */
680 public void ignorableWhitespace (char ch[], int start, int length)
681 throws SAXException
682 {
683 if (contentHandler != null) {
684 contentHandler.ignorableWhitespace(ch, start, length);
685 }
686 }
687
688
689 /**
690 * Adapter implementation method; do not call.
691 * Adapt a SAX1 processing instruction event.
692 *
693 * @param target The processing instruction target.
694 * @param data The remainder of the processing instruction
695 * @exception SAXException The client may raise a
696 * processing exception.
697 * @see org.xml.sax.DocumentHandler#processingInstruction
698 */
699 public void processingInstruction (String target, String data)
700 throws SAXException
701 {
702 if (contentHandler != null) {
703 contentHandler.processingInstruction(target, data);
704 }
705 }
706
707
708
709 ////////////////////////////////////////////////////////////////////
710 // Internal utility methods.
711 ////////////////////////////////////////////////////////////////////
712
713
714 /**
715 * Initialize the parser before each run.
731 parser.setDTDHandler(dtdHandler);
732 }
733 if (errorHandler != null) {
734 parser.setErrorHandler(errorHandler);
735 }
736 parser.setDocumentHandler(this);
737 locator = null;
738 }
739
740
741 /**
742 * Process a qualified (prefixed) name.
743 *
744 * <p>If the name has an undeclared prefix, use only the qname
745 * and make an ErrorHandler.error callback in case the app is
746 * interested.</p>
747 *
748 * @param qName The qualified (prefixed) name.
749 * @param isAttribute true if this is an attribute name.
750 * @return The name split into three parts.
751 * @exception SAXException The client may throw
752 * an exception if there is an error callback.
753 */
754 private String [] processName (String qName, boolean isAttribute,
755 boolean useException)
756 throws SAXException
757 {
758 String parts[] = nsSupport.processName(qName, nameParts,
759 isAttribute);
760 if (parts == null) {
761 if (useException)
762 throw makeException("Undeclared prefix: " + qName);
763 reportError("Undeclared prefix: " + qName);
764 parts = new String[3];
765 parts[0] = parts[1] = "";
766 parts[2] = qName.intern();
767 }
768 return parts;
769 }
770
771
772 /**
773 * Report a non-fatal error.
774 *
775 * @param message The error message.
776 * @exception SAXException The client may throw
777 * an exception.
778 */
779 void reportError (String message)
780 throws SAXException
781 {
782 if (errorHandler != null)
783 errorHandler.error(makeException(message));
784 }
785
786
787 /**
788 * Construct an exception for the current context.
789 *
790 * @param message The error message.
791 */
792 private SAXParseException makeException (String message)
793 {
794 if (locator != null) {
795 return new SAXParseException(message, locator);
796 } else {
797 return new SAXParseException(message, null, null, -1, -1);
798 }
799 }
800
801
802 /**
803 * Throw an exception if we are parsing.
804 *
805 * <p>Use this method to detect illegal feature or
806 * property changes.</p>
807 *
808 * @param type The type of thing (feature or property).
809 * @param name The feature or property name.
810 * @exception SAXNotSupportedException If a
811 * document is currently being parsed.
812 */
813 private void checkNotParsing (String type, String name)
814 throws SAXNotSupportedException
815 {
816 if (parsing) {
817 throw new SAXNotSupportedException("Cannot change " +
818 type + ' ' +
819 name + " while parsing");
820
821 }
822 }
823
824
825
826 ////////////////////////////////////////////////////////////////////
827 // Internal state.
828 ////////////////////////////////////////////////////////////////////
829
830 private NamespaceSupport nsSupport;
|
1 /*
2 * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
64 * @version 2.0.1 (sax2r2)
65 * @see org.xml.sax.helpers.XMLReaderAdapter
66 * @see org.xml.sax.XMLReader
67 * @see org.xml.sax.Parser
68 */
69 @SuppressWarnings("deprecation")
70 public class ParserAdapter implements XMLReader, DocumentHandler
71 {
72
73 ////////////////////////////////////////////////////////////////////
74 // Constructors.
75 ////////////////////////////////////////////////////////////////////
76
77
78 /**
79 * Construct a new parser adapter.
80 *
81 * <p>Use the "org.xml.sax.parser" property to locate the
82 * embedded SAX1 driver.</p>
83 *
84 * @throws SAXException If the embedded driver
85 * cannot be instantiated or if the
86 * org.xml.sax.parser property is not specified.
87 */
88 public ParserAdapter ()
89 throws SAXException
90 {
91 super();
92
93 String driver = SecuritySupport.getSystemProperty("org.xml.sax.parser");
94
95 try {
96 setup(ParserFactory.makeParser());
97 } catch (ClassNotFoundException e1) {
98 throw new
99 SAXException("Cannot find SAX1 driver class " +
100 driver, e1);
101 } catch (IllegalAccessException e2) {
102 throw new
103 SAXException("SAX1 driver class " +
104 driver +
111 } catch (ClassCastException e4) {
112 throw new
113 SAXException("SAX1 driver class " +
114 driver +
115 " does not implement org.xml.sax.Parser");
116 } catch (NullPointerException e5) {
117 throw new
118 SAXException("System property org.xml.sax.parser not specified");
119 }
120 }
121
122
123 /**
124 * Construct a new parser adapter.
125 *
126 * <p>Note that the embedded parser cannot be changed once the
127 * adapter is created; to embed a different parser, allocate
128 * a new ParserAdapter.</p>
129 *
130 * @param parser The SAX1 parser to embed.
131 * @throws java.lang.NullPointerException If the parser parameter
132 * is null.
133 */
134 public ParserAdapter (Parser parser)
135 {
136 super();
137 setup(parser);
138 }
139
140
141 /**
142 * Internal setup method.
143 *
144 * @param parser The embedded parser.
145 * @throws java.lang.NullPointerException If the parser parameter
146 * is null.
147 */
148 private void setup (Parser parser)
149 {
150 if (parser == null) {
151 throw new
152 NullPointerException("Parser argument must not be null");
153 }
154 this.parser = parser;
155 atts = new AttributesImpl();
156 nsSupport = new NamespaceSupport();
157 attAdapter = new AttributeListAdapter();
158 }
159
160
161
162 ////////////////////////////////////////////////////////////////////
163 // Implementation of org.xml.sax.XMLReader.
164 ////////////////////////////////////////////////////////////////////
165
166
167 //
168 // Internal constants for the sake of convenience.
169 //
170 private final static String FEATURES = "http://xml.org/sax/features/";
171 private final static String NAMESPACES = FEATURES + "namespaces";
172 private final static String NAMESPACE_PREFIXES = FEATURES + "namespace-prefixes";
173 private final static String XMLNS_URIs = FEATURES + "xmlns-uris";
174
175
176 /**
177 * Set a feature flag for the parser.
178 *
179 * <p>The only features recognized are namespaces and
180 * namespace-prefixes.</p>
181 *
182 * @param name The feature name, as a complete URI.
183 * @param value The requested feature value.
184 * @throws SAXNotRecognizedException If the feature
185 * can't be assigned or retrieved.
186 * @throws SAXNotSupportedException If the feature
187 * can't be assigned that value.
188 * @see org.xml.sax.XMLReader#setFeature
189 */
190 public void setFeature (String name, boolean value)
191 throws SAXNotRecognizedException, SAXNotSupportedException
192 {
193 if (name.equals(NAMESPACES)) {
194 checkNotParsing("feature", name);
195 namespaces = value;
196 if (!namespaces && !prefixes) {
197 prefixes = true;
198 }
199 } else if (name.equals(NAMESPACE_PREFIXES)) {
200 checkNotParsing("feature", name);
201 prefixes = value;
202 if (!prefixes && !namespaces) {
203 namespaces = true;
204 }
205 } else if (name.equals(XMLNS_URIs)) {
206 checkNotParsing("feature", name);
207 uris = value;
208 } else {
209 throw new SAXNotRecognizedException("Feature: " + name);
210 }
211 }
212
213
214 /**
215 * Check a parser feature flag.
216 *
217 * <p>The only features recognized are namespaces and
218 * namespace-prefixes.</p>
219 *
220 * @param name The feature name, as a complete URI.
221 * @return The current feature value.
222 * @throws SAXNotRecognizedException If the feature
223 * value can't be assigned or retrieved.
224 * @throws SAXNotSupportedException If the
225 * feature is not currently readable.
226 * @see org.xml.sax.XMLReader#setFeature
227 */
228 public boolean getFeature (String name)
229 throws SAXNotRecognizedException, SAXNotSupportedException
230 {
231 if (name.equals(NAMESPACES)) {
232 return namespaces;
233 } else if (name.equals(NAMESPACE_PREFIXES)) {
234 return prefixes;
235 } else if (name.equals(XMLNS_URIs)) {
236 return uris;
237 } else {
238 throw new SAXNotRecognizedException("Feature: " + name);
239 }
240 }
241
242
243 /**
244 * Set a parser property.
245 *
246 * <p>No properties are currently recognized.</p>
247 *
248 * @param name The property name.
249 * @param value The property value.
250 * @throws SAXNotRecognizedException If the property
251 * value can't be assigned or retrieved.
252 * @throws SAXNotSupportedException If the property
253 * can't be assigned that value.
254 * @see org.xml.sax.XMLReader#setProperty
255 */
256 public void setProperty (String name, Object value)
257 throws SAXNotRecognizedException, SAXNotSupportedException
258 {
259 throw new SAXNotRecognizedException("Property: " + name);
260 }
261
262
263 /**
264 * Get a parser property.
265 *
266 * <p>No properties are currently recognized.</p>
267 *
268 * @param name The property name.
269 * @return The property value.
270 * @throws SAXNotRecognizedException If the property
271 * value can't be assigned or retrieved.
272 * @throws SAXNotSupportedException If the property
273 * value is not currently readable.
274 * @see org.xml.sax.XMLReader#getProperty
275 */
276 public Object getProperty (String name)
277 throws SAXNotRecognizedException, SAXNotSupportedException
278 {
279 throw new SAXNotRecognizedException("Property: " + name);
280 }
281
282
283 /**
284 * Set the entity resolver.
285 *
286 * @param resolver The new entity resolver.
287 * @see org.xml.sax.XMLReader#setEntityResolver
288 */
289 public void setEntityResolver (EntityResolver resolver)
290 {
291 entityResolver = resolver;
292 }
363 errorHandler = handler;
364 }
365
366
367 /**
368 * Return the current error handler.
369 *
370 * @return The current error handler, or null if none was supplied.
371 * @see org.xml.sax.XMLReader#getEntityResolver
372 */
373 public ErrorHandler getErrorHandler ()
374 {
375 return errorHandler;
376 }
377
378
379 /**
380 * Parse an XML document.
381 *
382 * @param systemId The absolute URL of the document.
383 * @throws java.io.IOException If there is a problem reading
384 * the raw content of the document.
385 * @throws SAXException If there is a problem
386 * processing the document.
387 * @see #parse(org.xml.sax.InputSource)
388 * @see org.xml.sax.Parser#parse(java.lang.String)
389 */
390 public void parse (String systemId)
391 throws IOException, SAXException
392 {
393 parse(new InputSource(systemId));
394 }
395
396
397 /**
398 * Parse an XML document.
399 *
400 * @param input An input source for the document.
401 * @throws java.io.IOException If there is a problem reading
402 * the raw content of the document.
403 * @throws SAXException If there is a problem
404 * processing the document.
405 * @see #parse(java.lang.String)
406 * @see org.xml.sax.Parser#parse(org.xml.sax.InputSource)
407 */
408 public void parse (InputSource input)
409 throws IOException, SAXException
410 {
411 if (parsing) {
412 throw new SAXException("Parser is already in use");
413 }
414 setupParser();
415 parsing = true;
416 try {
417 parser.parse(input);
418 } finally {
419 parsing = false;
420 }
421 parsing = false;
422 }
423
431 /**
432 * Adapter implementation method; do not call.
433 * Adapt a SAX1 document locator event.
434 *
435 * @param locator A document locator.
436 * @see org.xml.sax.ContentHandler#setDocumentLocator
437 */
438 public void setDocumentLocator (Locator locator)
439 {
440 this.locator = locator;
441 if (contentHandler != null) {
442 contentHandler.setDocumentLocator(locator);
443 }
444 }
445
446
447 /**
448 * Adapter implementation method; do not call.
449 * Adapt a SAX1 start document event.
450 *
451 * @throws SAXException The client may raise a
452 * processing exception.
453 * @see org.xml.sax.DocumentHandler#startDocument
454 */
455 public void startDocument ()
456 throws SAXException
457 {
458 if (contentHandler != null) {
459 contentHandler.startDocument();
460 }
461 }
462
463
464 /**
465 * Adapter implementation method; do not call.
466 * Adapt a SAX1 end document event.
467 *
468 * @throws SAXException The client may raise a
469 * processing exception.
470 * @see org.xml.sax.DocumentHandler#endDocument
471 */
472 public void endDocument ()
473 throws SAXException
474 {
475 if (contentHandler != null) {
476 contentHandler.endDocument();
477 }
478 }
479
480
481 /**
482 * Adapter implementation method; do not call.
483 * Adapt a SAX1 startElement event.
484 *
485 * <p>If necessary, perform Namespace processing.</p>
486 *
487 * @param qName The qualified (prefixed) name.
488 * @param qAtts The XML attribute list (with qnames).
489 * @throws SAXException The client may raise a
490 * processing exception.
491 */
492 public void startElement (String qName, AttributeList qAtts)
493 throws SAXException
494 {
495 // These are exceptions from the
496 // first pass; they should be
497 // ignored if there's a second pass,
498 // but reported otherwise.
499 List<SAXException> exceptions = null;
500
501 // If we're not doing Namespace
502 // processing, dispatch this quickly.
503 if (!namespaces) {
504 if (contentHandler != null) {
505 attAdapter.setAttributeList(qAtts);
506 contentHandler.startElement("", "", qName.intern(),
507 attAdapter);
508 }
509 return;
599 // now handle the deferred exception reports
600 if (exceptions != null && errorHandler != null) {
601 for (int i = 0; i < exceptions.size(); i++)
602 errorHandler.error((SAXParseException)
603 (exceptions.get(i)));
604 }
605
606 // OK, finally report the event.
607 if (contentHandler != null) {
608 String name[] = processName(qName, false, false);
609 contentHandler.startElement(name[0], name[1], name[2], atts);
610 }
611 }
612
613
614 /**
615 * Adapter implementation method; do not call.
616 * Adapt a SAX1 end element event.
617 *
618 * @param qName The qualified (prefixed) name.
619 * @throws SAXException The client may raise a
620 * processing exception.
621 * @see org.xml.sax.DocumentHandler#endElement
622 */
623 public void endElement (String qName)
624 throws SAXException
625 {
626 // If we're not doing Namespace
627 // processing, dispatch this quickly.
628 if (!namespaces) {
629 if (contentHandler != null) {
630 contentHandler.endElement("", "", qName.intern());
631 }
632 return;
633 }
634
635 // Split the name.
636 String names[] = processName(qName, false, false);
637 if (contentHandler != null) {
638 contentHandler.endElement(names[0], names[1], names[2]);
639 Enumeration<String> ePrefixes = nsSupport.getDeclaredPrefixes();
640 while (ePrefixes.hasMoreElements()) {
641 String prefix = ePrefixes.nextElement();
642 contentHandler.endPrefixMapping(prefix);
643 }
644 }
645 nsSupport.popContext();
646 }
647
648
649 /**
650 * Adapter implementation method; do not call.
651 * Adapt a SAX1 characters event.
652 *
653 * @param ch An array of characters.
654 * @param start The starting position in the array.
655 * @param length The number of characters to use.
656 * @throws SAXException The client may raise a
657 * processing exception.
658 * @see org.xml.sax.DocumentHandler#characters
659 */
660 public void characters (char ch[], int start, int length)
661 throws SAXException
662 {
663 if (contentHandler != null) {
664 contentHandler.characters(ch, start, length);
665 }
666 }
667
668
669 /**
670 * Adapter implementation method; do not call.
671 * Adapt a SAX1 ignorable whitespace event.
672 *
673 * @param ch An array of characters.
674 * @param start The starting position in the array.
675 * @param length The number of characters to use.
676 * @throws SAXException The client may raise a
677 * processing exception.
678 * @see org.xml.sax.DocumentHandler#ignorableWhitespace
679 */
680 public void ignorableWhitespace (char ch[], int start, int length)
681 throws SAXException
682 {
683 if (contentHandler != null) {
684 contentHandler.ignorableWhitespace(ch, start, length);
685 }
686 }
687
688
689 /**
690 * Adapter implementation method; do not call.
691 * Adapt a SAX1 processing instruction event.
692 *
693 * @param target The processing instruction target.
694 * @param data The remainder of the processing instruction
695 * @throws SAXException The client may raise a
696 * processing exception.
697 * @see org.xml.sax.DocumentHandler#processingInstruction
698 */
699 public void processingInstruction (String target, String data)
700 throws SAXException
701 {
702 if (contentHandler != null) {
703 contentHandler.processingInstruction(target, data);
704 }
705 }
706
707
708
709 ////////////////////////////////////////////////////////////////////
710 // Internal utility methods.
711 ////////////////////////////////////////////////////////////////////
712
713
714 /**
715 * Initialize the parser before each run.
731 parser.setDTDHandler(dtdHandler);
732 }
733 if (errorHandler != null) {
734 parser.setErrorHandler(errorHandler);
735 }
736 parser.setDocumentHandler(this);
737 locator = null;
738 }
739
740
741 /**
742 * Process a qualified (prefixed) name.
743 *
744 * <p>If the name has an undeclared prefix, use only the qname
745 * and make an ErrorHandler.error callback in case the app is
746 * interested.</p>
747 *
748 * @param qName The qualified (prefixed) name.
749 * @param isAttribute true if this is an attribute name.
750 * @return The name split into three parts.
751 * @throws SAXException The client may throw
752 * an exception if there is an error callback.
753 */
754 private String [] processName (String qName, boolean isAttribute,
755 boolean useException)
756 throws SAXException
757 {
758 String parts[] = nsSupport.processName(qName, nameParts,
759 isAttribute);
760 if (parts == null) {
761 if (useException)
762 throw makeException("Undeclared prefix: " + qName);
763 reportError("Undeclared prefix: " + qName);
764 parts = new String[3];
765 parts[0] = parts[1] = "";
766 parts[2] = qName.intern();
767 }
768 return parts;
769 }
770
771
772 /**
773 * Report a non-fatal error.
774 *
775 * @param message The error message.
776 * @throws SAXException The client may throw
777 * an exception.
778 */
779 void reportError (String message)
780 throws SAXException
781 {
782 if (errorHandler != null)
783 errorHandler.error(makeException(message));
784 }
785
786
787 /**
788 * Construct an exception for the current context.
789 *
790 * @param message The error message.
791 */
792 private SAXParseException makeException (String message)
793 {
794 if (locator != null) {
795 return new SAXParseException(message, locator);
796 } else {
797 return new SAXParseException(message, null, null, -1, -1);
798 }
799 }
800
801
802 /**
803 * Throw an exception if we are parsing.
804 *
805 * <p>Use this method to detect illegal feature or
806 * property changes.</p>
807 *
808 * @param type The type of thing (feature or property).
809 * @param name The feature or property name.
810 * @throws SAXNotSupportedException If a
811 * document is currently being parsed.
812 */
813 private void checkNotParsing (String type, String name)
814 throws SAXNotSupportedException
815 {
816 if (parsing) {
817 throw new SAXNotSupportedException("Cannot change " +
818 type + ' ' +
819 name + " while parsing");
820
821 }
822 }
823
824
825
826 ////////////////////////////////////////////////////////////////////
827 // Internal state.
828 ////////////////////////////////////////////////////////////////////
829
830 private NamespaceSupport nsSupport;
|