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  * @version $Id: SAXParserImpl.java,v 1.7 2010-11-01 04:40:06 joehw Exp $
  66  */
  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) {
 169                     if (temp && Constants.IS_JDK8_OR_ABOVE) {
 170                         fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD,
 171                                 XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
 172                         fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA,
 173                                 XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
 174 
 175                     }
 176                 }
 177             }
 178         }
 179 
 180         // Set application's features, followed by validation features.
 181         setFeatures(features);
 182 
 183         // If validating, provide a default ErrorHandler that prints
 184         // validation errors with a warning telling the user to set an
 185         // ErrorHandler.
 186         if (spf.isValidating()) {
 187             fInitErrorHandler = new DefaultValidationErrorHandler(xmlReader.getLocale());
 188             xmlReader.setErrorHandler(fInitErrorHandler);
 189         }
 190         else {
 191             fInitErrorHandler = xmlReader.getErrorHandler();
 192         }
 193         xmlReader.setFeature0(VALIDATION_FEATURE, spf.isValidating());
 194 
 195         // Get the Schema object from the factory
 196         this.grammar = spf.getSchema();
 197         if (grammar != null) {
 198             XMLParserConfiguration config = xmlReader.getXMLParserConfiguration();
 199             XMLComponent validatorComponent = null;
 200             /** For Xerces grammars, use built-in schema validator. **/
 201             if (grammar instanceof XSGrammarPoolContainer) {
 202                 validatorComponent = new XMLSchemaValidator();
 203                 fSchemaValidationManager = new ValidationManager();
 204                 fUnparsedEntityHandler = new UnparsedEntityHandler(fSchemaValidationManager);
 205                 config.setDTDHandler(fUnparsedEntityHandler);
 206                 fUnparsedEntityHandler.setDTDHandler(xmlReader);
 207                 xmlReader.setDTDSource(fUnparsedEntityHandler);
 208                 fSchemaValidatorComponentManager = new SchemaValidatorConfiguration(config,
 209                         (XSGrammarPoolContainer) grammar, fSchemaValidationManager);
 210             }
 211             /** For third party grammars, use the JAXP validator component. **/
 212             else {
 213                 validatorComponent = new JAXPValidatorComponent(grammar.newValidatorHandler());
 214                 fSchemaValidationManager = null;
 215                 fUnparsedEntityHandler = null;
 216                 fSchemaValidatorComponentManager = config;
 217             }
 218             config.addRecognizedFeatures(validatorComponent.getRecognizedFeatures());
 219             config.addRecognizedProperties(validatorComponent.getRecognizedProperties());
 220             config.setDocumentHandler((XMLDocumentHandler) validatorComponent);
 221             ((XMLDocumentSource)validatorComponent).setDocumentHandler(xmlReader);
 222             xmlReader.setDocumentSource((XMLDocumentSource) validatorComponent);
 223             fSchemaValidator = validatorComponent;
 224         }
 225         else {
 226             fSchemaValidationManager = null;
 227             fUnparsedEntityHandler = null;
 228             fSchemaValidatorComponentManager = null;
 229             fSchemaValidator = null;
 230         }
 231 
 232         // Initial EntityResolver
 233         fInitEntityResolver = xmlReader.getEntityResolver();
 234     }
 235 
 236     /**
 237      * Set any features of our XMLReader based on any features set on the
 238      * SAXParserFactory.
 239      *
 240      * XXX Does not handle possible conflicts between SAX feature names and
 241      * JAXP specific feature names, eg. SAXParserFactory.isValidating()
 242      */
 243     private void setFeatures(Map<String, Boolean> features)
 244         throws SAXNotSupportedException, SAXNotRecognizedException {
 245         if (features != null) {
 246             for (Map.Entry<String, Boolean> entry : features.entrySet()) {
 247                 xmlReader.setFeature0(entry.getKey(), entry.getValue());
 248             }
 249         }
 250     }
 251 
 252     public Parser getParser() throws SAXException {
 253         // Xerces2 AbstractSAXParser implements SAX1 Parser
 254         // assert(xmlReader instanceof Parser);
 255         return (Parser) xmlReader;
 256     }
 257 
 258     /**
 259      * Returns the XMLReader that is encapsulated by the implementation of
 260      * this class.
 261      */
 262     public XMLReader getXMLReader() {
 263         return xmlReader;
 264     }
 265 
 266     public boolean isNamespaceAware() {
 267         try {
 268             return xmlReader.getFeature(NAMESPACES_FEATURE);
 269         }
 270         catch (SAXException x) {
 271             throw new IllegalStateException(x.getMessage());
 272         }
 273     }
 274 
 275     public boolean isValidating() {
 276         try {
 277             return xmlReader.getFeature(VALIDATION_FEATURE);
 278         }
 279         catch (SAXException x) {
 280             throw new IllegalStateException(x.getMessage());
 281         }
 282     }
 283 
 284     /**
 285      * Gets the XInclude processing mode for this parser
 286      * @return the state of XInclude processing mode
 287      */
 288     public boolean isXIncludeAware() {
 289         try {
 290             return xmlReader.getFeature(XINCLUDE_FEATURE);
 291         }
 292         catch (SAXException exc) {
 293             return false;
 294         }
 295     }
 296 
 297     /**
 298      * Sets the particular property in the underlying implementation of
 299      * org.xml.sax.XMLReader.
 300      */
 301     public void setProperty(String name, Object value)
 302         throws SAXNotRecognizedException, SAXNotSupportedException {
 303         xmlReader.setProperty(name, value);
 304     }
 305 
 306     /**
 307      * returns the particular property requested for in the underlying
 308      * implementation of org.xml.sax.XMLReader.
 309      */
 310     public Object getProperty(String name)
 311         throws SAXNotRecognizedException, SAXNotSupportedException {
 312         return xmlReader.getProperty(name);
 313     }
 314 
 315     public void parse(InputSource is, DefaultHandler dh)
 316         throws SAXException, IOException {
 317         if (is == null) {
 318             throw new IllegalArgumentException();
 319         }
 320         if (dh != null) {
 321             xmlReader.setContentHandler(dh);
 322             xmlReader.setEntityResolver(dh);
 323             xmlReader.setErrorHandler(dh);
 324             xmlReader.setDTDHandler(dh);
 325             xmlReader.setDocumentHandler(null);
 326         }
 327         xmlReader.parse(is);
 328     }
 329 
 330     public void parse(InputSource is, HandlerBase hb)
 331         throws SAXException, IOException {
 332         if (is == null) {
 333             throw new IllegalArgumentException();
 334         }
 335         if (hb != null) {
 336             xmlReader.setDocumentHandler(hb);
 337             xmlReader.setEntityResolver(hb);
 338             xmlReader.setErrorHandler(hb);
 339             xmlReader.setDTDHandler(hb);
 340             xmlReader.setContentHandler(null);
 341         }
 342         xmlReader.parse(is);
 343     }
 344 
 345     public Schema getSchema() {
 346         return grammar;
 347     }
 348 
 349     public void reset() {
 350         try {
 351             /** Restore initial values of features and properties. **/
 352             xmlReader.restoreInitState();
 353         }
 354         catch (SAXException exc) {
 355             // This should never happen. We only store recognized
 356             // features and properties in the hash maps. For now
 357             // just ignore it.
 358         }
 359         /** Restore various handlers. **/
 360         xmlReader.setContentHandler(null);
 361         xmlReader.setDTDHandler(null);
 362         if (xmlReader.getErrorHandler() != fInitErrorHandler) {
 363             xmlReader.setErrorHandler(fInitErrorHandler);
 364         }
 365         if (xmlReader.getEntityResolver() != fInitEntityResolver) {
 366             xmlReader.setEntityResolver(fInitEntityResolver);
 367         }
 368     }
 369 
 370     /*
 371      * PSVIProvider methods
 372      */
 373 
 374     public ElementPSVI getElementPSVI() {
 375         return ((PSVIProvider)xmlReader).getElementPSVI();
 376     }
 377 
 378     public AttributePSVI getAttributePSVI(int index) {
 379         return ((PSVIProvider)xmlReader).getAttributePSVI(index);
 380     }
 381 
 382     public AttributePSVI getAttributePSVIByName(String uri, String localname) {
 383         return ((PSVIProvider)xmlReader).getAttributePSVIByName(uri, localname);
 384     }
 385 
 386     /**
 387      * Extension of SAXParser. This class tracks changes to
 388      * features and properties to allow the parser to be reset to
 389      * its initial state.
 390      */
 391     public static class JAXPSAXParser extends com.sun.org.apache.xerces.internal.parsers.SAXParser {
 392 
 393         private final HashMap fInitFeatures = new HashMap();
 394         private final HashMap fInitProperties = new HashMap();
 395         private final SAXParserImpl fSAXParser;
 396         private XMLSecurityManager fSecurityManager;
 397         private XMLSecurityPropertyManager fSecurityPropertyMgr;
 398 
 399 
 400         public JAXPSAXParser() {
 401             this(null, null, null);
 402         }
 403 
 404         JAXPSAXParser(SAXParserImpl saxParser, XMLSecurityPropertyManager securityPropertyMgr,
 405                 XMLSecurityManager securityManager) {
 406             super();
 407             fSAXParser = saxParser;
 408             fSecurityManager = securityManager;
 409             fSecurityPropertyMgr = securityPropertyMgr;
 410             /**
 411              * This class may be used directly. So initialize the security manager if
 412              * it is null.
 413              */
 414             if (fSecurityManager == null) {
 415                 fSecurityManager = new XMLSecurityManager(true);
 416                 try {
 417                     super.setProperty(SECURITY_MANAGER, fSecurityManager);
 418                 } catch (SAXException e) {
 419                     throw new UnsupportedOperationException(
 420                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 421                     "property-not-recognized", new Object [] {SECURITY_MANAGER}), e);
 422                 }
 423             }
 424             if (fSecurityPropertyMgr == null) {
 425                 fSecurityPropertyMgr = new XMLSecurityPropertyManager();
 426                 try {
 427                     super.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
 428                 } catch (SAXException e) {
 429                     throw new UnsupportedOperationException(
 430                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 431                     "property-not-recognized", new Object [] {SECURITY_MANAGER}), e);
 432                 }
 433             }
 434         }
 435 
 436         /**
 437          * Override SAXParser's setFeature method to track the initial state
 438          * of features. This keeps us from affecting the performance of the
 439          * SAXParser when it is created with XMLReaderFactory.
 440          */
 441         public synchronized void setFeature(String name, boolean value)
 442             throws SAXNotRecognizedException, SAXNotSupportedException {
 443             if (name == null) {
 444                 // TODO: Add localized error message.
 445                 throw new NullPointerException();
 446             }
 447             if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 448                 try {
 449                     fSecurityManager.setSecureProcessing(value);
 450                     setProperty(SECURITY_MANAGER, fSecurityManager);
 451                 }
 452                 catch (SAXNotRecognizedException exc) {
 453                     // If the property is not supported
 454                     // re-throw the exception if the value is true.
 455                     if (value) {
 456                         throw exc;
 457                     }
 458                 }
 459                 catch (SAXNotSupportedException exc) {
 460                     // If the property is not supported
 461                     // re-throw the exception if the value is true.
 462                     if (value) {
 463                         throw exc;
 464                     }
 465                 }
 466                 return;
 467             }
 468             if (!fInitFeatures.containsKey(name)) {
 469                 boolean current = super.getFeature(name);
 470                 fInitFeatures.put(name, current ? Boolean.TRUE : Boolean.FALSE);
 471             }
 472             /** Forward feature to the schema validator if there is one. **/
 473             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 474                 setSchemaValidatorFeature(name, value);
 475             }
 476             super.setFeature(name, value);
 477         }
 478 
 479         public synchronized boolean getFeature(String name)
 480             throws SAXNotRecognizedException, SAXNotSupportedException {
 481             if (name == null) {
 482                 // TODO: Add localized error message.
 483                 throw new NullPointerException();
 484             }
 485             if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 486                 return fSecurityManager.isSecureProcessing();
 487             }
 488             return super.getFeature(name);
 489         }
 490 
 491         /**
 492          * Override SAXParser's setProperty method to track the initial state
 493          * of properties. This keeps us from affecting the performance of the
 494          * SAXParser when it is created with XMLReaderFactory.
 495          */
 496         public synchronized void setProperty(String name, Object value)
 497             throws SAXNotRecognizedException, SAXNotSupportedException {
 498             if (name == null) {
 499                 // TODO: Add localized error message.
 500                 throw new NullPointerException();
 501             }
 502             if (fSAXParser != null) {
 503                 // JAXP 1.2 support
 504                 if (JAXP_SCHEMA_LANGUAGE.equals(name)) {
 505                     // The spec says if a schema is given via SAXParserFactory
 506                     // the JAXP 1.2 properties shouldn't be allowed.
 507                     if (fSAXParser.grammar != null) {
 508                         throw new SAXNotSupportedException(
 509                                 SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), "schema-already-specified", new Object[] {name}));
 510                     }
 511                     if ( W3C_XML_SCHEMA.equals(value) ) {
 512                         //None of the properties will take effect till the setValidating(true) has been called
 513                         if( fSAXParser.isValidating() ) {
 514                             fSAXParser.schemaLanguage = W3C_XML_SCHEMA;
 515                             setFeature(XMLSCHEMA_VALIDATION_FEATURE, true);
 516                             // this will allow the parser not to emit DTD-related
 517                             // errors, as the spec demands
 518                             if (!fInitProperties.containsKey(JAXP_SCHEMA_LANGUAGE)) {
 519                                 fInitProperties.put(JAXP_SCHEMA_LANGUAGE, super.getProperty(JAXP_SCHEMA_LANGUAGE));
 520                             }
 521                             super.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
 522                         }
 523 
 524                     }
 525                     else if (value == null) {
 526                         fSAXParser.schemaLanguage = null;
 527                         setFeature(XMLSCHEMA_VALIDATION_FEATURE, false);
 528                     }
 529                     else {
 530                         // REVISIT: It would be nice if we could format this message
 531                         // using a user specified locale as we do in the underlying
 532                         // XMLReader -- mrglavas
 533                         throw new SAXNotSupportedException(
 534                             SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), "schema-not-supported", null));
 535                     }
 536                     return;
 537                 }
 538                 else if (JAXP_SCHEMA_SOURCE.equals(name)) {
 539                     // The spec says if a schema is given via SAXParserFactory
 540                     // the JAXP 1.2 properties shouldn't be allowed.
 541                     if (fSAXParser.grammar != null) {
 542                         throw new SAXNotSupportedException(
 543                                 SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), "schema-already-specified", new Object[] {name}));
 544                     }
 545                     String val = (String)getProperty(JAXP_SCHEMA_LANGUAGE);
 546                     if ( val != null && W3C_XML_SCHEMA.equals(val) ) {
 547                         if (!fInitProperties.containsKey(JAXP_SCHEMA_SOURCE)) {
 548                             fInitProperties.put(JAXP_SCHEMA_SOURCE, super.getProperty(JAXP_SCHEMA_SOURCE));
 549                         }
 550                         super.setProperty(name, value);
 551                     }
 552                     else {
 553                         throw new SAXNotSupportedException(
 554                             SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 555                             "jaxp-order-not-supported",
 556                             new Object[] {JAXP_SCHEMA_LANGUAGE, JAXP_SCHEMA_SOURCE}));
 557                     }
 558                     return;
 559                 }
 560             }
 561             /** Forward property to the schema validator if there is one. **/
 562             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 563                 setSchemaValidatorProperty(name, value);
 564             }
 565 
 566             //check if the property is managed by security manager
 567             if (fSecurityManager == null ||
 568                     !fSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) {
 569                 //check if the property is managed by security property manager
 570                 if (fSecurityPropertyMgr == null ||
 571                         !fSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, value)) {
 572                     //fall back to the existing property manager
 573                     if (!fInitProperties.containsKey(name)) {
 574                         fInitProperties.put(name, super.getProperty(name));
 575                     }
 576                     super.setProperty(name, value);
 577                 }
 578             }
 579 
 580         }
 581 
 582         public synchronized Object getProperty(String name)
 583             throws SAXNotRecognizedException, SAXNotSupportedException {
 584             if (name == null) {
 585                 // TODO: Add localized error message.
 586                 throw new NullPointerException();
 587             }
 588             if (fSAXParser != null && JAXP_SCHEMA_LANGUAGE.equals(name)) {
 589                 // JAXP 1.2 support
 590                 return fSAXParser.schemaLanguage;
 591             }
 592 
 593             /** Check to see if the property is managed by the security manager **/
 594             String propertyValue = (fSecurityManager != null) ?
 595                     fSecurityManager.getLimitAsString(name) : null;
 596             if (propertyValue != null) {
 597                 return propertyValue;
 598             } else {
 599                 propertyValue = (fSecurityPropertyMgr != null) ?
 600                     fSecurityPropertyMgr.getValue(name) : null;
 601                 if (propertyValue != null) {
 602                     return propertyValue;
 603                 }
 604             }
 605 
 606             return super.getProperty(name);
 607         }
 608 
 609         synchronized void restoreInitState()
 610             throws SAXNotRecognizedException, SAXNotSupportedException {
 611             Iterator iter;
 612             if (!fInitFeatures.isEmpty()) {
 613                 iter = fInitFeatures.entrySet().iterator();
 614                 while (iter.hasNext()) {
 615                     Map.Entry entry = (Map.Entry) iter.next();
 616                     String name = (String) entry.getKey();
 617                     boolean value = ((Boolean) entry.getValue()).booleanValue();
 618                     super.setFeature(name, value);
 619                 }
 620                 fInitFeatures.clear();
 621             }
 622             if (!fInitProperties.isEmpty()) {
 623                 iter = fInitProperties.entrySet().iterator();
 624                 while (iter.hasNext()) {
 625                     Map.Entry entry = (Map.Entry) iter.next();
 626                     String name = (String) entry.getKey();
 627                     Object value = entry.getValue();
 628                     super.setProperty(name, value);
 629                 }
 630                 fInitProperties.clear();
 631             }
 632         }
 633 
 634         public void parse(InputSource inputSource)
 635             throws SAXException, IOException {
 636             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 637                 if (fSAXParser.fSchemaValidationManager != null) {
 638                     fSAXParser.fSchemaValidationManager.reset();
 639                     fSAXParser.fUnparsedEntityHandler.reset();
 640                 }
 641                 resetSchemaValidator();
 642             }
 643             super.parse(inputSource);
 644         }
 645 
 646         public void parse(String systemId)
 647             throws SAXException, IOException {
 648             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 649                 if (fSAXParser.fSchemaValidationManager != null) {
 650                     fSAXParser.fSchemaValidationManager.reset();
 651                     fSAXParser.fUnparsedEntityHandler.reset();
 652                 }
 653                 resetSchemaValidator();
 654             }
 655             super.parse(systemId);
 656         }
 657 
 658         XMLParserConfiguration getXMLParserConfiguration() {
 659             return fConfiguration;
 660         }
 661 
 662         void setFeature0(String name, boolean value)
 663             throws SAXNotRecognizedException, SAXNotSupportedException {
 664             super.setFeature(name, value);
 665         }
 666 
 667         boolean getFeature0(String name)
 668             throws SAXNotRecognizedException, SAXNotSupportedException {
 669             return super.getFeature(name);
 670         }
 671 
 672         void setProperty0(String name, Object value)
 673             throws SAXNotRecognizedException, SAXNotSupportedException {
 674             super.setProperty(name, value);
 675         }
 676 
 677         Object getProperty0(String name)
 678             throws SAXNotRecognizedException, SAXNotSupportedException {
 679             return super.getProperty(name);
 680         }
 681 
 682         Locale getLocale() {
 683             return fConfiguration.getLocale();
 684         }
 685 
 686         private void setSchemaValidatorFeature(String name, boolean value)
 687             throws SAXNotRecognizedException, SAXNotSupportedException {
 688             try {
 689                 fSAXParser.fSchemaValidator.setFeature(name, value);
 690             }
 691             // This should never be thrown from the schema validator.
 692             catch (XMLConfigurationException e) {
 693                 String identifier = e.getIdentifier();
 694                 if (e.getType() == Status.NOT_RECOGNIZED) {
 695                     throw new SAXNotRecognizedException(
 696                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 697                         "feature-not-recognized", new Object [] {identifier}));
 698                 }
 699                 else {
 700                     throw new SAXNotSupportedException(
 701                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 702                         "feature-not-supported", new Object [] {identifier}));
 703                 }
 704             }
 705         }
 706 
 707         private void setSchemaValidatorProperty(String name, Object value)
 708             throws SAXNotRecognizedException, SAXNotSupportedException {
 709             try {
 710                 fSAXParser.fSchemaValidator.setProperty(name, value);
 711             }
 712             // This should never be thrown from the schema validator.
 713             catch (XMLConfigurationException e) {
 714                 String identifier = e.getIdentifier();
 715                 if (e.getType() == Status.NOT_RECOGNIZED) {
 716                     throw new SAXNotRecognizedException(
 717                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 718                         "property-not-recognized", new Object [] {identifier}));
 719                 }
 720                 else {
 721                     throw new SAXNotSupportedException(
 722                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 723                         "property-not-supported", new Object [] {identifier}));
 724                 }
 725             }
 726         }
 727 
 728         private void resetSchemaValidator() throws SAXException {
 729             try {
 730                 fSAXParser.fSchemaValidator.reset(fSAXParser.fSchemaValidatorComponentManager);
 731             }
 732             // This should never be thrown from the schema validator.
 733             catch (XMLConfigurationException e) {
 734                 throw new SAXException(e);
 735             }
 736         }
 737     }
 738 }