1 /*
   2  * Copyright (c) 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.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     @Override
 351     public boolean stop() {
 352         return xmlReader.stop();
 353     }
 354 
 355     @Override
 356     public boolean resume() {
 357         return xmlReader.resume();
 358     }
 359 
 360     public Schema getSchema() {
 361         return grammar;
 362     }
 363 
 364     public void reset() {
 365         try {
 366             /** Restore initial values of features and properties. **/
 367             xmlReader.restoreInitState();
 368         }
 369         catch (SAXException exc) {
 370             // This should never happen. We only store recognized
 371             // features and properties in the hash maps. For now
 372             // just ignore it.
 373         }
 374         /** Restore various handlers. **/
 375         xmlReader.setContentHandler(null);
 376         xmlReader.setDTDHandler(null);
 377         if (xmlReader.getErrorHandler() != fInitErrorHandler) {
 378             xmlReader.setErrorHandler(fInitErrorHandler);
 379         }
 380         if (xmlReader.getEntityResolver() != fInitEntityResolver) {
 381             xmlReader.setEntityResolver(fInitEntityResolver);
 382         }
 383     }
 384 
 385     /*
 386      * PSVIProvider methods
 387      */
 388 
 389     public ElementPSVI getElementPSVI() {
 390         return ((PSVIProvider)xmlReader).getElementPSVI();
 391     }
 392 
 393     public AttributePSVI getAttributePSVI(int index) {
 394         return ((PSVIProvider)xmlReader).getAttributePSVI(index);
 395     }
 396 
 397     public AttributePSVI getAttributePSVIByName(String uri, String localname) {
 398         return ((PSVIProvider)xmlReader).getAttributePSVIByName(uri, localname);
 399     }
 400 
 401     /**
 402      * Extension of SAXParser. This class tracks changes to
 403      * features and properties to allow the parser to be reset to
 404      * its initial state.
 405      */
 406     public static class JAXPSAXParser extends com.sun.org.apache.xerces.internal.parsers.SAXParser {
 407 
 408         private final HashMap fInitFeatures = new HashMap();
 409         private final HashMap fInitProperties = new HashMap();
 410         private final SAXParserImpl fSAXParser;
 411         private XMLSecurityManager fSecurityManager;
 412         private XMLSecurityPropertyManager fSecurityPropertyMgr;
 413 
 414 
 415         public JAXPSAXParser() {
 416             this(null, null, null);
 417         }
 418 
 419         JAXPSAXParser(SAXParserImpl saxParser, XMLSecurityPropertyManager securityPropertyMgr,
 420                 XMLSecurityManager securityManager) {
 421             super();
 422             fSAXParser = saxParser;
 423             fSecurityManager = securityManager;
 424             fSecurityPropertyMgr = securityPropertyMgr;
 425             /**
 426              * This class may be used directly. So initialize the security manager if
 427              * it is null.
 428              */
 429             if (fSecurityManager == null) {
 430                 fSecurityManager = new XMLSecurityManager(true);
 431                 try {
 432                     super.setProperty(SECURITY_MANAGER, fSecurityManager);
 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             if (fSecurityPropertyMgr == null) {
 440                 fSecurityPropertyMgr = new XMLSecurityPropertyManager();
 441                 try {
 442                     super.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
 443                 } catch (SAXException e) {
 444                     throw new UnsupportedOperationException(
 445                     SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 446                     "property-not-recognized", new Object [] {SECURITY_MANAGER}), e);
 447                 }
 448             }
 449         }
 450 
 451         /**
 452          * Override SAXParser's setFeature method to track the initial state
 453          * of features. This keeps us from affecting the performance of the
 454          * SAXParser when it is created with XMLReaderFactory.
 455          */
 456         public synchronized void setFeature(String name, boolean value)
 457             throws SAXNotRecognizedException, SAXNotSupportedException {
 458             if (name == null) {
 459                 // TODO: Add localized error message.
 460                 throw new NullPointerException();
 461             }
 462             if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 463                 try {
 464                     fSecurityManager.setSecureProcessing(value);
 465                     setProperty(SECURITY_MANAGER, fSecurityManager);
 466                 }
 467                 catch (SAXNotRecognizedException exc) {
 468                     // If the property is not supported
 469                     // re-throw the exception if the value is true.
 470                     if (value) {
 471                         throw exc;
 472                     }
 473                 }
 474                 catch (SAXNotSupportedException exc) {
 475                     // If the property is not supported
 476                     // re-throw the exception if the value is true.
 477                     if (value) {
 478                         throw exc;
 479                     }
 480                 }
 481                 return;
 482             }
 483             if (!fInitFeatures.containsKey(name)) {
 484                 boolean current = super.getFeature(name);
 485                 fInitFeatures.put(name, current ? Boolean.TRUE : Boolean.FALSE);
 486             }
 487             /** Forward feature to the schema validator if there is one. **/
 488             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 489                 setSchemaValidatorFeature(name, value);
 490             }
 491             super.setFeature(name, value);
 492         }
 493 
 494         public synchronized boolean getFeature(String name)
 495             throws SAXNotRecognizedException, SAXNotSupportedException {
 496             if (name == null) {
 497                 // TODO: Add localized error message.
 498                 throw new NullPointerException();
 499             }
 500             if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
 501                 return fSecurityManager.isSecureProcessing();
 502             }
 503             return super.getFeature(name);
 504         }
 505 
 506         /**
 507          * Override SAXParser's setProperty method to track the initial state
 508          * of properties. This keeps us from affecting the performance of the
 509          * SAXParser when it is created with XMLReaderFactory.
 510          */
 511         public synchronized void setProperty(String name, Object value)
 512             throws SAXNotRecognizedException, SAXNotSupportedException {
 513             if (name == null) {
 514                 // TODO: Add localized error message.
 515                 throw new NullPointerException();
 516             }
 517             if (fSAXParser != null) {
 518                 // JAXP 1.2 support
 519                 if (JAXP_SCHEMA_LANGUAGE.equals(name)) {
 520                     // The spec says if a schema is given via SAXParserFactory
 521                     // the JAXP 1.2 properties shouldn't be allowed.
 522                     if (fSAXParser.grammar != null) {
 523                         throw new SAXNotSupportedException(
 524                                 SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), "schema-already-specified", new Object[] {name}));
 525                     }
 526                     if ( W3C_XML_SCHEMA.equals(value) ) {
 527                         //None of the properties will take effect till the setValidating(true) has been called
 528                         if( fSAXParser.isValidating() ) {
 529                             fSAXParser.schemaLanguage = W3C_XML_SCHEMA;
 530                             setFeature(XMLSCHEMA_VALIDATION_FEATURE, true);
 531                             // this will allow the parser not to emit DTD-related
 532                             // errors, as the spec demands
 533                             if (!fInitProperties.containsKey(JAXP_SCHEMA_LANGUAGE)) {
 534                                 fInitProperties.put(JAXP_SCHEMA_LANGUAGE, super.getProperty(JAXP_SCHEMA_LANGUAGE));
 535                             }
 536                             super.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
 537                         }
 538 
 539                     }
 540                     else if (value == null) {
 541                         fSAXParser.schemaLanguage = null;
 542                         setFeature(XMLSCHEMA_VALIDATION_FEATURE, false);
 543                     }
 544                     else {
 545                         // REVISIT: It would be nice if we could format this message
 546                         // using a user specified locale as we do in the underlying
 547                         // XMLReader -- mrglavas
 548                         throw new SAXNotSupportedException(
 549                             SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), "schema-not-supported", null));
 550                     }
 551                     return;
 552                 }
 553                 else if (JAXP_SCHEMA_SOURCE.equals(name)) {
 554                     // The spec says if a schema is given via SAXParserFactory
 555                     // the JAXP 1.2 properties shouldn't be allowed.
 556                     if (fSAXParser.grammar != null) {
 557                         throw new SAXNotSupportedException(
 558                                 SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), "schema-already-specified", new Object[] {name}));
 559                     }
 560                     String val = (String)getProperty(JAXP_SCHEMA_LANGUAGE);
 561                     if ( val != null && W3C_XML_SCHEMA.equals(val) ) {
 562                         if (!fInitProperties.containsKey(JAXP_SCHEMA_SOURCE)) {
 563                             fInitProperties.put(JAXP_SCHEMA_SOURCE, super.getProperty(JAXP_SCHEMA_SOURCE));
 564                         }
 565                         super.setProperty(name, value);
 566                     }
 567                     else {
 568                         throw new SAXNotSupportedException(
 569                             SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 570                             "jaxp-order-not-supported",
 571                             new Object[] {JAXP_SCHEMA_LANGUAGE, JAXP_SCHEMA_SOURCE}));
 572                     }
 573                     return;
 574                 }
 575             }
 576             /** Forward property to the schema validator if there is one. **/
 577             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 578                 setSchemaValidatorProperty(name, value);
 579             }
 580 
 581             //check if the property is managed by security manager
 582             if (fSecurityManager == null ||
 583                     !fSecurityManager.setLimit(name, XMLSecurityManager.State.APIPROPERTY, value)) {
 584                 //check if the property is managed by security property manager
 585                 if (fSecurityPropertyMgr == null ||
 586                         !fSecurityPropertyMgr.setValue(name, XMLSecurityPropertyManager.State.APIPROPERTY, value)) {
 587                     //fall back to the existing property manager
 588                     if (!fInitProperties.containsKey(name)) {
 589                         fInitProperties.put(name, super.getProperty(name));
 590                     }
 591                     super.setProperty(name, value);
 592                 }
 593             }
 594 
 595         }
 596 
 597         public synchronized Object getProperty(String name)
 598             throws SAXNotRecognizedException, SAXNotSupportedException {
 599             if (name == null) {
 600                 // TODO: Add localized error message.
 601                 throw new NullPointerException();
 602             }
 603             if (fSAXParser != null && JAXP_SCHEMA_LANGUAGE.equals(name)) {
 604                 // JAXP 1.2 support
 605                 return fSAXParser.schemaLanguage;
 606             }
 607 
 608             /** Check to see if the property is managed by the security manager **/
 609             String propertyValue = (fSecurityManager != null) ?
 610                     fSecurityManager.getLimitAsString(name) : null;
 611             if (propertyValue != null) {
 612                 return propertyValue;
 613             } else {
 614                 propertyValue = (fSecurityPropertyMgr != null) ?
 615                     fSecurityPropertyMgr.getValue(name) : null;
 616                 if (propertyValue != null) {
 617                     return propertyValue;
 618                 }
 619             }
 620 
 621             return super.getProperty(name);
 622         }
 623 
 624         synchronized void restoreInitState()
 625             throws SAXNotRecognizedException, SAXNotSupportedException {
 626             Iterator iter;
 627             if (!fInitFeatures.isEmpty()) {
 628                 iter = fInitFeatures.entrySet().iterator();
 629                 while (iter.hasNext()) {
 630                     Map.Entry entry = (Map.Entry) iter.next();
 631                     String name = (String) entry.getKey();
 632                     boolean value = ((Boolean) entry.getValue()).booleanValue();
 633                     super.setFeature(name, value);
 634                 }
 635                 fInitFeatures.clear();
 636             }
 637             if (!fInitProperties.isEmpty()) {
 638                 iter = fInitProperties.entrySet().iterator();
 639                 while (iter.hasNext()) {
 640                     Map.Entry entry = (Map.Entry) iter.next();
 641                     String name = (String) entry.getKey();
 642                     Object value = entry.getValue();
 643                     super.setProperty(name, value);
 644                 }
 645                 fInitProperties.clear();
 646             }
 647         }
 648 
 649         public void parse(InputSource inputSource)
 650             throws SAXException, IOException {
 651             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 652                 if (fSAXParser.fSchemaValidationManager != null) {
 653                     fSAXParser.fSchemaValidationManager.reset();
 654                     fSAXParser.fUnparsedEntityHandler.reset();
 655                 }
 656                 resetSchemaValidator();
 657             }
 658             super.parse(inputSource);
 659         }
 660 
 661         public void parse(String systemId)
 662             throws SAXException, IOException {
 663             if (fSAXParser != null && fSAXParser.fSchemaValidator != null) {
 664                 if (fSAXParser.fSchemaValidationManager != null) {
 665                     fSAXParser.fSchemaValidationManager.reset();
 666                     fSAXParser.fUnparsedEntityHandler.reset();
 667                 }
 668                 resetSchemaValidator();
 669             }
 670             super.parse(systemId);
 671         }
 672 
 673         XMLParserConfiguration getXMLParserConfiguration() {
 674             return fConfiguration;
 675         }
 676 
 677         void setFeature0(String name, boolean value)
 678             throws SAXNotRecognizedException, SAXNotSupportedException {
 679             super.setFeature(name, value);
 680         }
 681 
 682         boolean getFeature0(String name)
 683             throws SAXNotRecognizedException, SAXNotSupportedException {
 684             return super.getFeature(name);
 685         }
 686 
 687         void setProperty0(String name, Object value)
 688             throws SAXNotRecognizedException, SAXNotSupportedException {
 689             super.setProperty(name, value);
 690         }
 691 
 692         Object getProperty0(String name)
 693             throws SAXNotRecognizedException, SAXNotSupportedException {
 694             return super.getProperty(name);
 695         }
 696 
 697         Locale getLocale() {
 698             return fConfiguration.getLocale();
 699         }
 700 
 701         private void setSchemaValidatorFeature(String name, boolean value)
 702             throws SAXNotRecognizedException, SAXNotSupportedException {
 703             try {
 704                 fSAXParser.fSchemaValidator.setFeature(name, value);
 705             }
 706             // This should never be thrown from the schema validator.
 707             catch (XMLConfigurationException e) {
 708                 String identifier = e.getIdentifier();
 709                 if (e.getType() == Status.NOT_RECOGNIZED) {
 710                     throw new SAXNotRecognizedException(
 711                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 712                         "feature-not-recognized", new Object [] {identifier}));
 713                 }
 714                 else {
 715                     throw new SAXNotSupportedException(
 716                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 717                         "feature-not-supported", new Object [] {identifier}));
 718                 }
 719             }
 720         }
 721 
 722         private void setSchemaValidatorProperty(String name, Object value)
 723             throws SAXNotRecognizedException, SAXNotSupportedException {
 724             try {
 725                 fSAXParser.fSchemaValidator.setProperty(name, value);
 726             }
 727             // This should never be thrown from the schema validator.
 728             catch (XMLConfigurationException e) {
 729                 String identifier = e.getIdentifier();
 730                 if (e.getType() == Status.NOT_RECOGNIZED) {
 731                     throw new SAXNotRecognizedException(
 732                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 733                         "property-not-recognized", new Object [] {identifier}));
 734                 }
 735                 else {
 736                     throw new SAXNotSupportedException(
 737                         SAXMessageFormatter.formatMessage(fConfiguration.getLocale(),
 738                         "property-not-supported", new Object [] {identifier}));
 739                 }
 740             }
 741         }
 742 
 743         private void resetSchemaValidator() throws SAXException {
 744             try {
 745                 fSAXParser.fSchemaValidator.reset(fSAXParser.fSchemaValidatorComponentManager);
 746             }
 747             // This should never be thrown from the schema validator.
 748             catch (XMLConfigurationException e) {
 749                 throw new SAXException(e);
 750             }
 751         }
 752     }
 753 }