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