0001: /*
0002: * The Apache Software License, Version 1.1
0003: *
0004: *
0005: * Copyright (c) 1999,2000 The Apache Software Foundation. All rights
0006: * reserved.
0007: *
0008: * Redistribution and use in source and binary forms, with or without
0009: * modification, are permitted provided that the following conditions
0010: * are met:
0011: *
0012: * 1. Redistributions of source code must retain the above copyright
0013: * notice, this list of conditions and the following disclaimer.
0014: *
0015: * 2. Redistributions in binary form must reproduce the above copyright
0016: * notice, this list of conditions and the following disclaimer in
0017: * the documentation and/or other materials provided with the
0018: * distribution.
0019: *
0020: * 3. The end-user documentation included with the redistribution,
0021: * if any, must include the following acknowledgment:
0022: * "This product includes software developed by the
0023: * Apache Software Foundation (http://www.apache.org/)."
0024: * Alternately, this acknowledgment may appear in the software itself,
0025: * if and wherever such third-party acknowledgments normally appear.
0026: *
0027: * 4. The names "Xerces" and "Apache Software Foundation" must
0028: * not be used to endorse or promote products derived from this
0029: * software without prior written permission. For written
0030: * permission, please contact apache@apache.org.
0031: *
0032: * 5. Products derived from this software may not be called "Apache",
0033: * nor may "Apache" appear in their name, without prior written
0034: * permission of the Apache Software Foundation.
0035: *
0036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0039: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
0040: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
0043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
0045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
0046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0047: * SUCH DAMAGE.
0048: * ====================================================================
0049: *
0050: * This software consists of voluntary contributions made by many
0051: * individuals on behalf of the Apache Software Foundation and was
0052: * originally based on software copyright (c) 1999, International
0053: * Business Machines, Inc., http://www.apache.org. For more
0054: * information on the Apache Software Foundation, please see
0055: * <http://www.apache.org/>.
0056: */
0057:
0058: package org.apache.xerces.parsers;
0059:
0060: import org.apache.xerces.framework.XMLAttrList;
0061: import org.apache.xerces.framework.XMLContentSpec;
0062: import org.apache.xerces.framework.XMLDocumentHandler;
0063: import org.apache.xerces.framework.XMLParser;
0064: import org.apache.xerces.readers.XMLEntityHandler;
0065: import org.apache.xerces.utils.QName;
0066: import org.apache.xerces.utils.StringPool;
0067: import org.apache.xerces.validators.common.XMLAttributeDecl;
0068: import org.apache.xerces.validators.common.XMLElementDecl;
0069:
0070: import org.xml.sax.Attributes;
0071: import org.xml.sax.AttributeList;
0072: import org.xml.sax.ContentHandler;
0073: import org.xml.sax.DocumentHandler;
0074: import org.xml.sax.DTDHandler;
0075: import org.xml.sax.EntityResolver;
0076: import org.xml.sax.Parser;
0077: import org.xml.sax.XMLReader;
0078: import org.xml.sax.SAXException;
0079: import org.xml.sax.SAXNotRecognizedException;
0080: import org.xml.sax.SAXNotSupportedException;
0081: import org.xml.sax.ext.DeclHandler;
0082: import org.xml.sax.ext.LexicalHandler;
0083: import org.xml.sax.helpers.AttributesImpl;
0084:
0085: // REVISIT: [SAX2beta] ContentHandler#skippedEntity(String)
0086:
0087: /**
0088: * SAXParser provides a parser which implements the SAX1 and SAX2
0089: * parser APIs.
0090: *
0091: * @version $Id: SAXParser.java,v 1.22 2001/02/01 09:58:19 andyc Exp $
0092: */
0093: public class SAXParser extends XMLParser implements XMLDocumentHandler,
0094: XMLDocumentHandler.DTDHandler, Parser, XMLReader {
0095:
0096: //
0097: // Constants
0098: //
0099:
0100: // private
0101:
0102: /** Features recognized by this parser. */
0103: private static final String RECOGNIZED_FEATURES[] = {
0104: // SAX2 core
0105: /*"http://xml.org/sax/features/normalize-text",*/
0106: /*"http://xml.org/sax/features/use-locator",*/
0107: "http://xml.org/sax/features/namespace-prefixes",
0108: "http://xml.org/sax/features/string-interning",
0109: // Xerces
0110: };
0111:
0112: /** Properties recognized by this parser. */
0113: private static final String RECOGNIZED_PROPERTIES[] = {
0114: // SAX2 core
0115: "http://xml.org/sax/properties/lexical-handler",
0116: "http://xml.org/sax/properties/declaration-handler",
0117: "http://xml.org/sax/properties/dom-node",
0118: // Xerces
0119: };
0120:
0121: // debugging
0122:
0123: /** Set to true and recompile to debug callbacks. */
0124: private static final boolean DEBUG_CALLBACKS = false;
0125:
0126: //
0127: // Data
0128: //
0129:
0130: // parser handlers
0131:
0132: /** Document handler. */
0133: private DocumentHandler fDocumentHandler;
0134:
0135: // parser/xmlreader handlers
0136:
0137: /** DTD handler. */
0138: private org.xml.sax.DTDHandler fDTDHandler;
0139:
0140: // xmlreader handlers
0141:
0142: /** Content handler. */
0143: private ContentHandler fContentHandler;
0144:
0145: /** Decl handler. */
0146: private DeclHandler fDeclHandler;
0147:
0148: /** Lexical handler. */
0149: private LexicalHandler fLexicalHandler;
0150:
0151: private boolean fNamespacePrefixes = false;
0152:
0153: // temp
0154:
0155: private transient AttributesImpl fAttributes = new AttributesImpl();
0156:
0157: //
0158: // Constructors
0159: //
0160:
0161: /** Default constructor. */
0162: public SAXParser() {
0163: initHandlers(true, this , this );
0164: }
0165:
0166: protected SAXParser(StringPool stringPool) {
0167: super (stringPool);
0168: initHandlers(true, this , this );
0169: }
0170:
0171: //
0172: // Public methods
0173: //
0174:
0175: // features and properties
0176:
0177: /**
0178: * Returns a list of features that this parser recognizes.
0179: * This method will never return null; if no features are
0180: * recognized, this method will return a zero length array.
0181: *
0182: * @see #isFeatureRecognized
0183: * @see #setFeature
0184: * @see #getFeature
0185: */
0186: public String[] getFeaturesRecognized() {
0187:
0188: // get features that super/this recognizes
0189: String super Recognized[] = super .getFeaturesRecognized();
0190: String this Recognized[] = RECOGNIZED_FEATURES;
0191:
0192: // is one or the other the empty set?
0193: int this Length = this Recognized.length;
0194: if (this Length == 0) {
0195: return super Recognized;
0196: }
0197: int super Length = super Recognized.length;
0198: if (super Length == 0) {
0199: return this Recognized;
0200: }
0201:
0202: // combine the two lists and return
0203: String recognized[] = new String[super Length + this Length];
0204: System
0205: .arraycopy(super Recognized, 0, recognized, 0,
0206: super Length);
0207: System.arraycopy(this Recognized, 0, recognized, super Length,
0208: this Length);
0209: return recognized;
0210:
0211: } // getFeaturesRecognized():String[]
0212:
0213: /**
0214: * Returns a list of properties that this parser recognizes.
0215: * This method will never return null; if no properties are
0216: * recognized, this method will return a zero length array.
0217: *
0218: * @see #isPropertyRecognized
0219: * @see #setProperty
0220: * @see #getProperty
0221: */
0222: public String[] getPropertiesRecognized() {
0223:
0224: // get properties that super/this recognizes
0225: String super Recognized[] = super .getPropertiesRecognized();
0226: String this Recognized[] = RECOGNIZED_PROPERTIES;
0227:
0228: // is one or the other the empty set?
0229: int this Length = this Recognized.length;
0230: if (this Length == 0) {
0231: return super Recognized;
0232: }
0233: int super Length = super Recognized.length;
0234: if (super Length == 0) {
0235: return this Recognized;
0236: }
0237:
0238: // combine the two lists and return
0239: String recognized[] = new String[super Length + this Length];
0240: System
0241: .arraycopy(super Recognized, 0, recognized, 0,
0242: super Length);
0243: System.arraycopy(this Recognized, 0, recognized, super Length,
0244: this Length);
0245: return recognized;
0246:
0247: }
0248:
0249: //
0250: // Protected methods
0251: //
0252:
0253: // SAX2 core features
0254:
0255: /**
0256: * <b>Note: Currently, the parser does not support this feature.</b>
0257: * Setting this feature to true will throw a SAXNotSupportedException.
0258: * <p>
0259: * Ensures that all consecutive text is returned in a single callback
0260: * to the DocumentHandler.characters or DocumentHandler.ignorableWhitespace
0261: * methods.
0262: * <p>
0263: * This method is the equivalent to the feature:
0264: * <pre>
0265: * http://xml.org/sax/features/normalize-text
0266: * <pre>
0267: *
0268: * @param normalize True to normalize; false not to normalize.
0269: *
0270: * @see #getNormalizeText
0271: * @see #setFeature
0272: */
0273: /*
0274: protected void setNormalizeText(boolean normalize)
0275: throws SAXNotRecognizedException, SAXNotSupportedException {
0276: if (normalize) {
0277: throw new SAXNotSupportedException("http://xml.org/sax/features/normalize-text");
0278: }
0279: }
0280: */
0281:
0282: /**
0283: * <b>Note: This feature is always false.</b>
0284: * <p>
0285: * Returns true if the parser normalizes all consecutive text into
0286: * a single callback to the DocumentHandler.characters or
0287: * DocumentHandler.ignorableWhitespace methods.
0288: *
0289: * @see #setNormalizeText
0290: */
0291: /*
0292: protected boolean getNormalizeText()
0293: throws SAXNotRecognizedException, SAXNotSupportedException {
0294: return false;
0295: }
0296: */
0297:
0298: /**
0299: * <b>Note: Currently, this parser always sets the locator.</b>
0300: * Setting this feature to false will throw a SAXNotSupportedException.
0301: * <p>
0302: * Provide a Locator using the DocumentHandler.setDocumentLocator
0303: * callback (true), or explicitly do not provide one (false).
0304: * <p>
0305: * This method is the equivalent to the feature:
0306: * <pre>
0307: * http://xml.org/sax/features/use-locator
0308: * </pre>
0309: *
0310: * @see #getUseLocator
0311: * @see #setFeature
0312: */
0313: /*
0314: protected void setUseLocator(boolean use)
0315: throws SAXNotRecognizedException, SAXNotSupportedException {
0316: if (!use) {
0317: throw new SAXNotSupportedException("http://xml.org/sax/features/use-locator");
0318: }
0319: }
0320: */
0321:
0322: /**
0323: * <b>Note: This feature is always true.</b>
0324: * <p>
0325: * Returns true if the locator is always set.
0326: *
0327: * @see #setUseLocator
0328: */
0329: /*
0330: protected boolean getUseLocator()
0331: throws SAXNotRecognizedException, SAXNotSupportedException {
0332: return true;
0333: }
0334: */
0335:
0336: // SAX2 core properties
0337: /**
0338: * Set the DTD declaration event handler.
0339: * <p>
0340: * This method is the equivalent to the property:
0341: * <pre>
0342: * http://xml.org/sax/properties/declaration-handler
0343: * </pre>
0344: *
0345: * @param handler The new handler.
0346: *
0347: * @see #getDeclHandler
0348: * @see #setProperty
0349: */
0350: protected void setDeclHandler(DeclHandler handler)
0351: throws SAXNotRecognizedException, SAXNotSupportedException {
0352: if (fParseInProgress) {
0353: throw new SAXNotSupportedException(
0354: "PAR011 Feature: http://xml.org/sax/properties/declaration-handler"
0355: + " is not supported during parse."
0356: + "\nhttp://xml.org/sax/properties/declaration-handler");
0357: }
0358: fDeclHandler = handler;
0359: }
0360:
0361: /**
0362: * Returns the DTD declaration event handler.
0363: *
0364: * @see #setDeclHandler
0365: */
0366: protected DeclHandler getDeclHandler()
0367: throws SAXNotRecognizedException, SAXNotSupportedException {
0368: return fDeclHandler;
0369: }
0370:
0371: /**
0372: * Set the lexical event handler.
0373: * <p>
0374: * This method is the equivalent to the property:
0375: * <pre>
0376: * http://xml.org/sax/properties/lexical-handler
0377: * </pre>
0378: *
0379: * @param handler lexical event handler
0380: *
0381: * @see #getLexicalHandler
0382: * @see #setProperty
0383: */
0384: protected void setLexicalHandler(LexicalHandler handler)
0385: throws SAXNotRecognizedException, SAXNotSupportedException {
0386: if (fParseInProgress) {
0387: throw new SAXNotSupportedException(
0388: "PAR011 Feature: http://xml.org/sax/properties/lexical-handler"
0389: + " is not supported during parse."
0390: + "\nhttp://xml.org/sax/properties/lexical-handler");
0391: }
0392: fLexicalHandler = handler;
0393: }
0394:
0395: /**
0396: * Returns the lexical handler.
0397: *
0398: * @see #setLexicalHandler
0399: */
0400: protected LexicalHandler getLexicalHandler()
0401: throws SAXNotRecognizedException, SAXNotSupportedException {
0402: return fLexicalHandler;
0403: }
0404:
0405: //
0406: // Parser methods
0407: //
0408:
0409: /** Sets the document handler. */
0410: public void setDocumentHandler(DocumentHandler handler) {
0411: fDocumentHandler = handler;
0412: }
0413:
0414: //
0415: // Parser/XMLReader methods
0416: //
0417:
0418: /**
0419: * Allow an application to register a DTD event handler.
0420: *
0421: * <p>If the application does not register a DTD handler, all DTD
0422: * events reported by the SAX parser will be silently ignored.</p>
0423: *
0424: * <p>Applications may register a new or different handler in the
0425: * middle of a parse, and the SAX parser must begin using the new
0426: * handler immediately.</p>
0427: *
0428: * @param handler The DTD handler.
0429: * @exception java.lang.NullPointerException If the handler
0430: * argument is null.
0431: * @see #getDTDHandler
0432: */
0433: public void setDTDHandler(org.xml.sax.DTDHandler handler) {
0434: fDTDHandler = handler;
0435: }
0436:
0437: /**
0438: * Return the current DTD handler.
0439: *
0440: * @return The current DTD handler, or null if none
0441: * has been registered.
0442: * @see #setDTDHandler
0443: */
0444: public org.xml.sax.DTDHandler getDTDHandler() {
0445: return fDTDHandler;
0446: }
0447:
0448: /**
0449: * Sets how the parser reports raw prefixed names,
0450: * and whether xmlns attributes are reported.
0451: * <p>
0452: * This method is the equivalent to the feature:
0453: * <pre>
0454: * http://xml.org/sax/features/namespaces-prefixes
0455: * <pre>
0456: *
0457: * @param process True to process namespaces; false to not process.
0458: *
0459: * @see #getNamespaces
0460: * @see #setFeature
0461: */
0462: protected void setNamespacePrefixes(boolean process)
0463: throws SAXNotRecognizedException, SAXNotSupportedException {
0464: if (fParseInProgress) {
0465: throw new SAXNotSupportedException(
0466: "PAR004 Cannot setFeature(http://xml.org/sax/features/namespace-prefixes): parse is in progress.\n"
0467: + "http://xml.org/sax/features/namespace-prefixes");
0468: }
0469: fNamespacePrefixes = process;
0470: }
0471:
0472: /**
0473: * Returns the http://xml.org/features/namespace-prefixes
0474: * value.
0475: *
0476: * @see #setNamespacePrefixes
0477: */
0478: protected boolean getNamespacePrefixes()
0479: throws SAXNotRecognizedException, SAXNotSupportedException {
0480: return fNamespacePrefixes;
0481: }
0482:
0483: //
0484: // XMLReader methods
0485: //
0486:
0487: /**
0488: * Set the state of any feature in a SAX2 parser. The parser
0489: * might not recognize the feature, and if it does recognize
0490: * it, it might not be able to fulfill the request.
0491: *
0492: * @param featureId The unique identifier (URI) of the feature.
0493: * @param state The requested state of the feature (true or false).
0494: *
0495: * @exception SAXNotRecognizedException If the
0496: * requested feature is not known.
0497: * @exception SAXNotSupportedException If the
0498: * requested feature is known, but the requested
0499: * state is not supported.
0500: */
0501: public void setFeature(String featureId, boolean state)
0502: throws SAXNotRecognizedException, SAXNotSupportedException {
0503:
0504: //
0505: // SAX2 Features
0506: //
0507:
0508: if (featureId.startsWith(SAX2_FEATURES_PREFIX)) {
0509: String feature = featureId.substring(SAX2_FEATURES_PREFIX
0510: .length());
0511:
0512: /*
0513: //
0514: // http://xml.org/sax/features/normalize-text
0515: // Ensure that all consecutive text is returned in a single callback to
0516: // DocumentHandler.characters or DocumentHandler.ignorableWhitespace
0517: // (true) or explicitly do not require it (false).
0518: //
0519: if (feature.equals("normalize-text")) {
0520: setNormalizeText(state);
0521: return;
0522: }
0523: */
0524: /*
0525: //
0526: // http://xml.org/sax/features/use-locator
0527: // Provide a Locator using the DocumentHandler.setDocumentLocator
0528: // callback (true), or explicitly do not provide one (false).
0529: //
0530: if (feature.equals("use-locator")) {
0531: setUseLocator(state);
0532: return;
0533: }
0534: */
0535:
0536: // http://xml.org/sax/features/namespace-prefixes
0537: // controls the reporting of raw prefixed names and Namespace
0538: // declarations (xmlns* attributes): when this feature is false
0539: // (the default), raw prefixed names may optionally be reported,
0540: // and xmlns* attributes must not be reported.
0541: //
0542: if (feature.equals("namespace-prefixes")) {
0543: setNamespacePrefixes(state);
0544: return;
0545: }
0546: // http://xml.org/sax/features/string-interning
0547: // controls the use of java.lang.String#intern() for strings
0548: // passed to SAX handlers.
0549: //
0550: if (feature.equals("string-interning")) {
0551: if (state) {
0552: throw new SAXNotSupportedException("PAR018 "
0553: + state + " state for feature \""
0554: + featureId + "\" is not supported.\n"
0555: + state + '\t' + featureId);
0556: }
0557: return;
0558: }
0559:
0560: //
0561: // Drop through and perform default processing
0562: //
0563: }
0564:
0565: //
0566: // Xerces Features
0567: //
0568:
0569: /*
0570: else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) {
0571: String feature = featureId.substring(XERCES_FEATURES_PREFIX.length());
0572: //
0573: // Drop through and perform default processing
0574: //
0575: }
0576: */
0577:
0578: //
0579: // Perform default processing
0580: //
0581: super .setFeature(featureId, state);
0582:
0583: } // setFeature(String,boolean)
0584:
0585: /**
0586: * Query the state of a feature.
0587: *
0588: * Query the current state of any feature in a SAX2 parser. The
0589: * parser might not recognize the feature.
0590: *
0591: * @param featureId The unique identifier (URI) of the feature
0592: * being set.
0593: * @return The current state of the feature.
0594: * @exception org.xml.sax.SAXNotRecognizedException If the
0595: * requested feature is not known.
0596: * @exception SAXNotSupportedException If the
0597: * requested feature is known but not supported.
0598: */
0599: public boolean getFeature(String featureId)
0600: throws SAXNotRecognizedException, SAXNotSupportedException {
0601:
0602: //
0603: // SAX2 Features
0604: //
0605:
0606: if (featureId.startsWith(SAX2_FEATURES_PREFIX)) {
0607: String feature = featureId.substring(SAX2_FEATURES_PREFIX
0608: .length());
0609:
0610: /*
0611: //
0612: // http://xml.org/sax/features/normalize-text
0613: // Ensure that all consecutive text is returned in a single callback to
0614: // DocumentHandler.characters or DocumentHandler.ignorableWhitespace
0615: // (true) or explicitly do not require it (false).
0616: //
0617: if (feature.equals("normalize-text")) {
0618: return getNormalizeText();
0619: }
0620: */
0621: /*
0622: //
0623: // http://xml.org/sax/features/use-locator
0624: // Provide a Locator using the DocumentHandler.setDocumentLocator
0625: // callback (true), or explicitly do not provide one (false).
0626: //
0627: if (feature.equals("use-locator")) {
0628: return getUseLocator();
0629: }
0630: */
0631:
0632: // http://xml.org/sax/features/namespace-prefixes
0633: // controls the reporting of raw prefixed names and Namespace
0634: // declarations (xmlns* attributes): when this feature is false
0635: // (the default), raw prefixed names may optionally be reported,
0636: // and xmlns* attributes must not be reported.
0637: //
0638: if (feature.equals("namespace-prefixes")) {
0639: return getNamespacePrefixes();
0640: }
0641: // http://xml.org/sax/features/string-interning
0642: // controls the use of java.lang.String#intern() for strings
0643: // passed to SAX handlers.
0644: //
0645: if (feature.equals("string-interning")) {
0646: return false;
0647: }
0648:
0649: //
0650: // Drop through and perform default processing
0651: //
0652: }
0653:
0654: //
0655: // Xerces Features
0656: //
0657:
0658: /*
0659: else if (featureId.startsWith(XERCES_FEATURES_PREFIX)) {
0660: //
0661: // Drop through and perform default processing
0662: //
0663: }
0664: */
0665:
0666: //
0667: // Perform default processing
0668: //
0669: return super .getFeature(featureId);
0670:
0671: } // getFeature(String):boolean
0672:
0673: /**
0674: * Set the value of any property in a SAX2 parser. The parser
0675: * might not recognize the property, and if it does recognize
0676: * it, it might not support the requested value.
0677: *
0678: * @param propertyId The unique identifier (URI) of the property
0679: * being set.
0680: * @param Object The value to which the property is being set.
0681: *
0682: * @exception SAXNotRecognizedException If the
0683: * requested property is not known.
0684: * @exception SAXNotSupportedException If the
0685: * requested property is known, but the requested
0686: * value is not supported.
0687: */
0688: public void setProperty(String propertyId, Object value)
0689: throws SAXNotRecognizedException, SAXNotSupportedException {
0690:
0691: //
0692: // SAX2 core properties
0693: //
0694:
0695: if (propertyId.startsWith(SAX2_PROPERTIES_PREFIX)) {
0696: String property = propertyId
0697: .substring(SAX2_PROPERTIES_PREFIX.length());
0698: //
0699: // http://xml.org/sax/properties/lexical-handler
0700: // Value type: org.xml.sax.ext.LexicalHandler
0701: // Access: read/write, pre-parse only
0702: // Set the lexical event handler.
0703: //
0704: if (property.equals("lexical-handler")) {
0705: try {
0706: setLexicalHandler((LexicalHandler) value);
0707: } catch (ClassCastException e) {
0708: throw new SAXNotSupportedException(
0709: "PAR012 For propertyID \""
0710: + propertyId
0711: + "\", the value \""
0712: + value
0713: + "\" cannot be cast to LexicalHandler."
0714: + '\n' + propertyId + '\t' + value
0715: + "\tLexicalHandler");
0716: }
0717: return;
0718: }
0719: //
0720: // http://xml.org/sax/properties/declaration-handler
0721: // Value type: org.xml.sax.ext.DeclHandler
0722: // Access: read/write, pre-parse only
0723: // Set the DTD declaration event handler.
0724: //
0725: if (property.equals("declaration-handler")) {
0726: try {
0727: setDeclHandler((DeclHandler) value);
0728: } catch (ClassCastException e) {
0729: throw new SAXNotSupportedException(
0730: "PAR012 For propertyID \""
0731: + propertyId
0732: + "\", the value \""
0733: + value
0734: + "\" cannot be cast to DeclHandler."
0735: + '\n' + propertyId + '\t' + value
0736: + "\tDeclHandler");
0737: }
0738: return;
0739: }
0740: //
0741: // http://xml.org/sax/properties/dom-node
0742: // Value type: DOM Node
0743: // Access: read-only
0744: // Get the DOM node currently being visited, if the SAX parser is
0745: // iterating over a DOM tree. If the parser recognises and supports
0746: // this property but is not currently visiting a DOM node, it should
0747: // return null (this is a good way to check for availability before the
0748: // parse begins).
0749: //
0750: if (property.equals("dom-node")) {
0751: throw new SAXNotSupportedException("PAR013 Property \""
0752: + propertyId + "\" is read only." + '\n'
0753: + propertyId); // read-only property
0754: }
0755: //
0756: // Drop through and perform default processing
0757: //
0758: }
0759:
0760: //
0761: // Xerces Properties
0762: //
0763:
0764: /*
0765: else if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) {
0766: //
0767: // Drop through and perform default processing
0768: //
0769: }
0770: */
0771:
0772: //
0773: // Perform default processing
0774: //
0775: super .setProperty(propertyId, value);
0776:
0777: } // setProperty(String,Object)
0778:
0779: /**
0780: * Query the value of a property.
0781: *
0782: * Return the current value of a property in a SAX2 parser.
0783: * The parser might not recognize the property.
0784: *
0785: * @param propertyId The unique identifier (URI) of the property
0786: * being set.
0787: * @return The current value of the property.
0788: * @exception org.xml.sax.SAXNotRecognizedException If the
0789: * requested property is not known.
0790: * @exception SAXNotSupportedException If the
0791: * requested property is known but not supported.
0792: */
0793: public Object getProperty(String propertyId)
0794: throws SAXNotRecognizedException, SAXNotSupportedException {
0795:
0796: //
0797: // SAX2 core properties
0798: //
0799:
0800: if (propertyId.startsWith(SAX2_PROPERTIES_PREFIX)) {
0801: String property = propertyId
0802: .substring(SAX2_PROPERTIES_PREFIX.length());
0803: //
0804: // http://xml.org/sax/properties/lexical-handler
0805: // Value type: org.xml.sax.ext.LexicalHandler
0806: // Access: read/write, pre-parse only
0807: // Set the lexical event handler.
0808: //
0809: if (property.equals("lexical-handler")) {
0810: return getLexicalHandler();
0811: }
0812: //
0813: // http://xml.org/sax/properties/declaration-handler
0814: // Value type: org.xml.sax.ext.DeclHandler
0815: // Access: read/write, pre-parse only
0816: // Set the DTD declaration event handler.
0817: //
0818: if (property.equals("declaration-handler")) {
0819: return getDeclHandler();
0820: }
0821: //
0822: // http://xml.org/sax/properties/dom-node
0823: // Value type: DOM Node
0824: // Access: read-only
0825: // Get the DOM node currently being visited, if the SAX parser is
0826: // iterating over a DOM tree. If the parser recognises and supports
0827: // this property but is not currently visiting a DOM node, it should
0828: // return null (this is a good way to check for availability before the
0829: // parse begins).
0830: //
0831: if (property.equals("dom-node")) {
0832: throw new SAXNotSupportedException(
0833: "PAR014 Cannot getProperty(\"" + propertyId
0834: + "\". No DOM Tree exists.\n"
0835: + propertyId); // we are not iterating a DOM tree
0836: }
0837: //
0838: // Drop through and perform default processing
0839: //
0840: }
0841:
0842: //
0843: // Xerces properties
0844: //
0845:
0846: /*
0847: else if (propertyId.startsWith(XERCES_PROPERTIES_PREFIX)) {
0848: //
0849: // Drop through and perform default processing
0850: //
0851: }
0852: */
0853:
0854: //
0855: // Perform default processing
0856: //
0857: return super .getProperty(propertyId);
0858:
0859: } // getProperty(String):Object
0860:
0861: /**
0862: * Allow an application to register a content event handler.
0863: *
0864: * <p>If the application does not register a content handler, all
0865: * content events reported by the SAX parser will be silently
0866: * ignored.</p>
0867: *
0868: * <p>Applications may register a new or different handler in the
0869: * middle of a parse, and the SAX parser must begin using the new
0870: * handler immediately.</p>
0871: *
0872: * @param handler The content handler.
0873: * @exception java.lang.NullPointerException If the handler
0874: * argument is null.
0875: * @see #getContentHandler
0876: */
0877: public void setContentHandler(ContentHandler handler) {
0878: if (handler == null) {
0879: throw new NullPointerException();
0880: }
0881: fContentHandler = handler;
0882: }
0883:
0884: /**
0885: * Return the current content handler.
0886: *
0887: * @return The current content handler, or null if none
0888: * has been registered.
0889: * @see #setContentHandler
0890: */
0891: public ContentHandler getContentHandler() {
0892: return fContentHandler;
0893: }
0894:
0895: //
0896: // XMLParser methods
0897: //
0898:
0899: /**
0900: * This function will be called when a <!DOCTYPE...> declaration is
0901: * encountered.
0902: */
0903: public void startDTD(QName rootElement, int publicId, int systemId)
0904: throws Exception {
0905: if (fLexicalHandler != null || DEBUG_CALLBACKS) {
0906:
0907: // strings
0908: String name = fStringPool.toString(rootElement.rawname);
0909: String pubid = fStringPool.toString(publicId);
0910: String sysid = fStringPool.toString(systemId);
0911:
0912: // perform callback
0913: if (DEBUG_CALLBACKS) {
0914: System.err.println("startDTD(" + name + ", " + pubid
0915: + ", " + sysid + ")");
0916: }
0917: if (fLexicalHandler != null) {
0918: fLexicalHandler.startDTD(name, pubid, sysid);
0919: }
0920: }
0921: }
0922:
0923: /**
0924: * This function will be called at the end of the DTD.
0925: */
0926: public void endDTD() throws Exception {
0927: if (DEBUG_CALLBACKS) {
0928: System.err.println("endDTD()");
0929: }
0930: if (fLexicalHandler != null) {
0931: fLexicalHandler.endDTD();
0932: }
0933: }
0934:
0935: /**
0936: * Report an element type declaration.
0937: *
0938: * The content model will consist of the string "EMPTY", the
0939: * string "ANY", or a parenthesised group, optionally followed
0940: * by an occurrence indicator. The model will be normalized so
0941: * that all whitespace is removed.
0942: *
0943: * @param name The element type name.
0944: * @param model The content model as a normalized string.
0945: * @exception SAXException The application may raise an exception.
0946: */
0947: public void elementDecl(QName elementDecl, int contentSpecType,
0948: int contentSpecIndex,
0949: XMLContentSpec.Provider contentSpecProvider)
0950: throws Exception {
0951:
0952: if (fDeclHandler != null || DEBUG_CALLBACKS) {
0953:
0954: // strings
0955: String name = fStringPool.toString(elementDecl.rawname);
0956: String contentModel;
0957: if (contentSpecType == XMLElementDecl.TYPE_ANY) {
0958: contentModel = "ANY";
0959: } else if (contentSpecType == XMLElementDecl.TYPE_EMPTY) {
0960: contentModel = "EMPTY";
0961: } else {
0962: contentModel = XMLContentSpec.toString(
0963: contentSpecProvider, fStringPool,
0964: contentSpecIndex);
0965: }
0966:
0967: // perform callback
0968: if (DEBUG_CALLBACKS) {
0969: System.err.println("elementDecl(" + name + ", "
0970: + contentModel + ")");
0971: }
0972: if (fDeclHandler != null) {
0973: fDeclHandler.elementDecl(name, contentModel);
0974: }
0975: }
0976:
0977: }
0978:
0979: /**
0980: * Report an attribute type declaration.
0981: *
0982: * Only the effective (first) declaration for an attribute will
0983: * be reported. The type will be one of the strings "CDATA",
0984: * "ID", "IDREF", "IDREFS", "NMTOKEN", "NMTOKENS", "ENTITY",
0985: * "ENTITIES", or "NOTATION", or a parenthesized token group with
0986: * the separator "|" and all whitespace removed.
0987: *
0988: * @param eName The name of the associated element.
0989: * @param aName The name of the attribute.
0990: * @param type A string representing the attribute type.
0991: * @param valueDefault A string representing the attribute default
0992: * ("#IMPLIED", "#REQUIRED", or "#FIXED") or null if
0993: * none of these applies.
0994: * @param value A string representing the attribute's default value,
0995: * or null if there is none.
0996: * @exception SAXException The application may raise an exception.
0997: */
0998: public void attlistDecl(QName elementDecl, QName attributeDecl,
0999: int attType, boolean attList, String enumString,
1000: int attDefaultType, int attDefaultValue) throws Exception {
1001: if (fDeclHandler != null || DEBUG_CALLBACKS) {
1002:
1003: // strings
1004: String eName = fStringPool.toString(elementDecl.rawname);
1005: String aName = fStringPool.toString(attributeDecl.rawname);
1006: String aType = enumString;
1007: if (attType != XMLAttributeDecl.TYPE_ENUMERATION) {
1008: switch (attType) {
1009: case XMLAttributeDecl.TYPE_CDATA: {
1010: aType = "CDATA";
1011: break;
1012: }
1013: case XMLAttributeDecl.TYPE_ENTITY: {
1014: aType = attList ? "ENTITIES" : "ENTITY";
1015: break;
1016: }
1017: case XMLAttributeDecl.TYPE_ID: {
1018: aType = "ID";
1019: break;
1020: }
1021: case XMLAttributeDecl.TYPE_IDREF: {
1022: aType = attList ? "IDREFS" : "IDREF";
1023: break;
1024: }
1025: case XMLAttributeDecl.TYPE_NMTOKEN: {
1026: aType = attList ? "NMTOKENS" : "NMTOKEN";
1027: break;
1028: }
1029: case XMLAttributeDecl.TYPE_NOTATION: {
1030: aType = "NOTATION " + enumString;
1031: break;
1032: }
1033: }
1034: }
1035: String aDefaultType = null;
1036: switch (attDefaultType) {
1037: case XMLAttributeDecl.DEFAULT_TYPE_FIXED: {
1038: aDefaultType = "#FIXED";
1039: break;
1040: }
1041: case XMLAttributeDecl.DEFAULT_TYPE_IMPLIED: {
1042: aDefaultType = "#IMPLIED";
1043: break;
1044: }
1045: case XMLAttributeDecl.DEFAULT_TYPE_REQUIRED: {
1046: aDefaultType = "#REQUIRED";
1047: break;
1048: }
1049: }
1050: String aDefaultValue = fStringPool
1051: .toString(attDefaultValue);
1052:
1053: // perform callback
1054: if (DEBUG_CALLBACKS) {
1055: System.err.println("attributeDecl(" + eName + ", "
1056: + aName + ", " + aType + ", " + aDefaultType
1057: + ", " + aDefaultValue + ")");
1058: }
1059: if (fDeclHandler != null) {
1060: fDeclHandler.attributeDecl(eName, aName, aType,
1061: aDefaultType, aDefaultValue);
1062: }
1063: }
1064: }
1065:
1066: /**
1067: * Report an internal parameter entity declaration.
1068: */
1069: public void internalPEDecl(int entityName, int entityValue)
1070: throws Exception {
1071:
1072: if (fDeclHandler != null || DEBUG_CALLBACKS) {
1073:
1074: // strings
1075: String name = "%" + fStringPool.toString(entityName);
1076: String value = fStringPool.toString(entityValue);
1077:
1078: // perform callback
1079: if (DEBUG_CALLBACKS) {
1080: System.err.println("internalEntityDecl(" + name + ", "
1081: + value + ")");
1082: }
1083: if (fDeclHandler != null) {
1084: fDeclHandler.internalEntityDecl(name, value);
1085: }
1086: }
1087:
1088: }
1089:
1090: /**
1091: * Report a parsed external parameter entity declaration.
1092: */
1093: public void externalPEDecl(int entityName, int publicId,
1094: int systemId) throws Exception {
1095:
1096: if (fDeclHandler != null || DEBUG_CALLBACKS) {
1097:
1098: // strings
1099: String name = "%" + fStringPool.toString(entityName);
1100: String pubid = fStringPool.toString(publicId);
1101: String sysid = fStringPool.toString(systemId);
1102:
1103: // perform callback
1104: if (DEBUG_CALLBACKS) {
1105: System.err.println("externalEntityDecl(" + name + ", "
1106: + pubid + ", " + sysid + ")");
1107: }
1108: if (fDeclHandler != null) {
1109: fDeclHandler.externalEntityDecl(name, pubid, sysid);
1110: }
1111: }
1112:
1113: }
1114:
1115: /**
1116: * Report an internal general entity declaration.
1117: */
1118: public void internalEntityDecl(int entityName, int entityValue)
1119: throws Exception {
1120:
1121: if (fDeclHandler != null || DEBUG_CALLBACKS) {
1122:
1123: // strings
1124: String name = fStringPool.toString(entityName);
1125: String value = fStringPool.toString(entityValue);
1126:
1127: // perform callback
1128: if (DEBUG_CALLBACKS) {
1129: System.err.println("internalEntityDecl(" + name + ", "
1130: + value + ")");
1131: }
1132: if (fDeclHandler != null) {
1133: fDeclHandler.internalEntityDecl(name, value);
1134: }
1135: }
1136:
1137: }
1138:
1139: /**
1140: * Report a parsed external general entity declaration.
1141: */
1142: public void externalEntityDecl(int entityName, int publicId,
1143: int systemId) throws Exception {
1144:
1145: if (fDeclHandler != null || DEBUG_CALLBACKS) {
1146:
1147: // strings
1148: String name = fStringPool.toString(entityName);
1149: String pubid = fStringPool.toString(publicId);
1150: String sysid = fStringPool.toString(systemId);
1151:
1152: // perform callback
1153: if (DEBUG_CALLBACKS) {
1154: System.err.println("externalEntityDecl(" + name + ", "
1155: + pubid + ", " + sysid + ")");
1156: }
1157: if (fDeclHandler != null) {
1158: fDeclHandler.externalEntityDecl(name, pubid, sysid);
1159: }
1160: }
1161:
1162: }
1163:
1164: /**
1165: * Receive notification of an unparsed entity declaration event.
1166: */
1167: public void unparsedEntityDecl(int entityName, int publicId,
1168: int systemId, int notationName) throws Exception {
1169:
1170: if (fDTDHandler != null || DEBUG_CALLBACKS) {
1171:
1172: // strings
1173: String name = fStringPool.toString(entityName);
1174: String pubid = fStringPool.toString(publicId);
1175: String sysid = fStringPool.toString(systemId);
1176: String notation = fStringPool.toString(notationName);
1177:
1178: // perform callback
1179: if (DEBUG_CALLBACKS) {
1180: System.err.println("unparsedEntityDecl(" + name + ", "
1181: + pubid + ", " + sysid + ", " + notation + ")");
1182: }
1183: if (fDTDHandler != null) {
1184: fDTDHandler.unparsedEntityDecl(name, pubid, sysid,
1185: notation);
1186: }
1187: }
1188:
1189: }
1190:
1191: /**
1192: * Receive notification of a notation declaration event.
1193: */
1194: public void notationDecl(int notationName, int publicId,
1195: int systemId) throws Exception {
1196:
1197: if (fDTDHandler != null || DEBUG_CALLBACKS) {
1198:
1199: // strings
1200: String name = fStringPool.toString(notationName);
1201: String pubid = fStringPool.toString(publicId);
1202: String sysid = fStringPool.toString(systemId);
1203:
1204: // perform callback
1205: if (DEBUG_CALLBACKS) {
1206: System.err.println("notationDecl(" + name + ", "
1207: + pubid + ", " + sysid + ")");
1208: }
1209: if (fDTDHandler != null) {
1210: fDTDHandler.notationDecl(name, pubid, sysid);
1211: }
1212: }
1213:
1214: }
1215:
1216: /** Start document. */
1217: public void startDocument() throws Exception {
1218:
1219: // perform callbacks
1220: if (DEBUG_CALLBACKS) {
1221: System.err.println("setDocumentLocator(<locator>)");
1222: System.err.println("startDocument()");
1223: }
1224: if (fDocumentHandler != null) {
1225: fDocumentHandler.setDocumentLocator(getLocator());
1226: fDocumentHandler.startDocument();
1227: }
1228: if (fContentHandler != null) {
1229: fContentHandler.setDocumentLocator(getLocator());
1230: fContentHandler.startDocument();
1231: }
1232:
1233: } // startDocument()
1234:
1235: /** End document. */
1236: public void endDocument() throws Exception {
1237:
1238: // perform callback
1239: if (DEBUG_CALLBACKS) {
1240: System.err.println("endDocument()");
1241: }
1242: if (fDocumentHandler != null) {
1243: fDocumentHandler.endDocument();
1244: }
1245: if (fContentHandler != null) {
1246: fContentHandler.endDocument();
1247: }
1248:
1249: } // endDocument()
1250:
1251: /** XML declaration. */
1252: public void xmlDecl(int versionIndex, int encodingIndex,
1253: int standaloneIndex) throws Exception {
1254:
1255: // perform callbacks
1256: if (DEBUG_CALLBACKS) {
1257: String notes = "";
1258: if (versionIndex != -1)
1259: notes += " version='"
1260: + fStringPool.toString(versionIndex) + "'";
1261: if (encodingIndex != -1)
1262: notes += " encoding='"
1263: + fStringPool.toString(encodingIndex) + "'";
1264: if (standaloneIndex != -1)
1265: notes += " standalone='"
1266: + fStringPool.toString(standaloneIndex) + "'";
1267: System.err.println("xmlDecl(<?xml" + notes + "?>)");
1268: }
1269:
1270: // release strings
1271: fStringPool.releaseString(versionIndex);
1272: fStringPool.releaseString(encodingIndex);
1273: fStringPool.releaseString(standaloneIndex);
1274:
1275: }
1276:
1277: /** Text declaration. */
1278: public void textDecl(int versionIndex, int encodingIndex)
1279: throws Exception {
1280:
1281: // perform callbacks
1282: if (DEBUG_CALLBACKS) {
1283: String notes = "";
1284: if (versionIndex != -1)
1285: notes += " version='"
1286: + fStringPool.toString(versionIndex) + "'";
1287: if (encodingIndex != -1)
1288: notes += " encoding='"
1289: + fStringPool.toString(encodingIndex) + "'";
1290: System.err.println("textDecl(<?xml" + notes + "?>)");
1291: }
1292:
1293: // release strings
1294: fStringPool.releaseString(versionIndex);
1295: fStringPool.releaseString(encodingIndex);
1296: }
1297:
1298: /**
1299: * Report the start of the scope of a namespace declaration.
1300: */
1301: public void startNamespaceDeclScope(int prefix, int uri)
1302: throws Exception {
1303:
1304: if (fContentHandler != null || DEBUG_CALLBACKS) {
1305:
1306: // strings
1307: String p = fStringPool.toString(prefix);
1308: String ns = fStringPool.toString(uri);
1309:
1310: // perform callback
1311: if (DEBUG_CALLBACKS) {
1312: System.err.println("startNamespaceDeclScope(" + p
1313: + ", " + ns + ")");
1314: }
1315: if (fContentHandler != null) {
1316: fContentHandler.startPrefixMapping(p, ns);
1317: }
1318: }
1319:
1320: }
1321:
1322: /**
1323: * Report the end of the scope of a namespace declaration.
1324: */
1325: public void endNamespaceDeclScope(int prefix) throws Exception {
1326:
1327: if (fContentHandler != null || DEBUG_CALLBACKS) {
1328:
1329: // strings
1330: String p = fStringPool.toString(prefix);
1331:
1332: // perform callback
1333: if (DEBUG_CALLBACKS) {
1334: System.err.println("endNamespaceDeclScope(" + p + ")");
1335: }
1336: if (fContentHandler != null) {
1337: fContentHandler.endPrefixMapping(p);
1338: }
1339: }
1340:
1341: }
1342:
1343: /** New callback from DOM Level 2. There is no corresponding SAX callout for this yet. */
1344: public void internalSubset(int internalSubset) {
1345: }
1346:
1347: /** Start element */
1348: public void startElement(QName element, XMLAttrList attrList,
1349: int attrListIndex) throws Exception {
1350:
1351: // parameters
1352: String name = fStringPool.toString(element.rawname);
1353: AttributeList attrs = attrList.getAttributeList(attrListIndex);
1354:
1355: // perform callback
1356: if (DEBUG_CALLBACKS) {
1357: String atts = attrs.getLength() > 0 ? "" : " ";
1358: for (int i = 0; i < attrs.getLength(); i++) {
1359: atts += " " + attrs.getName(i) + "='"
1360: + attrs.getValue(i) + "'";
1361: }
1362: System.err.println("startElement(" + name + "," + atts
1363: + ")");
1364: }
1365: if (fDocumentHandler != null) {
1366: fDocumentHandler.startElement(name, attrs);
1367: }
1368: if (fContentHandler != null) {
1369: boolean namespaces = getNamespaces();
1370: int uriIndex = element.uri;
1371: String uri = uriIndex != StringPool.EMPTY_STRING
1372: && namespaces ? fStringPool.toString(uriIndex) : "";
1373: int localIndex = element.localpart;
1374: String local = localIndex != -1 && namespaces ? fStringPool
1375: .toString(localIndex) : "";
1376: String raw = name;
1377: fAttributes.clear();
1378: for (int attrIndex = attrList.getFirstAttr(attrListIndex); attrIndex != -1; attrIndex = attrList
1379: .getNextAttr(attrIndex)) {
1380: int attrNameIndex = attrList.getAttrName(attrIndex);
1381: int attrUriIndex = attrList.getAttrURI(attrIndex);
1382: String attrUri = attrUriIndex != -1 && namespaces ? fStringPool
1383: .toString(attrUriIndex)
1384: : "";
1385: int attrLocalIndex = attrList
1386: .getAttrLocalpart(attrIndex);
1387: String attrLocal = attrLocalIndex != -1 && namespaces ? fStringPool
1388: .toString(attrLocalIndex)
1389: : "";
1390: String attrRaw = fStringPool.toString(attrNameIndex);
1391: String attrType = fStringPool.toString(attrList
1392: .getAttType(attrIndex));
1393: String attrValue = fStringPool.toString(attrList
1394: .getAttValue(attrIndex));
1395: //int attrPrefix = fStringPool.getPrefixForQName(attrNameIndex);
1396: int attrPrefix = attrList.getAttrPrefix(attrIndex);
1397: boolean namespacePrefixes = getNamespacePrefixes();
1398: if (!namespaces
1399: || namespacePrefixes
1400: || (attrPrefix != fStringPool
1401: .addSymbol("xmlns") && attrLocalIndex != fStringPool
1402: .addSymbol("xmlns")))
1403: fAttributes.addAttribute(attrUri, attrLocal,
1404: attrRaw, attrType, attrValue);
1405:
1406: }
1407: fContentHandler.startElement(uri, local, raw, fAttributes);
1408: }
1409:
1410: // free attribute list
1411: attrList.releaseAttrList(attrListIndex);
1412:
1413: } // startElement(QName,XMLAttrList,int)
1414:
1415: /** End element. */
1416: public void endElement(QName element) throws Exception {
1417:
1418: // perform callback
1419: if (DEBUG_CALLBACKS) {
1420: System.err.println("endElement("
1421: + fStringPool.toString(element.rawname) + ")");
1422: }
1423: if (fDocumentHandler != null) {
1424: fDocumentHandler.endElement(fStringPool
1425: .toString(element.rawname));
1426: }
1427: if (fContentHandler != null) {
1428: boolean namespaces = getNamespaces();
1429: int uriIndex = element.uri;
1430: String uri = uriIndex != StringPool.EMPTY_STRING
1431: && namespaces ? fStringPool.toString(uriIndex) : "";
1432: int localIndex = element.localpart;
1433: String local = localIndex != -1 && namespaces ? fStringPool
1434: .toString(localIndex) : "";
1435: String raw = fStringPool.toString(element.rawname);
1436: fContentHandler.endElement(uri, local, raw);
1437: }
1438:
1439: } // endElement(QName)
1440:
1441: /** Start entity reference. */
1442: public void startEntityReference(int entityName, int entityType,
1443: int entityContext) throws Exception {
1444: if (fLexicalHandler != null || DEBUG_CALLBACKS) {
1445: switch (entityType) {
1446: case XMLEntityHandler.ENTITYTYPE_INTERNAL_PE:
1447: case XMLEntityHandler.ENTITYTYPE_EXTERNAL_PE:
1448: if (DEBUG_CALLBACKS) {
1449: System.err.println("startEntity(%"
1450: + fStringPool.toString(entityName) + ")");
1451: }
1452: if (fLexicalHandler != null) {
1453: fLexicalHandler.startEntity("%"
1454: + fStringPool.toString(entityName));
1455: }
1456: break;
1457: case XMLEntityHandler.ENTITYTYPE_INTERNAL:
1458: case XMLEntityHandler.ENTITYTYPE_EXTERNAL:
1459: if (DEBUG_CALLBACKS) {
1460: System.err.println("startEntity("
1461: + fStringPool.toString(entityName) + ")");
1462: }
1463: if (fLexicalHandler != null) {
1464: fLexicalHandler.startEntity(fStringPool
1465: .toString(entityName));
1466: }
1467: break;
1468: case XMLEntityHandler.ENTITYTYPE_UNPARSED: // these are mentioned by name, not referenced
1469: throw new RuntimeException(
1470: "PAR015 startEntityReference(): ENTITYTYPE_UNPARSED");
1471: case XMLEntityHandler.ENTITYTYPE_DOCUMENT:
1472: break; // not reported
1473: case XMLEntityHandler.ENTITYTYPE_EXTERNAL_SUBSET:
1474: if (DEBUG_CALLBACKS) {
1475: System.err.println("startEntity(\"[dtd]\")");
1476: }
1477: if (fLexicalHandler != null) {
1478: fLexicalHandler.startEntity("[dtd]");
1479: }
1480: break;
1481: }
1482: }
1483: }
1484:
1485: /** End entity reference. */
1486: public void endEntityReference(int entityName, int entityType,
1487: int entityContext) throws Exception {
1488: if (fLexicalHandler != null || DEBUG_CALLBACKS) {
1489: switch (entityType) {
1490: case XMLEntityHandler.ENTITYTYPE_INTERNAL_PE:
1491: case XMLEntityHandler.ENTITYTYPE_EXTERNAL_PE:
1492: if (DEBUG_CALLBACKS) {
1493: System.err.println("endEntity(%"
1494: + fStringPool.toString(entityName) + ")");
1495: }
1496: if (fLexicalHandler != null) {
1497: fLexicalHandler.endEntity("%"
1498: + fStringPool.toString(entityName));
1499: }
1500: break;
1501: case XMLEntityHandler.ENTITYTYPE_INTERNAL:
1502: case XMLEntityHandler.ENTITYTYPE_EXTERNAL:
1503: if (DEBUG_CALLBACKS) {
1504: System.err.println("endEntity("
1505: + fStringPool.toString(entityName) + ")");
1506: }
1507: if (fLexicalHandler != null) {
1508: fLexicalHandler.endEntity(fStringPool
1509: .toString(entityName));
1510: }
1511: break;
1512: case XMLEntityHandler.ENTITYTYPE_UNPARSED: // these are mentioned by name, not referenced
1513: throw new RuntimeException(
1514: "PAR016 endEntityReference(): ENTITYTYPE_UNPARSED");
1515: case XMLEntityHandler.ENTITYTYPE_DOCUMENT:
1516: break; // not reported
1517: case XMLEntityHandler.ENTITYTYPE_EXTERNAL_SUBSET:
1518: if (DEBUG_CALLBACKS) {
1519: System.err.println("endEntity(\"[dtd]\")");
1520: }
1521: if (fLexicalHandler != null) {
1522: fLexicalHandler.endEntity("[dtd]");
1523: }
1524: break;
1525: }
1526: }
1527: }
1528:
1529: /** Start CDATA section. */
1530: public void startCDATA() throws Exception {
1531: if (DEBUG_CALLBACKS) {
1532: System.err.println("startCDATA()");
1533: }
1534: if (fLexicalHandler != null) {
1535: fLexicalHandler.startCDATA();
1536: }
1537: }
1538:
1539: /** End CDATA section. */
1540: public void endCDATA() throws Exception {
1541: if (DEBUG_CALLBACKS) {
1542: System.err.println("endCDATA()");
1543: }
1544: if (fLexicalHandler != null) {
1545: fLexicalHandler.endCDATA();
1546: }
1547: }
1548:
1549: /** Not called. */
1550: public void characters(int dataIndex) throws Exception {
1551: throw new RuntimeException("PAR017 cannot happen 5\n5");
1552: }
1553:
1554: /** Not called. */
1555: public void ignorableWhitespace(int dataIndex) throws Exception {
1556: throw new RuntimeException("PAR017 cannot happen 6\n6");
1557: }
1558:
1559: /** Processing instruction. */
1560: public void processingInstruction(int piTarget, int piData)
1561: throws Exception {
1562:
1563: if (fDocumentHandler != null || fContentHandler != null
1564: || DEBUG_CALLBACKS) {
1565: //
1566: // REVISIT - I keep running into SAX apps that expect
1567: // null data to be an empty string, which is contrary
1568: // to the comment for this method in the SAX API.
1569: //
1570:
1571: // strings
1572: String target = fStringPool.orphanString(piTarget);
1573: String data = piData == -1 ? "" : fStringPool
1574: .orphanString(piData);
1575:
1576: // perform callback
1577: if (DEBUG_CALLBACKS) {
1578: System.err.println("processingInstruction(" + target
1579: + ", " + data + ")");
1580: }
1581: if (fDocumentHandler != null) {
1582: fDocumentHandler.processingInstruction(target, data);
1583: }
1584: if (fContentHandler != null) {
1585: fContentHandler.processingInstruction(target, data);
1586: }
1587:
1588: } else {
1589: fStringPool.releaseString(piTarget);
1590: fStringPool.releaseString(piData);
1591: }
1592:
1593: }
1594:
1595: /** Comment. */
1596: public void comment(int dataIndex) throws Exception {
1597:
1598: if (fLexicalHandler != null || DEBUG_CALLBACKS) {
1599:
1600: // strings
1601: String data = fStringPool.orphanString(dataIndex);
1602:
1603: // perform callback
1604: if (DEBUG_CALLBACKS) {
1605: System.err.println("comment(" + data + ")");
1606: }
1607: if (fLexicalHandler != null) {
1608: fLexicalHandler.comment(data.toCharArray(), 0, data
1609: .length());
1610: }
1611: } else {
1612: fStringPool.releaseString(dataIndex);
1613: }
1614: }
1615:
1616: /** Characters. */
1617: public void characters(char ch[], int start, int length)
1618: throws Exception {
1619:
1620: // perform callback
1621: if (DEBUG_CALLBACKS) {
1622: System.err.println("characters(<char-data>) length "
1623: + length);
1624: }
1625: if (fDocumentHandler != null) {
1626: fDocumentHandler.characters(ch, start, length);
1627: }
1628: if (fContentHandler != null) {
1629: fContentHandler.characters(ch, start, length);
1630: }
1631:
1632: }
1633:
1634: /** Ignorable whitespace. */
1635: public void ignorableWhitespace(char ch[], int start, int length)
1636: throws Exception {
1637:
1638: // perform callback
1639: if (DEBUG_CALLBACKS) {
1640: System.err.println("ignorableWhitespace(<white-space>)");
1641: }
1642: if (fDocumentHandler != null) {
1643: fDocumentHandler.ignorableWhitespace(ch, start, length);
1644: }
1645: if (fContentHandler != null) {
1646: fContentHandler.ignorableWhitespace(ch, start, length);
1647: }
1648:
1649: }
1650:
1651: } // class SAXParser
|