KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xerces > parsers > AbstractSAXParser


1 /*
2  * Copyright 2001-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.xerces.parsers;
18
19 import java.io.IOException JavaDoc;
20 import java.util.Locale JavaDoc;
21
22 import org.apache.xerces.impl.Constants;
23 import org.apache.xerces.xs.PSVIProvider;
24 import org.apache.xerces.util.EntityResolverWrapper;
25 import org.apache.xerces.util.EntityResolver2Wrapper;
26 import org.apache.xerces.util.ErrorHandlerWrapper;
27 import org.apache.xerces.util.SAXMessageFormatter;
28 import org.apache.xerces.util.SymbolHash;
29 import org.apache.xerces.util.XMLSymbols;
30 import org.apache.xerces.xni.Augmentations;
31 import org.apache.xerces.xni.NamespaceContext;
32 import org.apache.xerces.xni.QName;
33 import org.apache.xerces.xni.XMLAttributes;
34 import org.apache.xerces.xni.XMLLocator;
35 import org.apache.xerces.xni.XMLResourceIdentifier;
36 import org.apache.xerces.xni.XMLString;
37 import org.apache.xerces.xni.XNIException;
38 import org.apache.xerces.xni.parser.XMLConfigurationException;
39 import org.apache.xerces.xni.parser.XMLEntityResolver;
40 import org.apache.xerces.xni.parser.XMLErrorHandler;
41 import org.apache.xerces.xni.parser.XMLInputSource;
42 import org.apache.xerces.xni.parser.XMLParseException;
43 import org.apache.xerces.xni.parser.XMLParserConfiguration;
44 import org.apache.xerces.xs.AttributePSVI;
45 import org.apache.xerces.xs.ElementPSVI;
46 import org.xml.sax.AttributeList JavaDoc;
47 import org.xml.sax.Attributes JavaDoc;
48 import org.xml.sax.ContentHandler JavaDoc;
49 import org.xml.sax.DTDHandler JavaDoc;
50 import org.xml.sax.DocumentHandler JavaDoc;
51 import org.xml.sax.EntityResolver JavaDoc;
52 import org.xml.sax.ErrorHandler JavaDoc;
53 import org.xml.sax.InputSource JavaDoc;
54 import org.xml.sax.Locator JavaDoc;
55 import org.xml.sax.Parser JavaDoc;
56 import org.xml.sax.SAXException JavaDoc;
57 import org.xml.sax.SAXNotRecognizedException JavaDoc;
58 import org.xml.sax.SAXNotSupportedException JavaDoc;
59 import org.xml.sax.SAXParseException JavaDoc;
60 import org.xml.sax.XMLReader JavaDoc;
61 import org.xml.sax.ext.Attributes2 JavaDoc;
62 import org.xml.sax.ext.DeclHandler JavaDoc;
63 import org.xml.sax.ext.EntityResolver2 JavaDoc;
64 import org.xml.sax.ext.LexicalHandler JavaDoc;
65 import org.xml.sax.ext.Locator2 JavaDoc;
66 import org.xml.sax.helpers.LocatorImpl JavaDoc;
67
68 /**
69  * This is the base class of all SAX parsers. It implements both the
70  * SAX1 and SAX2 parser functionality, while the actual pipeline is
71  * defined in the parser configuration.
72  *
73  * @author Arnaud Le Hors, IBM
74  * @author Andy Clark, IBM
75  *
76  * @version $Id: AbstractSAXParser.java,v 1.59 2005/06/24 02:33:43 mrglavas Exp $
77  */

