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