~ubuntu-branches/ubuntu/karmic/libxerces2-java/karmic

« back to all changes in this revision

Viewing changes to src/org/apache/xerces/jaxp/validation/XMLSchemaValidatorComponentManager.java

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2006-12-04 17:37:55 UTC
  • mfrom: (2.1.2 etch)
  • Revision ID: james.westby@ubuntu.com-20061204173755-hb6ybrrrk097zhx7
Tags: 2.8.1-1ubuntu1
* Merge with Debian unstable; remaining changes:
  - Build -gcj package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2005,2006 The Apache Software Foundation.
 
3
 * 
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * You may obtain a copy of the License at
 
7
 * 
 
8
 *      http://www.apache.org/licenses/LICENSE-2.0
 
9
 * 
 
10
 * Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS,
 
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
 
 
17
package org.apache.xerces.jaxp.validation;
 
18
 
 
19
import java.util.HashMap;
 
20
import java.util.Iterator;
 
21
import java.util.Map;
 
22
 
 
23
import javax.xml.XMLConstants;
 
24
 
 
25
import org.apache.xerces.impl.Constants;
 
26
import org.apache.xerces.impl.XMLEntityManager;
 
27
import org.apache.xerces.impl.XMLErrorReporter;
 
28
import org.apache.xerces.impl.validation.ValidationManager;
 
29
import org.apache.xerces.impl.xs.XMLSchemaValidator;
 
30
import org.apache.xerces.impl.xs.XSMessageFormatter;
 
31
import org.apache.xerces.util.DOMEntityResolverWrapper;
 
32
import org.apache.xerces.util.ErrorHandlerWrapper;
 
33
import org.apache.xerces.util.NamespaceSupport;
 
34
import org.apache.xerces.util.ParserConfigurationSettings;
 
35
import org.apache.xerces.util.SecurityManager;
 
36
import org.apache.xerces.util.SymbolTable;
 
37
import org.apache.xerces.xni.NamespaceContext;
 
38
import org.apache.xerces.xni.XNIException;
 
39
import org.apache.xerces.xni.parser.XMLComponent;
 
40
import org.apache.xerces.xni.parser.XMLComponentManager;
 
41
import org.apache.xerces.xni.parser.XMLConfigurationException;
 
42
import org.w3c.dom.ls.LSResourceResolver;
 
43
import org.xml.sax.ErrorHandler;
 
44
 
 
45
/**
 
46
 * <p>An implementation of XMLComponentManager for a schema validator.</p>
 
47
 * 
 
48
 * @author Michael Glavassevich, IBM
 
49
 * @version $Id: XMLSchemaValidatorComponentManager.java 381134 2006-02-26 18:20:57Z mrglavas $
 
50
 */
 
51
final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettings implements
 