78 public abstract class AbstractSAXParser
79     extends AbstractXMLDocumentParser
80     implements PSVIProvider, // PSVI
81
Parser JavaDoc, XMLReader JavaDoc // SAX1, SAX2
82
{
83
84     //
85
// Constants
86
//
87

88     // features
89

90     /** Feature identifier: namespaces. */
91     protected static final String JavaDoc NAMESPACES =
92         Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
93
94     /** Feature identifier: namespace prefixes. */
95     protected static final String JavaDoc NAMESPACE_PREFIXES =
96         Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACE_PREFIXES_FEATURE;
97
98     /** Feature id: string interning. */
99     protected static final String JavaDoc STRING_INTERNING =
100         Constants.SAX_FEATURE_PREFIX + Constants.STRING_INTERNING_FEATURE;
101     
102     /** Feature identifier: allow notation and unparsed entity events to be sent out of order. */
103     // this is not meant to be a recognized feature, but we need it here to use
104
// if it is already a recognized feature for the pipeline
105
protected static final String JavaDoc ALLOW_UE_AND_NOTATION_EVENTS =
106         Constants.SAX_FEATURE_PREFIX + Constants.ALLOW_DTD_EVENTS_AFTER_ENDDTD_FEATURE;
107
108     /** Recognized features. */
109     private static final String JavaDoc[] RECOGNIZED_FEATURES = {
110         NAMESPACES,
111         NAMESPACE_PREFIXES,
112         STRING_INTERNING,
113     };
114
115     // properties
116

117     /** Property id: lexical handler. */
118     protected static final String JavaDoc LEXICAL_HANDLER =
119         Constants.SAX_PROPERTY_PREFIX + Constants.LEXICAL_HANDLER_PROPERTY;
120
121     /** Property id: declaration handler. */
122     protected static final String JavaDoc DECLARATION_HANDLER =
123         Constants.SAX_PROPERTY_PREFIX + Constants.DECLARATION_HANDLER_PROPERTY;
124
125     /** Property id: DOM node. */
126     protected static final String JavaDoc DOM_NODE =
127         Constants.SAX_PROPERTY_PREFIX + Constants.DOM_NODE_PROPERTY;
128
129     /** Recognized properties. */
130     private static final String JavaDoc[] RECOGNIZED_PROPERTIES = {
131         LEXICAL_HANDLER,
132         DECLARATION_HANDLER,
133         DOM_NODE,
134     };
135
136     //
137
// Data
138
//
139

140     // features
141

142     /** Namespaces. */
143     protected boolean fNamespaces;
144
145     /** Namespace prefixes. */
146     protected boolean fNamespacePrefixes = false;
147     
148     /** Lexical handler parameter entities. */
149     protected boolean fLexicalHandlerParameterEntities = true;
150     
151     /** Standalone document declaration. */
152     protected boolean fStandalone;
153     
154     /** Resolve DTD URIs. */
155     protected boolean fResolveDTDURIs = true;
156     
157     /** Use EntityResolver2. */
158     protected boolean fUseEntityResolver2 = true;
159     
160     /**
161      * XMLNS URIs: Namespace declarations in the
162      * http://www.w3.org/2000/xmlns/ namespace.
163      */

164     protected boolean fXMLNSURIs = false;
165
166     // parser handlers
167

168     /** Content handler. */
169     protected ContentHandler JavaDoc fContentHandler;
170
171     /** Document handler. */
172     protected DocumentHandler JavaDoc fDocumentHandler;
173     
174     /** Namespace context */
175     protected NamespaceContext fNamespaceContext;
176
177     /** DTD handler. */
178     protected org.xml.sax.DTDHandler JavaDoc fDTDHandler;
179
180     /** Decl handler. */
181     protected DeclHandler JavaDoc fDeclHandler;
182
183     /** Lexical handler. */
184     protected LexicalHandler JavaDoc fLexicalHandler;
185
186     protected QName fQName = new QName();
187
188     // state
189

190     /**
191      * True if a parse is in progress. This state is needed because
192      * some features/properties cannot be set while parsing (e.g.
193      * validation and namespaces).
194      */

195     protected boolean fParseInProgress = false;
196
197     // track the version of the document being parsed
198
protected String JavaDoc fVersion;
199
200     // temp vars
201
private final AttributesProxy fAttributesProxy = new AttributesProxy();
202     private Augmentations fAugmentations = null;
203
204
205     // temporary buffer for sending normalized values
206
// REVISIT: what should be the size of the buffer?
207
private static final int BUFFER_SIZE = 20;
208     private char[] fCharBuffer = new char[BUFFER_SIZE];
209
210     // allows us to keep track of whether an attribute has
211
// been declared twice, so that we can avoid exposing the
212
// second declaration to any registered DeclHandler
213
protected SymbolHash fDeclaredAttrs = null;
214
215     //
216
// Constructors
217
//
218

219     /** Default constructor. */
220     protected AbstractSAXParser(XMLParserConfiguration config) {
221         super(config);
222
223         config.addRecognizedFeatures(RECOGNIZED_FEATURES);
224         config.addRecognizedProperties(RECOGNIZED_PROPERTIES);
225
226         try {
227             config.setFeature(ALLOW_UE_AND_NOTATION_EVENTS, false);
228         }
229         catch (XMLConfigurationException e) {
230             // it wasn't a recognized feature, so we don't worry about it
231
}
232     } // <init>(XMLParserConfiguration)
233

234     //
235
// XMLDocumentHandler methods
236
//
237

238     /**
239      * The start of the document.
240      *
241      * @param locator The document locator, or null if the document
242      * location cannot be reported during the parsing
243      * of this document. However, it is <em>strongly</em>
244      * recommended that a locator be supplied that can
245      * at least report the system identifier of the
246      * document.
247      * @param encoding The auto-detected IANA encoding name of the entity
248      * stream. This value will be null in those situations
249      * where the entity encoding is not auto-detected (e.g.
250      * internal entities or a document entity that is
251      * parsed from a java.io.Reader).
252      * @param namespaceContext
253      * The namespace context in effect at the
254      * start of this document.
255      * This object represents the current context.
256      * Implementors of this class are responsible
257      * for copying the namespace bindings from the
258      * the current context (and its parent contexts)
259      * if that information is important.
260      * @param augs Additional information that may include infoset augmentations
261      *
262      * @throws XNIException Thrown by handler to signal an error.
263      */

264     public void startDocument(XMLLocator locator, String JavaDoc encoding,
265                               NamespaceContext namespaceContext, Augmentations augs)
266         throws XNIException {
267         
268         fNamespaceContext = namespaceContext;
269
270         try {
271             // SAX1
272
if (fDocumentHandler != null) {
273                 if (locator != null) {
274                     fDocumentHandler.setDocumentLocator(new LocatorProxy(locator));
275                 }
276                 fDocumentHandler.startDocument();
277             }
278
279             // SAX2
280
if (fContentHandler != null) {
281                 if (locator != null) {
282                     fContentHandler.setDocumentLocator(new LocatorProxy(locator));
283                 }
284                 fContentHandler.startDocument();
285             }
286         }
287         catch (SAXException JavaDoc e) {
288             throw new XNIException(e);
289         }
290
291     } // startDocument(locator,encoding,augs)
292

293     /**
294      * Notifies of the presence of an XMLDecl line in the document. If
295      * present, this method will be called immediately following the
296      * startDocument call.
297      *
298      * @param version The XML version.
299      * @param encoding The IANA encoding name of the document, or null if
300      * not specified.
301      * @param standalone The standalone value, or null if not specified.
302      * @param augs Additional information that may include infoset augmentations
303      *
304      * @throws XNIException Thrown by handler to signal an error.
305      */

306     public void xmlDecl(String JavaDoc version, String JavaDoc encoding, String JavaDoc standalone, Augmentations augs)
307         throws XNIException {
308         // the version need only be set once; if
309
// document's XML 1.0|1.1, that's how it'll stay
310
fVersion = version;
311         fStandalone = "yes".equals(standalone);
312     } // xmlDecl(String,String,String)
313

314     /**
315      * Notifies of the presence of the DOCTYPE line in the document.
316      *
317      * @param rootElement The name of the root element.
318      * @param publicId The public identifier if an external DTD or null
319      * if the external DTD is specified using SYSTEM.
320      * @param systemId The system identifier if an external DTD, null
321      * otherwise.
322      * @param augs Additional information that may include infoset augmentations
323      *
324      * @throws XNIException Thrown by handler to signal an error.
325      */

326     public void doctypeDecl(String JavaDoc rootElement,
327                             String JavaDoc publicId, String JavaDoc systemId, Augmentations augs)
328         throws XNIException {
329         fInDTD = true;
330
331         try {
332             // SAX2 extension
333
if (fLexicalHandler != null) {
334                 fLexicalHandler.startDTD(rootElement, publicId, systemId);
335             }
336         }
337         catch (SAXException JavaDoc e) {
338             throw new XNIException(e);
339         }
340
341         // is there a DeclHandler?
342
if(fDeclHandler != null) {
343             fDeclaredAttrs = new SymbolHash();
344         }
345
346     } // doctypeDecl(String,String,String)
347

348         /**
349      * This method notifies of the start of an entity. The DTD has the
350      * pseudo-name of "[dtd]" parameter entity names start with '%'; and
351      * general entity names are just the entity name.
352      * <p>
353      * <strong>Note:</strong> Since the document is an entity, the handler
354      * will be notified of the start of the document entity by calling the
355      * startEntity method with the entity name "[xml]" <em>before</em> calling
356      * the startDocument method. When exposing entity boundaries through the
357      * SAX API, the document entity is never reported, however.
358      * <p>
359      * <strong>Note:</strong> This method is not called for entity references
360      * appearing as part of attribute values.
361      *
362      * @param name The name of the entity.
363      * @param identifier The resource identifier.
364      * @param encoding The auto-detected IANA encoding name of the entity
365      * stream. This value will be null in those situations
366      * where the entity encoding is not auto-detected (e.g.
367      * internal parameter entities).
368      * @param augs Additional information that may include infoset augmentations
369      *
370      * @throws XNIException Thrown by handler to signal an error.
371      */

372     public void startGeneralEntity(String JavaDoc name, XMLResourceIdentifier identifier,
373                                    String JavaDoc encoding, Augmentations augs)
374         throws XNIException {
375         
376         try {
377             // Only report startEntity if this entity was actually read.
378
if (augs != null && Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
379                 // report skipped entity to content handler
380
if (fContentHandler != null) {
381                     fContentHandler.skippedEntity(name);
382                 }
383             }
384             else {
385                 // SAX2 extension
386
if (fLexicalHandler != null) {
387                     fLexicalHandler.startEntity(name);
388                 }
389             }
390         }
391         catch (SAXException JavaDoc e) {
392             throw new XNIException(e);
393         }
394
395     } // startGeneralEntity(String,String,String,String,String)
396

397     /**
398      * This method notifies the end of an entity. The DTD has the pseudo-name
399      * of "[dtd]" parameter entity names start with '%'; and general entity
400      * names are just the entity name.
401      * <p>
402      * <strong>Note:</strong> Since the document is an entity, the handler
403      * will be notified of the end of the document entity by calling the
404      * endEntity method with the entity name "[xml]" <em>after</em> calling
405      * the endDocument method. When exposing entity boundaries through the
406      * SAX API, the document entity is never reported, however.
407      * <p>
408      * <strong>Note:</strong> This method is not called for entity references
409      * appearing as part of attribute values.
410      *
411      * @param name The name of the entity.
412      * @param augs Additional information that may include infoset augmentations
413      *
414      * @throws XNIException Thrown by handler to signal an error.
415      */

416     public void endGeneralEntity(String JavaDoc name, Augmentations augs) throws XNIException {
417
418         try {
419             // Only report endEntity if this entity was actually read.
420
if (augs == null || !Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
421                 // SAX2 extension
422
if (fLexicalHandler != null) {
423                     fLexicalHandler.endEntity(name);
424                 }
425             }
426         }
427         catch (SAXException JavaDoc e) {
428             throw new XNIException(e);
429         }
430
431     } // endEntity(String)
432

433      /**
434      * The start of an element. If the document specifies the start element
435      * by using an empty tag, then the startElement method will immediately
436      * be followed by the endElement method, with no intervening methods.
437      *
438      * @param element The name of the element.
439      * @param attributes The element attributes.
440      * @param augs Additional information that may include infoset augmentations
441      *
442      * @throws XNIException Thrown by handler to signal an error.
443      */

444     public void startElement(QName element, XMLAttributes attributes, Augmentations augs)
445         throws XNIException {
446
447         try {
448             // SAX1
449
if (fDocumentHandler != null) {
450                 // REVISIT: should we support schema-normalized-value for SAX1 events
451
//
452
fAttributesProxy.setAttributes(attributes);
453                 fDocumentHandler.startElement(element.rawname, fAttributesProxy);
454             }
455
456             // SAX2
457
if (fContentHandler != null) {
458                 
459                 if (fNamespaces) {
460                     // send prefix mapping events
461
startNamespaceMapping();
462
463                     // REVISIT: It should not be necessary to iterate over the attribute
464
// list when the set of [namespace attributes] is empty for this
465
// element. This should be computable from the NamespaceContext, but
466
// since we currently don't report the mappings for the xml prefix
467
// we cannot use the declared prefix count for the current context
468
// to skip this section. -- mrglavas
469
int len = attributes.getLength();
470                     if (!fNamespacePrefixes) {
471                         for (int i = len - 1; i >= 0; --i) {
472                             attributes.getName(i, fQName);
473                             if ((fQName.prefix == XMLSymbols.PREFIX_XMLNS) ||
474                                (fQName.rawname == XMLSymbols.PREFIX_XMLNS)) {
475                                 // remove namespace declaration attributes
476
attributes.removeAttributeAt(i);
477                             }
478                         }
479                     }
480                     else if (!fXMLNSURIs) {
481                         for (int i = len - 1; i >= 0; --i) {
482                             attributes.getName(i, fQName);
483                             if ((fQName.prefix == XMLSymbols.PREFIX_XMLNS) ||
484                                (fQName.rawname == XMLSymbols.PREFIX_XMLNS)) {
485                                 // localpart should be empty string as per SAX documentation:
486
// http://www.saxproject.org/?selected=namespaces
487
fQName.prefix = "";
488                                 fQName.uri = "";
489                                 fQName.localpart = "";
490                                 attributes.setName(i, fQName);
491                             }
492                         }
493                     }
494                 }
495                 
496                 fAugmentations = augs;
497                 
498                 String JavaDoc uri = element.uri != null ? element.uri : "";
499                 String JavaDoc localpart = fNamespaces ? element.localpart : "";
500                 fAttributesProxy.setAttributes(attributes);
501                 fContentHandler.startElement(uri, localpart, element.rawname,
502                                              fAttributesProxy);
503             }
504         }
505         catch (SAXException JavaDoc e) {
506             throw new XNIException(e);
507         }
508
509     } // startElement(QName,XMLAttributes)
510

511     /**
512      * Character content.
513      *
514      * @param text The content.
515      * @param augs Additional information that may include infoset augmentations
516      *
517      * @throws XNIException Thrown by handler to signal an error.
518      */

519     public void characters(XMLString text, Augmentations augs) throws XNIException {
520         
521         // if type is union (XML Schema) it is possible that we receive
522
// character call with empty data
523
if (text.length == 0) {
524             return;
525         }
526
527
528         try {
529             // SAX1
530
if (fDocumentHandler != null) {
531                 // REVISIT: should we support schema-normalized-value for SAX1 events
532
//
533
fDocumentHandler.characters(text.ch, text.offset, text.length);
534             }
535
536             // SAX2
537
if (fContentHandler != null) {
538                 fContentHandler.characters(text.ch, text.offset, text.length);
539             }
540         }
541         catch (SAXException JavaDoc e) {
542             throw new XNIException(e);
543         }
544
545     } // characters(XMLString)
546

547     /**
548      * Ignorable whitespace. For this method to be called, the document
549      * source must have some way of determining that the text containing
550      * only whitespace characters should be considered ignorable. For
551      * example, the validator can determine if a length of whitespace
552      * characters in the document are ignorable based on the element
553      * content model.
554      *
555      * @param text The ignorable whitespace.
556      * @param augs Additional information that may include infoset augmentations
557      *
558      * @throws XNIException Thrown by handler to signal an error.
559      */

560     public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException {
561
562         try {
563             // SAX1
564
if (fDocumentHandler != null) {
565                 fDocumentHandler.ignorableWhitespace(text.ch, text.offset, text.length);
566             }
567
568             // SAX2
569
if (fContentHandler != null) {
570                 fContentHandler.ignorableWhitespace(text.ch, text.offset, text.length);
571             }
572         }
573         catch (SAXException JavaDoc e) {
574             throw new XNIException(e);
575         }
576
577     } // ignorableWhitespace(XMLString)
578

579     /**
580      * The end of an element.
581      *
582      * @param element The name of the element.
583      * @param augs Additional information that may include infoset augmentations
584      *
585      * @throws XNIException Thrown by handler to signal an error.
586      */

587     public void endElement(QName element, Augmentations augs) throws XNIException {
588         
589
590         try {
591             // SAX1
592
if (fDocumentHandler != null) {
593                 fDocumentHandler.endElement(element.rawname);
594             }
595
596             // SAX2
597
if (fContentHandler != null) {
598                 fAugmentations = augs;
599                 String JavaDoc uri = element.uri != null ? element.uri : "";
600                 String JavaDoc localpart = fNamespaces ? element.localpart : "";
601                 fContentHandler.endElement(uri, localpart,
602                                            element.rawname);
603                 if (fNamespaces) {
604                     endNamespaceMapping();
605                 }
606             }
607         }
608         catch (SAXException JavaDoc e) {
609             throw new XNIException(e);
610         }
611
612     } // endElement(QName)
613

614         /**
615      * The start of a CDATA section.
616      * @param augs Additional information that may include infoset augmentations
617      *
618      * @throws XNIException Thrown by handler to signal an error.
619      */

620     public void startCDATA(Augmentations augs) throws XNIException {
621
622         try {
623             // SAX2 extension
624
if (fLexicalHandler != null) {
625                 fLexicalHandler.startCDATA();
626             }
627         }
628         catch (SAXException JavaDoc e) {
629             throw new XNIException(e);
630         }
631
632     } // startCDATA()
633

634     /**
635      * The end of a CDATA section.
636      * @param augs Additional information that may include infoset augmentations
637      *
638      * @throws XNIException Thrown by handler to signal an error.
639      */

640     public void endCDATA(Augmentations augs) throws XNIException {
641
642         try {
643             // SAX2 extension
644
if (fLexicalHandler != null) {
645                 fLexicalHandler.endCDATA();
646             }
647         }
648         catch (SAXException JavaDoc e) {
649             throw new XNIException(e);
650         }
651
652     } // endCDATA()
653

654     /**
655      * A comment.
656      *
657      * @param text The text in the comment.
658      * @param augs Additional information that may include infoset augmentations
659      *
660      * @throws XNIException Thrown by application to signal an error.
661      */

662     public void comment(XMLString text, Augmentations augs) throws XNIException {
663
664         try {
665             // SAX2 extension
666
if (fLexicalHandler != null) {
667                 fLexicalHandler.comment(text.ch, 0, text.length);
668             }
669         }
670         catch (SAXException JavaDoc e) {
671             throw new XNIException(e);
672         }
673
674     } // comment(XMLString)
675

676     /**
677      * A processing instruction. Processing instructions consist of a
678      * target name and, optionally, text data. The data is only meaningful
679      * to the application.
680      * <p>
681      * Typically, a processing instruction's data will contain a series
682      * of pseudo-attributes. These pseudo-attributes follow the form of
683      * element attributes but are <strong>not</strong> parsed or presented
684      * to the application as anything other than text. The application is
685      * responsible for parsing the data.
686      *
687      * @param target The target.
688      * @param data The data or null if none specified.
689      * @param augs Additional information that may include infoset augmentations
690      *
691      * @throws XNIException Thrown by handler to signal an error.
692      */

693     public void processingInstruction(String JavaDoc target, XMLString data, Augmentations augs)
694         throws XNIException {
695
696         //
697
// REVISIT - I keep running into SAX apps that expect
698
// null data to be an empty string, which is contrary
699
// to the comment for this method in the SAX API.
700
//
701

702         try {
703             // SAX1
704
if (fDocumentHandler != null) {
705                 fDocumentHandler.processingInstruction(target,
706                                                        data.toString());
707             }
708
709             // SAX2
710
if (fContentHandler != null) {
711                 fContentHandler.processingInstruction(target, data.toString());
712             }
713         }
714         catch (SAXException JavaDoc e) {
715             throw new XNIException(e);
716         }
717
718     } // processingInstruction(String,XMLString)
719

720
721     /**
722      * The end of the document.
723      * @param augs Additional information that may include infoset augmentations
724      *
725      * @throws XNIException Thrown by handler to signal an error.
726      */

727     public void endDocument(Augmentations augs) throws XNIException {
728
729         try {
730             // SAX1
731
if (fDocumentHandler != null) {
732                 fDocumentHandler.endDocument();
733             }
734
735             // SAX2
736
if (fContentHandler != null) {
737                 fContentHandler.endDocument();
738             }
739         }
740         catch (SAXException JavaDoc e) {
741             throw new XNIException(e);
742         }
743
744     } // endDocument()
745

746     //
747
// XMLDTDHandler methods
748
//
749

750     /**
751      * The start of the DTD external subset.
752      *
753      * @param augs Additional information that may include infoset
754      * augmentations.
755      *
756      * @throws XNIException Thrown by handler to signal an error.
757      */

758     public void startExternalSubset(XMLResourceIdentifier identifier,
759                                     Augmentations augs) throws XNIException {
760         startParameterEntity("[dtd]", null, null, augs);
761     }
762
763     /**
764      * The end of the DTD external subset.
765      *
766      * @param augs Additional information that may include infoset
767      * augmentations.
768      *
769      * @throws XNIException Thrown by handler to signal an error.
770      */

771     public void endExternalSubset(Augmentations augs) throws XNIException {
772         endParameterEntity("[dtd]", augs);
773     }
774
775     /**
776      * This method notifies of the start of parameter entity. The DTD has the
777      * pseudo-name of "[dtd]" parameter entity names start with '%'; and
778      * general entity names are just the entity name.
779      * <p>
780      * <strong>Note:</strong> Since the document is an entity, the handler
781      * will be notified of the start of the document entity by calling the
782      * startEntity method with the entity name "[xml]" <em>before</em> calling
783      * the startDocument method. When exposing entity boundaries through the
784      * SAX API, the document entity is never reported, however.
785      * <p>
786      * <strong>Note:</strong> This method is not called for entity references
787      * appearing as part of attribute values.
788      *
789      * @param name The name of the parameter entity.
790      * @param identifier The resource identifier.
791      * @param encoding The auto-detected IANA encoding name of the entity
792      * stream. This value will be null in those situations
793      * where the entity encoding is not auto-detected (e.g.
794      * internal parameter entities).
795      * @param augs Additional information that may include infoset
796      * augmentations.
797      *
798      * @throws XNIException Thrown by handler to signal an error.
799      */

800     public void startParameterEntity(String JavaDoc name,
801                                      XMLResourceIdentifier identifier,
802                                      String JavaDoc encoding, Augmentations augs)
803         throws XNIException {
804
805         try {
806             // Only report startEntity if this entity was actually read.
807
if (augs != null && Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
808                 // report skipped entity to content handler
809
if (fContentHandler != null) {
810                     fContentHandler.skippedEntity(name);
811                 }
812             }
813             else {
814                 // SAX2 extension
815
if (fLexicalHandler != null && fLexicalHandlerParameterEntities) {
816                     fLexicalHandler.startEntity(name);
817                 }
818             }
819         }
820         catch (SAXException JavaDoc e) {
821             throw new XNIException(e);
822         }
823
824     } // startParameterEntity(String,identifier,String,Augmentation)
825

826     /**
827      * This method notifies the end of an entity. The DTD has the pseudo-name
828      * of "[dtd]" parameter entity names start with '%'; and general entity
829      * names are just the entity name.
830      * <p>
831      * <strong>Note:</strong> Since the document is an entity, the handler
832      * will be notified of the end of the document entity by calling the
833      * endEntity method with the entity name "[xml]" <em>after</em> calling
834      * the endDocument method. When exposing entity boundaries through the
835      * SAX API, the document entity is never reported, however.
836      * <p>
837      * <strong>Note:</strong> This method is not called for entity references
838      * appearing as part of attribute values.
839      *
840      * @param name The name of the parameter entity.
841      * @param augs Additional information that may include infoset
842      * augmentations.
843      *
844      * @throws XNIException Thrown by handler to signal an error.
845      */

846     public void endParameterEntity(String JavaDoc name, Augmentations augs) throws XNIException {
847
848         try {
849             // Only report endEntity if this entity was actually read.
850
if (augs == null || !Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
851                 // SAX2 extension
852
if (fLexicalHandler != null && fLexicalHandlerParameterEntities) {
853                     fLexicalHandler.endEntity(name);
854                 }
855             }
856         }
857         catch (SAXException JavaDoc e) {
858             throw new XNIException(e);
859         }
860
861     } // endEntity(String)
862

863     /**
864      * An element declaration.
865      *
866      * @param name The name of the element.
867      * @param contentModel The element content model.
868      *
869      * @param augs Additional information that may include infoset
870      * augmentations.
871      *
872      * @throws XNIException Thrown by handler to signal an error.
873      */

874     public void elementDecl(String JavaDoc name, String JavaDoc contentModel, Augmentations augs)
875         throws XNIException {
876
877         try {
878             // SAX2 extension
879
if (fDeclHandler != null) {
880                 fDeclHandler.elementDecl(name, contentModel);
881             }
882         }
883         catch (SAXException JavaDoc e) {
884             throw new XNIException(e);
885         }
886
887     } // elementDecl(String,String, Augmentations)
888

889     /**
890      * An attribute declaration.
891      *
892      * @param elementName The name of the element that this attribute
893      * is associated with.
894      * @param attributeName The name of the attribute.
895      * @param type The attribute type. This value will be one of
896      * the following: "CDATA", "ENTITY", "ENTITIES",
897      * "ENUMERATION", "ID", "IDREF", "IDREFS",
898      * "NMTOKEN", "NMTOKENS", or "NOTATION".
899      * @param enumeration If the type has the value "ENUMERATION" or
900      * "NOTATION", this array holds the allowed attribute
901      * values; otherwise, this array is null.
902      * @param defaultType The attribute default type. This value will be
903      * one of the following: "#FIXED", "#IMPLIED",
904      * "#REQUIRED", or null.
905      * @param defaultValue The attribute default value, or null if no
906      * default value is specified.
907      *
908      * @param nonNormalizedDefaultValue The attribute default value with no normalization
909      * performed, or null if no default value is specified.
910      * @param augs Additional information that may include infoset
911      * augmentations.
912      *
913      * @throws XNIException Thrown by handler to signal an error.
914      */

915     public void attributeDecl(String JavaDoc elementName, String JavaDoc attributeName,
916                               String JavaDoc type, String JavaDoc[] enumeration,
917                               String JavaDoc defaultType, XMLString defaultValue,
918                               XMLString nonNormalizedDefaultValue, Augmentations augs) throws XNIException {
919
920         try {
921             // SAX2 extension
922
if (fDeclHandler != null) {
923                 // used as a key to detect duplicate attribute definitions.
924
String JavaDoc elemAttr = new StringBuffer JavaDoc(elementName).append("<").append(attributeName).toString();
925                 if(fDeclaredAttrs.get(elemAttr) != null) {
926                     // we aren't permitted to return duplicate attribute definitions
927
return;
928                 }
929                 fDeclaredAttrs.put(elemAttr, Boolean.TRUE);
930                 if (type.equals("NOTATION") ||
931                     type.equals("ENUMERATION")) {
932
933                     StringBuffer JavaDoc str = new StringBuffer JavaDoc();
934                     if (type.equals("NOTATION")) {
935                       str.append(type);
936                       str.append(" (");
937                     }
938                     else {
939                       str.append("(");
940                     }
941                     for (int i = 0; i < enumeration.length; i++) {
942                         str.append(enumeration[i]);
943                         if (i < enumeration.length - 1) {
944                             str.append('|');
945                         }
946                     }
947                     str.append(')');
948                     type = str.toString();
949                 }
950                 String JavaDoc value = (defaultValue==null) ? null : defaultValue.toString();
951                 fDeclHandler.attributeDecl(elementName, attributeName,
952                                            type, defaultType, value);
953             }
954         }
955         catch (SAXException JavaDoc e) {
956             throw new XNIException(e);
957         }
958
959     } // attributeDecl(String,String,String,String[],String,XMLString, XMLString, Augmentations)
960

961     /**
962      * An internal entity declaration.
963      *
964      * @param name The name of the entity. Parameter entity names start with
965      * '%', whereas the name of a general entity is just the
966      * entity name.
967      * @param text The value of the entity.
968      * @param nonNormalizedText The non-normalized value of the entity. This
969      * value contains the same sequence of characters that was in
970      * the internal entity declaration, without any entity
971      * references expanded.
972      *
973      * @param augs Additional information that may include infoset
974      * augmentations.
975      *
976      * @throws XNIException Thrown by handler to signal an error.
977      */

978     public void internalEntityDecl(String JavaDoc name, XMLString text,
979                                    XMLString nonNormalizedText,
980                                    Augmentations augs) throws XNIException {
981
982         try {
983             // SAX2 extensions
984
if (fDeclHandler != null) {
985                 fDeclHandler.internalEntityDecl(name, text.toString());
986             }
987         }
988         catch (SAXException JavaDoc e) {
989             throw new XNIException(e);
990         }
991
992     } // internalEntityDecl(String,XMLString,XMLString)
993

994     /**
995      * An external entity declaration.
996      *
997      * @param name The name of the entity. Parameter entity names start
998      * with '%', whereas the name of a general entity is just
999      * the entity name.
1000     * @param identifier An object containing all location information
1001     * pertinent to this entity.
1002     * @param augs Additional information that may include infoset
1003     * augmentations.
1004     *
1005     * @throws XNIException Thrown by handler to signal an error.
1006     */

1007    public void externalEntityDecl(String JavaDoc name, XMLResourceIdentifier identifier,
1008                                   Augmentations augs) throws XNIException {
1009        try {
1010            // SAX2 extension
1011
if (fDeclHandler != null) {
1012                String JavaDoc publicId = identifier.getPublicId();
1013                String JavaDoc systemId = fResolveDTDURIs ?
1014                    identifier.getExpandedSystemId() : identifier.getLiteralSystemId();
1015                fDeclHandler.externalEntityDecl(name, publicId, systemId);
1016            }
1017        }
1018        catch (SAXException JavaDoc e) {
1019            throw new XNIException(e);
1020        }
1021
1022    } // externalEntityDecl(String,,XMLResourceIdentifier, Augmentations)
1023

1024    /**
1025     * An unparsed entity declaration.
1026     *
1027     * @param name The name of the entity.
1028     * @param identifier An object containing all location information
1029     * pertinent to this entity.
1030     * @param notation The name of the notation.
1031     *
1032     * @param augs Additional information that may include infoset
1033     * augmentations.
1034     *
1035     * @throws XNIException Thrown by handler to signal an error.
1036     */

1037    public void unparsedEntityDecl(String JavaDoc name, XMLResourceIdentifier identifier,
1038                                   String JavaDoc notation,
1039                                   Augmentations augs) throws XNIException {
1040        try {
1041            // SAX2 extension
1042
if (fDTDHandler != null) {
1043                String JavaDoc publicId = identifier.getPublicId();
1044                String JavaDoc systemId = fResolveDTDURIs ?
1045                    identifier.getExpandedSystemId() : identifier.getLiteralSystemId();
1046                fDTDHandler.unparsedEntityDecl(name, publicId, systemId, notation);
1047            }
1048        }
1049        catch (SAXException JavaDoc e) {
1050            throw new XNIException(e);
1051        }
1052
1053    } // unparsedEntityDecl(String,XMLResourceIdentifier, String, Augmentations)
1054

1055    /**
1056     * A notation declaration
1057     *
1058     * @param name The name of the notation.
1059     * @param identifier An object containing all location information
1060     * pertinent to this notation.
1061     * @param augs Additional information that may include infoset
1062     * augmentations.
1063     *
1064     * @throws XNIException Thrown by handler to signal an error.
1065     */

1066    public void notationDecl(String JavaDoc name, XMLResourceIdentifier identifier,
1067                             Augmentations augs) throws XNIException {
1068        try {
1069            // SAX1 and SAX2
1070
if (fDTDHandler != null) {
1071                String JavaDoc publicId = identifier.getPublicId();
1072                String JavaDoc systemId = fResolveDTDURIs ?
1073                    identifier.getExpandedSystemId() : identifier.getLiteralSystemId();
1074                fDTDHandler.notationDecl(name, publicId, systemId);
1075            }
1076        }
1077        catch (SAXException JavaDoc e) {
1078            throw new XNIException(e);
1079        }
1080
1081    } // notationDecl(String,XMLResourceIdentifier, Augmentations)
1082

1083    /**
1084     * The end of the DTD.
1085     *
1086     * @param augs Additional information that may include infoset
1087     * augmentations.
1088     *
1089     * @throws XNIException Thrown by handler to signal an error.
1090     */

1091    public void endDTD(Augmentations augs) throws XNIException {
1092        fInDTD = false;
1093
1094        try {
1095            // SAX2 extension
1096
if (fLexicalHandler != null) {
1097                fLexicalHandler.endDTD();
1098            }
1099        }
1100        catch (SAXException JavaDoc e) {
1101            throw new XNIException(e);
1102        }
1103        if(fDeclaredAttrs != null) {
1104            // help out the GC
1105
fDeclaredAttrs.clear();
1106        }
1107
1108    } // endDTD()
1109

1110    //
1111
// Parser and XMLReader methods
1112
//
1113

1114    /**
1115     * Parses the input source specified by the given system identifier.
1116     * <p>
1117     * This method is equivalent to the following:
1118     * <pre>
1119     * parse(new InputSource(systemId));
1120     * </pre>
1121     *
1122     * @param systemId The system identifier (URI).
1123     *
1124     * @exception org.xml.sax.SAXException Throws exception on SAX error.
1125     * @exception java.io.IOException Throws exception on i/o error.
1126     */

1127    public void parse(String JavaDoc systemId) throws SAXException JavaDoc, IOException JavaDoc {
1128
1129        // parse document
1130
XMLInputSource source = new XMLInputSource(null, systemId, null);
1131        try {
1132            parse(source);
1133        }
1134
1135        // wrap XNI exceptions as SAX exceptions
1136
catch (XMLParseException e) {
1137            Exception JavaDoc ex = e.getException();
1138            if (ex == null) {
1139                // must be a parser exception; mine it for locator info and throw
1140
// a SAXParseException
1141
LocatorImpl JavaDoc locatorImpl = new LocatorImpl JavaDoc(){
1142                    public String JavaDoc getXMLVersion() {
1143                        return fVersion;
1144                    }
1145                    // since XMLParseExceptions know nothing about encoding,
1146
// we cannot return anything meaningful in this context.
1147
// We *could* consult the LocatorProxy, but the
1148
// application can do this itself if it wishes to possibly
1149
// be mislead.
1150
public String JavaDoc getEncoding() {
1151                        return null;
1152                    }
1153                };
1154                locatorImpl.setPublicId(e.getPublicId());
1155                locatorImpl.setSystemId(e.getExpandedSystemId());
1156                locatorImpl.setLineNumber(e.getLineNumber());
1157                locatorImpl.setColumnNumber(e.getColumnNumber());
1158                throw new SAXParseException JavaDoc(e.getMessage(), locatorImpl);
1159            }
1160            if (ex instanceof SAXException JavaDoc) {
1161                // why did we create an XMLParseException?
1162
throw (SAXException JavaDoc)ex;
1163            }
1164            if (ex instanceof IOException JavaDoc) {
1165                throw (IOException JavaDoc)ex;
1166            }
1167            throw new SAXException JavaDoc(ex);
1168        }
1169        catch (XNIException e) {
1170            Exception JavaDoc ex = e.getException();
1171            if (ex == null) {
1172                throw new SAXException JavaDoc(e.getMessage());
1173            }
1174            if (ex instanceof SAXException JavaDoc) {
1175                throw (SAXException JavaDoc)ex;
1176            }
1177            if (ex instanceof IOException JavaDoc) {
1178                throw (IOException JavaDoc)ex;
1179            }
1180            throw new SAXException JavaDoc(ex);
1181        }
1182
1183    } // parse(String)
1184

1185    /**
1186     * parse
1187     *
1188     * @param inputSource
1189     *
1190     * @exception org.xml.sax.SAXException
1191     * @exception java.io.IOException
1192     */

1193    public void parse(InputSource inputSource)
1194        throws SAXException JavaDoc, IOException JavaDoc {
1195
1196        // parse document
1197
try {
1198            XMLInputSource xmlInputSource =
1199                new XMLInputSource(inputSource.getPublicId(),
1200                                   inputSource.getSystemId(),
1201                                   null);
1202            xmlInputSource.setByteStream(inputSource.getByteStream());
1203            xmlInputSource.setCharacterStream(inputSource.getCharacterStream());
1204            xmlInputSource.setEncoding(inputSource.getEncoding());
1205            parse(xmlInputSource);
1206        }
1207
1208        // wrap XNI exceptions as SAX exceptions
1209
catch (XMLParseException e) {
1210            Exception JavaDoc ex = e.getException();
1211            if (ex == null) {
1212                // must be a parser exception; mine it for locator info and throw
1213
// a SAXParseException
1214
LocatorImpl JavaDoc locatorImpl = new LocatorImpl JavaDoc() {
1215                    public String JavaDoc getXMLVersion() {
1216                        return fVersion;
1217                    }
1218                    // since XMLParseExceptions know nothing about encoding,
1219
// we cannot return anything meaningful in this context.
1220
// We *could* consult the LocatorProxy, but the
1221
// application can do this itself if it wishes to possibly
1222
// be mislead.
1223
public String JavaDoc getEncoding() {
1224                        return null;
1225                    }
1226                };
1227                locatorImpl.setPublicId(e.getPublicId());
1228                locatorImpl.setSystemId(e.getExpandedSystemId());
1229                locatorImpl.setLineNumber(e.getLineNumber());
1230                locatorImpl.setColumnNumber(e.getColumnNumber());
1231                throw new SAXParseException JavaDoc(e.getMessage(), locatorImpl);
1232            }
1233            if (ex instanceof SAXException JavaDoc) {
1234                // why did we create an XMLParseException?
1235
throw (SAXException JavaDoc)ex;
1236            }
1237            if (ex instanceof IOException JavaDoc) {
1238                throw (IOException JavaDoc)ex;
1239            }
1240            throw new SAXException JavaDoc(ex);
1241        }
1242        catch (XNIException e) {
1243            Exception JavaDoc ex = e.getException();
1244            if (ex == null) {
1245                throw new SAXException JavaDoc(e.getMessage());
1246            }
1247            if (ex instanceof SAXException JavaDoc) {
1248                throw (SAXException JavaDoc)ex;
1249            }
1250            if (ex instanceof IOException JavaDoc) {
1251                throw (IOException JavaDoc)ex;
1252            }
1253            throw new SAXException JavaDoc(ex);
1254        }
1255
1256    } // parse(InputSource)
1257

1258    /**
1259     * Sets the resolver used to resolve external entities. The EntityResolver
1260     * interface supports resolution of public and system identifiers.
1261     *
1262     * @param resolver The new entity resolver. Passing a null value will
1263     * uninstall the currently installed resolver.
1264     */

1265    public void setEntityResolver(EntityResolver resolver) {
1266
1267        try {
1268            XMLEntityResolver xer = (XMLEntityResolver) fConfiguration.getProperty(ENTITY_RESOLVER);
1269            if (fUseEntityResolver2 && resolver instanceof EntityResolver2 JavaDoc) {
1270                if (xer instanceof EntityResolver2Wrapper) {
1271                    EntityResolver2Wrapper er2w = (EntityResolver2Wrapper) xer;
1272                    er2w.setEntityResolver((EntityResolver2 JavaDoc) resolver);
1273                }
1274                else {
1275                    fConfiguration.setProperty(ENTITY_RESOLVER,
1276                            new EntityResolver2Wrapper((EntityResolver2 JavaDoc) resolver));
1277                }
1278            }
1279            else {
1280                if (xer instanceof EntityResolverWrapper) {
1281                    EntityResolverWrapper erw = (EntityResolverWrapper) xer;
1282                    erw.setEntityResolver(resolver);
1283                }
1284                else {
1285                    fConfiguration.setProperty(ENTITY_RESOLVER,
1286                            new EntityResolverWrapper(resolver));
1287                }
1288            }
1289        }
1290        catch (XMLConfigurationException e) {
1291            // do nothing
1292
}
1293
1294    } // setEntityResolver(EntityResolver)
1295

1296    /**
1297     * Return the current entity resolver.
1298     *
1299     * @return The current entity resolver, or null if none
1300     * has been registered.
1301     * @see #setEntityResolver
1302     */

1303    public EntityResolver getEntityResolver() {
1304
1305        EntityResolver entityResolver = null;
1306        try {
1307            XMLEntityResolver xmlEntityResolver =
1308                (XMLEntityResolver)fConfiguration.getProperty(ENTITY_RESOLVER);
1309            if (xmlEntityResolver != null) {
1310                if (xmlEntityResolver instanceof EntityResolverWrapper) {
1311                    entityResolver =
1312                        ((EntityResolverWrapper) xmlEntityResolver).getEntityResolver();
1313                }
1314                else if (xmlEntityResolver instanceof EntityResolver2Wrapper) {
1315                    entityResolver =
1316                        ((EntityResolver2Wrapper) xmlEntityResolver).getEntityResolver();
1317                }
1318            }
1319        }
1320        catch (XMLConfigurationException e) {
1321            // do nothing
1322
}
1323        return entityResolver;
1324
1325    } // getEntityResolver():EntityResolver
1326

1327    /**
1328     * Allow an application to register an error event handler.
1329     *
1330     * <p>If the application does not register an error handler, all
1331     * error events reported by the SAX parser will be silently
1332     * ignored; however, normal processing may not continue. It is
1333     * highly recommended that all SAX applications implement an
1334     * error handler to avoid unexpected bugs.</p>
1335     *
1336     * <p>Applications may register a new or different handler in the
1337     * middle of a parse, and the SAX parser must begin using the new
1338     * handler immediately.</p>
1339     *
1340     * @param errorHandler The error handler.
1341     * @see #getErrorHandler
1342     */

1343    public void setErrorHandler(ErrorHandler errorHandler) {
1344
1345        try {
1346            XMLErrorHandler xeh = (XMLErrorHandler) fConfiguration.getProperty(ERROR_HANDLER);
1347            if (xeh instanceof ErrorHandlerWrapper) {
1348                ErrorHandlerWrapper ehw = (ErrorHandlerWrapper) xeh;
1349                ehw.setErrorHandler(errorHandler);
1350            }
1351            else {
1352                fConfiguration.setProperty(ERROR_HANDLER,
1353                        new ErrorHandlerWrapper(errorHandler));
1354            }
1355        }
1356        catch (XMLConfigurationException e) {
1357            // do nothing
1358
}
1359
1360    } // setErrorHandler(ErrorHandler)
1361

1362    /**
1363     * Return the current error handler.
1364     *
1365     * @return The current error handler, or null if none
1366     * has been registered.
1367     * @see #setErrorHandler
1368     */

1369    public ErrorHandler getErrorHandler() {
1370
1371        ErrorHandler errorHandler = null;
1372        try {
1373            XMLErrorHandler xmlErrorHandler =
1374                (XMLErrorHandler)fConfiguration.getProperty(ERROR_HANDLER);
1375            if (xmlErrorHandler != null &&
1376                xmlErrorHandler instanceof ErrorHandlerWrapper) {
1377                errorHandler = ((ErrorHandlerWrapper)xmlErrorHandler).getErrorHandler();
1378            }
1379        }
1380        catch (XMLConfigurationException e) {
1381            // do nothing
1382
}
1383        return errorHandler;
1384
1385    } // getErrorHandler():ErrorHandler
1386

1387    /**
1388     * Set the locale to use for messages.
1389     *
1390     * @param locale The locale object to use for localization of messages.
1391     *
1392     * @exception SAXException An exception thrown if the parser does not
1393     * support the specified locale.
1394     *
1395     * @see org.xml.sax.Parser
1396     */

1397    public void setLocale(Locale JavaDoc locale) throws SAXException JavaDoc {
1398        //REVISIT:this methods is not part of SAX2 interfaces, we should throw exception
1399
//if any application uses SAX2 and sets locale also. -nb
1400
fConfiguration.setLocale(locale);
1401
1402    } // setLocale(Locale)
1403

1404    /**
1405     * Allow an application to register a DTD event handler.
1406     * <p>
1407     * If the application does not register a DTD handler, all DTD
1408     * events reported by the SAX parser will be silently ignored.
1409     * <p>
1410     * Applications may register a new or different handler in the
1411     * middle of a parse, and the SAX parser must begin using the new
1412     * handler immediately.
1413     *
1414     * @param dtdHandler The DTD handler.
1415     *
1416
1417     * @see #getDTDHandler
1418     */

1419    public void setDTDHandler(DTDHandler JavaDoc dtdHandler) {
1420        fDTDHandler = dtdHandler;
1421    } // setDTDHandler(DTDHandler)
1422

1423    //
1424
// Parser methods
1425
//
1426

1427    /**
1428     * Allow an application to register a document event handler.
1429     * <p>
1430     * If the application does not register a document handler, all
1431     * document events reported by the SAX parser will be silently
1432     * ignored (this is the default behaviour implemented by
1433     * HandlerBase).
1434     * <p>
1435     * Applications may register a new or different handler in the
1436     * middle of a parse, and the SAX parser must begin using the new
1437     * handler immediately.
1438     *
1439     * @param documentHandler The document handler.
1440     */

1441    public void setDocumentHandler(DocumentHandler JavaDoc documentHandler) {
1442        fDocumentHandler = documentHandler;
1443    } // setDocumentHandler(DocumentHandler)
1444

1445    //
1446
// XMLReader methods
1447
//
1448

1449    /**
1450     * Allow an application to register a content event handler.
1451     * <p>
1452     * If the application does not register a content handler, all
1453     * content events reported by the SAX parser will be silently
1454     * ignored.
1455     * <p>
1456     * Applications may register a new or different handler in the
1457     * middle of a parse, and the SAX parser must begin using the new
1458     * handler immediately.
1459     *
1460     * @param contentHandler The content handler.
1461     *
1462     * @see #getContentHandler
1463     */

1464    public void setContentHandler(ContentHandler JavaDoc contentHandler) {
1465        fContentHandler = contentHandler;
1466    } // setContentHandler(ContentHandler)
1467

1468    /**
1469     * Return the current content handler.
1470     *
1471     * @return The current content handler, or null if none
1472     * has been registered.
1473     *
1474     * @see #setContentHandler
1475     */

1476    public ContentHandler JavaDoc getContentHandler() {
1477        return fContentHandler;
1478    } // getContentHandler():ContentHandler
1479

1480    /**
1481     * Return the current DTD handler.
1482     *
1483     * @return The current DTD handler, or null if none
1484     * has been registered.
1485     * @see #setDTDHandler
1486     */

1487    public DTDHandler JavaDoc getDTDHandler() {
1488        return fDTDHandler;
1489    } // getDTDHandler():DTDHandler
1490

1491    /**
1492     * Set the state of any feature in a SAX2 parser. The parser
1493     * might not recognize the feature, and if it does recognize
1494     * it, it might not be able to fulfill the request.
1495     *
1496     * @param featureId The unique identifier (URI) of the feature.
1497     * @param state The requested state of the feature (true or false).
1498     *
1499     * @exception SAXNotRecognizedException If the
1500     * requested feature is not known.
1501     * @exception SAXNotSupportedException If the
1502     * requested feature is known, but the requested
1503     * state is not supported.
1504     */

1505    public void setFeature(String JavaDoc featureId, boolean state)
1506        throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
1507
1508        try {
1509            //
1510
// SAX2 Features
1511
//
1512

1513            if (featureId.startsWith(Constants.SAX_FEATURE_PREFIX)) {
1514                final int suffixLength = featureId.length() - Constants.SAX_FEATURE_PREFIX.length();
1515
1516                // http://xml.org/sax/features/namespaces
1517
if (suffixLength == Constants.NAMESPACES_FEATURE.length() &&
1518                    featureId.endsWith(Constants.NAMESPACES_FEATURE)) {
1519                    fConfiguration.setFeature(featureId, state);
1520                    fNamespaces = state;
1521                    return;
1522                }
1523                
1524                // http://xml.org/sax/features/namespace-prefixes
1525
// controls the reporting of raw prefixed names and Namespace
1526
// declarations (xmlns* attributes): when this feature is false
1527
// (the default), raw prefixed names may optionally be reported,
1528
// and xmlns* attributes must not be reported.
1529
//
1530
if (suffixLength == Constants.NAMESPACE_PREFIXES_FEATURE.length() &&
1531                    featureId.endsWith(Constants.NAMESPACE_PREFIXES_FEATURE)) {
1532                    fConfiguration.setFeature(featureId, state);
1533                    fNamespacePrefixes = state;
1534                    return;
1535                }
1536                
1537                // http://xml.org/sax/features/string-interning
1538
// controls the use of java.lang.String#intern() for strings
1539
// passed to SAX handlers.
1540
//
1541
if (suffixLength == Constants.STRING_INTERNING_FEATURE.length() &&
1542                    featureId.endsWith(Constants.STRING_INTERNING_FEATURE)) {
1543                    if (!state) {
1544                        throw new SAXNotSupportedException JavaDoc(
1545                            SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
1546                            "false-not-supported", new Object JavaDoc [] {featureId}));
1547                    }
1548                    return;
1549                }
1550                
1551                // http://xml.org/sax/features/lexical-handler/parameter-entities
1552
// controls whether the beginning and end of parameter entities
1553
// will be reported to the LexicalHandler.
1554
//
1555
if (suffixLength == Constants.LEXICAL_HANDLER_PARAMETER_ENTITIES_FEATURE.length() &&
1556                    featureId.endsWith(Constants.LEXICAL_HANDLER_PARAMETER_ENTITIES_FEATURE)) {
1557                    fLexicalHandlerParameterEntities = state;
1558                    return;
1559                }
1560                
1561                // http://xml.org/sax/features/resolve-dtd-uris
1562
// controls whether system identifiers will be absolutized relative to
1563
// their base URIs before reporting.
1564
//
1565
if (suffixLength == Constants.RESOLVE_DTD_URIS_FEATURE.length() &&
1566                    featureId.endsWith(Constants.RESOLVE_DTD_URIS_FEATURE)) {
1567                    fResolveDTDURIs = state;
1568                    return;
1569                }
1570                
1571                // http://xml.org/sax/features/unicode-normalization-checking
1572
// controls whether Unicode normalization checking is performed
1573
// as per Appendix B of the XML 1.1 specification
1574
//
1575
if (suffixLength == Constants.UNICODE_NORMALIZATION_CHECKING_FEATURE.length() &&
1576                    featureId.endsWith(Constants.UNICODE_NORMALIZATION_CHECKING_FEATURE)) {
1577                    // REVISIT: Allow this feature to be set once Unicode normalization
1578
// checking is supported -- mrglavas.
1579
if (state) {
1580                        throw new SAXNotSupportedException JavaDoc(
1581                            SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
1582                            "true-not-supported", new Object JavaDoc [] {featureId}));
1583                    }
1584                    return;
1585                }
1586                
1587                // http://xml.org/sax/features/xmlns-uris
1588
// controls whether the parser reports that namespace declaration
1589
// attributes as being in the namespace: http://www.w3.org/2000/xmlns/
1590
//
1591
if (suffixLength == Constants.XMLNS_URIS_FEATURE.length() &&
1592                    featureId.endsWith(Constants.XMLNS_URIS_FEATURE)) {
1593                    fXMLNSURIs = state;
1594                    return;
1595                }
1596                
1597                // http://xml.org/sax/features/use-entity-resolver2
1598
// controls whether the methods of an object implementing
1599
// org.xml.sax.ext.EntityResolver2 will be used by the parser.
1600
//
1601
if (suffixLength == Constants.USE_ENTITY_RESOLVER2_FEATURE.length() &&
1602                    featureId.endsWith(Constants.USE_ENTITY_RESOLVER2_FEATURE)) {
1603                    if (state != fUseEntityResolver2) {
1604                        fUseEntityResolver2 = state;
1605                        // Refresh EntityResolver wrapper.
1606
setEntityResolver(getEntityResolver());
1607                    }
1608                    return;
1609                }
1610                
1611                //
1612
// Read only features.
1613
//
1614

1615                // http://xml.org/sax/features/is-standalone
1616
// reports whether the document specified a standalone document declaration.
1617
// http://xml.org/sax/features/use-attributes2
1618
// reports whether Attributes objects passed to startElement also implement
1619
// the org.xml.sax.ext.Attributes2 interface.
1620
// http://xml.org/sax/features/use-locator2
1621
// reports whether Locator objects passed to setDocumentLocator also implement
1622
// the org.xml.sax.ext.Locator2 interface.
1623
// http://xml.org/sax/features/xml-1.1
1624
// reports whether the parser supports both XML 1.1 and XML 1.0.
1625
if ((suffixLength == Constants.IS_STANDALONE_FEATURE.length() &&
1626                    featureId.endsWith(Constants.IS_STANDALONE_FEATURE)) ||
1627                    (suffixLength == Constants.USE_ATTRIBUTES2_FEATURE.length() &&
1628                    featureId.endsWith(Constants.USE_ATTRIBUTES2_FEATURE)) ||
1629                    (suffixLength == Constants.USE_LOCATOR2_FEATURE.length() &&
1630                    featureId.endsWith(Constants.USE_LOCATOR2_FEATURE)) ||
1631                    (suffixLength == Constants.XML_11_FEATURE.length() &&
1632                    featureId.endsWith(Constants.XML_11_FEATURE))) {
1633                    throw new SAXNotSupportedException JavaDoc(
1634                        SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
1635                        "feature-read-only", new Object JavaDoc [] {featureId}));
1636                }
1637                
1638
1639                //
1640
// Drop through and perform default processing
1641
//
1642
}
1643
1644            //
1645
// Xerces Features
1646
//
1647

