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