52
        XMLComponentManager {
 
53
    
 
54
    // feature identifiers
 
55
    
 
56
    /** Feature identifier: schema validation. */
 
57
    private static final String SCHEMA_VALIDATION =
 
58
        Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE;
 
59
    
 
60
    /** Feature identifier: validation. */
 
61
    private static final String VALIDATION =
 
62
        Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
 
63
    
 
64
    /** Feature identifier: use grammar pool only. */
 
65
    private static final String USE_GRAMMAR_POOL_ONLY =
 
66
        Constants.XERCES_FEATURE_PREFIX + Constants.USE_GRAMMAR_POOL_ONLY_FEATURE;
 
67
    
 
68
    /** Feature identifier: whether to ignore xsi:type attributes until a global element declaration is encountered */
 
69
    protected static final String IGNORE_XSI_TYPE =
 
70
        Constants.XERCES_FEATURE_PREFIX + Constants.IGNORE_XSI_TYPE_FEATURE;
 
71
    
 
72
    /** Feature identifier: whether to ignore ID/IDREF errors */
 
73
    protected static final String ID_IDREF_CHECKING =
 
74
        Constants.XERCES_FEATURE_PREFIX + Constants.ID_IDREF_CHECKING_FEATURE;
 
75
    
 
76
    /** Feature identifier: whether to ignore unparsed entity errors */
 
77
    protected static final String UNPARSED_ENTITY_CHECKING =
 
78
        Constants.XERCES_FEATURE_PREFIX + Constants.UNPARSED_ENTITY_CHECKING_FEATURE;
 
79
    
 
80
    /** Feature identifier: whether to ignore identity constraint errors */
 
81
    protected static final String IDENTITY_CONSTRAINT_CHECKING =
 
82
        Constants.XERCES_FEATURE_PREFIX + Constants.IDC_CHECKING_FEATURE;
 
83
    
 
84
    // property identifiers
 
85
 
 
86
    /** Property identifier: entity manager. */
 
87
    private static final String ENTITY_MANAGER =
 
88
        Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
 
89
    
 
90
    /** Property identifier: entity resolver. */
 
91
    private static final String ENTITY_RESOLVER =
 
92
        Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
 
93
    
 
94
    /** Property identifier: error handler. */
 
95
    private static final String ERROR_HANDLER = 
 
96
        Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
 
97
    
 
98
    /** Property identifier: error reporter. */
 
99
    private static final String ERROR_REPORTER =
 
100
        Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
 
101
    
 
102
    /** Property identifier: namespace context. */
 
103
    private static final String NAMESPACE_CONTEXT =
 
104
        Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_CONTEXT_PROPERTY;
 
105
    
 
106
    /** Property identifier: XML Schema validator. */
 
107
    private static final String SCHEMA_VALIDATOR =
 
108
        Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY;
 
109
    
 
110
    /** Property identifier: security manager. */
 
111
    private static final String SECURITY_MANAGER =
 
112
        Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
 
113
    
 
114
    /** Property identifier: symbol table. */
 
115
    private static final String SYMBOL_TABLE =
 
116
        Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
 
117
    
 
118
    /** Property identifier: validation manager. */
 
119
    private static final String VALIDATION_MANAGER =
 
120
        Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY;
 
121
    
 
122
    /** Property identifier: grammar pool. */
 
123
    private static final String XMLGRAMMAR_POOL =
 
124
        Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
 
125
    
 
126
    //
 
127
    // Data
 
128
    //
 
129
    
 
130
    /** 
 
131
     * fConfigUpdated is set to true if there has been any change to the configuration settings, 
 
132
     * i.e a feature or a property was changed.
 
133
     */
 
134
    private boolean fConfigUpdated = true;
 
135
    
 
136
    /** 
 
137
     * Tracks whether the validator should use components from 
 
138
     * the grammar pool to the exclusion of all others.
 
139
     */
 
140
    private boolean fUseGrammarPoolOnly;
 
141
    
 
142
    /** Lookup map for components required for validation. **/
 
143
    private final HashMap fComponents = new HashMap();
 
144
    
 
145
    //
 
146
    // Components
 
147
    //
 
148
    
 
149
    /** Entity manager. */
 
150
    private XMLEntityManager fEntityManager;
 
151
    
 
152
    /** Error reporter. */
 
153
    private XMLErrorReporter fErrorReporter;
 
154
    
 
155
    /** Namespace context. */
 
156
    private NamespaceContext fNamespaceContext;
 
157
    
 
158
    /** XML Schema validator. */
 
159
    private XMLSchemaValidator fSchemaValidator;
 
160
       
 
161
    /** Validation manager. */
 
162
    private ValidationManager fValidationManager;
 
163
    
 
164
    //
 
165
    // Configuration
 
166
    //
 
167
    
 
168
    /** Stores initial feature values for validator reset. */
 
169
    private HashMap fInitFeatures = new HashMap();
 
170
    
 
171
    /** Stores initial property values for validator reset. */
 
172
    private HashMap fInitProperties = new HashMap();
 
173
    
 
174
    /** Stores the initial security manager. */
 
175
    private SecurityManager fInitSecurityManager = null;
 
176
    
 
177
    //
 
178
    // User Objects
 
179
    //
 
180
    
 
181
    /** Application's ErrorHandler. **/
 
182
    private ErrorHandler fErrorHandler = null;
 
183
    
 
184
    /** Application's LSResourceResolver. */
 
185
    private LSResourceResolver fResourceResolver = null;
 
186
    
 
187
    /** Constructs a component manager suitable for Xerces' schema validator. */
 
188
    public XMLSchemaValidatorComponentManager(XSGrammarPoolContainer grammarContainer) {
 
189
        
 
190
        // setup components 
 
191
        fEntityManager = new XMLEntityManager();
 
192
        fComponents.put(ENTITY_MANAGER, fEntityManager);
 
193
        
 
194
        fErrorReporter = new XMLErrorReporter();
 
195
        fComponents.put(ERROR_REPORTER, fErrorReporter);
 
196
        
 
197
        fNamespaceContext = new NamespaceSupport();
 
198
        fComponents.put(NAMESPACE_CONTEXT, fNamespaceContext);
 
199
        
 
200
        fSchemaValidator = new XMLSchemaValidator();
 
201
        fComponents.put(SCHEMA_VALIDATOR, fSchemaValidator);
 
202
        
 
203
        fValidationManager = new ValidationManager();
 
204
        fComponents.put(VALIDATION_MANAGER, fValidationManager);
 
205
        
 
206
        // setup other properties
 
207
        fComponents.put(ENTITY_RESOLVER, null);
 
208
        fComponents.put(ERROR_HANDLER, null);
 
209
        fComponents.put(SECURITY_MANAGER, null);
 
210
        fComponents.put(SYMBOL_TABLE, new SymbolTable());
 
211
        
 
212
        // setup grammar pool
 
213
        fComponents.put(XMLGRAMMAR_POOL, grammarContainer.getGrammarPool());
 
214
        fUseGrammarPoolOnly = grammarContainer.isFullyComposed();
 
215
        
 
216
        // add schema message formatter to error reporter
 
217
        fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, new XSMessageFormatter());
 
218
        
 
219
        // add all recognized features and properties and apply their defaults
 
220
        addRecognizedParamsAndSetDefaults(fEntityManager, grammarContainer);
 
221
        addRecognizedParamsAndSetDefaults(fErrorReporter, grammarContainer);
 
222
        addRecognizedParamsAndSetDefaults(fSchemaValidator, grammarContainer);
 
223
        
 
224
        // if the secure processing feature is set to true, add a security manager to the configuration
 
225
        Boolean secureProcessing = grammarContainer.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING);
 