1648            /*
1649            else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) {
1650                String feature = featureId.substring(XERCES_FEATURES_PREFIX.length());
1651                //
1652                // Drop through and perform default processing
1653                //
1654            }
1655            */

1656
1657            //
1658
// Default handling
1659
//
1660

1661            fConfiguration.setFeature(featureId, state);
1662        }
1663        catch (XMLConfigurationException e) {
1664            String JavaDoc identifier = e.getIdentifier();
1665            if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
1666                throw new SAXNotRecognizedException JavaDoc(
1667                    SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
1668                    "feature-not-recognized", new Object JavaDoc [] {identifier}));
1669            }
1670            else {
1671                throw new SAXNotSupportedException JavaDoc(
1672                    SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
1673                    "feature-not-supported", new Object JavaDoc [] {identifier}));
1674            }
1675        }
1676
1677    } // setFeature(String,boolean)
1678

1679    /**
1680     * Query the state of a feature.
1681     *
1682     * Query the current state of any feature in a SAX2 parser. The
1683     * parser might not recognize the feature.
1684     *
1685     * @param featureId The unique identifier (URI) of the feature
1686     * being set.
1687     * @return The current state of the feature.
1688     * @exception org.xml.sax.SAXNotRecognizedException If the
1689     * requested feature is not known.
1690     * @exception SAXNotSupportedException If the
1691     * requested feature is known but not supported.
1692     */

