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.impl.xs.opti;
0019:
0020: import java.io.IOException;
0021: import java.util.Locale;
0022:
0023: import org.apache.xerces.impl.Constants;
0024: import org.apache.xerces.impl.XML11DTDScannerImpl;
0025: import org.apache.xerces.impl.XML11NSDocumentScannerImpl;
0026: import org.apache.xerces.impl.XMLDTDScannerImpl;
0027: import org.apache.xerces.impl.XMLEntityHandler;
0028: import org.apache.xerces.impl.XMLEntityManager;
0029: import org.apache.xerces.impl.XMLErrorReporter;
0030: import org.apache.xerces.impl.XMLNSDocumentScannerImpl;
0031: import org.apache.xerces.impl.XMLVersionDetector;
0032: import org.apache.xerces.impl.dv.DTDDVFactory;
0033: import org.apache.xerces.impl.msg.XMLMessageFormatter;
0034: import org.apache.xerces.impl.validation.ValidationManager;
0035: import org.apache.xerces.impl.xs.XSMessageFormatter;
0036: import org.apache.xerces.parsers.BasicParserConfiguration;
0037: import org.apache.xerces.util.SymbolTable;
0038: import org.apache.xerces.xni.XMLLocator;
0039: import org.apache.xerces.xni.XNIException;
0040: import org.apache.xerces.xni.grammars.XMLGrammarPool;
0041: import org.apache.xerces.xni.parser.XMLComponent;
0042: import org.apache.xerces.xni.parser.XMLComponentManager;
0043: import org.apache.xerces.xni.parser.XMLConfigurationException;
0044: import org.apache.xerces.xni.parser.XMLDTDScanner;
0045: import org.apache.xerces.xni.parser.XMLDocumentScanner;
0046: import org.apache.xerces.xni.parser.XMLInputSource;
0047: import org.apache.xerces.xni.parser.XMLPullParserConfiguration;
0048: import org.w3c.dom.Document;
0049:
0050: /**
0051: * @xerces.internal
0052: *
0053: * @author Rahul Srivastava, Sun Microsystems Inc.
0054: *
0055: * @version $Id: SchemaParsingConfig.java 467849 2006-10-26 03:16:00Z mrglavas $
0056: */
0057: public class SchemaParsingConfig extends BasicParserConfiguration
0058: implements XMLPullParserConfiguration {
0059:
0060: //
0061: // Constants
0062: //
0063:
0064: protected final static String XML11_DATATYPE_VALIDATOR_FACTORY = "org.apache.xerces.impl.dv.dtd.XML11DTDDVFactoryImpl";
0065:
0066: // feature identifiers
0067:
0068: /** Feature identifier: warn on duplicate attribute definition. */
0069: protected static final String WARN_ON_DUPLICATE_ATTDEF = Constants.XERCES_FEATURE_PREFIX
0070: + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE;
0071:
0072: /** Feature identifier: warn on duplicate entity definition. */
0073: // protected static final String WARN_ON_DUPLICATE_ENTITYDEF = Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE;
0074: /** Feature identifier: warn on undeclared element definition. */
0075: protected static final String WARN_ON_UNDECLARED_ELEMDEF = Constants.XERCES_FEATURE_PREFIX
0076: + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE;
0077:
0078: /** Feature identifier: allow Java encodings. */
0079: protected static final String ALLOW_JAVA_ENCODINGS = Constants.XERCES_FEATURE_PREFIX
0080: + Constants.ALLOW_JAVA_ENCODINGS_FEATURE;
0081:
0082: /** Feature identifier: continue after fatal error. */
0083: protected static final String CONTINUE_AFTER_FATAL_ERROR = Constants.XERCES_FEATURE_PREFIX
0084: + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
0085:
0086: /** Feature identifier: load external DTD. */
0087: protected static final String LOAD_EXTERNAL_DTD = Constants.XERCES_FEATURE_PREFIX
0088: + Constants.LOAD_EXTERNAL_DTD_FEATURE;
0089:
0090: /** Feature identifier: notify built-in refereces. */
0091: protected static final String NOTIFY_BUILTIN_REFS = Constants.XERCES_FEATURE_PREFIX
0092: + Constants.NOTIFY_BUILTIN_REFS_FEATURE;
0093:
0094: /** Feature identifier: notify character refereces. */
0095: protected static final String NOTIFY_CHAR_REFS = Constants.XERCES_FEATURE_PREFIX
0096: + Constants.NOTIFY_CHAR_REFS_FEATURE;
0097:
0098: /** Feature identifier: expose schema normalized value */
0099: protected static final String NORMALIZE_DATA = Constants.XERCES_FEATURE_PREFIX
0100: + Constants.SCHEMA_NORMALIZED_VALUE;
0101:
0102: /** Feature identifier: send element default value via characters() */
0103: protected static final String SCHEMA_ELEMENT_DEFAULT = Constants.XERCES_FEATURE_PREFIX
0104: + Constants.SCHEMA_ELEMENT_DEFAULT;
0105:
0106: /** Feature identifier: generate synthetic annotations. */
0107: protected static final String GENERATE_SYNTHETIC_ANNOTATIONS = Constants.XERCES_FEATURE_PREFIX
0108: + Constants.GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE;
0109:
0110: // property identifiers
0111:
0112: /** Property identifier: error reporter. */
0113: protected static final String ERROR_REPORTER = Constants.XERCES_PROPERTY_PREFIX
0114: + Constants.ERROR_REPORTER_PROPERTY;
0115:
0116: /** Property identifier: entity manager. */
0117: protected static final String ENTITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX
0118: + Constants.ENTITY_MANAGER_PROPERTY;
0119:
0120: /** Property identifier document scanner: */
0121: protected static final String DOCUMENT_SCANNER = Constants.XERCES_PROPERTY_PREFIX
0122: + Constants.DOCUMENT_SCANNER_PROPERTY;
0123:
0124: /** Property identifier: DTD scanner. */
0125: protected static final String DTD_SCANNER = Constants.XERCES_PROPERTY_PREFIX
0126: + Constants.DTD_SCANNER_PROPERTY;
0127:
0128: /** Property identifier: grammar pool. */
0129: protected static final String XMLGRAMMAR_POOL = Constants.XERCES_PROPERTY_PREFIX
0130: + Constants.XMLGRAMMAR_POOL_PROPERTY;
0131:
0132: /** Property identifier: DTD validator. */
0133: protected static final String DTD_VALIDATOR = Constants.XERCES_PROPERTY_PREFIX
0134: + Constants.DTD_VALIDATOR_PROPERTY;
0135:
0136: /** Property identifier: namespace binder. */
0137: protected static final String NAMESPACE_BINDER = Constants.XERCES_PROPERTY_PREFIX
0138: + Constants.NAMESPACE_BINDER_PROPERTY;
0139:
0140: /** Property identifier: datatype validator factory. */
0141: protected static final String DATATYPE_VALIDATOR_FACTORY = Constants.XERCES_PROPERTY_PREFIX
0142: + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY;
0143:
0144: protected static final String VALIDATION_MANAGER = Constants.XERCES_PROPERTY_PREFIX
0145: + Constants.VALIDATION_MANAGER_PROPERTY;
0146:
0147: /** Property identifier: XML Schema validator. */
0148: protected static final String SCHEMA_VALIDATOR = Constants.XERCES_PROPERTY_PREFIX
0149: + Constants.SCHEMA_VALIDATOR_PROPERTY;
0150:
0151: // debugging
0152:
0153: /** Set to true and recompile to print exception stack trace. */
0154: private static final boolean PRINT_EXCEPTION_STACK_TRACE = false;
0155:
0156: //
0157: // Data
0158: //
0159:
0160: //
0161: // XML 1.0 components
0162: //
0163:
0164: /** The XML 1.0 Datatype validator factory. */
0165: protected final DTDDVFactory fDatatypeValidatorFactory;
0166:
0167: /** The XML 1.0 Document scanner. */
0168: protected final XMLNSDocumentScannerImpl fNamespaceScanner;
0169:
0170: /** The XML 1.0 DTD scanner. */
0171: protected final XMLDTDScannerImpl fDTDScanner;
0172:
0173: //
0174: // XML 1.1 components
0175: //
0176:
0177: /** The XML 1.1 Datatype validator factory. */
0178: protected DTDDVFactory fXML11DatatypeFactory = null;
0179:
0180: /** The XML 1.1 Document scanner. */
0181: protected XML11NSDocumentScannerImpl fXML11NSDocScanner = null;
0182:
0183: /** The XML 1.1 DTD scanner. **/
0184: protected XML11DTDScannerImpl fXML11DTDScanner = null;
0185:
0186: // common components (non-configurable)
0187:
0188: /** Current Datatype validator factory. */
0189: protected DTDDVFactory fCurrentDVFactory;
0190:
0191: /** Current scanner */
0192: protected XMLDocumentScanner fCurrentScanner;
0193:
0194: /** Current DTD scanner. */
0195: protected XMLDTDScanner fCurrentDTDScanner;
0196:
0197: /** Grammar pool. */
0198: protected XMLGrammarPool fGrammarPool;
0199:
0200: /** XML version detector. */
0201: protected final XMLVersionDetector fVersionDetector;
0202:
0203: // common components (configurable)
0204:
0205: /** Error reporter. */
0206: protected final XMLErrorReporter fErrorReporter;
0207:
0208: /** Entity manager. */
0209: protected final XMLEntityManager fEntityManager;
0210:
0211: /** Input Source */
0212: protected XMLInputSource fInputSource;
0213:
0214: protected SchemaDOMParser fSchemaDOMParser;
0215:
0216: protected final ValidationManager fValidationManager;
0217: // state
0218:
0219: /** Locator */
0220: protected XMLLocator fLocator;
0221:
0222: /**
0223: * True if a parse is in progress. This state is needed because
0224: * some features/properties cannot be set while parsing (e.g.
0225: * validation and namespaces).
0226: */
0227: protected boolean fParseInProgress = false;
0228:
0229: /**
0230: * fConfigUpdated is set to true if there has been any change to the configuration settings,
0231: * i.e a feature or a property was changed.
0232: */
0233: protected boolean fConfigUpdated = false;
0234:
0235: /** Flag indiciating whether XML11 components have been initialized. */
0236: private boolean f11Initialized = false;
0237:
0238: //
0239: // Constructors
0240: //
0241:
0242: /** Default constructor. */
0243: public SchemaParsingConfig() {
0244: this (null, null, null);
0245: } // <init>()
0246:
0247: /**
0248: * Constructs a parser configuration using the specified symbol table.
0249: *
0250: * @param symbolTable The symbol table to use.
0251: */
0252: public SchemaParsingConfig(SymbolTable symbolTable) {
0253: this (symbolTable, null, null);
0254: } // <init>(SymbolTable)
0255:
0256: /**
0257: * Constructs a parser configuration using the specified symbol table and
0258: * grammar pool.
0259: * <p>
0260: * <strong>REVISIT:</strong>
0261: * Grammar pool will be updated when the new validation engine is
0262: * implemented.
0263: *
0264: * @param symbolTable The symbol table to use.
0265: * @param grammarPool The grammar pool to use.
0266: */
0267: public SchemaParsingConfig(SymbolTable symbolTable,
0268: XMLGrammarPool grammarPool) {
0269: this (symbolTable, grammarPool, null);
0270: } // <init>(SymbolTable,XMLGrammarPool)
0271:
0272: /**
0273: * Constructs a parser configuration using the specified symbol table,
0274: * grammar pool, and parent settings.
0275: * <p>
0276: * <strong>REVISIT:</strong>
0277: * Grammar pool will be updated when the new validation engine is
0278: * implemented.
0279: *
0280: * @param symbolTable The symbol table to use.
0281: * @param grammarPool The grammar pool to use.
0282: * @param parentSettings The parent settings.
0283: */
0284: public SchemaParsingConfig(SymbolTable symbolTable,
0285: XMLGrammarPool grammarPool,
0286: XMLComponentManager parentSettings) {
0287: super (symbolTable, parentSettings);
0288:
0289: // add default recognized features
0290: final String[] recognizedFeatures = { PARSER_SETTINGS,
0291: WARN_ON_DUPLICATE_ATTDEF, WARN_ON_UNDECLARED_ELEMDEF,
0292: ALLOW_JAVA_ENCODINGS, CONTINUE_AFTER_FATAL_ERROR,
0293: LOAD_EXTERNAL_DTD, NOTIFY_BUILTIN_REFS,
0294: NOTIFY_CHAR_REFS, GENERATE_SYNTHETIC_ANNOTATIONS };
0295: addRecognizedFeatures(recognizedFeatures);
0296: fFeatures.put(PARSER_SETTINGS, Boolean.TRUE);
0297: // set state for default features
0298: fFeatures.put(WARN_ON_DUPLICATE_ATTDEF, Boolean.FALSE);
0299: //setFeature(WARN_ON_DUPLICATE_ENTITYDEF, false);
0300: fFeatures.put(WARN_ON_UNDECLARED_ELEMDEF, Boolean.FALSE);
0301: fFeatures.put(ALLOW_JAVA_ENCODINGS, Boolean.FALSE);
0302: fFeatures.put(CONTINUE_AFTER_FATAL_ERROR, Boolean.FALSE);
0303: fFeatures.put(LOAD_EXTERNAL_DTD, Boolean.TRUE);
0304: fFeatures.put(NOTIFY_BUILTIN_REFS, Boolean.FALSE);
0305: fFeatures.put(NOTIFY_CHAR_REFS, Boolean.FALSE);
0306: fFeatures.put(GENERATE_SYNTHETIC_ANNOTATIONS, Boolean.FALSE);
0307:
0308: // add default recognized properties
0309: final String[] recognizedProperties = { ERROR_REPORTER,
0310: ENTITY_MANAGER, DOCUMENT_SCANNER, DTD_SCANNER,
0311: DTD_VALIDATOR, NAMESPACE_BINDER, XMLGRAMMAR_POOL,
0312: DATATYPE_VALIDATOR_FACTORY, VALIDATION_MANAGER,
0313: GENERATE_SYNTHETIC_ANNOTATIONS };
0314: addRecognizedProperties(recognizedProperties);
0315:
0316: fGrammarPool = grammarPool;
0317: if (fGrammarPool != null) {
0318: setProperty(XMLGRAMMAR_POOL, fGrammarPool);
0319: }
0320:
0321: fEntityManager = new XMLEntityManager();
0322: fProperties.put(ENTITY_MANAGER, fEntityManager);
0323: addComponent(fEntityManager);
0324:
0325: fErrorReporter = new XMLErrorReporter();
0326: fErrorReporter.setDocumentLocator(fEntityManager
0327: .getEntityScanner());
0328: fProperties.put(ERROR_REPORTER, fErrorReporter);
0329: addComponent(fErrorReporter);
0330:
0331: fNamespaceScanner = new XMLNSDocumentScannerImpl();
0332: fProperties.put(DOCUMENT_SCANNER, fNamespaceScanner);
0333: addRecognizedParamsAndSetDefaults(fNamespaceScanner);
0334:
0335: fDTDScanner = new XMLDTDScannerImpl();
0336: fProperties.put(DTD_SCANNER, fDTDScanner);
0337: addRecognizedParamsAndSetDefaults(fDTDScanner);
0338:
0339: fDatatypeValidatorFactory = DTDDVFactory.getInstance();
0340: fProperties.put(DATATYPE_VALIDATOR_FACTORY,
0341: fDatatypeValidatorFactory);
0342:
0343: fValidationManager = new ValidationManager();
0344: fProperties.put(VALIDATION_MANAGER, fValidationManager);
0345:
0346: fVersionDetector = new XMLVersionDetector();
0347:
0348: // add message formatters
0349: if (fErrorReporter
0350: .getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
0351: XMLMessageFormatter xmft = new XMLMessageFormatter();
0352: fErrorReporter.putMessageFormatter(
0353: XMLMessageFormatter.XML_DOMAIN, xmft);
0354: fErrorReporter.putMessageFormatter(
0355: XMLMessageFormatter.XMLNS_DOMAIN, xmft);
0356: }
0357:
0358: if (fErrorReporter
0359: .getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
0360: XSMessageFormatter xmft = new XSMessageFormatter();
0361: fErrorReporter.putMessageFormatter(
0362: XSMessageFormatter.SCHEMA_DOMAIN, xmft);
0363: }
0364:
0365: // set locale
0366: try {
0367: setLocale(Locale.getDefault());
0368: } catch (XNIException e) {
0369: // do nothing
0370: // REVISIT: What is the right thing to do? -Ac
0371: }
0372:
0373: } // <init>(SymbolTable,XMLGrammarPool)
0374:
0375: //
0376: // Public methods
0377: //
0378:
0379: /**
0380: * Returns the state of a feature.
0381: *
0382: * @param featureId The feature identifier.
0383: * @return true if the feature is supported
0384: *
0385: * @throws XMLConfigurationException Thrown for configuration error.
0386: * In general, components should
0387: * only throw this exception if
0388: * it is <strong>really</strong>
0389: * a critical error.
0390: */
0391: public boolean getFeature(String featureId)
0392: throws XMLConfigurationException {
0393: // make this feature special
0394: if (featureId.equals(PARSER_SETTINGS)) {
0395: return fConfigUpdated;
0396: }
0397: return super .getFeature(featureId);
0398:
0399: } // getFeature(String):boolean
0400:
0401: /**
0402: * Set the state of a feature.
0403: *
0404: * Set the state of any feature in a SAX2 parser. The parser
0405: * might not recognize the feature, and if it does recognize
0406: * it, it might not be able to fulfill the request.
0407: *
0408: * @param featureId The unique identifier (URI) of the feature.
0409: * @param state The requested state of the feature (true or false).
0410: *
0411: * @exception org.apache.xerces.xni.parser.XMLConfigurationException If the
0412: * requested feature is not known.
0413: */
0414: public void setFeature(String featureId, boolean state)
0415: throws XMLConfigurationException {
0416:
0417: fConfigUpdated = true;
0418:
0419: // forward to every XML 1.0 component
0420: fNamespaceScanner.setFeature(featureId, state);
0421: fDTDScanner.setFeature(featureId, state);
0422:
0423: // forward to every XML 1.1 component
0424: if (f11Initialized) {
0425: try {
0426: fXML11DTDScanner.setFeature(featureId, state);
0427: }
0428: // ignore the exception.
0429: catch (Exception e) {
0430: }
0431: try {
0432: fXML11NSDocScanner.setFeature(featureId, state);
0433: }
0434: // ignore the exception
0435: catch (Exception e) {
0436: }
0437: }
0438:
0439: // save state if noone "objects"
0440: super .setFeature(featureId, state);
0441:
0442: } // setFeature(String,boolean)
0443:
0444: /**
0445: * setProperty
0446: *
0447: * @param propertyId
0448: * @param value
0449: */
0450: public void setProperty(String propertyId, Object value)
0451: throws XMLConfigurationException {
0452:
0453: fConfigUpdated = true;
0454:
0455: // forward to every XML 1.0 component
0456: fNamespaceScanner.setProperty(propertyId, value);
0457: fDTDScanner.setProperty(propertyId, value);
0458:
0459: // forward to every XML 1.1 component
0460: if (f11Initialized) {
0461: try {
0462: fXML11DTDScanner.setProperty(propertyId, value);
0463: }
0464: // ignore the exception.
0465: catch (Exception e) {
0466: }
0467: try {
0468: fXML11NSDocScanner.setProperty(propertyId, value);
0469: }
0470: // ignore the exception
0471: catch (Exception e) {
0472: }
0473: }
0474:
0475: // store value if noone "objects"
0476: super .setProperty(propertyId, value);
0477:
0478: } // setProperty(String,Object)
0479:
0480: /**
0481: * Set the locale to use for messages.
0482: *
0483: * @param locale The locale object to use for localization of messages.
0484: *
0485: * @exception XNIException Thrown if the parser does not support the
0486: * specified locale.
0487: */
0488: public void setLocale(Locale locale) throws XNIException {
0489: super .setLocale(locale);
0490: fErrorReporter.setLocale(locale);
0491: } // setLocale(Locale)
0492:
0493: //
0494: // XMLPullParserConfiguration methods
0495: //
0496:
0497: // parsing
0498:
0499: /**
0500: * Sets the input source for the document to parse.
0501: *
0502: * @param inputSource The document's input source.
0503: *
0504: * @exception XMLConfigurationException Thrown if there is a
0505: * configuration error when initializing the
0506: * parser.
0507: * @exception IOException Thrown on I/O error.
0508: *
0509: * @see #parse(boolean)
0510: */
0511: public void setInputSource(XMLInputSource inputSource)
0512: throws XMLConfigurationException, IOException {
0513:
0514: // REVISIT: this method used to reset all the components and
0515: // construct the pipeline. Now reset() is called
0516: // in parse (boolean) just before we parse the document
0517: // Should this method still throw exceptions..?
0518:
0519: fInputSource = inputSource;
0520:
0521: } // setInputSource(XMLInputSource)
0522:
0523: /**
0524: * Parses the document in a pull parsing fashion.
0525: *
0526: * @param complete True if the pull parser should parse the
0527: * remaining document completely.
0528: *
0529: * @return True if there is more document to parse.
0530: *
0531: * @exception XNIException Any XNI exception, possibly wrapping
0532: * another exception.
0533: * @exception IOException An IO exception from the parser, possibly
0534: * from a byte stream or character stream
0535: * supplied by the parser.
0536: *
0537: * @see #setInputSource
0538: */
0539: public boolean parse(boolean complete) throws XNIException,
0540: IOException {
0541: //
0542: // reset and configure pipeline and set InputSource.
0543: if (fInputSource != null) {
0544: try {
0545: fValidationManager.reset();
0546: fVersionDetector.reset(this );
0547: reset();
0548:
0549: short version = fVersionDetector
0550: .determineDocVersion(fInputSource);
0551: // XML 1.0
0552: if (version == Constants.XML_VERSION_1_0) {
0553: configurePipeline();
0554: resetXML10();
0555: }
0556: // XML 1.1
0557: else if (version == Constants.XML_VERSION_1_1) {
0558: initXML11Components();
0559: configureXML11Pipeline();
0560: resetXML11();
0561: }
0562: // Unrecoverable error reported during version detection
0563: else {
0564: return false;
0565: }
0566:
0567: // mark configuration as fixed
0568: fConfigUpdated = false;
0569:
0570: // resets and sets the pipeline.
0571: fVersionDetector.startDocumentParsing(
0572: (XMLEntityHandler) fCurrentScanner, version);
0573: fInputSource = null;
0574: } catch (XNIException ex) {
0575: if (PRINT_EXCEPTION_STACK_TRACE)
0576: ex.printStackTrace();
0577: throw ex;
0578: } catch (IOException ex) {
0579: if (PRINT_EXCEPTION_STACK_TRACE)
0580: ex.printStackTrace();
0581: throw ex;
0582: } catch (RuntimeException ex) {
0583: if (PRINT_EXCEPTION_STACK_TRACE)
0584: ex.printStackTrace();
0585: throw ex;
0586: } catch (Exception ex) {
0587: if (PRINT_EXCEPTION_STACK_TRACE)
0588: ex.printStackTrace();
0589: throw new XNIException(ex);
0590: }
0591: }
0592:
0593: try {
0594: return fCurrentScanner.scanDocument(complete);
0595: } catch (XNIException ex) {
0596: if (PRINT_EXCEPTION_STACK_TRACE)
0597: ex.printStackTrace();
0598: throw ex;
0599: } catch (IOException ex) {
0600: if (PRINT_EXCEPTION_STACK_TRACE)
0601: ex.printStackTrace();
0602: throw ex;
0603: } catch (RuntimeException ex) {
0604: if (PRINT_EXCEPTION_STACK_TRACE)
0605: ex.printStackTrace();
0606: throw ex;
0607: } catch (Exception ex) {
0608: if (PRINT_EXCEPTION_STACK_TRACE)
0609: ex.printStackTrace();
0610: throw new XNIException(ex);
0611: }
0612:
0613: } // parse(boolean):boolean
0614:
0615: /**
0616: * If the application decides to terminate parsing before the xml document
0617: * is fully parsed, the application should call this method to free any
0618: * resource allocated during parsing. For example, close all opened streams.
0619: */
0620: public void cleanup() {
0621: fEntityManager.closeReaders();
0622: }
0623:
0624: //
0625: // XMLParserConfiguration methods
0626: //
0627:
0628: /**
0629: * Parses the specified input source.
0630: *
0631: * @param source The input source.
0632: *
0633: * @exception XNIException Throws exception on XNI error.
0634: * @exception java.io.IOException Throws exception on i/o error.
0635: */
0636: public void parse(XMLInputSource source) throws XNIException,
0637: IOException {
0638:
0639: if (fParseInProgress) {
0640: // REVISIT - need to add new error message
0641: throw new XNIException(
0642: "FWK005 parse may not be called while parsing.");
0643: }
0644: fParseInProgress = true;
0645:
0646: try {
0647: setInputSource(source);
0648: parse(true);
0649: } catch (XNIException ex) {
0650: if (PRINT_EXCEPTION_STACK_TRACE)
0651: ex.printStackTrace();
0652: throw ex;
0653: } catch (IOException ex) {
0654: if (PRINT_EXCEPTION_STACK_TRACE)
0655: ex.printStackTrace();
0656: throw ex;
0657: } catch (RuntimeException ex) {
0658: if (PRINT_EXCEPTION_STACK_TRACE)
0659: ex.printStackTrace();
0660: throw ex;
0661: } catch (Exception ex) {
0662: if (PRINT_EXCEPTION_STACK_TRACE)
0663: ex.printStackTrace();
0664: throw new XNIException(ex);
0665: } finally {
0666: fParseInProgress = false;
0667: // close all streams opened by xerces
0668: this .cleanup();
0669: }
0670:
0671: } // parse(InputSource)
0672:
0673: //
0674: // Protected methods
0675: //
0676:
0677: /**
0678: * Reset all components before parsing.
0679: *
0680: * @throws XNIException Thrown if an error occurs during initialization.
0681: */
0682: public void reset() throws XNIException {
0683:
0684: // set handlers
0685: if (fSchemaDOMParser == null) {
0686: fSchemaDOMParser = new SchemaDOMParser(this );
0687: }
0688: fDocumentHandler = fSchemaDOMParser;
0689: fDTDHandler = fSchemaDOMParser;
0690: fDTDContentModelHandler = fSchemaDOMParser;
0691:
0692: // initialize the common components
0693: super .reset();
0694:
0695: } // reset()
0696:
0697: /** Configures the XML 1.0 pipeline. */
0698: protected void configurePipeline() {
0699:
0700: if (fCurrentDVFactory != fDatatypeValidatorFactory) {
0701: fCurrentDVFactory = fDatatypeValidatorFactory;
0702: // use XML 1.0 datatype library
0703: setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory);
0704: }
0705:
0706: // setup document pipeline
0707: if (fCurrentScanner != fNamespaceScanner) {
0708: fCurrentScanner = fNamespaceScanner;
0709: setProperty(DOCUMENT_SCANNER, fCurrentScanner);
0710: }
0711: fNamespaceScanner.setDocumentHandler(fDocumentHandler);
0712: if (fDocumentHandler != null) {
0713: fDocumentHandler.setDocumentSource(fNamespaceScanner);
0714: }
0715: fLastComponent = fNamespaceScanner;
0716:
0717: // setup dtd pipeline
0718: if (fCurrentDTDScanner != fDTDScanner) {
0719: fCurrentDTDScanner = fDTDScanner;
0720: setProperty(DTD_SCANNER, fCurrentDTDScanner);
0721: }
0722: fDTDScanner.setDTDHandler(fDTDHandler);
0723: if (fDTDHandler != null) {
0724: fDTDHandler.setDTDSource(fDTDScanner);
0725: }
0726: fDTDScanner.setDTDContentModelHandler(fDTDContentModelHandler);
0727: if (fDTDContentModelHandler != null) {
0728: fDTDContentModelHandler
0729: .setDTDContentModelSource(fDTDScanner);
0730: }
0731:
0732: } // configurePipeline()
0733:
0734: /** Configures the XML 1.1 pipeline. */
0735: protected void configureXML11Pipeline() {
0736:
0737: if (fCurrentDVFactory != fXML11DatatypeFactory) {
0738: fCurrentDVFactory = fXML11DatatypeFactory;
0739: // use XML 1.1 datatype library
0740: setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory);
0741: }
0742:
0743: // setup document pipeline
0744: if (fCurrentScanner != fXML11NSDocScanner) {
0745: fCurrentScanner = fXML11NSDocScanner;
0746: setProperty(DOCUMENT_SCANNER, fCurrentScanner);
0747: }
0748: fXML11NSDocScanner.setDocumentHandler(fDocumentHandler);
0749: if (fDocumentHandler != null) {
0750: fDocumentHandler.setDocumentSource(fXML11NSDocScanner);
0751: }
0752: fLastComponent = fXML11NSDocScanner;
0753:
0754: // setup dtd pipeline
0755: if (fCurrentDTDScanner != fXML11DTDScanner) {
0756: fCurrentDTDScanner = fXML11DTDScanner;
0757: setProperty(DTD_SCANNER, fCurrentDTDScanner);
0758: }
0759: fXML11DTDScanner.setDTDHandler(fDTDHandler);
0760: if (fDTDHandler != null) {
0761: fDTDHandler.setDTDSource(fXML11DTDScanner);
0762: }
0763: fXML11DTDScanner
0764: .setDTDContentModelHandler(fDTDContentModelHandler);
0765: if (fDTDContentModelHandler != null) {
0766: fDTDContentModelHandler
0767: .setDTDContentModelSource(fXML11DTDScanner);
0768: }
0769:
0770: } // configureXML11Pipeline()
0771:
0772: // features and properties
0773:
0774: /**
0775: * Check a feature. If feature is know and supported, this method simply
0776: * returns. Otherwise, the appropriate exception is thrown.
0777: *
0778: * @param featureId The unique identifier (URI) of the feature.
0779: *
0780: * @throws XMLConfigurationException Thrown for configuration error.
0781: * In general, components should
0782: * only throw this exception if
0783: * it is <strong>really</strong>
0784: * a critical error.
0785: */
0786: protected void checkFeature(String featureId)
0787: throws XMLConfigurationException {
0788:
0789: //
0790: // Xerces Features
0791: //
0792:
0793: if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
0794: final int suffixLength = featureId.length()
0795: - Constants.XERCES_FEATURE_PREFIX.length();
0796:
0797: //
0798: // http://apache.org/xml/features/validation/dynamic
0799: // Allows the parser to validate a document only when it
0800: // contains a grammar. Validation is turned on/off based
0801: // on each document instance, automatically.
0802: //
0803: if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE
0804: .length()
0805: && featureId
0806: .endsWith(Constants.DYNAMIC_VALIDATION_FEATURE)) {
0807: return;
0808: }
0809: //
0810: // http://apache.org/xml/features/validation/default-attribute-values
0811: //
0812: if (suffixLength == Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE
0813: .length()
0814: && featureId
0815: .endsWith(Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE)) {
0816: // REVISIT
0817: short type = XMLConfigurationException.NOT_SUPPORTED;
0818: throw new XMLConfigurationException(type, featureId);
0819: }
0820: //
0821: // http://apache.org/xml/features/validation/default-attribute-values
0822: //
0823: if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE
0824: .length()
0825: && featureId
0826: .endsWith(Constants.VALIDATE_CONTENT_MODELS_FEATURE)) {
0827: // REVISIT
0828: short type = XMLConfigurationException.NOT_SUPPORTED;
0829: throw new XMLConfigurationException(type, featureId);
0830: }
0831: //
0832: // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar
0833: //
0834: if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE
0835: .length()
0836: && featureId
0837: .endsWith(Constants.LOAD_DTD_GRAMMAR_FEATURE)) {
0838: return;
0839: }
0840: //
0841: // http://apache.org/xml/features/validation/nonvalidating/load-external-dtd
0842: //
0843: if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE
0844: .length()
0845: && featureId
0846: .endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
0847: return;
0848: }
0849:
0850: //
0851: // http://apache.org/xml/features/validation/default-attribute-values
0852: //
0853: if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE
0854: .length()
0855: && featureId
0856: .endsWith(Constants.VALIDATE_DATATYPES_FEATURE)) {
0857: short type = XMLConfigurationException.NOT_SUPPORTED;
0858: throw new XMLConfigurationException(type, featureId);
0859: }
0860: }
0861:
0862: //
0863: // Not recognized
0864: //
0865:
0866: super .checkFeature(featureId);
0867:
0868: } // checkFeature(String)
0869:
0870: /**
0871: * Check a property. If the property is know and supported, this method
0872: * simply returns. Otherwise, the appropriate exception is thrown.
0873: *
0874: * @param propertyId The unique identifier (URI) of the property
0875: * being set.
0876: *
0877: * @throws XMLConfigurationException Thrown for configuration error.
0878: * In general, components should
0879: * only throw this exception if
0880: * it is <strong>really</strong>
0881: * a critical error.
0882: */
0883: protected void checkProperty(String propertyId)
0884: throws XMLConfigurationException {
0885:
0886: //
0887: // Xerces Properties
0888: //
0889:
0890: if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
0891: final int suffixLength = propertyId.length()
0892: - Constants.XERCES_PROPERTY_PREFIX.length();
0893:
0894: if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length()
0895: && propertyId
0896: .endsWith(Constants.DTD_SCANNER_PROPERTY)) {
0897: return;
0898: }
0899: }
0900:
0901: if (propertyId.startsWith(Constants.JAXP_PROPERTY_PREFIX)) {
0902: final int suffixLength = propertyId.length()
0903: - Constants.JAXP_PROPERTY_PREFIX.length();
0904:
0905: if (suffixLength == Constants.SCHEMA_SOURCE.length()
0906: && propertyId.endsWith(Constants.SCHEMA_SOURCE)) {
0907: return;
0908: }
0909: }
0910:
0911: //
0912: // Not recognized
0913: //
0914:
0915: super .checkProperty(propertyId);
0916:
0917: } // checkProperty(String)
0918:
0919: /**
0920: * Adds all of the component's recognized features and properties
0921: * to the list of default recognized features and properties, and
0922: * sets default values on the configuration for features and
0923: * properties which were previously absent from the configuration.
0924: *
0925: * @param component The component whose recognized features
0926: * and properties will be added to the configuration
0927: */
0928: private void addRecognizedParamsAndSetDefaults(
0929: XMLComponent component) {
0930:
0931: // register component's recognized features
0932: String[] recognizedFeatures = component.getRecognizedFeatures();
0933: addRecognizedFeatures(recognizedFeatures);
0934:
0935: // register component's recognized properties
0936: String[] recognizedProperties = component
0937: .getRecognizedProperties();
0938: addRecognizedProperties(recognizedProperties);
0939:
0940: // set default values
0941: if (recognizedFeatures != null) {
0942: for (int i = 0; i < recognizedFeatures.length; ++i) {
0943: String featureId = recognizedFeatures[i];
0944: Boolean state = component.getFeatureDefault(featureId);
0945: if (state != null) {
0946: // Do not overwrite values already set on the configuration.
0947: if (!fFeatures.containsKey(featureId)) {
0948: fFeatures.put(featureId, state);
0949: // For newly added components who recognize this feature
0950: // but did not offer a default value, we need to make
0951: // sure these components will get an opportunity to read
0952: // the value before parsing begins.
0953: fConfigUpdated = true;
0954: }
0955: }
0956: }
0957: }
0958: if (recognizedProperties != null) {
0959: for (int i = 0; i < recognizedProperties.length; ++i) {
0960: String propertyId = recognizedProperties[i];
0961: Object value = component.getPropertyDefault(propertyId);
0962: if (value != null) {
0963: // Do not overwrite values already set on the configuration.
0964: if (!fProperties.containsKey(propertyId)) {
0965: fProperties.put(propertyId, value);
0966: // For newly added components who recognize this property
0967: // but did not offer a default value, we need to make
0968: // sure these components will get an opportunity to read
0969: // the value before parsing begins.
0970: fConfigUpdated = true;
0971: }
0972: }
0973: }
0974: }
0975: }
0976:
0977: /**
0978: * Reset all XML 1.0 components before parsing
0979: */
0980: protected final void resetXML10() throws XNIException {
0981: // Reset XML 1.0 components
0982: fNamespaceScanner.reset(this );
0983: fDTDScanner.reset(this );
0984: } // resetXML10()
0985:
0986: /**
0987: * Reset all XML 1.1 components before parsing
0988: */
0989: protected final void resetXML11() throws XNIException {
0990: // Reset XML 1.1 components
0991: fXML11NSDocScanner.reset(this );
0992: fXML11DTDScanner.reset(this );
0993: } // resetXML11()
0994:
0995: //
0996: // other methods
0997: //
0998:
0999: /** Returns the Document object. */
1000: public Document getDocument() {
1001: return fSchemaDOMParser.getDocument();
1002: }
1003:
1004: /** */
1005: public void resetNodePool() {
1006: // REVISIT: to implement: introduce a node pool to reuse DTM nodes.
1007: // reset this pool here.
1008: }
1009:
1010: private void initXML11Components() {
1011: if (!f11Initialized) {
1012: // create datatype factory
1013: fXML11DatatypeFactory = DTDDVFactory
1014: .getInstance(XML11_DATATYPE_VALIDATOR_FACTORY);
1015:
1016: // setup XML 1.1 DTD pipeline
1017: fXML11DTDScanner = new XML11DTDScannerImpl();
1018: addRecognizedParamsAndSetDefaults(fXML11DTDScanner);
1019:
1020: // setup XML 1.1. document pipeline - namespace aware
1021: fXML11NSDocScanner = new XML11NSDocumentScannerImpl();
1022: addRecognizedParamsAndSetDefaults(fXML11NSDocScanner);
1023:
1024: f11Initialized = true;
1025: }
1026: }
1027: }
|