226
        if (Boolean.TRUE.equals(secureProcessing)) {
 
227
            fInitSecurityManager = new SecurityManager();
 
228
        }
 
229
        fComponents.put(SECURITY_MANAGER, fInitSecurityManager);
 
230
        
 
231
        /* TODO: are other XMLSchemaValidator default values never set?
 
232
         * Initial investigation indicates that they aren't set, but
 
233
         * that they all have default values of false, so it works out
 
234
         * anyway -PM
 
235
         */
 
236
        fFeatures.put(IGNORE_XSI_TYPE, Boolean.FALSE);
 
237
        fFeatures.put(ID_IDREF_CHECKING, Boolean.TRUE);
 
238
        fFeatures.put(IDENTITY_CONSTRAINT_CHECKING, Boolean.TRUE);
 
239
        fFeatures.put(UNPARSED_ENTITY_CHECKING, Boolean.TRUE);
 
240
    }
 
241
 
 
242
    /**
 
243
     * Returns the state of a feature.
 
244
     * 
 
245
     * @param featureId The feature identifier.
 
246
     * @return true if the feature is supported
 
247
     * 
 
248
     * @throws XMLConfigurationException Thrown for configuration error.
 
249
     *                                   In general, components should
 
250
     *                                   only throw this exception if
 
251
     *                                   it is <strong>really</strong>
 
252
     *                                   a critical error.
 
253
     */
 