1693    public boolean getFeature(String JavaDoc featureId)
1694        throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
1695
1696        try {
1697            //
1698
// SAX2 Features
1699
//
1700

1701            if (featureId.startsWith(Constants.SAX_FEATURE_PREFIX)) {
1702                final int suffixLength = featureId.length() - Constants.SAX_FEATURE_PREFIX.length();
1703
1704                // http://xml.org/sax/features/namespace-prefixes
1705
// controls the reporting of raw prefixed names and Namespace
1706
// declarations (xmlns* attributes): when this feature is false
1707
// (the default), raw prefixed names may optionally be reported,
1708
// and xmlns* attributes must not be reported.
1709
//
1710
if (suffixLength == Constants.NAMESPACE_PREFIXES_FEATURE.length() &&
1711                    featureId.endsWith(Constants.NAMESPACE_PREFIXES_FEATURE)) {
1712                    boolean state = fConfiguration.getFeature(featureId);
1713                    return state;
1714                }
1715                // http://xml.org/sax/features/string-interning
1716
// controls the use of java.lang.String#intern() for strings
1717
// passed to SAX handlers.
1718
//
1719
if (suffixLength == Constants.STRING_INTERNING_FEATURE.length() &&
1720                    featureId.endsWith(Constants.STRING_INTERNING_FEATURE)) {
1721                    return true;
1722                }
1723                
1724                // http://xml.org/sax/features/is-standalone
1725
// reports whether the document specified a standalone document declaration.
1726
//
1727
if (suffixLength == Constants.IS_STANDALONE_FEATURE.length() &&
1728                    featureId.endsWith(Constants.IS_STANDALONE_FEATURE)) {
1729                    return fStandalone;
1730                }
1731                
1732                // http://xml.org/sax/features/xml-1.1
1733
// reports whether the parser supports both XML 1.1 and XML 1.0.
1734
//
1735
if (suffixLength == Constants.XML_11_FEATURE.length() &&
1736                    featureId.endsWith(Constants.XML_11_FEATURE)) {
1737                    return (fConfiguration instanceof XML11Configurable);
1738                }
1739                
1740                // http://xml.org/sax/features/lexical-handler/parameter-entities
1741
// controls whether the beginning and end of parameter entities
1742
// will be reported to the LexicalHandler.
1743
//
1744
if (suffixLength == Constants.LEXICAL_HANDLER_PARAMETER_ENTITIES_FEATURE.length() &&
1745                    featureId.endsWith(Constants.LEXICAL_HANDLER_PARAMETER_ENTITIES_FEATURE)) {
1746                    return fLexicalHandlerParameterEntities;
1747                }
1748                
1749                // http://xml.org/sax/features/resolve-dtd-uris
1750
// controls whether system identifiers will be absolutized relative to
1751
// their base URIs before reporting.
1752
if (suffixLength == Constants.RESOLVE_DTD_URIS_FEATURE.length() &&
1753                    featureId.endsWith(Constants.RESOLVE_DTD_URIS_FEATURE)) {
1754                    return fResolveDTDURIs;
1755                }
1756                
1757                // http://xml.org/sax/features/xmlns-uris
1758
// controls whether the parser reports that namespace declaration
1759
// attributes as being in the namespace: http://www.w3.org/2000/xmlns/
1760
//
1761
if (suffixLength == Constants.XMLNS_URIS_FEATURE.length() &&
1762                    featureId.endsWith(Constants.XMLNS_URIS_FEATURE)) {
1763                    return fXMLNSURIs;
1764                }
1765                
1766                // http://xml.org/sax/features/unicode-normalization-checking
1767
// controls whether Unicode normalization checking is performed
1768
// as per Appendix B of the XML 1.1 specification
1769
//
1770
if (suffixLength == Constants.UNICODE_NORMALIZATION_CHECKING_FEATURE.length() &&
1771                    featureId.endsWith(Constants.UNICODE_NORMALIZATION_CHECKING_FEATURE)) {
1772                    // REVISIT: Allow this feature to be set once Unicode normalization
1773
// checking is supported -- mrglavas.
1774
return false;
1775                }
1776                
1777                // http://xml.org/sax/features/use-entity-resolver2
1778
// controls whether the methods of an object implementing
1779
// org.xml.sax.ext.EntityResolver2 will be used by the parser.
1780
//
1781
if (suffixLength == Constants.USE_ENTITY_RESOLVER2_FEATURE.length() &&
1782                    featureId.endsWith(Constants.USE_ENTITY_RESOLVER2_FEATURE)) {
1783                    return fUseEntityResolver2;
1784                }
1785                
1786                // http://xml.org/sax/features/use-attributes2
1787
// reports whether Attributes objects passed to startElement also implement
1788
// the org.xml.sax.ext.Attributes2 interface.
1789
// http://xml.org/sax/features/use-locator2
1790
// reports whether Locator objects passed to setDocumentLocator also implement
1791
// the org.xml.sax.ext.Locator2 interface.
1792
//
1793
if ((suffixLength == Constants.USE_ATTRIBUTES2_FEATURE.length() &&
1794                    featureId.endsWith(Constants.USE_ATTRIBUTES2_FEATURE)) ||
1795                    (suffixLength == Constants.USE_LOCATOR2_FEATURE.length() &&
1796                    featureId.endsWith(Constants.USE_LOCATOR2_FEATURE))) {
1797                    return true;
1798                }
1799                
1800
1801                //
1802
// Drop through and perform default processing
1803
//
1804
}
1805
1806            //
1807
// Xerces Features
1808
//
1809

1810            /*
1811            else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) {
1812                //
1813                // Drop through and perform default processing
1814                //
1815            }
1816            */

1817
1818            return fConfiguration.getFeature(featureId);
1819        }
1820        catch (XMLConfigurationException e) {
1821            String JavaDoc identifier = e.getIdentifier();
1822            if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
1823                throw new SAXNotRecognizedException JavaDoc(
1824                    SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
1825                    "feature-not-recognized", new Object JavaDoc [] {identifier}));
1826            }
1827            else {
1828                throw new SAXNotSupportedException JavaDoc(
1829                    SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
1830                    "feature-not-supported", new Object JavaDoc [] {identifier}));
1831            }
1832        }
1833
1834    } // getFeature(String):boolean
1835

