0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017:
0018: package org.apache.xerces.parsers;
0019:
0020: import java.io.IOException;
0021: import java.util.ArrayList;
0022: import java.util.HashMap;
0023: import java.util.Locale;
0024:
0025: import org.apache.xerces.impl.Constants;
0026: import org.apache.xerces.impl.XML11DTDScannerImpl;
0027: import org.apache.xerces.impl.XML11DocumentScannerImpl;
0028: import org.apache.xerces.impl.XML11NSDocumentScannerImpl;
0029: import org.apache.xerces.impl.XMLDTDScannerImpl;
0030: import org.apache.xerces.impl.XMLDocumentScannerImpl;
0031: import org.apache.xerces.impl.XMLEntityHandler;
0032: import org.apache.xerces.impl.XMLEntityManager;
0033: import org.apache.xerces.impl.XMLErrorReporter;
0034: import org.apache.xerces.impl.XMLNSDocumentScannerImpl;
0035: import org.apache.xerces.impl.XMLVersionDetector;
0036: import org.apache.xerces.impl.dv.DTDDVFactory;
0037: import org.apache.xerces.impl.msg.XMLMessageFormatter;
0038: import org.apache.xerces.impl.validation.ValidationManager;
0039: import org.apache.xerces.util.ParserConfigurationSettings;
0040: import org.apache.xerces.util.SymbolTable;
0041: import org.apache.xerces.xni.XMLDTDContentModelHandler;
0042: import org.apache.xerces.xni.XMLDTDHandler;
0043: import org.apache.xerces.xni.XMLDocumentHandler;
0044: import org.apache.xerces.xni.XMLLocator;
0045: import org.apache.xerces.xni.XNIException;
0046: import org.apache.xerces.xni.grammars.XMLGrammarPool;
0047: import org.apache.xerces.xni.parser.XMLComponent;
0048: import org.apache.xerces.xni.parser.XMLComponentManager;
0049: import org.apache.xerces.xni.parser.XMLConfigurationException;
0050: import org.apache.xerces.xni.parser.XMLDTDScanner;
0051: import org.apache.xerces.xni.parser.XMLDocumentScanner;
0052: import org.apache.xerces.xni.parser.XMLDocumentSource;
0053: import org.apache.xerces.xni.parser.XMLEntityResolver;
0054: import org.apache.xerces.xni.parser.XMLErrorHandler;
0055: import org.apache.xerces.xni.parser.XMLInputSource;
0056: import org.apache.xerces.xni.parser.XMLPullParserConfiguration;
0057:
0058: /**
0059: * This class is the non vlaidating parser configuration
0060: * used to parse XML 1.0 and XML 1.1 documents.
0061: *
0062: * Xerces parser that uses this configuration is <strong>not</strong> <a href="http://www.w3.org/TR/REC-xml#sec-conformance">conformant</a>
0063: * non-validating XML processor, since conformant non-validating processor is required
0064: * to process "all the declarations they read in the internal DTD subset ... must use the information in those declarations to normalize attribute values,
0065: * include the replacement text of internal entities, and supply default attribute values".
0066:
0067: * @author Elena Litani, IBM
0068: * @author John Kim, IBM
0069: * @author Michael Glavassevich, IBM
0070: *
0071: * @version $Id: XML11NonValidatingConfiguration.java 447239 2006-09-18 05:08:26Z mrglavas $
0072: */
0073: public class XML11NonValidatingConfiguration extends
0074: ParserConfigurationSettings implements
0075: XMLPullParserConfiguration, XML11Configurable {
0076:
0077: //
0078: // Constants
0079: //
0080: protected final static String XML11_DATATYPE_VALIDATOR_FACTORY = "org.apache.xerces.impl.dv.dtd.XML11DTDDVFactoryImpl";
0081:
0082: // feature identifiers
0083:
0084: /** Feature identifier: validation. */
0085: protected static final String VALIDATION = Constants.SAX_FEATURE_PREFIX
0086: + Constants.VALIDATION_FEATURE;
0087:
0088: /** Feature identifier: namespaces. */
0089: protected static final String NAMESPACES = Constants.SAX_FEATURE_PREFIX
0090: + Constants.NAMESPACES_FEATURE;
0091:
0092: /** Feature identifier: external general entities. */
0093: protected static final String EXTERNAL_GENERAL_ENTITIES = Constants.SAX_FEATURE_PREFIX
0094: + Constants.EXTERNAL_GENERAL_ENTITIES_FEATURE;
0095:
0096: /** Feature identifier: external parameter entities. */
0097: protected static final String EXTERNAL_PARAMETER_ENTITIES = Constants.SAX_FEATURE_PREFIX
0098: + Constants.EXTERNAL_PARAMETER_ENTITIES_FEATURE;
0099:
0100: /** Feature identifier: continue after fatal error. */
0101: protected static final String CONTINUE_AFTER_FATAL_ERROR = Constants.XERCES_FEATURE_PREFIX
0102: + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
0103:
0104: // property identifiers
0105:
0106: /** Property identifier: xml string. */
0107: protected static final String XML_STRING = Constants.SAX_PROPERTY_PREFIX
0108: + Constants.XML_STRING_PROPERTY;
0109:
0110: /** Property identifier: symbol table. */
0111: protected static final String SYMBOL_TABLE = Constants.XERCES_PROPERTY_PREFIX
0112: + Constants.SYMBOL_TABLE_PROPERTY;
0113:
0114: /** Property identifier: error handler. */
0115: protected static final String ERROR_HANDLER = Constants.XERCES_PROPERTY_PREFIX
0116: + Constants.ERROR_HANDLER_PROPERTY;
0117:
0118: /** Property identifier: entity resolver. */
0119: protected static final String ENTITY_RESOLVER = Constants.XERCES_PROPERTY_PREFIX
0120: + Constants.ENTITY_RESOLVER_PROPERTY;
0121:
0122: /** Property identifier: error reporter. */
0123: protected static final String ERROR_REPORTER = Constants.XERCES_PROPERTY_PREFIX
0124: + Constants.ERROR_REPORTER_PROPERTY;
0125:
0126: /** Property identifier: entity manager. */
0127: protected static final String ENTITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX
0128: + Constants.ENTITY_MANAGER_PROPERTY;
0129:
0130: /** Property identifier document scanner: */
0131: protected static final String DOCUMENT_SCANNER = Constants.XERCES_PROPERTY_PREFIX
0132: + Constants.DOCUMENT_SCANNER_PROPERTY;
0133:
0134: /** Property identifier: DTD scanner. */
0135: protected static final String DTD_SCANNER = Constants.XERCES_PROPERTY_PREFIX
0136: + Constants.DTD_SCANNER_PROPERTY;
0137:
0138: /** Property identifier: grammar pool. */
0139: protected static final String XMLGRAMMAR_POOL = Constants.XERCES_PROPERTY_PREFIX
0140: + Constants.XMLGRAMMAR_POOL_PROPERTY;
0141:
0142: /** Property identifier: DTD validator. */
0143: protected static final String DTD_VALIDATOR = Constants.XERCES_PROPERTY_PREFIX
0144: + Constants.DTD_VALIDATOR_PROPERTY;
0145:
0146: /** Property identifier: namespace binder. */
0147: protected static final String NAMESPACE_BINDER = Constants.XERCES_PROPERTY_PREFIX
0148: + Constants.NAMESPACE_BINDER_PROPERTY;
0149:
0150: /** Property identifier: datatype validator factory. */
0151: protected static final String DATATYPE_VALIDATOR_FACTORY = Constants.XERCES_PROPERTY_PREFIX
0152: + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY;
0153:
0154: protected static final String VALIDATION_MANAGER = Constants.XERCES_PROPERTY_PREFIX
0155: + Constants.VALIDATION_MANAGER_PROPERTY;
0156:
0157: // debugging
0158:
0159: /** Set to true and recompile to print exception stack trace. */
0160: protected static final boolean PRINT_EXCEPTION_STACK_TRACE = false;
0161:
0162: //
0163: // Data
0164: //
0165: protected SymbolTable fSymbolTable;
0166: protected XMLInputSource fInputSource;
0167: protected ValidationManager fValidationManager;
0168: protected XMLVersionDetector fVersionDetector;
0169: protected XMLLocator fLocator;
0170: protected Locale fLocale;
0171:
0172: /** XML 1.0 Components. */
0173: protected ArrayList fComponents;
0174:
0175: /** XML 1.1. Components. */
0176: protected ArrayList fXML11Components = null;
0177:
0178: /** Common components: XMLEntityManager, XMLErrorReporter */
0179: protected ArrayList fCommonComponents = null;
0180:
0181: /** The document handler. */
0182: protected XMLDocumentHandler fDocumentHandler;
0183:
0184: /** The DTD handler. */
0185: protected XMLDTDHandler fDTDHandler;
0186:
0187: /** The DTD content model handler. */
0188: protected XMLDTDContentModelHandler fDTDContentModelHandler;
0189:
0190: /** Last component in the document pipeline */
0191: protected XMLDocumentSource fLastComponent;
0192:
0193: /**
0194: * True if a parse is in progress. This state is needed because
0195: * some features/properties cannot be set while parsing (e.g.
0196: * namespaces).
0197: */
0198: protected boolean fParseInProgress = false;
0199:
0200: /** fConfigUpdated is set to true if there has been any change to the configuration settings,
0201: * i.e a feature or a property was changed.
0202: */
0203: protected boolean fConfigUpdated = false;
0204:
0205: //
0206: // XML 1.0 components
0207: //
0208:
0209: /** The XML 1.0 Datatype validator factory. */
0210: protected DTDDVFactory fDatatypeValidatorFactory;
0211:
0212: /** The XML 1.0 Document scanner that does namespace binding. */
0213: protected XMLNSDocumentScannerImpl fNamespaceScanner;
0214:
0215: /** The XML 1.0 Non-namespace implementation of scanner */
0216: protected XMLDocumentScannerImpl fNonNSScanner;
0217:
0218: /** The XML 1.0 DTD scanner. */
0219: protected XMLDTDScanner fDTDScanner;
0220:
0221: //
0222: // XML 1.1 components
0223: //
0224:
0225: /** The XML 1.1 datatype factory. **/
0226: protected DTDDVFactory fXML11DatatypeFactory = null;
0227:
0228: /** The XML 1.1 document scanner that does namespace binding. **/
0229: protected XML11NSDocumentScannerImpl fXML11NSDocScanner = null;
0230:
0231: /** The XML 1.1 document scanner that does not do namespace binding. **/
0232: protected XML11DocumentScannerImpl fXML11DocScanner = null;
0233:
0234: /** The XML 1.1 DTD scanner. **/
0235: protected XML11DTDScannerImpl fXML11DTDScanner = null;
0236:
0237: //
0238: // Common components
0239: //
0240:
0241: /** Grammar pool. */
0242: protected XMLGrammarPool fGrammarPool;
0243:
0244: /** Error reporter. */
0245: protected XMLErrorReporter fErrorReporter;
0246:
0247: /** Entity manager. */
0248: protected XMLEntityManager fEntityManager;
0249:
0250: /** Current scanner */
0251: protected XMLDocumentScanner fCurrentScanner;
0252:
0253: /** Current Datatype validator factory. */
0254: protected DTDDVFactory fCurrentDVFactory;
0255:
0256: /** Current DTD scanner. */
0257: protected XMLDTDScanner fCurrentDTDScanner;
0258:
0259: /** Flag indiciating whether XML11 components have been initialized. */
0260: private boolean f11Initialized = false;
0261:
0262: //
0263: // Constructors
0264: //
0265:
0266: /** Default constructor. */
0267: public XML11NonValidatingConfiguration() {
0268: this (null, null, null);
0269: } // <init>()
0270:
0271: /**
0272: * Constructs a parser configuration using the specified symbol table.
0273: *
0274: * @param symbolTable The symbol table to use.
0275: */
0276: public XML11NonValidatingConfiguration(SymbolTable symbolTable) {
0277: this (symbolTable, null, null);
0278: } // <init>(SymbolTable)
0279:
0280: /**
0281: * Constructs a parser configuration using the specified symbol table and
0282: * grammar pool.
0283: * <p>
0284: * <strong>REVISIT:</strong>
0285: * Grammar pool will be updated when the new validation engine is
0286: * implemented.
0287: *
0288: * @param symbolTable The symbol table to use.
0289: * @param grammarPool The grammar pool to use.
0290: */
0291: public XML11NonValidatingConfiguration(SymbolTable symbolTable,
0292: XMLGrammarPool grammarPool) {
0293: this (symbolTable, grammarPool, null);
0294: } // <init>(SymbolTable,XMLGrammarPool)
0295:
0296: /**
0297: * Constructs a parser configuration using the specified symbol table,
0298: * grammar pool, and parent settings.
0299: * <p>
0300: * <strong>REVISIT:</strong>
0301: * Grammar pool will be updated when the new validation engine is
0302: * implemented.
0303: *
0304: * @param symbolTable The symbol table to use.
0305: * @param grammarPool The grammar pool to use.
0306: * @param parentSettings The parent settings.
0307: */
0308: public XML11NonValidatingConfiguration(SymbolTable symbolTable,
0309: XMLGrammarPool grammarPool,
0310: XMLComponentManager parentSettings) {
0311:
0312: super (parentSettings);
0313:
0314: // create a vector to hold all the components in use
0315: // XML 1.0 specialized components
0316: fComponents = new ArrayList();
0317: // XML 1.1 specialized components
0318: fXML11Components = new ArrayList();
0319: // Common components for XML 1.1. and XML 1.0
0320: fCommonComponents = new ArrayList();
0321:
0322: // create storage for recognized features and properties
0323: fRecognizedFeatures = new ArrayList();
0324: fRecognizedProperties = new ArrayList();
0325:
0326: // create table for features and properties
0327: fFeatures = new HashMap();
0328: fProperties = new HashMap();
0329:
0330: // add default recognized features
0331: final String[] recognizedFeatures = {
0332: CONTINUE_AFTER_FATAL_ERROR, // from XMLDTDScannerImpl
0333: VALIDATION, NAMESPACES, EXTERNAL_GENERAL_ENTITIES,
0334: EXTERNAL_PARAMETER_ENTITIES, PARSER_SETTINGS };
0335: addRecognizedFeatures(recognizedFeatures);
0336:
0337: // set state for default features
0338: fFeatures.put(VALIDATION, Boolean.FALSE);
0339: fFeatures.put(NAMESPACES, Boolean.TRUE);
0340: fFeatures.put(EXTERNAL_GENERAL_ENTITIES, Boolean.TRUE);
0341: fFeatures.put(EXTERNAL_PARAMETER_ENTITIES, Boolean.TRUE);
0342: fFeatures.put(CONTINUE_AFTER_FATAL_ERROR, Boolean.FALSE);
0343: fFeatures.put(PARSER_SETTINGS, Boolean.TRUE);
0344:
0345: // add default recognized properties
0346: final String[] recognizedProperties = { XML_STRING,
0347: SYMBOL_TABLE, ERROR_HANDLER, ENTITY_RESOLVER,
0348: ERROR_REPORTER, ENTITY_MANAGER, DOCUMENT_SCANNER,
0349: DTD_SCANNER, DTD_VALIDATOR, DATATYPE_VALIDATOR_FACTORY,
0350: VALIDATION_MANAGER, XML_STRING, XMLGRAMMAR_POOL, };
0351: addRecognizedProperties(recognizedProperties);
0352:
0353: if (symbolTable == null) {
0354: symbolTable = new SymbolTable();
0355: }
0356: fSymbolTable = symbolTable;
0357: fProperties.put(SYMBOL_TABLE, fSymbolTable);
0358:
0359: fGrammarPool = grammarPool;
0360: if (fGrammarPool != null) {
0361: fProperties.put(XMLGRAMMAR_POOL, fGrammarPool);
0362: }
0363:
0364: fEntityManager = new XMLEntityManager();
0365: fProperties.put(ENTITY_MANAGER, fEntityManager);
0366: addCommonComponent(fEntityManager);
0367:
0368: fErrorReporter = new XMLErrorReporter();
0369: fErrorReporter.setDocumentLocator(fEntityManager
0370: .getEntityScanner());
0371: fProperties.put(ERROR_REPORTER, fErrorReporter);
0372: addCommonComponent(fErrorReporter);
0373:
0374: fNamespaceScanner = new XMLNSDocumentScannerImpl();
0375: fProperties.put(DOCUMENT_SCANNER, fNamespaceScanner);
0376: addComponent((XMLComponent) fNamespaceScanner);
0377:
0378: fDTDScanner = new XMLDTDScannerImpl();
0379: fProperties.put(DTD_SCANNER, fDTDScanner);
0380: addComponent((XMLComponent) fDTDScanner);
0381:
0382: fDatatypeValidatorFactory = DTDDVFactory.getInstance();
0383: fProperties.put(DATATYPE_VALIDATOR_FACTORY,
0384: fDatatypeValidatorFactory);
0385:
0386: fValidationManager = new ValidationManager();
0387: fProperties.put(VALIDATION_MANAGER, fValidationManager);
0388:
0389: fVersionDetector = new XMLVersionDetector();
0390:
0391: // add message formatters
0392: if (fErrorReporter
0393: .getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
0394: XMLMessageFormatter xmft = new XMLMessageFormatter();
0395: fErrorReporter.putMessageFormatter(
0396: XMLMessageFormatter.XML_DOMAIN, xmft);
0397: fErrorReporter.putMessageFormatter(
0398: XMLMessageFormatter.XMLNS_DOMAIN, xmft);
0399: }
0400:
0401: // set locale
0402: try {
0403: setLocale(Locale.getDefault());
0404: } catch (XNIException e) {
0405: // do nothing
0406: // REVISIT: What is the right thing to do? -Ac
0407: }
0408:
0409: fConfigUpdated = false;
0410:
0411: } // <init>(SymbolTable,XMLGrammarPool)
0412:
0413: /**
0414: * Sets the input source for the document to parse.
0415: *
0416: * @param inputSource The document's input source.
0417: *
0418: * @exception XMLConfigurationException Thrown if there is a
0419: * configuration error when initializing the
0420: * parser.
0421: * @exception IOException Thrown on I/O error.
0422: *
0423: * @see #parse(boolean)
0424: */
0425: public void setInputSource(XMLInputSource inputSource)
0426: throws XMLConfigurationException, IOException {
0427:
0428: // REVISIT: this method used to reset all the components and
0429: // construct the pipeline. Now reset() is called
0430: // in parse (boolean) just before we parse the document
0431: // Should this method still throw exceptions..?
0432:
0433: fInputSource = inputSource;
0434:
0435: } // setInputSource(XMLInputSource)
0436:
0437: /**
0438: * Set the locale to use for messages.
0439: *
0440: * @param locale The locale object to use for localization of messages.
0441: *
0442: * @exception XNIException Thrown if the parser does not support the
0443: * specified locale.
0444: */
0445: public void setLocale(Locale locale) throws XNIException {
0446: fLocale = locale;
0447: fErrorReporter.setLocale(locale);
0448: } // setLocale(Locale)
0449:
0450: /**
0451: * Sets the document handler on the last component in the pipeline
0452: * to receive information about the document.
0453: *
0454: * @param documentHandler The document handler.
0455: */
0456: public void setDocumentHandler(XMLDocumentHandler documentHandler) {
0457: fDocumentHandler = documentHandler;
0458: if (fLastComponent != null) {
0459: fLastComponent.setDocumentHandler(fDocumentHandler);
0460: if (fDocumentHandler != null) {
0461: fDocumentHandler.setDocumentSource(fLastComponent);
0462: }
0463: }
0464: } // setDocumentHandler(XMLDocumentHandler)
0465:
0466: /** Returns the registered document handler. */
0467: public XMLDocumentHandler getDocumentHandler() {
0468: return fDocumentHandler;
0469: } // getDocumentHandler():XMLDocumentHandler
0470:
0471: /**
0472: * Sets the DTD handler.
0473: *
0474: * @param dtdHandler The DTD handler.
0475: */
0476: public void setDTDHandler(XMLDTDHandler dtdHandler) {
0477: fDTDHandler = dtdHandler;
0478: } // setDTDHandler(XMLDTDHandler)
0479:
0480: /** Returns the registered DTD handler. */
0481: public XMLDTDHandler getDTDHandler() {
0482: return fDTDHandler;
0483: } // getDTDHandler():XMLDTDHandler
0484:
0485: /**
0486: * Sets the DTD content model handler.
0487: *
0488: * @param handler The DTD content model handler.
0489: */
0490: public void setDTDContentModelHandler(
0491: XMLDTDContentModelHandler handler) {
0492: fDTDContentModelHandler = handler;
0493: } // setDTDContentModelHandler(XMLDTDContentModelHandler)
0494:
0495: /** Returns the registered DTD content model handler. */
0496: public XMLDTDContentModelHandler getDTDContentModelHandler() {
0497: return fDTDContentModelHandler;
0498: } // getDTDContentModelHandler():XMLDTDContentModelHandler
0499:
0500: /**
0501: * Sets the resolver used to resolve external entities. The EntityResolver
0502: * interface supports resolution of public and system identifiers.
0503: *
0504: * @param resolver The new entity resolver. Passing a null value will
0505: * uninstall the currently installed resolver.
0506: */
0507: public void setEntityResolver(XMLEntityResolver resolver) {
0508: fProperties.put(ENTITY_RESOLVER, resolver);
0509: } // setEntityResolver(XMLEntityResolver)
0510:
0511: /**
0512: * Return the current entity resolver.
0513: *
0514: * @return The current entity resolver, or null if none
0515: * has been registered.
0516: * @see #setEntityResolver
0517: */
0518: public XMLEntityResolver getEntityResolver() {
0519: return (XMLEntityResolver) fProperties.get(ENTITY_RESOLVER);
0520: } // getEntityResolver():XMLEntityResolver
0521:
0522: /**
0523: * Allow an application to register an error event handler.
0524: *
0525: * <p>If the application does not register an error handler, all
0526: * error events reported by the SAX parser will be silently
0527: * ignored; however, normal processing may not continue. It is
0528: * highly recommended that all SAX applications implement an
0529: * error handler to avoid unexpected bugs.</p>
0530: *
0531: * <p>Applications may register a new or different handler in the
0532: * middle of a parse, and the SAX parser must begin using the new
0533: * handler immediately.</p>
0534: *
0535: * @param errorHandler The error handler.
0536: * @exception java.lang.NullPointerException If the handler
0537: * argument is null.
0538: * @see #getErrorHandler
0539: */
0540: public void setErrorHandler(XMLErrorHandler errorHandler) {
0541: fProperties.put(ERROR_HANDLER, errorHandler);
0542: } // setErrorHandler(XMLErrorHandler)
0543:
0544: /**
0545: * Return the current error handler.
0546: *
0547: * @return The current error handler, or null if none
0548: * has been registered.
0549: * @see #setErrorHandler
0550: */
0551: public XMLErrorHandler getErrorHandler() {
0552: // REVISIT: Should this be a property?
0553: return (XMLErrorHandler) fProperties.get(ERROR_HANDLER);
0554: } // getErrorHandler():XMLErrorHandler
0555:
0556: /**
0557: * If the application decides to terminate parsing before the xml document
0558: * is fully parsed, the application should call this method to free any
0559: * resource allocated during parsing. For example, close all opened streams.
0560: */
0561: public void cleanup() {
0562: fEntityManager.closeReaders();
0563: }
0564:
0565: /**
0566: * Parses the specified input source.
0567: *
0568: * @param source The input source.
0569: *
0570: * @exception XNIException Throws exception on XNI error.
0571: * @exception java.io.IOException Throws exception on i/o error.
0572: */
0573: public void parse(XMLInputSource source) throws XNIException,
0574: IOException {
0575:
0576: if (fParseInProgress) {
0577: // REVISIT - need to add new error message
0578: throw new XNIException(
0579: "FWK005 parse may not be called while parsing.");
0580: }
0581: fParseInProgress = true;
0582:
0583: try {
0584: setInputSource(source);
0585: parse(true);
0586: } catch (XNIException ex) {
0587: if (PRINT_EXCEPTION_STACK_TRACE)
0588: ex.printStackTrace();
0589: throw ex;
0590: } catch (IOException ex) {
0591: if (PRINT_EXCEPTION_STACK_TRACE)
0592: ex.printStackTrace();
0593: throw ex;
0594: } catch (RuntimeException ex) {
0595: if (PRINT_EXCEPTION_STACK_TRACE)
0596: ex.printStackTrace();
0597: throw ex;
0598: } catch (Exception ex) {
0599: if (PRINT_EXCEPTION_STACK_TRACE)
0600: ex.printStackTrace();
0601: throw new XNIException(ex);
0602: } finally {
0603: fParseInProgress = false;
0604: // close all streams opened by xerces
0605: this .cleanup();
0606: }
0607:
0608: } // parse(InputSource)
0609:
0610: public boolean parse(boolean complete) throws XNIException,
0611: IOException {
0612: //
0613: // reset and configure pipeline and set InputSource.
0614: if (fInputSource != null) {
0615: try {
0616: fValidationManager.reset();
0617: fVersionDetector.reset(this );
0618: resetCommon();
0619:
0620: short version = fVersionDetector
0621: .determineDocVersion(fInputSource);
0622: // XML 1.0
0623: if (version == Constants.XML_VERSION_1_0) {
0624: configurePipeline();
0625: reset();
0626: }
0627: // XML 1.1
0628: else if (version == Constants.XML_VERSION_1_1) {
0629: initXML11Components();
0630: configureXML11Pipeline();
0631: resetXML11();
0632: }
0633: // Unrecoverable error reported during version detection
0634: else {
0635: return false;
0636: }
0637:
0638: // mark configuration as fixed
0639: fConfigUpdated = false;
0640:
0641: // resets and sets the pipeline.
0642: fVersionDetector.startDocumentParsing(
0643: (XMLEntityHandler) fCurrentScanner, version);
0644: fInputSource = null;
0645: } catch (XNIException ex) {
0646: if (PRINT_EXCEPTION_STACK_TRACE)
0647: ex.printStackTrace();
0648: throw ex;
0649: } catch (IOException ex) {
0650: if (PRINT_EXCEPTION_STACK_TRACE)
0651: ex.printStackTrace();
0652: throw ex;
0653: } catch (RuntimeException ex) {
0654: if (PRINT_EXCEPTION_STACK_TRACE)
0655: ex.printStackTrace();
0656: throw ex;
0657: } catch (Exception ex) {
0658: if (PRINT_EXCEPTION_STACK_TRACE)
0659: ex.printStackTrace();
0660: throw new XNIException(ex);
0661: }
0662: }
0663:
0664: try {
0665: return fCurrentScanner.scanDocument(complete);
0666: } catch (XNIException ex) {
0667: if (PRINT_EXCEPTION_STACK_TRACE)
0668: ex.printStackTrace();
0669: throw ex;
0670: } catch (IOException ex) {
0671: if (PRINT_EXCEPTION_STACK_TRACE)
0672: ex.printStackTrace();
0673: throw ex;
0674: } catch (RuntimeException ex) {
0675: if (PRINT_EXCEPTION_STACK_TRACE)
0676: ex.printStackTrace();
0677: throw ex;
0678: } catch (Exception ex) {
0679: if (PRINT_EXCEPTION_STACK_TRACE)
0680: ex.printStackTrace();
0681: throw new XNIException(ex);
0682: }
0683:
0684: } // parse(boolean):boolean
0685:
0686: /**
0687: * Returns the state of a feature.
0688: *
0689: * @param featureId The feature identifier.
0690: * @return true if the feature is supported
0691: *
0692: * @throws XMLConfigurationException Thrown for configuration error.
0693: * In general, components should
0694: * only throw this exception if
0695: * it is <strong>really</strong>
0696: * a critical error.
0697: */
0698: public boolean getFeature(String featureId)
0699: throws XMLConfigurationException {
0700: // make this feature special
0701: if (featureId.equals(PARSER_SETTINGS)) {
0702: return fConfigUpdated;
0703: }
0704: return super .getFeature(featureId);
0705:
0706: } // getFeature(String):boolean
0707:
0708: /**
0709: * Set the state of a feature.
0710: *
0711: * Set the state of any feature in a SAX2 parser. The parser
0712: * might not recognize the feature, and if it does recognize
0713: * it, it might not be able to fulfill the request.
0714: *
0715: * @param featureId The unique identifier (URI) of the feature.
0716: * @param state The requested state of the feature (true or false).
0717: *
0718: * @exception org.apache.xerces.xni.parser.XMLConfigurationException If the
0719: * requested feature is not known.
0720: */
0721: public void setFeature(String featureId, boolean state)
0722: throws XMLConfigurationException {
0723: fConfigUpdated = true;
0724: // forward to every XML 1.0 component
0725: int count = fComponents.size();
0726: for (int i = 0; i < count; i++) {
0727: XMLComponent c = (XMLComponent) fComponents.get(i);
0728: c.setFeature(featureId, state);
0729: }
0730: // forward it to common components
0731: count = fCommonComponents.size();
0732: for (int i = 0; i < count; i++) {
0733: XMLComponent c = (XMLComponent) fCommonComponents.get(i);
0734: c.setFeature(featureId, state);
0735: }
0736:
0737: // forward to every XML 1.1 component
0738: count = fXML11Components.size();
0739: for (int i = 0; i < count; i++) {
0740: XMLComponent c = (XMLComponent) fXML11Components.get(i);
0741: try {
0742: c.setFeature(featureId, state);
0743: } catch (Exception e) {
0744: // no op
0745: }
0746: }
0747: // save state if noone "objects"
0748: super .setFeature(featureId, state);
0749:
0750: } // setFeature(String,boolean)
0751:
0752: /**
0753: * setProperty
0754: *
0755: * @param propertyId
0756: * @param value
0757: */
0758: public void setProperty(String propertyId, Object value)
0759: throws XMLConfigurationException {
0760: fConfigUpdated = true;
0761: // forward to every XML 1.0 component
0762: int count = fComponents.size();
0763: for (int i = 0; i < count; i++) {
0764: XMLComponent c = (XMLComponent) fComponents.get(i);
0765: c.setProperty(propertyId, value);
0766: }
0767: // forward it to every common Component
0768: count = fCommonComponents.size();
0769: for (int i = 0; i < count; i++) {
0770: XMLComponent c = (XMLComponent) fCommonComponents.get(i);
0771: c.setProperty(propertyId, value);
0772: }
0773: // forward it to every XML 1.1 component
0774: count = fXML11Components.size();
0775: for (int i = 0; i < count; i++) {
0776: XMLComponent c = (XMLComponent) fXML11Components.get(i);
0777: try {
0778: c.setProperty(propertyId, value);
0779: } catch (Exception e) {
0780: // ignore it
0781: }
0782: }
0783:
0784: // store value if noone "objects"
0785: super .setProperty(propertyId, value);
0786:
0787: } // setProperty(String,Object)
0788:
0789: /** Returns the locale. */
0790: public Locale getLocale() {
0791: return fLocale;
0792: } // getLocale():Locale
0793:
0794: /**
0795: * reset all XML 1.0 components before parsing and namespace context
0796: */
0797: protected void reset() throws XNIException {
0798: int count = fComponents.size();
0799: for (int i = 0; i < count; i++) {
0800: XMLComponent c = (XMLComponent) fComponents.get(i);
0801: c.reset(this );
0802: }
0803:
0804: } // reset()
0805:
0806: /**
0807: * reset all common components before parsing
0808: */
0809: protected void resetCommon() throws XNIException {
0810: // reset common components
0811: int count = fCommonComponents.size();
0812: for (int i = 0; i < count; i++) {
0813: XMLComponent c = (XMLComponent) fCommonComponents.get(i);
0814: c.reset(this );
0815: }
0816:
0817: } // resetCommon()
0818:
0819: /**
0820: * reset all components before parsing and namespace context
0821: */
0822: protected void resetXML11() throws XNIException {
0823: // reset every component
0824: int count = fXML11Components.size();
0825: for (int i = 0; i < count; i++) {
0826: XMLComponent c = (XMLComponent) fXML11Components.get(i);
0827: c.reset(this );
0828: }
0829:
0830: } // resetXML11()
0831:
0832: /**
0833: * Configures the XML 1.1 pipeline.
0834: * Note: this method also resets the new XML11 components.
0835: */
0836: protected void configureXML11Pipeline() {
0837: if (fCurrentDVFactory != fXML11DatatypeFactory) {
0838: fCurrentDVFactory = fXML11DatatypeFactory;
0839: setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory);
0840: }
0841:
0842: // setup DTD pipeline
0843: if (fCurrentDTDScanner != fXML11DTDScanner) {
0844: fCurrentDTDScanner = fXML11DTDScanner;
0845: setProperty(DTD_SCANNER, fCurrentDTDScanner);
0846: }
0847: fXML11DTDScanner.setDTDHandler(fDTDHandler);
0848: fXML11DTDScanner
0849: .setDTDContentModelHandler(fDTDContentModelHandler);
0850:
0851: // setup XML 1.1 document pipeline
0852: if (fFeatures.get(NAMESPACES) == Boolean.TRUE) {
0853: if (fCurrentScanner != fXML11NSDocScanner) {
0854: fCurrentScanner = fXML11NSDocScanner;
0855: setProperty(DOCUMENT_SCANNER, fXML11NSDocScanner);
0856: }
0857:
0858: fXML11NSDocScanner.setDTDValidator(null);
0859: fXML11NSDocScanner.setDocumentHandler(fDocumentHandler);
0860: if (fDocumentHandler != null) {
0861: fDocumentHandler.setDocumentSource(fXML11NSDocScanner);
0862: }
0863: fLastComponent = fXML11NSDocScanner;
0864:
0865: } else {
0866: // create components
0867: if (fXML11DocScanner == null) {
0868: // non namespace document pipeline
0869: fXML11DocScanner = new XML11DocumentScannerImpl();
0870: addXML11Component(fXML11DocScanner);
0871: }
0872: if (fCurrentScanner != fXML11DocScanner) {
0873: fCurrentScanner = fXML11DocScanner;
0874: setProperty(DOCUMENT_SCANNER, fXML11DocScanner);
0875: }
0876: fXML11DocScanner.setDocumentHandler(fDocumentHandler);
0877:
0878: if (fDocumentHandler != null) {
0879: fDocumentHandler.setDocumentSource(fXML11DocScanner);
0880: }
0881: fLastComponent = fXML11DocScanner;
0882: }
0883:
0884: } // configureXML11Pipeline()
0885:
0886: /** Configures the pipeline. */
0887: protected void configurePipeline() {
0888: if (fCurrentDVFactory != fDatatypeValidatorFactory) {
0889: fCurrentDVFactory = fDatatypeValidatorFactory;
0890: // use XML 1.0 datatype library
0891: setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory);
0892: }
0893:
0894: // setup DTD pipeline
0895: if (fCurrentDTDScanner != fDTDScanner) {
0896: fCurrentDTDScanner = fDTDScanner;
0897: setProperty(DTD_SCANNER, fCurrentDTDScanner);
0898: }
0899: fDTDScanner.setDTDHandler(fDTDHandler);
0900: fDTDScanner.setDTDContentModelHandler(fDTDContentModelHandler);
0901:
0902: // setup document pipeline
0903: if (fFeatures.get(NAMESPACES) == Boolean.TRUE) {
0904: if (fCurrentScanner != fNamespaceScanner) {
0905: fCurrentScanner = fNamespaceScanner;
0906: setProperty(DOCUMENT_SCANNER, fNamespaceScanner);
0907: }
0908: fNamespaceScanner.setDTDValidator(null);
0909: fNamespaceScanner.setDocumentHandler(fDocumentHandler);
0910: if (fDocumentHandler != null) {
0911: fDocumentHandler.setDocumentSource(fNamespaceScanner);
0912: }
0913: fLastComponent = fNamespaceScanner;
0914: } else {
0915: // create components
0916: if (fNonNSScanner == null) {
0917: fNonNSScanner = new XMLDocumentScannerImpl();
0918: // add components
0919: addComponent((XMLComponent) fNonNSScanner);
0920:
0921: }
0922: if (fCurrentScanner != fNonNSScanner) {
0923: fCurrentScanner = fNonNSScanner;
0924: setProperty(DOCUMENT_SCANNER, fNonNSScanner);
0925:
0926: }
0927:
0928: fNonNSScanner.setDocumentHandler(fDocumentHandler);
0929: if (fDocumentHandler != null) {
0930: fDocumentHandler.setDocumentSource(fNonNSScanner);
0931: }
0932: fLastComponent = fNonNSScanner;
0933: }
0934:
0935: } // configurePipeline()
0936:
0937: // features and properties
0938:
0939: /**
0940: * Check a feature. If feature is know and supported, this method simply
0941: * returns. Otherwise, the appropriate exception is thrown.
0942: *
0943: * @param featureId The unique identifier (URI) of the feature.
0944: *
0945: * @throws XMLConfigurationException Thrown for configuration error.
0946: * In general, components should
0947: * only throw this exception if
0948: * it is <strong>really</strong>
0949: * a critical error.
0950: */
0951: protected void checkFeature(String featureId)
0952: throws XMLConfigurationException {
0953:
0954: //
0955: // Xerces Features
0956: //
0957:
0958: if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
0959: final int suffixLength = featureId.length()
0960: - Constants.XERCES_FEATURE_PREFIX.length();
0961:
0962: //
0963: // http://apache.org/xml/features/validation/dynamic
0964: // Allows the parser to validate a document only when it
0965: // contains a grammar. Validation is turned on/off based
0966: // on each document instance, automatically.
0967: //
0968: if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE
0969: .length()
0970: && featureId
0971: .endsWith(Constants.DYNAMIC_VALIDATION_FEATURE)) {
0972: return;
0973: }
0974:
0975: //
0976: // http://apache.org/xml/features/validation/default-attribute-values
0977: //
0978: if (suffixLength == Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE
0979: .length()
0980: && featureId
0981: .endsWith(Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE)) {
0982: // REVISIT
0983: short type = XMLConfigurationException.NOT_SUPPORTED;
0984: throw new XMLConfigurationException(type, featureId);
0985: }
0986: //
0987: // http://apache.org/xml/features/validation/default-attribute-values
0988: //
0989: if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE
0990: .length()
0991: && featureId
0992: .endsWith(Constants.VALIDATE_CONTENT_MODELS_FEATURE)) {
0993: // REVISIT
0994: short type = XMLConfigurationException.NOT_SUPPORTED;
0995: throw new XMLConfigurationException(type, featureId);
0996: }
0997: //
0998: // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar
0999: //
1000: if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE
1001: .length()
1002: && featureId
1003: .endsWith(Constants.LOAD_DTD_GRAMMAR_FEATURE)) {
1004: return;
1005: }
1006: //
1007: // http://apache.org/xml/features/validation/nonvalidating/load-external-dtd
1008: //
1009: if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE
1010: .length()
1011: && featureId
1012: .endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
1013: return;
1014: }
1015:
1016: //
1017: // http://apache.org/xml/features/validation/default-attribute-values
1018: //
1019: if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE
1020: .length()
1021: && featureId
1022: .endsWith(Constants.VALIDATE_DATATYPES_FEATURE)) {
1023: short type = XMLConfigurationException.NOT_SUPPORTED;
1024: throw new XMLConfigurationException(type, featureId);
1025: }
1026:
1027: // special performance feature: only component manager is allowed to set it.
1028: if (suffixLength == Constants.PARSER_SETTINGS.length()
1029: && featureId.endsWith(Constants.PARSER_SETTINGS)) {
1030: short type = XMLConfigurationException.NOT_SUPPORTED;
1031: throw new XMLConfigurationException(type, featureId);
1032: }
1033: }
1034:
1035: //
1036: // Not recognized
1037: //
1038:
1039: super .checkFeature(featureId);
1040:
1041: } // checkFeature(String)
1042:
1043: /**
1044: * Check a property. If the property is know and supported, this method
1045: * simply returns. Otherwise, the appropriate exception is thrown.
1046: *
1047: * @param propertyId The unique identifier (URI) of the property
1048: * being set.
1049: *
1050: * @throws XMLConfigurationException Thrown for configuration error.
1051: * In general, components should
1052: * only throw this exception if
1053: * it is <strong>really</strong>
1054: * a critical error.
1055: */
1056: protected void checkProperty(String propertyId)
1057: throws XMLConfigurationException {
1058:
1059: //
1060: // Xerces Properties
1061: //
1062:
1063: if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
1064: final int suffixLength = propertyId.length()
1065: - Constants.XERCES_PROPERTY_PREFIX.length();
1066:
1067: if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length()
1068: && propertyId
1069: .endsWith(Constants.DTD_SCANNER_PROPERTY)) {
1070: return;
1071: }
1072: }
1073:
1074: if (propertyId.startsWith(Constants.JAXP_PROPERTY_PREFIX)) {
1075: final int suffixLength = propertyId.length()
1076: - Constants.JAXP_PROPERTY_PREFIX.length();
1077:
1078: if (suffixLength == Constants.SCHEMA_SOURCE.length()
1079: && propertyId.endsWith(Constants.SCHEMA_SOURCE)) {
1080: return;
1081: }
1082: }
1083:
1084: // special cases
1085: if (propertyId.startsWith(Constants.SAX_PROPERTY_PREFIX)) {
1086: final int suffixLength = propertyId.length()
1087: - Constants.SAX_PROPERTY_PREFIX.length();
1088:
1089: //
1090: // http://xml.org/sax/properties/xml-string
1091: // Value type: String
1092: // Access: read-only
1093: // Get the literal string of characters associated with the
1094: // current event. If the parser recognises and supports this
1095: // property but is not currently parsing text, it should return
1096: // null (this is a good way to check for availability before the
1097: // parse begins).
1098: //
1099: if (suffixLength == Constants.XML_STRING_PROPERTY.length()
1100: && propertyId
1101: .endsWith(Constants.XML_STRING_PROPERTY)) {
1102: // REVISIT - we should probably ask xml-dev for a precise
1103: // definition of what this is actually supposed to return, and
1104: // in exactly which circumstances.
1105: short type = XMLConfigurationException.NOT_SUPPORTED;
1106: throw new XMLConfigurationException(type, propertyId);
1107: }
1108: }
1109:
1110: //
1111: // Not recognized
1112: //
1113:
1114: super .checkProperty(propertyId);
1115:
1116: } // checkProperty(String)
1117:
1118: /**
1119: * Adds a component to the parser configuration. This method will
1120: * also add all of the component's recognized features and properties
1121: * to the list of default recognized features and properties.
1122: *
1123: * @param component The component to add.
1124: */
1125: protected void addComponent(XMLComponent component) {
1126:
1127: // don't add a component more than once
1128: if (fComponents.contains(component)) {
1129: return;
1130: }
1131: fComponents.add(component);
1132: addRecognizedParamsAndSetDefaults(component);
1133:
1134: } // addComponent(XMLComponent)
1135:
1136: /**
1137: * Adds common component to the parser configuration. This method will
1138: * also add all of the component's recognized features and properties
1139: * to the list of default recognized features and properties.
1140: *
1141: * @param component The component to add.
1142: */
1143: protected void addCommonComponent(XMLComponent component) {
1144:
1145: // don't add a component more than once
1146: if (fCommonComponents.contains(component)) {
1147: return;
1148: }
1149: fCommonComponents.add(component);
1150: addRecognizedParamsAndSetDefaults(component);
1151:
1152: } // addCommonComponent(XMLComponent)
1153:
1154: /**
1155: * Adds an XML 1.1 component to the parser configuration. This method will
1156: * also add all of the component's recognized features and properties
1157: * to the list of default recognized features and properties.
1158: *
1159: * @param component The component to add.
1160: */
1161: protected void addXML11Component(XMLComponent component) {
1162:
1163: // don't add a component more than once
1164: if (fXML11Components.contains(component)) {
1165: return;
1166: }
1167: fXML11Components.add(component);
1168: addRecognizedParamsAndSetDefaults(component);
1169:
1170: } // addXML11Component(XMLComponent)
1171:
1172: /**
1173: * Adds all of the component's recognized features and properties
1174: * to the list of default recognized features and properties, and
1175: * sets default values on the configuration for features and
1176: * properties which were previously absent from the configuration.
1177: *
1178: * @param component The component whose recognized features
1179: * and properties will be added to the configuration
1180: */
1181: protected void addRecognizedParamsAndSetDefaults(
1182: XMLComponent component) {
1183:
1184: // register component's recognized features
1185: String[] recognizedFeatures = component.getRecognizedFeatures();
1186: addRecognizedFeatures(recognizedFeatures);
1187:
1188: // register component's recognized properties
1189: String[] recognizedProperties = component
1190: .getRecognizedProperties();
1191: addRecognizedProperties(recognizedProperties);
1192:
1193: // set default values
1194: if (recognizedFeatures != null) {
1195: for (int i = 0; i < recognizedFeatures.length; ++i) {
1196: String featureId = recognizedFeatures[i];
1197: Boolean state = component.getFeatureDefault(featureId);
1198: if (state != null) {
1199: // Do not overwrite values already set on the configuration.
1200: if (!fFeatures.containsKey(featureId)) {
1201: fFeatures.put(featureId, state);
1202: // For newly added components who recognize this feature
1203: // but did not offer a default value, we need to make
1204: // sure these components will get an opportunity to read
1205: // the value before parsing begins.
1206: fConfigUpdated = true;
1207: }
1208: }
1209: }
1210: }
1211: if (recognizedProperties != null) {
1212: for (int i = 0; i < recognizedProperties.length; ++i) {
1213: String propertyId = recognizedProperties[i];
1214: Object value = component.getPropertyDefault(propertyId);
1215: if (value != null) {
1216: // Do not overwrite values already set on the configuration.
1217: if (!fProperties.containsKey(propertyId)) {
1218: fProperties.put(propertyId, value);
1219: // For newly added components who recognize this property
1220: // but did not offer a default value, we need to make
1221: // sure these components will get an opportunity to read
1222: // the value before parsing begins.
1223: fConfigUpdated = true;
1224: }
1225: }
1226: }
1227: }
1228: }
1229:
1230: private void initXML11Components() {
1231: if (!f11Initialized) {
1232:
1233: // create datatype factory
1234: fXML11DatatypeFactory = DTDDVFactory
1235: .getInstance(XML11_DATATYPE_VALIDATOR_FACTORY);
1236:
1237: // setup XML 1.1 DTD pipeline
1238: fXML11DTDScanner = new XML11DTDScannerImpl();
1239: addXML11Component(fXML11DTDScanner);
1240:
1241: // setup XML 1.1. document pipeline - namespace aware
1242: fXML11NSDocScanner = new XML11NSDocumentScannerImpl();
1243: addXML11Component(fXML11NSDocScanner);
1244:
1245: f11Initialized = true;
1246: }
1247: }
1248:
1249: } // class XML11NonValidatingConfiguration
|