254
    public boolean getFeature(String featureId)
 
255
            throws XMLConfigurationException {
 
256
        if (PARSER_SETTINGS.equals(featureId)) {
 
257
            return fConfigUpdated;
 
258
        }
 
259
        else if (VALIDATION.equals(featureId) || SCHEMA_VALIDATION.equals(featureId)) {
 
260
            return true;
 
261
        }
 
262
        else if (USE_GRAMMAR_POOL_ONLY.equals(featureId)) {
 
263
            return fUseGrammarPoolOnly;
 
264
        }
 
265
        else if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(featureId)) {
 
266
            return getProperty(SECURITY_MANAGER) != null;
 
267
        }
 
268
        return super.getFeature(featureId);
 
269
    }
 
270
    
 
271
    /**
 
272
     * Set the state of a feature.
 
273
     *
 
274
     * @param featureId The unique identifier (URI) of the feature.
 
275
     * @param state The requested state of the feature (true or false).
 
276
     *
 
277
     * @exception XMLConfigurationException If the requested feature is not known.
 
278
     */
 
279
    public void setFeature(String featureId, boolean value) throws XMLConfigurationException {
 
280
        if (PARSER_SETTINGS.equals(featureId)) {
 
281
            throw new XMLConfigurationException(XMLConfigurationException.NOT_SUPPORTED, featureId);
 
282
        }
 
283
        else if (value == false && (VALIDATION.equals(featureId) || SCHEMA_VALIDATION.equals(featureId))) {
 
284
            throw new XMLConfigurationException(XMLConfigurationException.NOT_SUPPORTED, featureId);
 
285
        }
 
286
        else if (USE_GRAMMAR_POOL_ONLY.equals(featureId) && value != fUseGrammarPoolOnly) {
 
287
            throw new XMLConfigurationException(XMLConfigurationException.NOT_SUPPORTED, featureId);
 
288
        }
 
289
        if (XMLConstants.FEATURE_SECURE_PROCESSING.equals(featureId)) {
 
290
            setProperty(SECURITY_MANAGER, value ? new SecurityManager() : null);
 
291
            return;
 
292
        }
 
293
        fConfigUpdated = true;
 
294
        fEntityManager.setFeature(featureId, value);
 
295
        fErrorReporter.setFeature(featureId, value);
 
296
        fSchemaValidator.setFeature(featureId, value);
 
297
        if (!fInitFeatures.containsKey(featureId)) {
 
298
            boolean current = super.getFeature(featureId);
 
299
            fInitFeatures.put(featureId, current ? Boolean.TRUE : Boolean.FALSE); 
 
300
        }
 
301
        super.setFeature(featureId, value);
 
302
    }
 
303
    
 
304
    /**
 
305
     * Returns the value of a property.
 
306
     * 
 
307
     * @param propertyId The property identifier.
 
308
     * @return the value of the property
 
309
     * 
 
310
     * @throws XMLConfigurationException Thrown for configuration error.
 
311
     *                                   In general, components should
 
312
     *                                   only throw this exception if
 
313
     *                                   it is <strong>really</strong>
 
314
     *                                   a critical error.
 
315
     */
 
316
    public Object getProperty(String propertyId)
 
317
            throws XMLConfigurationException {
 
318
        final Object component = fComponents.get(propertyId);
 
319
        if (component != null) {
 
320
            return component;
 
321
        }
 
322
        else if (fComponents.containsKey(propertyId)) {
 
323
            return null;
 
324
        }
 
325
        return super.getProperty(propertyId);
 
326
    }
 
327
    
 
328
    /**
 
329
     * Sets the state of a property.
 
330
     * 
 
331
     * @param propertyId The unique identifier (URI) of the property.
 
332
     * @param value The requested state of the property.
 
333
     * 
 
334
     * @exception XMLConfigurationException If the requested property is not known.
 
335
     */
 
