1 /*
2  * Copyright (c) 2011, 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.parsers;
22 
23 import com.sun.org.apache.xerces.internal.impl.Constants;
24 import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator;
25 import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter;
26 import com.sun.org.apache.xerces.internal.util.FeatureState;
27 import com.sun.org.apache.xerces.internal.util.PropertyState;
28 import com.sun.org.apache.xerces.internal.util.Status;
29 import com.sun.org.apache.xerces.internal.util.SymbolTable;
30 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
31 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
32 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
33 
34 /**
35  * This is the "standard" parser configuration. It extends the DTD
36  * configuration with the standard set of parser components.
37  * The standard set of parser components include those needed
38  * to parse and validate with DTD's, and those needed for XML
39  * Schema.</p>
40  * <p>
41  * In addition to the features and properties recognized by the base
42  * parser configuration, this class recognizes these additional
43  * features and properties:
44  * <ul>
45  * <li>Features
46  *  <ul>
47  *  <li>http://apache.org/xml/features/validation/schema</li>
48  *  <li>http://apache.org/xml/features/validation/schema-full-checking</li>
49  *  <li>http://apache.org/xml/features/validation/schema/normalized-value</li>
50  *  <li>http://apache.org/xml/features/validation/schema/element-default</li>
51  *  </ul>
52  * <li>Properties
53  *  <ul>
54  *   <li>http://apache.org/xml/properties/internal/error-reporter</li>
55  *   <li>http://apache.org/xml/properties/internal/entity-manager</li>
56  *   <li>http://apache.org/xml/properties/internal/document-scanner</li>
57  *   <li>http://apache.org/xml/properties/internal/dtd-scanner</li>
58  *   <li>http://apache.org/xml/properties/internal/grammar-pool</li>
59  *   <li>http://apache.org/xml/properties/internal/validator/dtd</li>
60  *   <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li>
61  *  </ul>
62  * </ul>
63  *
64  * @author Arnaud  Le Hors, IBM
65  * @author Andy Clark, IBM
66  *
67  */
68 public class StandardParserConfiguration
69     extends DTDConfiguration {
70 
71     //
72     // Constants
73     //
74 
75     // feature identifiers
76 
77     /** Feature identifier: expose schema normalized value */
78     protected static final String NORMALIZE_DATA =
79     Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_NORMALIZED_VALUE;
80 
81 
82     /** Feature identifier: send element default value via characters() */
83     protected static final String SCHEMA_ELEMENT_DEFAULT =
84     Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_ELEMENT_DEFAULT;
85 
86 
87     /** Feature identifier: augment PSVI */
88     protected static final String SCHEMA_AUGMENT_PSVI =
89     Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_AUGMENT_PSVI;
90 
91 
92     /** feature identifier: XML Schema validation */
93     protected static final String XMLSCHEMA_VALIDATION =
94     Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE;
95 
96     /** feature identifier: XML Schema validation -- full checking */
97     protected static final String XMLSCHEMA_FULL_CHECKING =
98     Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_FULL_CHECKING;
99 
100     /** Feature: generate synthetic annotations */
101     protected static final String GENERATE_SYNTHETIC_ANNOTATIONS =
102         Constants.XERCES_FEATURE_PREFIX + Constants.GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE;
103 
104     /** Feature identifier: validate annotations */
105     protected static final String VALIDATE_ANNOTATIONS =
106         Constants.XERCES_FEATURE_PREFIX + Constants.VALIDATE_ANNOTATIONS_FEATURE;
107 
108     /** Feature identifier: honour all schemaLocations */
109     protected static final String HONOUR_ALL_SCHEMALOCATIONS =
110         Constants.XERCES_FEATURE_PREFIX + Constants.HONOUR_ALL_SCHEMALOCATIONS_FEATURE;
111 
112     /** Feature identifier: whether to ignore xsi:type attributes until a global element declaration is encountered */
113     protected static final String IGNORE_XSI_TYPE =
114         Constants.XERCES_FEATURE_PREFIX + Constants.IGNORE_XSI_TYPE_FEATURE;
115 
116     /** Feature identifier: whether to ignore ID/IDREF errors */
117     protected static final String ID_IDREF_CHECKING =
118         Constants.XERCES_FEATURE_PREFIX + Constants.ID_IDREF_CHECKING_FEATURE;
119 
120     /** Feature identifier: whether to ignore unparsed entity errors */
121     protected static final String UNPARSED_ENTITY_CHECKING =
122         Constants.XERCES_FEATURE_PREFIX + Constants.UNPARSED_ENTITY_CHECKING_FEATURE;
123 
124     /** Feature identifier: whether to ignore identity constraint errors */
125     protected static final String IDENTITY_CONSTRAINT_CHECKING =
126         Constants.XERCES_FEATURE_PREFIX + Constants.IDC_CHECKING_FEATURE;
127 
128     /** Feature identifier: namespace growth */
129     protected static final String NAMESPACE_GROWTH =
130         Constants.XERCES_FEATURE_PREFIX + Constants.NAMESPACE_GROWTH_FEATURE;
131 
132     /** Feature identifier: tolerate duplicates */
133     protected static final String TOLERATE_DUPLICATES =
134         Constants.XERCES_FEATURE_PREFIX + Constants.TOLERATE_DUPLICATES_FEATURE;
135 
136     // property identifiers
137 
138     /** Property identifier: XML Schema validator. */
139     protected static final String SCHEMA_VALIDATOR =
140         Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY;
141 
142     /** Property identifier: schema location. */
143     protected static final String SCHEMA_LOCATION =
144     Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_LOCATION;
145 
146     /** Property identifier: no namespace schema location. */
147     protected static final String SCHEMA_NONS_LOCATION =
148     Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_NONS_LOCATION;
149 
150     /** Property identifier: Schema DV Factory */
151     protected static final String SCHEMA_DV_FACTORY =
152         Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY;
153 
154     /** Property identifier: root type definition. */
155     protected static final String ROOT_TYPE_DEF =
156         Constants.XERCES_PROPERTY_PREFIX + Constants.ROOT_TYPE_DEFINITION_PROPERTY;
157 
158     /** Property identifier: root element declaration. */
159     protected static final String ROOT_ELEMENT_DECL =
160         Constants.XERCES_PROPERTY_PREFIX + Constants.ROOT_ELEMENT_DECLARATION_PROPERTY;
161 
162     //
163     // Data
164     //
165 
166     // components (non-configurable)
167 
168     /** XML Schema Validator. */
169     protected XMLSchemaValidator fSchemaValidator;
170 
171     //
172     // Constructors
173     //
174 
175     /** Default constructor. */
StandardParserConfiguration()176     public StandardParserConfiguration() {
177         this(null, null, null);
178     } // <init>()
179 
180     /**
181      * Constructs a parser configuration using the specified symbol table.
182      *
183      * @param symbolTable The symbol table to use.
184      */
StandardParserConfiguration(SymbolTable symbolTable)185     public StandardParserConfiguration(SymbolTable symbolTable) {
186         this(symbolTable, null, null);
187     } // <init>(SymbolTable)
188 
189     /**
190      * Constructs a parser configuration using the specified symbol table and
191      * grammar pool.
192      * <p>
193      * <strong>REVISIT:</strong>
194      * Grammar pool will be updated when the new validation engine is
195      * implemented.
196      *
197      * @param symbolTable The symbol table to use.
198      * @param grammarPool The grammar pool to use.
199      */
StandardParserConfiguration(SymbolTable symbolTable, XMLGrammarPool grammarPool)200     public StandardParserConfiguration(SymbolTable symbolTable,
201                                        XMLGrammarPool grammarPool) {
202         this(symbolTable, grammarPool, null);
203     } // <init>(SymbolTable,XMLGrammarPool)
204 
205     /**
206      * Constructs a parser configuration using the specified symbol table,
207      * grammar pool, and parent settings.
208      * <p>
209      * <strong>REVISIT:</strong>
210      * Grammar pool will be updated when the new validation engine is
211      * implemented.
212      *
213      * @param symbolTable    The symbol table to use.
214      * @param grammarPool    The grammar pool to use.
215      * @param parentSettings The parent settings.
216      */
StandardParserConfiguration(SymbolTable symbolTable, XMLGrammarPool grammarPool, XMLComponentManager parentSettings)217     public StandardParserConfiguration(SymbolTable symbolTable,
218                                        XMLGrammarPool grammarPool,
219                                        XMLComponentManager parentSettings) {
220         super(symbolTable, grammarPool, parentSettings);
221 
222         // add default recognized features
223         final String[] recognizedFeatures = {
224             NORMALIZE_DATA,
225             SCHEMA_ELEMENT_DEFAULT,
226             SCHEMA_AUGMENT_PSVI,
227             GENERATE_SYNTHETIC_ANNOTATIONS,
228             VALIDATE_ANNOTATIONS,
229             HONOUR_ALL_SCHEMALOCATIONS,
230             NAMESPACE_GROWTH,
231             TOLERATE_DUPLICATES,
232             // NOTE: These shouldn't really be here but since the XML Schema
233             //       validator is constructed dynamically, its recognized
234             //       features might not have been set and it would cause a
235             //       not-recognized exception to be thrown. -Ac
236             XMLSCHEMA_VALIDATION,
237             XMLSCHEMA_FULL_CHECKING,
238             IGNORE_XSI_TYPE,
239             ID_IDREF_CHECKING,
240             IDENTITY_CONSTRAINT_CHECKING,
241             UNPARSED_ENTITY_CHECKING,
242         };
243         addRecognizedFeatures(recognizedFeatures);
244 
245         // set state for default features
246         setFeature(SCHEMA_ELEMENT_DEFAULT, true);
247         setFeature(NORMALIZE_DATA, true);
248         setFeature(SCHEMA_AUGMENT_PSVI, true);
249         setFeature(GENERATE_SYNTHETIC_ANNOTATIONS, false);
250         setFeature(VALIDATE_ANNOTATIONS, false);
251         setFeature(HONOUR_ALL_SCHEMALOCATIONS, false);
252         setFeature(IGNORE_XSI_TYPE, false);
253         setFeature(ID_IDREF_CHECKING, true);
254         setFeature(IDENTITY_CONSTRAINT_CHECKING, true);
255         setFeature(UNPARSED_ENTITY_CHECKING, true);
256         setFeature(NAMESPACE_GROWTH, false);
257         setFeature(TOLERATE_DUPLICATES, false);
258 
259         // add default recognized properties
260 
261         final String[] recognizedProperties = {
262             // NOTE: These shouldn't really be here but since the XML Schema
263             //       validator is constructed dynamically, its recognized
264             //       properties might not have been set and it would cause a
265             //       not-recognized exception to be thrown. -Ac
266             SCHEMA_LOCATION,
267             SCHEMA_NONS_LOCATION,
268             ROOT_TYPE_DEF,
269             ROOT_ELEMENT_DECL,
270             SCHEMA_DV_FACTORY,
271         };
272 
273         addRecognizedProperties(recognizedProperties);
274     } // <init>(SymbolTable,XMLGrammarPool)
275 
276     //
277     // Public methods
278     //
279 
280     /** Configures the pipeline. */
configurePipeline()281     protected void configurePipeline() {
282         super.configurePipeline();
283         if ( getFeature(XMLSCHEMA_VALIDATION )) {
284             // If schema validator was not in the pipeline insert it.
285             if (fSchemaValidator == null) {
286                 fSchemaValidator = new XMLSchemaValidator();
287 
288                 // add schema component
289                 fProperties.put(SCHEMA_VALIDATOR, fSchemaValidator);
290                 addComponent(fSchemaValidator);
291                  // add schema message formatter
292                 if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
293                     XSMessageFormatter xmft = new XSMessageFormatter();
294                     fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, xmft);
295                 }
296 
297             }
298             fLastComponent = fSchemaValidator;
299             fNamespaceBinder.setDocumentHandler(fSchemaValidator);
300 
301             fSchemaValidator.setDocumentHandler(fDocumentHandler);
302             fSchemaValidator.setDocumentSource(fNamespaceBinder);
303         }
304 
305 
306     } // configurePipeline()
307 
308     // features and properties
309 
310     /**
311      * Check a feature. If feature is know and supported, this method simply
312      * returns. Otherwise, the appropriate exception is thrown.
313      *
314      * @param featureId The unique identifier (URI) of the feature.
315      *
316      * @throws XMLConfigurationException Thrown for configuration error.
317      *                                   In general, components should
318      *                                   only throw this exception if
319      *                                   it is <strong>really</strong>
320      *                                   a critical error.
321      */
checkFeature(String featureId)322     protected FeatureState checkFeature(String featureId)
323         throws XMLConfigurationException {
324 
325         //
326         // Xerces Features
327         //
328 
329         if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
330             final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
331 
332             //
333             // http://apache.org/xml/features/validation/schema
334             //   Lets the user turn Schema validation support on/off.
335             //
336             if (suffixLength == Constants.SCHEMA_VALIDATION_FEATURE.length() &&
337                 featureId.endsWith(Constants.SCHEMA_VALIDATION_FEATURE)) {
338                 return FeatureState.RECOGNIZED;
339             }
340             // activate full schema checking
341             if (suffixLength == Constants.SCHEMA_FULL_CHECKING.length() &&
342                 featureId.endsWith(Constants.SCHEMA_FULL_CHECKING)) {
343                 return FeatureState.RECOGNIZED;
344             }
345             // Feature identifier: expose schema normalized value
346             //  http://apache.org/xml/features/validation/schema/normalized-value
347             if (suffixLength == Constants.SCHEMA_NORMALIZED_VALUE.length() &&
348                 featureId.endsWith(Constants.SCHEMA_NORMALIZED_VALUE)) {
349                 return FeatureState.RECOGNIZED;
350             }
351             // Feature identifier: send element default value via characters()
352             // http://apache.org/xml/features/validation/schema/element-default
353             if (suffixLength == Constants.SCHEMA_ELEMENT_DEFAULT.length() &&
354                 featureId.endsWith(Constants.SCHEMA_ELEMENT_DEFAULT)) {
355                 return FeatureState.RECOGNIZED;
356             }
357         }
358 
359         //
360         // Not recognized
361         //
362 
363         return super.checkFeature(featureId);
364 
365     } // checkFeature(String)
366 
367     /**
368      * Check a property. If the property is know and supported, this method
369      * simply returns. Otherwise, the appropriate exception is thrown.
370      *
371      * @param propertyId The unique identifier (URI) of the property
372      *                   being set.
373      *
374      * @throws XMLConfigurationException Thrown for configuration error.
375      *                                   In general, components should
376      *                                   only throw this exception if
377      *                                   it is <strong>really</strong>
378      *                                   a critical error.
379      */
checkProperty(String propertyId)380     protected PropertyState checkProperty(String propertyId)
381         throws XMLConfigurationException {
382 
383         //
384         // Xerces Properties
385         //
386 
387         if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
388             final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();
389 
390             if (suffixLength == Constants.SCHEMA_LOCATION.length() &&
391                 propertyId.endsWith(Constants.SCHEMA_LOCATION)) {
392                 return PropertyState.RECOGNIZED;
393             }
394             if (suffixLength == Constants.SCHEMA_NONS_LOCATION.length() &&
395                 propertyId.endsWith(Constants.SCHEMA_NONS_LOCATION)) {
396                 return PropertyState.RECOGNIZED;
397             }
398         }
399 
400         if (propertyId.startsWith(Constants.JAXP_PROPERTY_PREFIX)) {
401             final int suffixLength = propertyId.length() - Constants.JAXP_PROPERTY_PREFIX.length();
402 
403             if (suffixLength == Constants.SCHEMA_SOURCE.length() &&
404                 propertyId.endsWith(Constants.SCHEMA_SOURCE)) {
405                 return PropertyState.RECOGNIZED;
406             }
407         }
408 
409         //
410         // Not recognized
411         //
412 
413         return super.checkProperty(propertyId);
414 
415     } // checkProperty(String)
416 
417 } // class StandardParserConfiguration
418