1836    /**
1837     * Set the value of any property in a SAX2 parser. The parser
1838     * might not recognize the property, and if it does recognize
1839     * it, it might not support the requested value.
1840     *
1841     * @param propertyId The unique identifier (URI) of the property
1842     * being set.
1843     * @param value The value to which the property is being set.
1844     *
1845     * @exception SAXNotRecognizedException If the
1846     * requested property is not known.
1847     * @exception SAXNotSupportedException If the
1848     * requested property is known, but the requested
1849     * value is not supported.
1850     */

1851    public void setProperty(String JavaDoc propertyId, Object JavaDoc value)
1852        throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
1853
1854        try {
1855            //
1856
// SAX2 core properties
1857
//
1858

1859            if (propertyId.startsWith(Constants.SAX_PROPERTY_PREFIX)) {
1860                final int suffixLength = propertyId.length() - Constants.SAX_PROPERTY_PREFIX.length();
1861
1862                //
1863
// http://xml.org/sax/properties/lexical-handler
1864
// Value type: org.xml.sax.ext.LexicalHandler
1865
// Access: read/write, pre-parse only
1866
// Set the lexical event handler.
1867
//
1868
if (suffixLength == Constants.LEXICAL_HANDLER_PROPERTY.length() &&
1869                    propertyId.endsWith(Constants.LEXICAL_HANDLER_PROPERTY)) {
1870                    try {
1871                        setLexicalHandler((LexicalHandler JavaDoc)value);
1872                    }
1873                    catch (ClassCastException JavaDoc e) {
1874                        throw new SAXNotSupportedException JavaDoc(
1875                            SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
1876                            "incompatible-class", new Object JavaDoc [] {propertyId, "org.xml.sax.ext.LexicalHandler"}));
1877                    }
1878                    return;
1879                }
1880                //
1881
// http://xml.org/sax/properties/declaration-handler
1882
// Value type: org.xml.sax.ext.DeclHandler
1883
// Access: read/write, pre-parse only
1884
// Set the DTD declaration event handler.
1885
//
1886
if (suffixLength == Constants.DECLARATION_HANDLER_PROPERTY.length() &&
1887                    propertyId.endsWith(Constants.DECLARATION_HANDLER_PROPERTY)) {
1888                    try {
1889                        setDeclHandler((DeclHandler JavaDoc)value);
1890                    }
1891                    catch (ClassCastException JavaDoc e) {
1892                        throw new SAXNotSupportedException JavaDoc(
1893                            SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
1894                            "incompatible-class", new Object JavaDoc [] {propertyId, "org.xml.sax.ext.DeclHandler"}));
1895                    }
1896                    return;
1897                }
1898                //
1899
// http://xml.org/sax/properties/dom-node
1900
// Value type: DOM Node
1901
// Access: read-only
1902
// Get the DOM node currently being visited, if the SAX parser is
1903
// iterating over a DOM tree. If the parser recognises and
1904
// supports this property but is not currently visiting a DOM
1905
// node, it should return null (this is a good way to check for
1906
// availability before the parse begins).
1907
// http://xml.org/sax/properties/document-xml-version
1908
// Value type: java.lang.String
1909
// Access: read-only
1910
// The literal string describing the actual XML version of the document.
1911
//
1912
if ((suffixLength == Constants.DOM_NODE_PROPERTY.length() &&
1913                    propertyId.endsWith(Constants.DOM_NODE_PROPERTY)) ||
1914                    (suffixLength == Constants.DOCUMENT_XML_VERSION_PROPERTY.length() &&
1915                    propertyId.endsWith(Constants.DOCUMENT_XML_VERSION_PROPERTY))) {
1916                    throw new SAXNotSupportedException JavaDoc(
1917                        SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
1918                        "property-read-only", new Object JavaDoc [] {propertyId}));
1919                }
1920                //
1921
// Drop through and perform default processing
1922
//
1923
}
1924
1925            //
1926
// Xerces Properties
1927
//
1928