336
    public void setProperty(String propertyId, Object value) throws XMLConfigurationException {
 
337
        if ( ENTITY_MANAGER.equals(propertyId) || ERROR_REPORTER.equals(propertyId) ||
 
338
             NAMESPACE_CONTEXT.equals(propertyId) || SCHEMA_VALIDATOR.equals(propertyId) ||
 
339
             SYMBOL_TABLE.equals(propertyId) || VALIDATION_MANAGER.equals(propertyId) ||
 
340
             XMLGRAMMAR_POOL.equals(propertyId)) {
 
341
            throw new XMLConfigurationException(XMLConfigurationException.NOT_SUPPORTED, propertyId);
 
342
        }
 
343
        fConfigUpdated = true;
 
344
        fEntityManager.setProperty(propertyId, value);
 
345
        fErrorReporter.setProperty(propertyId, value);
 
346
        fSchemaValidator.setProperty(propertyId, value);
 
347
        if (ENTITY_RESOLVER.equals(propertyId) || ERROR_HANDLER.equals(propertyId) || 
 
348
                SECURITY_MANAGER.equals(propertyId)) {
 
349
            fComponents.put(propertyId, value);
 
350
            return;
 
351
        }
 
352
        if (!fInitProperties.containsKey(propertyId)) {
 
353
            fInitProperties.put(propertyId, super.getProperty(propertyId));
 
354
        }
 
355
        super.setProperty(propertyId, value);
 
356
    }
 
357
    
 
358
    /**
 
359
     * Adds all of the component's recognized features and properties
 
360
     * to the list of default recognized features and properties, and
 
361
     * sets default values on the configuration for features and
 
362
     * properties which were previously absent from the configuration.
 
363
     *
 
364
     * @param component The component whose recognized features
 
365
     * and properties will be added to the configuration
 
366
     */
 
367
    public void addRecognizedParamsAndSetDefaults(XMLComponent component, XSGrammarPoolContainer grammarContainer) {
 
368
        
 
369
        // register component's recognized features
 
370
        final String[] recognizedFeatures = component.getRecognizedFeatures();
 
371
        addRecognizedFeatures(recognizedFeatures);
 
372
        
 
373
        // register component's recognized properties
 
374
        final String[] recognizedProperties = component.getRecognizedProperties();
 
375
        addRecognizedProperties(recognizedProperties);
 
376
 
 
377
        // set default values
 
378
        setFeatureDefaults(component, recognizedFeatures, grammarContainer);
 
379
        setPropertyDefaults(component, recognizedProperties);
 
380
    }
 
381
    
 
382
    /** Calls reset on each of the components owned by this component manager. **/
 
383
    public void reset() throws XNIException {
 
384
        fNamespaceContext.reset();
 
385
        fValidationManager.reset();
 
386
        fEntityManager.reset(this);
 
387
        fErrorReporter.reset(this);
 
388
        fSchemaValidator.reset(this);
 
389
        // Mark configuration as fixed.
 
390
        fConfigUpdated = false;
 
391
    }
 
392
    
 
393
    void setErrorHandler(ErrorHandler errorHandler) {
 
394
        fErrorHandler = errorHandler;
 
395
        setProperty(ERROR_HANDLER, (errorHandler != null) ? new ErrorHandlerWrapper(errorHandler) : 
 
396
                new ErrorHandlerWrapper(DraconianErrorHandler.getInstance()));
 
397
    }
 
398
    
 
399
    ErrorHandler getErrorHandler() {
 
400
        return fErrorHandler;
 
401
    }
 
402
    
 
403
    void setResourceResolver(LSResourceResolver resourceResolver) {
 
404
        fResourceResolver = resourceResolver;
 
405
        setProperty(ENTITY_RESOLVER, new DOMEntityResolverWrapper(resourceResolver));
 
406
    }
 
