1 /*
2  * Copyright (c) 2006, 2016, 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.validation;
22 
23 import java.util.HashMap;
24 import java.util.Locale;
25 import java.util.Map;
26 
27 import javax.xml.XMLConstants;
28 
29 import com.sun.org.apache.xerces.internal.impl.Constants;
30 import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
31 import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
32 import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
33 import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator;
34 import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter;
35 import com.sun.org.apache.xerces.internal.util.DOMEntityResolverWrapper;
36 import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper;
37 import com.sun.org.apache.xerces.internal.util.FeatureState;
38 import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
39 import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings;
40 import com.sun.org.apache.xerces.internal.util.PropertyState;
41 import com.sun.org.apache.xerces.internal.util.Status;
42 import com.sun.org.apache.xerces.internal.util.SymbolTable;
43 import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager;
44 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager;
45 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
46 import com.sun.org.apache.xerces.internal.xni.XNIException;
47 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
48 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
49 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
50 import javax.xml.catalog.CatalogFeatures;
51 import jdk.xml.internal.JdkXmlUtils;
52 import org.w3c.dom.ls.LSResourceResolver;
53 import org.xml.sax.ErrorHandler;
54 
55 /**
56  * <p>An implementation of XMLComponentManager for a schema validator.</p>
57  *
58  * @author Michael Glavassevich, IBM
59  */
60 final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettings implements
61         XMLComponentManager {
62 
63     // feature identifiers
64 
65     /** Feature identifier: schema validation. */
66     private static final String SCHEMA_VALIDATION =
67         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE;
68 
69     /** Feature identifier: validation. */
70     private static final String VALIDATION =
71         Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
72 
73     /** Feature identifier: use grammar pool only. */
74     private static final String USE_GRAMMAR_POOL_ONLY =
75         Constants.XERCES_FEATURE_PREFIX + Constants.USE_GRAMMAR_POOL_ONLY_FEATURE;
76 
77     /** Feature identifier: whether to ignore xsi:type attributes until a global element declaration is encountered */
78     protected static final String IGNORE_XSI_TYPE =
79         Constants.XERCES_FEATURE_PREFIX + Constants.IGNORE_XSI_TYPE_FEATURE;
80 
81     /** Feature identifier: whether to ignore ID/IDREF errors */
82     protected static final String ID_IDREF_CHECKING =
83         Constants.XERCES_FEATURE_PREFIX + Constants.ID_IDREF_CHECKING_FEATURE;
84 
85     /** Feature identifier: whether to ignore unparsed entity errors */
86     protected static final String UNPARSED_ENTITY_CHECKING =
87         Constants.XERCES_FEATURE_PREFIX + Constants.UNPARSED_ENTITY_CHECKING_FEATURE;
88 
89     /** Feature identifier: whether to ignore identity constraint errors */
90     protected static final String IDENTITY_CONSTRAINT_CHECKING =
91         Constants.XERCES_FEATURE_PREFIX + Constants.IDC_CHECKING_FEATURE;
92 
93     /** Feature identifier: disallow DOCTYPE declaration */
94     private static final String DISALLOW_DOCTYPE_DECL_FEATURE =
95         Constants.XERCES_FEATURE_PREFIX + Constants.DISALLOW_DOCTYPE_DECL_FEATURE;
96 
97     /** Feature identifier: expose schema normalized value */
98     private static final String NORMALIZE_DATA =
99         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_NORMALIZED_VALUE;
100 
101     /** Feature identifier: send element default value via characters() */
102     private static final String SCHEMA_ELEMENT_DEFAULT =
103         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_ELEMENT_DEFAULT;
104 
105     /** Feature identifier: augment PSVI */
106     private static final String SCHEMA_AUGMENT_PSVI =
107         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_AUGMENT_PSVI;
108 
109     // property identifiers
110 
111     /** Property identifier: entity manager. */
112     private static final String ENTITY_MANAGER =
113         Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
114 
115     /** Property identifier: entity resolver. */
116     private static final String ENTITY_RESOLVER =
117         Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
118 
119     /** Property identifier: error handler. */
120     private static final String ERROR_HANDLER =
121         Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
122 
123     /** Property identifier: error reporter. */
124     private static final String ERROR_REPORTER =
125         Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
126 
127     /** Property identifier: namespace context. */
128     private static final String NAMESPACE_CONTEXT =
129         Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_CONTEXT_PROPERTY;
130 
131     /** Property identifier: XML Schema validator. */
132     private static final String SCHEMA_VALIDATOR =
133         Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY;
134 
135     /** Property identifier: security manager. */
136     private static final String SECURITY_MANAGER =
137         Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
138 
139     /** Property identifier: security property manager. */
140     private static final String XML_SECURITY_PROPERTY_MANAGER =
141             Constants.XML_SECURITY_PROPERTY_MANAGER;
142 
143     /** Property identifier: symbol table. */
144     private static final String SYMBOL_TABLE =
145         Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
146 
147     /** Property identifier: validation manager. */
148     private static final String VALIDATION_MANAGER =
149         Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY;
150 
151     /** Property identifier: grammar pool. */
152     private static final String XMLGRAMMAR_POOL =
153         Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
154 
155     /** Property identifier: locale. */
156     private static final String LOCALE =
157         Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY;
158 
159     //
160     // Data
161     //
162     /**
163      * <p>State of secure mode.</p>
164      */
165     private boolean _isSecureMode = false;
166 
167     /**
168      * fConfigUpdated is set to true if there has been any change to the configuration settings,
169      * i.e a feature or a property was changed.
170      */
171     private boolean fConfigUpdated = true;
172 
173     /**
174      * Tracks whether the validator should use components from
175      * the grammar pool to the exclusion of all others.
176      */
177     private boolean fUseGrammarPoolOnly;
178 
179     /** Lookup map for components required for validation. **/
180     private final HashMap<String, Object> fComponents = new HashMap<>();
181 
182     //
183     // Components
184     //
185 
186     /** Entity manager. */
187     private XMLEntityManager fEntityManager;
188 
189     /** Error reporter. */
190     private XMLErrorReporter fErrorReporter;
191 
192     /** Namespace context. */
193     private NamespaceContext fNamespaceContext;
194 
195     /** XML Schema validator. */
196     private XMLSchemaValidator fSchemaValidator;
197 
198     /** Validation manager. */
199     private ValidationManager fValidationManager;
200 
201     //
202     // Configuration
203     //
204 
205     /** Stores initial feature values for validator reset. */
206     private final HashMap<String, Boolean> fInitFeatures = new HashMap<>();
207 
208     /** Stores initial property values for validator reset. */
209     private final HashMap<String, Object> fInitProperties = new HashMap<>();
210 
211     /** Stores the initial security manager. */
212     private XMLSecurityManager fInitSecurityManager;
213 
214     /** Stores the initial security property manager. */
215     private final XMLSecurityPropertyManager fSecurityPropertyMgr;
216 
217     //
218     // User Objects
219     //
220 
221     /** Application's ErrorHandler. **/
222     private ErrorHandler fErrorHandler = null;
223 
224     /** Application's LSResourceResolver. */
225     private LSResourceResolver fResourceResolver = null;
226 
227     /** Locale chosen by the application. */
228     private Locale fLocale = null;
229 
230     /** Constructs a component manager suitable for Xerces' schema validator. */
XMLSchemaValidatorComponentManager(XSGrammarPoolContainer grammarContainer)231     public XMLSchemaValidatorComponentManager(XSGrammarPoolContainer grammarContainer) {
232         // setup components
233         fEntityManager = new XMLEntityManager();
234         fComponents.put(ENTITY_MANAGER, fEntityManager);
235 
236         fErrorReporter = new XMLErrorReporter();
237         fComponents.put(ERROR_REPORTER, fErrorReporter);
238 
239         fNamespaceContext = new NamespaceSupport();
240         fComponents.put(NAMESPACE_CONTEXT, fNamespaceContext);
241 
242         fSchemaValidator = new XMLSchemaValidator();
243         fComponents.put(SCHEMA_VALIDATOR, fSchemaValidator);
244 
245         fValidationManager = new ValidationManager();
246         fComponents.put(VALIDATION_MANAGER, fValidationManager);
247 
248         // setup other properties
249         fComponents.put(ENTITY_RESOLVER, null);
250         fComponents.put(ERROR_HANDLER, null);
251 
252         fComponents.put(SYMBOL_TABLE, new SymbolTable());
253 
254         // setup grammar pool
255         fComponents.put(XMLGRAMMAR_POOL, grammarContainer.getGrammarPool());
256         fUseGrammarPoolOnly = grammarContainer.isFullyComposed();
257 
258         // add schema message formatter to error reporter
259         fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, new XSMessageFormatter());
260 
261         // add all recognized features and properties and apply their defaults
262         final String [] recognizedFeatures = {
263                 DISALLOW_DOCTYPE_DECL_FEATURE,
264                 NORMALIZE_DATA,
265                 SCHEMA_ELEMENT_DEFAULT,
266                 SCHEMA_AUGMENT_PSVI,
267                 XMLConstants.USE_CATALOG,
268                 JdkXmlUtils.OVERRIDE_PARSER
269         };
270         addRecognizedFeatures(recognizedFeatures);
271         fFeatures.put(DISALLOW_DOCTYPE_DECL_FEATURE, Boolean.FALSE);
272         fFeatures.put(NORMALIZE_DATA, Boolean.FALSE);
273         fFeatures.put(SCHEMA_ELEMENT_DEFAULT, Boolean.FALSE);
274         fFeatures.put(SCHEMA_AUGMENT_PSVI, Boolean.TRUE);
275         fFeatures.put(XMLConstants.USE_CATALOG, grammarContainer.getFeature(XMLConstants.USE_CATALOG));
276         fFeatures.put(JdkXmlUtils.OVERRIDE_PARSER, grammarContainer.getFeature(JdkXmlUtils.OVERRIDE_PARSER));
277 
278         addRecognizedParamsAndSetDefaults(fEntityManager, grammarContainer);
279         addRecognizedParamsAndSetDefaults(fErrorReporter, grammarContainer);
280         addRecognizedParamsAndSetDefaults(fSchemaValidator, grammarContainer);
281 
282         /* TODO: are other XMLSchemaValidator default values never set?
283          * Initial investigation indicates that they aren't set, but
284          * that they all have default values of false, so it works out
285          * anyway -PM
286          */
287         fFeatures.put(IGNORE_XSI_TYPE, Boolean.FALSE);
288         fFeatures.put(ID_IDREF_CHECKING, Boolean.TRUE);
289         fFeatures.put(IDENTITY_CONSTRAINT_CHECKING, Boolean.TRUE);
290         fFeatures.put(UNPARSED_ENTITY_CHECKING, Boolean.TRUE);
291 
292         boolean secureProcessing = grammarContainer.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING);
293         if (System.getSecurityManager() != null) {
294             _isSecureMode = true;
295             secureProcessing = true;
296         }
297 
298         fInitSecurityManager = (XMLSecurityManager)
299                 grammarContainer.getProperty(SECURITY_MANAGER);
300         if (fInitSecurityManager != null ) {
301             fInitSecurityManager.setSecureProcessing(secureProcessing);
302         } else {
303             fInitSecurityManager = new XMLSecurityManager(secureProcessing);
304         }
305 
306         setProperty(SECURITY_MANAGER, fInitSecurityManager);
307 
308         //pass on properties set on SchemaFactory
309         fSecurityPropertyMgr = (XMLSecurityPropertyManager)
310                 grammarContainer.getProperty(Constants.XML_SECURITY_PROPERTY_MANAGER);
311         setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
312 
313         //initialize Catalog properties
314         for( CatalogFeatures.Feature f : CatalogFeatures.Feature.values()) {
315             setProperty(f.getPropertyName(), grammarContainer.getProperty(f.getPropertyName()));
316         }
317 
318         setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE,
319                 grammarContainer.getProperty(JdkXmlUtils.CDATA_CHUNK_SIZE));
320     }
321 
322     /**
323      * Returns the state of a feature.
324      *
325      * @param featureId The feature identifier.
326      * @return true if the feature is supported
327      *
328      * @throws XMLConfigurationException Thrown for configuration error.
329      *                                   In general, components should
330      *                                   only throw this exception if
331      *                                   it is <strong>really</strong>
332      *                                   a critical error.
333      */
getFeatureState(String featureId)334     public FeatureState getFeatureState(String featureId)
335             throws XMLConfigurationException {
336         if (PARSER_SETTINGS.equals(featureId)) {
337             return FeatureState.is(fConfigUpdated);
338         }
339         else if (VALIDATION.equals(featureId) || SCHEMA_VALIDATION.equals(featureId)) {
340             return FeatureState.is(true);
341         }
342         else if (USE_GRAMMAR_POOL_ONLY.equals(featureId)) {
343             return FeatureState.is(fUseGrammarPoolOnly);
344         }
345         else if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(featureId)) {
346             return FeatureState.is(fInitSecurityManager.isSecureProcessing());
347         }
348         else if (SCHEMA_ELEMENT_DEFAULT.equals(featureId)) {
349             return FeatureState.is(true); //pre-condition: VALIDATION and SCHEMA_VALIDATION are always true
350         }
351         return super.getFeatureState(featureId);
352     }
353 
354     /**
355      * Set the state of a feature.
356      *
357      * @param featureId The unique identifier (URI) of the feature.
358      * @param state The requested state of the feature (true or false).
359      *
360      * @exception XMLConfigurationException If the requested feature is not known.
361      */
setFeature(String featureId, boolean value)362     public void setFeature(String featureId, boolean value) throws XMLConfigurationException {
363         if (PARSER_SETTINGS.equals(featureId)) {
364             throw new XMLConfigurationException(Status.NOT_SUPPORTED, featureId);
365         }
366         else if (value == false && (VALIDATION.equals(featureId) || SCHEMA_VALIDATION.equals(featureId))) {
367             throw new XMLConfigurationException(Status.NOT_SUPPORTED, featureId);
368         }
369         else if (USE_GRAMMAR_POOL_ONLY.equals(featureId) && value != fUseGrammarPoolOnly) {
370             throw new XMLConfigurationException(Status.NOT_SUPPORTED, featureId);
371         }
372         if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(featureId)) {
373             if (_isSecureMode && !value) {
374                 throw new XMLConfigurationException(Status.NOT_ALLOWED, XMLConstants.FEATURE_SECURE_PROCESSING);
375             }
376 
377             fInitSecurityManager.setSecureProcessing(value);
378             setProperty(SECURITY_MANAGER, fInitSecurityManager);
379 
380             if (value) {
381                 fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD,
382                         XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
383                 fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA,
384                         XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP);
385                 setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr);
386             }
387 
388             return;
389         }
390         fConfigUpdated = true;
391         fEntityManager.setFeature(featureId, value);
392         fErrorReporter.setFeature(featureId, value);
393         fSchemaValidator.setFeature(featureId, value);
394         if (!fInitFeatures.containsKey(featureId)) {
395             boolean current = super.getFeature(featureId);
396             fInitFeatures.put(featureId, current ? Boolean.TRUE : Boolean.FALSE);
397         }
398         super.setFeature(featureId, value);
399     }
400 
401     /**
402      * Returns the value of a property.
403      *
404      * @param propertyId The property identifier.
405      * @return the value of the property
406      *
407      * @throws XMLConfigurationException Thrown for configuration error.
408      *                                   In general, components should
409      *                                   only throw this exception if
410      *                                   it is <strong>really</strong>
411      *                                   a critical error.
412      */
getPropertyState(String propertyId)413     public PropertyState getPropertyState(String propertyId)
414             throws XMLConfigurationException {
415         if (LOCALE.equals(propertyId)) {
416             return PropertyState.is(getLocale());
417         }
418         final Object component = fComponents.get(propertyId);
419         if (component != null) {
420             return PropertyState.is(component);
421         }
422         else if (fComponents.containsKey(propertyId)) {
423             return PropertyState.is(null);
424         }
425         return super.getPropertyState(propertyId);
426     }
427 
428     /**
429      * Sets the state of a property.
430      *
431      * @param propertyId The unique identifier (URI) of the property.
432      * @param value The requested state of the property.
433      *
434      * @exception XMLConfigurationException If the requested property is not known.
435      */
setProperty(String propertyId, Object value)436     public void setProperty(String propertyId, Object value) throws XMLConfigurationException {
437         if ( ENTITY_MANAGER.equals(propertyId) || ERROR_REPORTER.equals(propertyId) ||
438              NAMESPACE_CONTEXT.equals(propertyId) || SCHEMA_VALIDATOR.equals(propertyId) ||
439              SYMBOL_TABLE.equals(propertyId) || VALIDATION_MANAGER.equals(propertyId) ||
440              XMLGRAMMAR_POOL.equals(propertyId)) {
441             throw new XMLConfigurationException(Status.NOT_SUPPORTED, propertyId);
442         }
443         fConfigUpdated = true;
444         fEntityManager.setProperty(propertyId, value);
445         fErrorReporter.setProperty(propertyId, value);
446         fSchemaValidator.setProperty(propertyId, value);
447         if (ENTITY_RESOLVER.equals(propertyId) || ERROR_HANDLER.equals(propertyId) ||
448                 SECURITY_MANAGER.equals(propertyId)) {
449             fComponents.put(propertyId, value);
450             return;
451         }
452         else if (LOCALE.equals(propertyId)) {
453             setLocale((Locale) value);
454             fComponents.put(propertyId, value);
455             return;
456         }
457         //check if the property is managed by security manager
458         if (fInitSecurityManager == null ||
459                 !fInitSecurityManager.setLimit(propertyId, XMLSecurityManager.State.APIPROPERTY, value)) {
460             //check if the property is managed by security property manager
461             if (fSecurityPropertyMgr == null ||
462                     !fSecurityPropertyMgr.setValue(propertyId, XMLSecurityPropertyManager.State.APIPROPERTY, value)) {
463                 //fall back to the existing property manager
464                 if (!fInitProperties.containsKey(propertyId)) {
465                     fInitProperties.put(propertyId, super.getProperty(propertyId));
466                 }
467                 super.setProperty(propertyId, value);
468             }
469         }
470     }
471 
472     /**
473      * Adds all of the component's recognized features and properties
474      * to the list of default recognized features and properties, and
475      * sets default values on the configuration for features and
476      * properties which were previously absent from the configuration.
477      *
478      * @param component The component whose recognized features
479      * and properties will be added to the configuration
480      */
addRecognizedParamsAndSetDefaults(XMLComponent component, XSGrammarPoolContainer grammarContainer)481     public void addRecognizedParamsAndSetDefaults(XMLComponent component, XSGrammarPoolContainer grammarContainer) {
482 
483         // register component's recognized features
484         final String[] recognizedFeatures = component.getRecognizedFeatures();
485         addRecognizedFeatures(recognizedFeatures);
486 
487         // register component's recognized properties
488         final String[] recognizedProperties = component.getRecognizedProperties();
489         addRecognizedProperties(recognizedProperties);
490 
491         // set default values
492         setFeatureDefaults(component, recognizedFeatures, grammarContainer);
493         setPropertyDefaults(component, recognizedProperties);
494     }
495 
496     /** Calls reset on each of the components owned by this component manager. **/
reset()497     public void reset() throws XNIException {
498         fNamespaceContext.reset();
499         fValidationManager.reset();
500         fEntityManager.reset(this);
501         fErrorReporter.reset(this);
502         fSchemaValidator.reset(this);
503         // Mark configuration as fixed.
504         fConfigUpdated = false;
505     }
506 
setErrorHandler(ErrorHandler errorHandler)507     void setErrorHandler(ErrorHandler errorHandler) {
508         fErrorHandler = errorHandler;
509         setProperty(ERROR_HANDLER, (errorHandler != null) ? new ErrorHandlerWrapper(errorHandler) :
510                 new ErrorHandlerWrapper(DraconianErrorHandler.getInstance()));
511     }
512 
getErrorHandler()513     ErrorHandler getErrorHandler() {
514         return fErrorHandler;
515     }
516 
setResourceResolver(LSResourceResolver resourceResolver)517     void setResourceResolver(LSResourceResolver resourceResolver) {
518         fResourceResolver = resourceResolver;
519         setProperty(ENTITY_RESOLVER, new DOMEntityResolverWrapper(resourceResolver));
520     }
521 
getResourceResolver()522     LSResourceResolver getResourceResolver() {
523         return fResourceResolver;
524     }
525 
setLocale(Locale locale)526     void setLocale(Locale locale) {
527         fLocale = locale;
528         fErrorReporter.setLocale(locale);
529     }
530 
getLocale()531     Locale getLocale() {
532         return fLocale;
533     }
534 
535     /** Cleans out configuration, restoring it to its initial state. */
restoreInitialState()536     void restoreInitialState() {
537         fConfigUpdated = true;
538 
539         // Remove error resolver and error handler
540         fComponents.put(ENTITY_RESOLVER, null);
541         fComponents.put(ERROR_HANDLER, null);
542 
543         // Set the Locale back to null.
544         setLocale(null);
545         fComponents.put(LOCALE, null);
546 
547         // Restore initial security manager
548         fInitSecurityManager.setSecureProcessing(true);
549         fComponents.put(SECURITY_MANAGER, fInitSecurityManager);
550 
551         // Set the Locale back to null.
552         setLocale(null);
553         fComponents.put(LOCALE, null);
554 
555         // Reset feature and property values to their initial values
556         if (!fInitFeatures.isEmpty()) {
557             for (Map.Entry<String, Boolean> entry : fInitFeatures.entrySet()) {
558                 String name = entry.getKey();
559                 boolean value = entry.getValue();
560                 super.setFeature(name, value);
561             }
562             fInitFeatures.clear();
563         }
564         if (!fInitProperties.isEmpty()) {
565             for (Map.Entry<String, Object> entry : fInitProperties.entrySet()) {
566                 String name = entry.getKey();
567                 Object value = entry.getValue();
568                 super.setProperty(name, value);
569             }
570             fInitProperties.clear();
571         }
572     }
573 
574     /** Sets feature defaults for the given component on this configuration. */
setFeatureDefaults(final XMLComponent component, final String [] recognizedFeatures, XSGrammarPoolContainer grammarContainer)575     private void setFeatureDefaults(final XMLComponent component,
576             final String [] recognizedFeatures, XSGrammarPoolContainer grammarContainer) {
577         if (recognizedFeatures != null) {
578             for (int i = 0; i < recognizedFeatures.length; ++i) {
579                 String featureId = recognizedFeatures[i];
580                 Boolean state = grammarContainer.getFeature(featureId);
581                 if (state == null) {
582                     state = component.getFeatureDefault(featureId);
583                 }
584                 if (state != null) {
585                     // Do not overwrite values already set on the configuration.
586                     if (!fFeatures.containsKey(featureId)) {
587                         fFeatures.put(featureId, state);
588                         // For newly added components who recognize this feature
589                         // but did not offer a default value, we need to make
590                         // sure these components will get an opportunity to read
591                         // the value before parsing begins.
592                         fConfigUpdated = true;
593                     }
594                 }
595             }
596         }
597     }
598 
599     /** Sets property defaults for the given component on this configuration. */
setPropertyDefaults(final XMLComponent component, final String [] recognizedProperties)600     private void setPropertyDefaults(final XMLComponent component, final String [] recognizedProperties) {
601         if (recognizedProperties != null) {
602             for (int i = 0; i < recognizedProperties.length; ++i) {
603                 String propertyId = recognizedProperties[i];
604                 Object value = component.getPropertyDefault(propertyId);
605                 if (value != null) {
606                     // Do not overwrite values already set on the configuration.
607                     if (!fProperties.containsKey(propertyId)) {
608                         fProperties.put(propertyId, value);
609                         // For newly added components who recognize this property
610                         // but did not offer a default value, we need to make
611                         // sure these components will get an opportunity to read
612                         // the value before parsing begins.
613                         fConfigUpdated = true;
614                     }
615                 }
616             }
617         }
618     }
619 
620 } // XMLSchemaValidatorComponentManager
621