1929            /*
1930            else if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) {
1931                //
1932                // Drop through and perform default processing
1933                //
1934            }
1935            */

1936
1937            //
1938
// Perform default processing
1939
//
1940

1941            fConfiguration.setProperty(propertyId, value);
1942        }
1943        catch (XMLConfigurationException e) {
1944            String JavaDoc identifier = e.getIdentifier();
1945            if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
1946                throw new SAXNotRecognizedException JavaDoc(
1947                    SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
1948                    "property-not-recognized", new Object JavaDoc [] {identifier}));
1949            }
1950            else {
1951                throw new SAXNotSupportedException JavaDoc(
1952                    SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
1953                    "property-not-supported", new Object JavaDoc [] {identifier}));
1954            }
1955        }
1956
1957    } // setProperty(String,Object)
1958

1959    /**
1960     * Query the value of a property.
1961     *
1962     * Return the current value of a property in a SAX2 parser.
1963     * The parser might not recognize the property.
1964     *
1965     * @param propertyId The unique identifier (URI) of the property
1966     * being set.
1967     * @return The current value of the property.
1968     * @exception org.xml.sax.SAXNotRecognizedException If the
1969     * requested property is not known.
1970     * @exception SAXNotSupportedException If the
1971     * requested property is known but not supported.
1972     */

