1 /*
   2  * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
   3  */
   4 /*
   5  * Licensed to the Apache Software Foundation (ASF) under one or more
   6  * contributor license agreements.  See the NOTICE file distributed with
   7  * this work for additional information regarding copyright ownership.
   8  * The ASF licenses this file to You under the Apache License, Version 2.0
   9  * (the "License"); you may not use this file except in compliance with
  10  * the License.  You may obtain a copy of the License at
  11  *
  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 
  21 package com.sun.org.apache.xerces.internal.jaxp;
  22 
  23 import com.sun.org.apache.xerces.internal.impl.Constants;
  24 import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
  25 import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator;
  26 import com.sun.org.apache.xerces.internal.jaxp.validation.XSGrammarPoolContainer;
  27 import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter;
  28 import com.sun.org.apache.xerces.internal.util.Status;
  29 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
  30 import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
  31 import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
  32 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
  33 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
  34 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  35 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
  36 import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
  37 import com.sun.org.apache.xerces.internal.xs.AttributePSVI;
  38 import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
  39 import com.sun.org.apache.xerces.internal.xs.PSVIProvider;
  40 import java.io.IOException;
  41 import java.util.HashMap;
  42 import java.util.Iterator;
  43 import java.util.Locale;
  44 import java.util.Map;
  45 import javax.xml.XMLConstants;
  46 import javax.xml.validation.Schema;
  47 import org.xml.sax.EntityResolver;
  48 import org.xml.sax.ErrorHandler;
  49 import org.xml.sax.HandlerBase;
  50 import org.xml.sax.InputSource;
  51 import org.xml.sax.Parser;
  52 import org.xml.sax.SAXException;
  53 import org.xml.sax.SAXNotRecognizedException;
  54 import org.xml.sax.SAXNotSupportedException;
  55 import org.xml.sax.XMLReader;
  56 import org.xml.sax.helpers.DefaultHandler;
  57 
  58 /**
  59  * This is the implementation specific class for the
  60  * <code>javax.xml.parsers.SAXParser</code>.
  61  *
  62  * @author Rajiv Mordani
  63  * @author Edwin Goei
  64  *
  65  */
  66 public class SAXParserImpl extends javax.xml.parsers.SAXParser
  67     implements JAXPConstants, PSVIProvider {
  68 
  69     /** Feature identifier: namespaces. */
  70     private static final String NAMESPACES_FEATURE =
  71         Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
  72 
  73     /** Feature identifier: namespace prefixes. */
  74     private static final String NAMESPACE_PREFIXES_FEATURE =
  75         Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACE_PREFIXES_FEATURE;
  76 
  77     /** Feature identifier: validation. */
  78     private static final String VALIDATION_FEATURE =
  79         Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
  80 
  81     /** Feature identifier: XML Schema validation */
  82     private static final String XMLSCHEMA_VALIDATION_FEATURE =
  83         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE;
  84 
  85     /** Feature identifier: XInclude processing */
  86     private static final String XINCLUDE_FEATURE =
  87         Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FEATURE;
  88 
  89     /** Property identifier: security manager. */
  90     private static final String SECURITY_MANAGER =
  91         Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
  92 
  93     /** Property identifier: Security property manager. */
  94     private static final String XML_SECURITY_PROPERTY_MANAGER =
  95             Constants.XML_SECURITY_PROPERTY_MANAGER;
  96 
  97     private final JAXPSAXParser xmlReader;
  98     private String schemaLanguage = null;     // null means DTD
  99     private final Schema grammar;
 100 
 101     private final XMLComponent fSchemaValidator;
 102     private final XMLComponentManager fSchemaValidatorComponentManager;
 103     private final ValidationManager fSchemaValidationManager;
 104     private final UnparsedEntityHandler fUnparsedEntityHandler;
 105 
 106     /** Initial ErrorHandler */
 107     private final ErrorHandler fInitErrorHandler;
 108 
 109     /** Initial EntityResolver */
 110     private final EntityResolver fInitEntityResolver;
 111 
 112     private final XMLSecurityManager fSecurityManager;
 113     private final XMLSecurityPropertyManager fSecurityPropertyMgr;
 114 
 115     /**
 116      * Create a SAX parser with the associated features
 117      * @param features Map of SAX features, may be null
 118      */
 119     SAXParserImpl(SAXParserFactoryImpl spf, Map<String, Boolean> features)
 120         throws SAXException {
 121         this(spf, features, false);
 122     }
 123 
 124     /**
 125      * Create a SAX parser with the associated features
 126      * @param features Map of SAX features, may be null
 127      */
 128     SAXParserImpl(SAXParserFactoryImpl spf, Map<String, Boolean> features, boolean secureProcessing)
 129         throws SAXException
 130     {
 131         fSecurityManager = new XMLSecurityManager(secureProcessing);
 132         fSecurityPropertyMgr = new XMLSecurityPropertyManager();
 133         // Instantiate a SAXParser directly and not through SAX so that we use the right ClassLoader
 134         xmlReader = new JAXPSAXParser(this, fSecurityPropertyMgr, fSecurityManager);
 135 
 136         // JAXP "namespaceAware" == SAX Namespaces feature
 137         // Note: there is a compatibility problem here with default values:
 138         // JAXP default is false while SAX 2 default is true!
 139         xmlReader.setFeature0(NAMESPACES_FEATURE, spf.isNamespaceAware());
 140 
 141         // SAX "namespaces" and "namespace-prefixes" features should not
 142         // both be false.  We make them opposite for backward compatibility
 143         // since JAXP 1.0 apps may want to receive xmlns* attributes.
 144         xmlReader.setFeature0(NAMESPACE_PREFIXES_FEATURE, !spf.isNamespaceAware());
 145 
 146         // Avoid setting the XInclude processing feature if the value is false.
 147         // This will keep the configuration from throwing an exception if it
 148         // does not support XInclude.
 149         if (spf.isXIncludeAware()) {
 150             xmlReader.setFeature0(XINCLUDE_FEATURE, true);
 151         }
 152 
 153         xmlReader.setProperty0(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
 154 
 155         xmlReader.setProperty0(SECURITY_MANAGER, fSecurityManager);
 156 
 157         if (secureProcessing) {
 158             /**
 159              * By default, secure processing is set, no external access is allowed.
 160              * However, we need to check if it is actively set on the factory since we
 161              * allow the use of the System Property or jaxp.properties to override
 162              * the default value
 163              */
 164             if (features != null) {
 165 
 166                 Boolean temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING);
 167                 if (temp != null) {
 168                     if (temp && Constants.IS_JDK8_OR_ABOVE) {
 169                         fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD,
 170                                 XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
 171                         fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA,
 172                                 XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
 173 
 174                     }
 175                 }
 176             }
 177         }
 178 
 179         // Set application's features, followed by validation features.
 180         setFeatures(features);
 181 
 182         // If validating, provide a default ErrorHandler that prints
 183         // validation errors with a warning telling the user to set an
 184         // ErrorHandler.
 185         if (spf.isValidating()) {
 186             fInitErrorHandler = new DefaultValidationErrorHandler(xmlReader.getLocale());
 187             xmlReader.setErrorHandler(fInitErrorHandler);
 188         }
 189         else {
 190             fInitErrorHandler = xmlReader.getErrorHandler();
 191         }
 192         xmlReader.setFeature0(VALIDATION_FEATURE, spf.isValidating());
 193 
 194         // Get the Schema object from the factory
 195         this.grammar = spf.getSchema();
 196         if (grammar != null) {
 197             XMLParserConfiguration config = xmlReader.getXMLParserConfiguration();
 198             XMLComponent validatorComponent = null;
 199             /** For Xerces grammars, use built-in schema validator. **/
 200             if (grammar instanceof XSGrammarPoolContainer) {
 201                 validatorComponent = new XMLSchemaValidator();
 202                 fSchemaValidationManager = new ValidationManager();
 203                 fUnparsedEntityHandler = new UnparsedEntityHandler(fSchemaValidationManager);
 204                 config.setDTDHandler(fUnparsedEntityHandler);
 205                 fUnparsedEntityHandler.setDTDHandler(xmlReader);
 206                 xmlReader.setDTDSource(fUnparsedEntityHandler);
 207                 fSchemaValidatorComponentManager = new SchemaValidatorConfiguration(config,
 208                         (XSGrammarPoolContainer) grammar, fSchemaValidationManager);
 209             }
 210             /** For third party grammars, use the JAXP validator component. **/
 211             else {
 212                 validatorComponent = new JAXPValidatorComponent(grammar.newValidatorHandler());
 213                 fSchemaValidationManager = null;
 214                 fUnparsedEntityHandler = null;
 215                 fSchemaValidatorComponentManager = config;
 216             }
 217             config.addRecognizedFeatures(validatorComponent.getRecognizedFeatures());
 218             config.addRecognizedProperties(validatorComponent.getRecognizedProperties());
 219             config.setDocumentHandler((XMLDocumentHandler) validatorComponent);
 220             ((XMLDocumentSource)validatorComponent).setDocumentHandler(xmlReader);
 221             xmlReader.setDocumentSource((XMLDocumentSource) validatorComponent);
 222             fSchemaValidator = validatorComponent;
 223         }
 224         else {
 225             fSchemaValidationManager = null;
 226             fUnparsedEntityHandler = null;
 227             fSchemaValidatorComponentManager = null;
 228             fSchemaValidator = null;
 229         }
 230 
 231         // Initial EntityResolver
 232         fInitEntityResolver = xmlReader.getEntityResolver();
 233     }
 234 
 235     /**
 236      * Set any features of our XMLReader based on any features set on the
 237      * SAXParserFactory.
 238      *
 239      * XXX Does not handle possible conflicts between SAX feature names and
 240      * JAXP specific feature names, eg. SAXParserFactory.isValidating()
 241      */
 242     private void setFeatures(Map<String, Boolean> features)
 243         throws SAXNotSupportedException, SAXNotRecognizedException {
 244         if (features != null) {
 245             for (Map.Entry<String, Boolean> entry : features.entrySet()) {
 246                 xmlReader.setFeature0(entry.getKey(), entry.getValue());
 247             }
 248         }
 249     }
 250 
 251     public Parser getParser() throws SAXException {
 252         // Xerces2 AbstractSAXParser implements SAX1 Parser
 253         // assert(xmlReader instanceof Parser);
 254         return (Parser) xmlReader;
 255     }
 256 
 257     /**
 258      * Returns the XMLReader that is encapsulated by the implementation of
 259      * this class.
 260      */
 261     public XMLReader getXMLReader() {
 262         return xmlReader;
 263     }
 264 
 265     public boolean isNamespaceAware() {
 266         try {
 267             return xmlReader.getFeature(NAMESPACES_FEATURE);
 268         }
 269         catch (SAXException x) {
 270             throw new IllegalStateException(x.getMessage());
 271         }
 272     }
 273 
 274     public boolean isValidating() {
 275         try {
 276             return xmlReader.getFeature(VALIDATION_FEATURE);
 277         }
 278         catch (SAXException x) {
 279             throw new IllegalStateException(x.getMessage());
 280         }
 281     }
 282 
 283     /**
 284      * Gets the XInclude processing mode for this parser
 285      * @return the state of XInclude processing mode
 286      */
 287     public boolean isXIncludeAware() {
 288         try {
 289             return xmlReader.getFeature(XINCLUDE_FEATURE);
 290         }
 291         catch (SAXException exc) {
 292             return false;
 293         }
 294     }
 295 
 296     /**
 297      * Sets the particular property in the underlying implementation of
 298      * org.xml.sax.XMLReader.
 299      */
 300     public void setProperty(String name, Object value)
 301         throws SAXNotRecognizedException, SAXNotSupportedException {
 302         xmlReader.setProperty(name, value);
 303     }
 304 
 305     /**
 306      * returns the particular property requested for in the underlying
 307      * implementation of org.xml.sax.XMLReader.
 308      */
 309     public Object getProperty(String name)
 310         throws SAXNotRecognizedException, SAXNotSupportedException {
 311         return xmlReader.getProperty(name);
 312     }
 313 
 314     public void parse(InputSource is, DefaultHandler dh)
 315         throws SAXException, IOException {
 316         if (is == null) {
 317             throw new IllegalArgumentException();
 318         }
 319         if (dh != null) {
 320             xmlReader.setContentHandler(dh);
 321             xmlReader.setEntityResolver(dh);
 322             xmlReader.setErrorHandler(dh);
 323             xmlReader.setDTDHandler(dh);
 324             xmlReader.setDocumentHandler(null);
 325         }
 326         xmlReader.parse(is);
 327     }
 328 
 329     public void parse(InputSource is, HandlerBase hb)
 330         throws SAXException, IOException {
 331         if (is == null) {
 332             throw new IllegalArgumentException();
 333         }
 334         if (hb != null) {
 335             xmlReader.setDocumentHandler(hb);
 336             xmlReader.setEntityResolver(hb);
 337             xmlReader.setErrorHandler(hb);
 338             xmlReader.setDTDHandler(hb);
 339             xmlReader.setContentHandler(null);
 340         }
 341         xmlReader.parse(is);
 342     }
 343 
 344     public Schema getSchema() {
 345         return grammar;
 346     }
 347 
 348     public void reset() {
 349         try {
 350             /** Restore initial values of features and properties. **/
 351             xmlReader.restoreInitState();
 352         }
 353         catch (SAXException exc) {
 354             // This should never happen. We only store recognized
 355             // features and properties in the hash maps. For now
 356             // just ignore it.
 357         }
 358         /** Restore various handlers. **/
 359         xmlReader.setContentHandler(null);
 360         xmlReader.setDTDHandler(null);
 361         if (xmlReader.getErrorHandler() != fInitErrorHandler) {
 362             xmlReader.setErrorHandler(fInitErrorHandler);
 363         }
 364         if (xmlReader.getEntityResolver() != fInitEntityResolver) {
 365             xmlReader.setEntityResolver(fInitEntityResolver);
 366         }
 367     }
 368 
 369     /*
 370      * PSVIProvider methods
 371      */
 372 
 373     public ElementPSVI getElementPSVI() {
 374         return ((PSVIProvider)xmlReader).getElementPSVI();
 375     }
 376 
 377     public AttributePSVI getAttributePSVI(int index) {
 378         return ((PSVIProvider)xmlReader).getAttributePSVI(index);
 379     }
 380 
 381     public AttributePSVI getAttributePSVIByName(String uri, String localname) {
 382         return ((PSVIProvider)xmlReader).getAttributePSVIByName(uri, localname);
 383     }
 384 
 385     /**
 386      * Extension of SAXParser. This class tracks changes to
 387      * features and properties to allow the parser to be reset to
 388      * its initial state.
 389      */
 390     public static class JAXPSAXParser extends com.sun.org.apache.xerces.internal.parsers.SAXParser {
 391 
 392         private final HashMap fInitFeatures = new HashMap();
 393         private final HashMap fInitProperties = new HashMap();
 394         private final SAXParserImpl fSAXParser;
 395         private XMLSecurityManager fSecurityManager;
 396         private XMLSecurityPropertyManager fSecurityPropertyMgr;
 397 
 398 
 399         public JAXPSAXParser() {
 400             this(null, null, null);
 401         }
 402 
 403         JAXPSAXParser(SAXParserImpl saxParser, XMLSecurityPropertyManager securityPropertyMgr,
 404                 XMLSecurityManager securityManager) {
 405             super();
 406             fSAXParser = saxParser;
 407             fSecurityManager = securityManager;
 408             fSecurityPropertyMgr = securityPropertyMgr;
 409             /**
 410              * This class may be used directly. So initialize the security manager if
 411              * it is null.
 412              */
 413             if (fSecurityManager == null) {
 414                 fSecurityManager = new XMLSecurityManager(true);
 415                 try {
 416                     super.setProperty(SECURITY_MANAGER, fSecurityManager);
 417                 } catch (SAXException e) {
 418                     throw new UnsupportedOperationException(
 419                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 420                     "property-not-recognized", new Object [] {SECURITY_MANAGER}), e);
 421                 }
 422             }
 423             if (fSecurityPropertyMgr == null) {
 424                 fSecurityPropertyMgr = new XMLSecurityPropertyManager();
 425                 try {
 426                     super.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
 427                 } catch (SAXException e) {
 428                     throw new UnsupportedOperationException(
 429                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 430                     "property-not-recognized", new Object [] {SECURITY_MANAGER}), e);
 431                 }
 432             }
 433         }
 434 
 435         /**
 436          * Override SAXParser's setFeature method to track the initial state
 437          * of features. This keeps us from affecting the performance of the
 438          * SAXParser when it is created with XMLReaderFactory.
 439          */
 440         public synchronized void setFeature(String name, boolean value)
 441             throws SAXNotRecognizedException, SAXNotSupportedException {
 442             if (name == null) {
 443                 // TODO: Add localized error message.
 444                 throw new NullPointerException();
 445             }
 446             if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 447                 try {
 448                     fSecurityManager.setSecureProcessing(value);
 449                     setProperty(SECURITY_MANAGER, fSecurityManager);
 450                 }
 451                 catch (SAXNotRecognizedException exc) {
 452                     // If the property is not supported
 453                     // re-throw the exception if the value is true.
 454                     if (value) {
 455                         throw exc;
 456                     }
 457                 }
 458                 catch (SAXNotSupportedException exc) {
 459                     // If the property is not supported
 460                     // re-throw the exception if the value is true.
 461                     if (value) {
 462                         throw exc;
 463                     }
 464                 }
 465                 return;
 466             }
 467             if (!fInitFeatures.containsKey(name)) {
 468                 boolean current = super.getFeature(name);
 469                 fInitFeatures.put(name, current ? Boolean.TRUE : Boolean.FALSE);
 470             }
 471             /** Forward feature to the schema validator if there is one. **/
 472             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 473                 setSchemaValidatorFeature(name, value);
 474             }
 475             super.setFeature(name, value);
 476         }
 477 
 478         public synchronized boolean getFeature(String name)
 479             throws SAXNotRecognizedException, SAXNotSupportedException {
 480             if (name == null) {
 481                 // TODO: Add localized error message.
 482                 throw new NullPointerException();
 483             }
 484             if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 485                 return fSecurityManager.isSecureProcessing();
 486             }
 487             return super.getFeature(name);
 488         }
 489 
 490         /**
 491          * Override SAXParser's setProperty method to track the initial state
 492          * of properties. This keeps us from affecting the performance of the
 493          * SAXParser when it is created with XMLReaderFactory.
 494          */
 495         public synchronized void setProperty(String name, Object value)
 496             throws SAXNotRecognizedException, SAXNotSupportedException {
 497             if (name == null) {
 498                 // TODO: Add localized error message.
 499                 throw new NullPointerException();
 500             }
 501             if (fSAXParser != null) {
 502                 // JAXP 1.2 support
 503                 if (JAXP_SCHEMA_LANGUAGE.equals(name)) {
 504                     // The spec says if a schema is given via SAXParserFactory
 505                     // the JAXP 1.2 properties shouldn't be allowed.
 506                     if (fSAXParser.grammar != null) {
 507                         throw new SAXNotSupportedException(
 508                                 SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), "schema-already-specified", new Object[] {name}));
 509                     }
 510                     if ( W3C_XML_SCHEMA.equals(value) ) {
 511                         //None of the properties will take effect till the setValidating(true) has been called
 512                         if( fSAXParser.isValidating() ) {
 513                             fSAXParser.schemaLanguage = W3C_XML_SCHEMA;
 514                             setFeature(XMLSCHEMA_VALIDATION_FEATURE, true);
 515                             // this will allow the parser not to emit DTD-related
 516                             // errors, as the spec demands
 517                             if (!fInitProperties.containsKey(JAXP_SCHEMA_LANGUAGE)) {
 518                                 fInitProperties.put(JAXP_SCHEMA_LANGUAGE, super.getProperty(JAXP_SCHEMA_LANGUAGE));
 519                             }
 520                             super.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
 521                         }
 522 
 523                     }
 524                     else if (value == null) {
 525                         fSAXParser.schemaLanguage = null;
 526                         setFeature(XMLSCHEMA_VALIDATION_FEATURE, false);
 527                     }
 528                     else {
 529                         // REVISIT: It would be nice if we could format this message
 530                         // using a user specified locale as we do in the underlying
 531                         // XMLReader -- mrglavas
 532                         throw new SAXNotSupportedException(
 533                             SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), "schema-not-supported", null));
 534                     }
 535                     return;
 536                 }
 537                 else if (JAXP_SCHEMA_SOURCE.equals(name)) {
 538                     // The spec says if a schema is given via SAXParserFactory
 539                     // the JAXP 1.2 properties shouldn't be allowed.
 540                     if (fSAXParser.grammar != null) {
 541                         throw new SAXNotSupportedException(
 542                                 SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), "schema-already-specified", new Object[] {name}));
 543                     }
 544                     String val = (String)getProperty(JAXP_SCHEMA_LANGUAGE);
 545                     if ( val != null && W3C_XML_SCHEMA.equals(val) ) {
 546                         if (!fInitProperties.containsKey(JAXP_SCHEMA_SOURCE)) {
 547                             fInitProperties.put(JAXP_SCHEMA_SOURCE, super.getProperty(JAXP_SCHEMA_SOURCE));
 548                         }
 549                         super.setProperty(name, value);
 550                     }
 551                     else {
 552                         throw new SAXNotSupportedException(
 553                             SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 554                             "jaxp-order-not-supported",
 555                             new Object[] {JAXP_SCHEMA_LANGUAGE, JAXP_SCHEMA_SOURCE}));
 556                     }
 557                     return;
 558                 }
 559             }
 560             /** Forward property to the schema validator if there is one. **/
 561             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 562                 setSchemaValidatorProperty(name, value);
 563             }
 564 
 565             //check if the property is managed by security manager
 566             if (fSecurityManager == null ||
 567                     !fSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) {
 568                 //check if the property is managed by security property manager
 569                 if (fSecurityPropertyMgr == null ||
 570                         !fSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, value)) {
 571                     //fall back to the existing property manager
 572                     if (!fInitProperties.containsKey(name)) {
 573                         fInitProperties.put(name, super.getProperty(name));
 574                     }
 575                     super.setProperty(name, value);
 576                 }
 577             }
 578 
 579         }
 580 
 581         public synchronized Object getProperty(String name)
 582             throws SAXNotRecognizedException, SAXNotSupportedException {
 583             if (name == null) {
 584                 // TODO: Add localized error message.
 585                 throw new NullPointerException();
 586             }
 587             if (fSAXParser != null && JAXP_SCHEMA_LANGUAGE.equals(name)) {
 588                 // JAXP 1.2 support
 589                 return fSAXParser.schemaLanguage;
 590             }
 591 
 592             /** Check to see if the property is managed by the security manager **/
 593             String propertyValue = (fSecurityManager != null) ?
 594                     fSecurityManager.getLimitAsString(name) : null;
 595             if (propertyValue != null) {
 596                 return propertyValue;
 597             } else {
 598                 propertyValue = (fSecurityPropertyMgr != null) ?
 599                     fSecurityPropertyMgr.getValue(name) : null;
 600                 if (propertyValue != null) {
 601                     return propertyValue;
 602                 }
 603             }
 604 
 605             return super.getProperty(name);
 606         }
 607 
 608         synchronized void restoreInitState()
 609             throws SAXNotRecognizedException, SAXNotSupportedException {
 610             Iterator iter;
 611             if (!fInitFeatures.isEmpty()) {
 612                 iter = fInitFeatures.entrySet().iterator();
 613                 while (iter.hasNext()) {
 614                     Map.Entry entry = (Map.Entry) iter.next();
 615                     String name = (String) entry.getKey();
 616                     boolean value = ((Boolean) entry.getValue()).booleanValue();
 617                     super.setFeature(name, value);
 618                 }
 619                 fInitFeatures.clear();
 620             }
 621             if (!fInitProperties.isEmpty()) {
 622                 iter = fInitProperties.entrySet().iterator();
 623                 while (iter.hasNext()) {
 624                     Map.Entry entry = (Map.Entry) iter.next();
 625                     String name = (String) entry.getKey();
 626                     Object value = entry.getValue();
 627                     super.setProperty(name, value);
 628                 }
 629                 fInitProperties.clear();
 630             }
 631         }
 632 
 633         public void parse(InputSource inputSource)
 634             throws SAXException, IOException {
 635             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 636                 if (fSAXParser.fSchemaValidationManager != null) {
 637                     fSAXParser.fSchemaValidationManager.reset();
 638                     fSAXParser.fUnparsedEntityHandler.reset();
 639                 }
 640                 resetSchemaValidator();
 641             }
 642             super.parse(inputSource);
 643         }
 644 
 645         public void parse(String systemId)
 646             throws SAXException, IOException {
 647             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 648                 if (fSAXParser.fSchemaValidationManager != null) {
 649                     fSAXParser.fSchemaValidationManager.reset();
 650                     fSAXParser.fUnparsedEntityHandler.reset();
 651                 }
 652                 resetSchemaValidator();
 653             }
 654             super.parse(systemId);
 655         }
 656 
 657         XMLParserConfiguration getXMLParserConfiguration() {
 658             return fConfiguration;
 659         }
 660 
 661         void setFeature0(String name, boolean value)
 662             throws SAXNotRecognizedException, SAXNotSupportedException {
 663             super.setFeature(name, value);
 664         }
 665 
 666         boolean getFeature0(String name)
 667             throws SAXNotRecognizedException, SAXNotSupportedException {
 668             return super.getFeature(name);
 669         }
 670 
 671         void setProperty0(String name, Object value)
 672             throws SAXNotRecognizedException, SAXNotSupportedException {
 673             super.setProperty(name, value);
 674         }
 675 
 676         Object getProperty0(String name)
 677             throws SAXNotRecognizedException, SAXNotSupportedException {
 678             return super.getProperty(name);
 679         }
 680 
 681         Locale getLocale() {
 682             return fConfiguration.getLocale();
 683         }
 684 
 685         private void setSchemaValidatorFeature(String name, boolean value)
 686             throws SAXNotRecognizedException, SAXNotSupportedException {
 687             try {
 688                 fSAXParser.fSchemaValidator.setFeature(name, value);
 689             }
 690             // This should never be thrown from the schema validator.
 691             catch (XMLConfigurationException e) {
 692                 String identifier = e.getIdentifier();
 693                 if (e.getType() == Status.NOT_RECOGNIZED) {
 694                     throw new SAXNotRecognizedException(
 695                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 696                         "feature-not-recognized", new Object [] {identifier}));
 697                 }
 698                 else {
 699                     throw new SAXNotSupportedException(
 700                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 701                         "feature-not-supported", new Object [] {identifier}));
 702                 }
 703             }
 704         }
 705 
 706         private void setSchemaValidatorProperty(String name, Object value)
 707             throws SAXNotRecognizedException, SAXNotSupportedException {
 708             try {
 709                 fSAXParser.fSchemaValidator.setProperty(name, value);
 710             }
 711             // This should never be thrown from the schema validator.
 712             catch (XMLConfigurationException e) {
 713                 String identifier = e.getIdentifier();
 714                 if (e.getType() == Status.NOT_RECOGNIZED) {
 715                     throw new SAXNotRecognizedException(
 716                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 717                         "property-not-recognized", new Object [] {identifier}));
 718                 }
 719                 else {
 720                     throw new SAXNotSupportedException(
 721                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 722                         "property-not-supported", new Object [] {identifier}));
 723                 }
 724             }
 725         }
 726 
 727         private void resetSchemaValidator() throws SAXException {
 728             try {
 729                 fSAXParser.fSchemaValidator.reset(fSAXParser.fSchemaValidatorComponentManager);
 730             }
 731             // This should never be thrown from the schema validator.
 732             catch (XMLConfigurationException e) {
 733                 throw new SAXException(e);
 734             }
 735         }
 736     }
 737 }