407
    
 
408
    public LSResourceResolver getResourceResolver() {
 
409
        return fResourceResolver;
 
410
    }
 
411
    
 
412
    /** Cleans out configuration, restoring it to its initial state. */
 
413
    void restoreInitialState() {
 
414
        fConfigUpdated = true;
 
415
        
 
416
        // Remove error resolver and error handler
 
417
        fComponents.put(ENTITY_RESOLVER, null);
 
418
        fComponents.put(ERROR_HANDLER, null);
 
419
        
 
420
        // Restore initial security manager
 
421
        fComponents.put(SECURITY_MANAGER, fInitSecurityManager);
 
422
        
 
423
        // Reset feature and property values to their initial values
 
424
        if (!fInitFeatures.isEmpty()) {
 
425
            Iterator iter = fInitFeatures.entrySet().iterator();
 
426
            while (iter.hasNext()) {
 
427
                Map.Entry entry = (Map.Entry) iter.next();
 
428
                String name = (String) entry.getKey();
 
429
                boolean value = ((Boolean) entry.getValue()).booleanValue();
 
430
                super.setFeature(name, value);
 
431
            }
 
432
            fInitFeatures.clear();
 
433
        }
 
434
        if (!fInitProperties.isEmpty()) {
 
435
            Iterator iter = fInitProperties.entrySet().iterator();
 
436
            while (iter.hasNext()) {
 
437
                Map.Entry entry = (Map.Entry) iter.next();
 
438
                String name = (String) entry.getKey();
 
439
                Object value = entry.getValue();
 
440
                super.setProperty(name, value);
 
441
            }
 
442
            fInitProperties.clear();
 
443
        }
 
444
    }
 
445
    
 
446
    /** Sets feature defaults for the given component on this configuration. */
 
447
    private void setFeatureDefaults(final XMLComponent component, 
 
448
            final String [] recognizedFeatures, XSGrammarPoolContainer grammarContainer) {
 
449
        if (recognizedFeatures != null) {
 
450
            for (int i = 0; i < recognizedFeatures.length; ++i) {
 
451
                String featureId = recognizedFeatures[i];
 
452
                Boolean state = grammarContainer.getFeature(featureId);
 
453
                if (state == null) {
 
454
                    state = component.getFeatureDefault(featureId);
 
455
                }
 
456
                if (state != null) {
 
457
                    // Do not overwrite values already set on the configuration.
 
458
                    if (!fFeatures.containsKey(featureId)) {
 
459
                        fFeatures.put(featureId, state);
 
460
                        // For newly added components who recognize this feature
 
461
                        // but did not offer a default value, we need to make
 
462
                        // sure these components will get an opportunity to read
 
463
                        // the value before parsing begins.
 
464
                        fConfigUpdated = true;
 
465
                    }
 
466
                }
 
467
            }
 
468
        }
 
469
    }
 
470
    
 
471
    /** Sets property defaults for the given component on this configuration. */
 
472
    private void setPropertyDefaults(final XMLComponent component, final String [] recognizedProperties) {
 
473
        if (recognizedProperties != null) {
 
474
            for (int i = 0; i < recognizedProperties.length; ++i) {
 
475
                String propertyId = recognizedProperties[i];
 
476
                Object value = component.getPropertyDefault(propertyId);
 
477
                if (value != null) {
 
478
                    // Do not overwrite values already set on the configuration.
 
479
                    if (!fProperties.containsKey(propertyId)) {
 
480
                        fProperties.put(propertyId, value);
 
481
                        // For newly added components who recognize this property
 
482
                        // but did not offer a default value, we need to make
 
483
                        // sure these components will get an opportunity to read
 
484
                        // the value before parsing begins.
 
485
                        fConfigUpdated = true;
 
486
                    }
 
487
                }
 
488
            }
 
489
        }
 
490
    }
 
491
    
 
492
} // XMLSchemaValidatorComponentManager
 
493
 
 
 
b'\\ No newline at end of file'