1973    public Object JavaDoc getProperty(String JavaDoc propertyId)
1974        throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
1975
1976        try {
1977            //
1978
// SAX2 core properties
1979
//
1980

1981            if (propertyId.startsWith(Constants.SAX_PROPERTY_PREFIX)) {
1982                final int suffixLength = propertyId.length() - Constants.SAX_PROPERTY_PREFIX.length();
1983
1984                //
1985
// http://xml.org/sax/properties/document-xml-version
1986
// Value type: java.lang.String
1987
// Access: read-only
1988
// The literal string describing the actual XML version of the document.
1989
//
1990
if (suffixLength == Constants.DOCUMENT_XML_VERSION_PROPERTY.length() &&
1991                    propertyId.endsWith(Constants.DOCUMENT_XML_VERSION_PROPERTY)) {
1992                    return fVersion;
1993                }
1994                
1995                //
1996
// http://xml.org/sax/properties/lexical-handler
1997
// Value type: org.xml.sax.ext.LexicalHandler
1998
// Access: read/write, pre-parse only
1999
// Set the lexical event handler.
2000
//
2001
if (suffixLength == Constants.LEXICAL_HANDLER_PROPERTY.length() &&
2002                    propertyId.endsWith(Constants.LEXICAL_HANDLER_PROPERTY)) {
2003                    return getLexicalHandler();
2004                }
2005                //
2006
// http://xml.org/sax/properties/declaration-handler
2007
// Value type: org.xml.sax.ext.DeclHandler
2008
// Access: read/write, pre-parse only
2009
// Set the DTD declaration event handler.
2010
//
2011
if (suffixLength == Constants.DECLARATION_HANDLER_PROPERTY.length() &&
2012                    propertyId.endsWith(Constants.DECLARATION_HANDLER_PROPERTY)) {
2013                    return getDeclHandler();
2014                }
2015                
2016                //
2017
// http://xml.org/sax/properties/dom-node
2018
// Value type: DOM Node
2019
// Access: read-only
2020
// Get the DOM node currently being visited, if the SAX parser is
2021
// iterating over a DOM tree. If the parser recognises and
2022
// supports this property but is not currently visiting a DOM
2023
// node, it should return null (this is a good way to check for
2024
// availability before the parse begins).
2025
//
2026
if (suffixLength == Constants.DOM_NODE_PROPERTY.length() &&
2027                    propertyId.endsWith(Constants.DOM_NODE_PROPERTY)) {
2028                    // we are not iterating a DOM tree
2029
throw new SAXNotSupportedException JavaDoc(
2030                        SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
2031                        "dom-node-read-not-supported", null));
2032                }
2033                
2034                //
2035
// Drop through and perform default processing
2036
//
2037
}
2038
2039            //
2040
// Xerces properties
2041
//
2042

2043            /*
2044            else if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) {
2045                //
2046                // Drop through and perform default processing
2047                //
2048            }
2049            */

2050
2051            //
2052
// Perform default processing
2053
//
2054

2055            return fConfiguration.getProperty(propertyId);
2056        }
2057        catch (XMLConfigurationException e) {
2058            String JavaDoc identifier = e.getIdentifier();
2059            if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
2060                throw new SAXNotRecognizedException JavaDoc(
2061                    SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
2062                    "property-not-recognized", new Object JavaDoc [] {identifier}));
2063            }
2064            else {
2065                throw new SAXNotSupportedException JavaDoc(
2066                    SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
2067                    "property-not-supported", new Object JavaDoc [] {identifier}));
2068            }
2069        }
2070
2071    } // getProperty(String):Object
2072

2073    //
2074
// Protected methods
2075
//
2076

2077    // SAX2 core properties
2078

2079    /**
2080     * Set the DTD declaration event handler.
2081     * <p>
2082     * This method is the equivalent to the property:
2083     * <pre>
2084     * http://xml.org/sax/properties/declaration-handler
2085     * </pre>
2086     *
2087     * @param handler The new handler.
2088     *
2089     * @see #getDeclHandler
2090     * @see #setProperty
2091     */

