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