2092    protected void setDeclHandler(DeclHandler JavaDoc handler)
2093        throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
2094
2095        if (fParseInProgress) {
2096            throw new SAXNotSupportedException JavaDoc(
2097                SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
2098                "property-not-parsing-supported",
2099                new Object JavaDoc [] {"http://xml.org/sax/properties/declaration-handler"}));
2100        }
2101        fDeclHandler = handler;
2102
2103    } // setDeclHandler(DeclHandler)
2104

2105    /**
2106     * Returns the DTD declaration event handler.
2107     *
2108     * @see #setDeclHandler
2109     */

2110    protected DeclHandler JavaDoc getDeclHandler()
2111        throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
2112        return fDeclHandler;
2113    } // getDeclHandler():DeclHandler
2114

2115    /**
2116     * Set the lexical event handler.
2117     * <p>
2118     * This method is the equivalent to the property:
2119     * <pre>
2120     * http://xml.org/sax/properties/lexical-handler
2121     * </pre>
2122     *
2123     * @param handler lexical event handler
2124     *
2125     * @see #getLexicalHandler
2126     * @see #setProperty
2127     */

2128    protected void setLexicalHandler(LexicalHandler JavaDoc handler)
2129        throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
2130
2131        if (fParseInProgress) {
2132            throw new SAXNotSupportedException JavaDoc(
2133                SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
2134                "property-not-parsing-supported",
2135                new Object JavaDoc [] {"http://xml.org/sax/properties/lexical-handler"}));
2136        }
2137        fLexicalHandler = handler;
2138
2139    } // setLexicalHandler(LexicalHandler)
2140

2141    /**
2142     * Returns the lexical handler.
2143     *
2144     * @see #setLexicalHandler
2145     */

2146    protected LexicalHandler JavaDoc getLexicalHandler()
2147        throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
2148        return fLexicalHandler;
2149    } // getLexicalHandler():LexicalHandler
2150

2151    /**
2152     * Send startPrefixMapping events
2153     */

2154    protected final void startNamespaceMapping() throws SAXException JavaDoc{
2155        int count = fNamespaceContext.getDeclaredPrefixCount();
2156        if (count > 0) {
2157            String JavaDoc prefix = null;
2158            String JavaDoc uri = null;
2159            for (int i = 0; i < count; i++) {
2160                prefix = fNamespaceContext.getDeclaredPrefixAt(i);
2161                uri = fNamespaceContext.getURI(prefix);
2162                fContentHandler.startPrefixMapping(prefix,
2163                    (uri == null) ? "" : uri);
2164            }
2165        }
2166    }
2167    
2168    /**
2169     * Send endPrefixMapping events
2170     */

2171    protected final void endNamespaceMapping() throws SAXException JavaDoc {
2172        int count = fNamespaceContext.getDeclaredPrefixCount();
2173        if (count > 0) {
2174            for (int i = 0; i < count; i++) {
2175                fContentHandler.endPrefixMapping(fNamespaceContext.getDeclaredPrefixAt(i));
2176            }
2177        }
2178    }
2179    
2180    //
2181
// XMLDocumentParser methods
2182
//
2183

2184    /**
2185     * Reset all components before parsing.
2186     *
2187     * @throws XNIException Thrown if an error occurs during initialization.
2188     */

2189    public void reset() throws XNIException {
2190        super.reset();
2191
2192        // reset state
2193
fInDTD = false;
2194        fVersion = "1.0";
2195        fStandalone = false;
2196
2197        // features
2198
fNamespaces = fConfiguration.getFeature(NAMESPACES);
2199        fNamespacePrefixes = fConfiguration.getFeature(NAMESPACE_PREFIXES);
2200        fAugmentations = null;
2201        fDeclaredAttrs = null;
2202        
2203    } // reset()
2204

2205    //
2206
// Classes
2207
//
2208

2209    protected class LocatorProxy
2210        implements Locator2 JavaDoc {
2211
2212        //
2213
// Data
2214
//
2215

2216        /** XML locator. */
2217        protected XMLLocator fLocator;
2218
2219        //
2220
// Constructors
2221
//
2222

2223        /** Constructs an XML locator proxy. */
2224        public LocatorProxy(XMLLocator locator) {
2225            fLocator = locator;
2226        }
2227
2228        //
2229
// Locator methods
2230
//
2231

2232        /** Public identifier. */
2233        public String JavaDoc getPublicId() {
2234            return fLocator.getPublicId();
2235        }
2236
2237        /** System identifier. */
2238        public String JavaDoc getSystemId() {
2239            return fLocator.getExpandedSystemId();
2240        }
2241        /** Line number. */
2242        public int getLineNumber() {
2243            return fLocator.getLineNumber();
2244        }
2245
2246        /** Column number. */
2247        public int getColumnNumber() {
2248            return fLocator.getColumnNumber();
2249        }
2250
2251        // Locator2 methods
2252
public String JavaDoc getXMLVersion() {
2253            return fLocator.getXMLVersion();
2254        }
2255
2256        public String JavaDoc getEncoding() {
2257            return fLocator.getEncoding();
2258        }
2259
2260    } // class LocatorProxy
2261

2262    protected static final class AttributesProxy
2263        implements AttributeList JavaDoc, Attributes2 JavaDoc {
2264
2265        //
2266
// Data
2267
//
2268

2269        /** XML attributes. */
2270        protected XMLAttributes fAttributes;
2271
2272        //
2273
// Public methods
2274
//
2275

2276        /** Sets the XML attributes. */
2277        public void setAttributes(XMLAttributes attributes) {
2278            fAttributes = attributes;
2279        } // setAttributes(XMLAttributes)
2280

2281        public int getLength() {
2282            return fAttributes.getLength();
2283        }
2284
2285        public String JavaDoc getName(int i) {
2286            return fAttributes.getQName(i);
2287        }
2288
2289        public String JavaDoc getQName(int index) {
2290            return fAttributes.getQName(index);
2291        }
2292
2293        public String JavaDoc getURI(int index) {
2294            // REVISIT: this hides the fact that internally we use
2295
// null instead of empty string
2296
// SAX requires URI to be a string or an empty string
2297
String JavaDoc uri= fAttributes.getURI(index);
2298            return uri != null ? uri : "";
2299        }
2300
2301        public String JavaDoc getLocalName(int index) {
2302            return fAttributes.getLocalName(index);
2303        }
2304
2305        public String JavaDoc getType(int i) {
2306            return fAttributes.getType(i);
2307        }
2308
2309        public String JavaDoc getType(String JavaDoc name) {
2310            return fAttributes.getType(name);
2311        }
2312
2313        public String JavaDoc getType(String JavaDoc uri, String JavaDoc localName) {
2314            return uri.equals("") ? fAttributes.getType(null, localName) :
2315                                    fAttributes.getType(uri, localName);
2316        }
2317
2318        public String JavaDoc getValue(int i) {
2319            return fAttributes.getValue(i);
2320        }
2321
2322        public String JavaDoc getValue(String JavaDoc name) {
2323            return fAttributes.getValue(name);
2324        }
2325
2326        public String JavaDoc getValue(String JavaDoc uri, String JavaDoc localName) {
2327            return uri.equals("") ? fAttributes.getValue(null, localName) :
2328                                    fAttributes.getValue(uri, localName);
2329        }
2330
2331        public int getIndex(String JavaDoc qName) {
2332            return fAttributes.getIndex(qName);
2333        }
2334
2335        public int getIndex(String JavaDoc uri, String JavaDoc localPart) {
2336            return uri.equals("") ? fAttributes.getIndex(null, localPart) :
2337                                    fAttributes.getIndex(uri, localPart);
2338        }
2339        
2340        // Attributes2 methods
2341
// REVISIT: Localize exception messages. -- mrglavas
2342
public boolean isDeclared(int index) {
2343            if (index < 0 || index >= fAttributes.getLength()) {
2344                throw new ArrayIndexOutOfBoundsException JavaDoc(index);
2345            }
2346            return Boolean.TRUE.equals(
2347                fAttributes.getAugmentations(index).getItem(
2348                Constants.ATTRIBUTE_DECLARED));
2349        }
2350        
2351        public boolean isDeclared(String JavaDoc qName) {
2352            int index = getIndex(qName);
2353            if (index == -1) {
2354                throw new IllegalArgumentException JavaDoc(qName);
2355            }
2356            return Boolean.TRUE.equals(
2357                fAttributes.getAugmentations(index).getItem(
2358                Constants.ATTRIBUTE_DECLARED));
2359        }
2360        
2361        public boolean isDeclared(String JavaDoc uri, String JavaDoc localName) {
2362            int index = getIndex(uri, localName);
2363            if (index == -1) {
2364                throw new IllegalArgumentException JavaDoc(localName);
2365            }
2366            return Boolean.TRUE.equals(
2367                fAttributes.getAugmentations(index).getItem(
2368                Constants.ATTRIBUTE_DECLARED));
2369        }
2370                
2371        public boolean isSpecified(int index) {
2372            if (index < 0 || index >= fAttributes.getLength()) {
2373                throw new ArrayIndexOutOfBoundsException JavaDoc(index);
2374            }
2375            return fAttributes.isSpecified(index);
2376        }
2377        
2378        public boolean isSpecified(String JavaDoc qName) {
2379            int index = getIndex(qName);
2380            if (index == -1) {
2381                throw new IllegalArgumentException JavaDoc(qName);
2382            }
2383            return fAttributes.isSpecified(index);
2384        }
2385        
2386        public boolean isSpecified(String JavaDoc uri, String JavaDoc localName) {
2387            int index = getIndex(uri, localName);
2388            if (index == -1) {
2389                throw new IllegalArgumentException JavaDoc(localName);
2390            }
2391            return fAttributes.isSpecified(index);
2392        }
2393
2394    } // class AttributesProxy
2395

2396
2397    // PSVIProvider methods
2398

2399    public ElementPSVI getElementPSVI(){
2400        return (fAugmentations != null)?(ElementPSVI)fAugmentations.getItem(Constants.ELEMENT_PSVI):null;
2401    }
2402
2403
2404    public AttributePSVI getAttributePSVI(int index){
2405
2406        return (AttributePSVI)fAttributesProxy.fAttributes.getAugmentations(index).getItem(Constants.ATTRIBUTE_PSVI);
2407    }
2408
2409
2410    public AttributePSVI getAttributePSVIByName(String JavaDoc uri,
2411                                                String JavaDoc localname){
2412        return (AttributePSVI)fAttributesProxy.fAttributes.getAugmentations(uri, localname).getItem(Constants.ATTRIBUTE_PSVI);
2413    }
2414
2415} // class AbstractSAXParser
2416
Popular Tags