1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.xerces.parsers;
19
20 import java.io.IOException;
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.Locale;
24
25 import org.apache.xerces.impl.Constants;
26 import org.apache.xerces.impl.XML11DTDScannerImpl;
27 import org.apache.xerces.impl.XML11DocumentScannerImpl;
28 import org.apache.xerces.impl.XML11NSDocumentScannerImpl;
29 import org.apache.xerces.impl.XMLDTDScannerImpl;
30 import org.apache.xerces.impl.XMLDocumentScannerImpl;
31 import org.apache.xerces.impl.XMLEntityHandler;
32 import org.apache.xerces.impl.XMLEntityManager;
33 import org.apache.xerces.impl.XMLErrorReporter;
34 import org.apache.xerces.impl.XMLNSDocumentScannerImpl;
35 import org.apache.xerces.impl.XMLVersionDetector;
36 import org.apache.xerces.impl.dtd.XML11DTDProcessor;
37 import org.apache.xerces.impl.dtd.XML11DTDValidator;
38 import org.apache.xerces.impl.dtd.XML11NSDTDValidator;
39 import org.apache.xerces.impl.dtd.XMLDTDProcessor;
40 import org.apache.xerces.impl.dtd.XMLDTDValidator;
41 import org.apache.xerces.impl.dtd.XMLNSDTDValidator;
42 import org.apache.xerces.impl.dv.DTDDVFactory;
43 import org.apache.xerces.impl.msg.XMLMessageFormatter;
44 import org.apache.xerces.impl.validation.ValidationManager;
45 import org.apache.xerces.impl.xs.XMLSchemaValidator;
46 import org.apache.xerces.impl.xs.XSMessageFormatter;
47 import org.apache.xerces.util.ParserConfigurationSettings;
48 import org.apache.xerces.util.SymbolTable;
49 import org.apache.xerces.xni.XMLDTDContentModelHandler;
50 import org.apache.xerces.xni.XMLDTDHandler;
51 import org.apache.xerces.xni.XMLDocumentHandler;
52 import org.apache.xerces.xni.XMLLocator;
53 import org.apache.xerces.xni.XNIException;
54 import org.apache.xerces.xni.grammars.XMLGrammarPool;
55 import org.apache.xerces.xni.parser.XMLComponent;
56 import org.apache.xerces.xni.parser.XMLComponentManager;
57 import org.apache.xerces.xni.parser.XMLConfigurationException;
58 import org.apache.xerces.xni.parser.XMLDTDScanner;
59 import org.apache.xerces.xni.parser.XMLDocumentScanner;
60 import org.apache.xerces.xni.parser.XMLDocumentSource;
61 import org.apache.xerces.xni.parser.XMLEntityResolver;
62 import org.apache.xerces.xni.parser.XMLErrorHandler;
63 import org.apache.xerces.xni.parser.XMLInputSource;
64 import org.apache.xerces.xni.parser.XMLPullParserConfiguration;
65
66 /**
67 * This class is the configuration used to parse XML 1.0 and XML 1.1 documents.
68 *
69 * @author Elena Litani, IBM
70 * @author Neil Graham, IBM
71 * @author Michael Glavassevich, IBM
72 *
73 * @version $Id: XML11Configuration.java 548192 2007-06-18 03:34:19Z mrglavas $
74 */
75 public class XML11Configuration extends ParserConfigurationSettings
76 implements XMLPullParserConfiguration, XML11Configurable {
77
78 //
79 // Constants
80 //
81 protected final static String XML11_DATATYPE_VALIDATOR_FACTORY =
82 "org.apache.xerces.impl.dv.dtd.XML11DTDDVFactoryImpl";
83
84 // feature identifiers
85
86 /** Feature identifier: warn on duplicate attribute definition. */
87 protected static final String WARN_ON_DUPLICATE_ATTDEF =
88 Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE;
89
90 /** Feature identifier: warn on duplicate entity definition. */
91 protected static final String WARN_ON_DUPLICATE_ENTITYDEF =
92 Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE;
93
94 /** Feature identifier: warn on undeclared element definition. */
95 protected static final String WARN_ON_UNDECLARED_ELEMDEF =
96 Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE;
97
98 /** Feature identifier: allow Java encodings. */
99 protected static final String ALLOW_JAVA_ENCODINGS =
100 Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE;
101
102 /** Feature identifier: continue after fatal error. */
103 protected static final String CONTINUE_AFTER_FATAL_ERROR =
104 Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
105
106 /** Feature identifier: load external DTD. */
107 protected static final String LOAD_EXTERNAL_DTD =
108 Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE;
109
110 /** Feature identifier: notify built-in refereces. */
111 protected static final String NOTIFY_BUILTIN_REFS =
112 Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_BUILTIN_REFS_FEATURE;
113
114 /** Feature identifier: notify character refereces. */
115 protected static final String NOTIFY_CHAR_REFS =
116 Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_CHAR_REFS_FEATURE;
117
118 /** Feature identifier: expose schema normalized value */
119 protected static final String NORMALIZE_DATA =
120 Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_NORMALIZED_VALUE;
121
122 /** Feature identifier: send element default value via characters() */
123 protected static final String SCHEMA_ELEMENT_DEFAULT =
124 Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_ELEMENT_DEFAULT;
125
126 /** Feature identifier: augment PSVI */
127 protected static final String SCHEMA_AUGMENT_PSVI =
128 Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_AUGMENT_PSVI;
129
130 /** feature identifier: XML Schema validation */
131 protected static final String XMLSCHEMA_VALIDATION =
132 Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE;
133
134 /** feature identifier: XML Schema validation -- full checking */
135 protected static final String XMLSCHEMA_FULL_CHECKING =
136 Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_FULL_CHECKING;
137
138 /** Feature: generate synthetic annotations */
139 protected static final String GENERATE_SYNTHETIC_ANNOTATIONS =
140 Constants.XERCES_FEATURE_PREFIX + Constants.GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE;
141
142 /** Feature identifier: validate annotations */
143 protected static final String VALIDATE_ANNOTATIONS =
144 Constants.XERCES_FEATURE_PREFIX + Constants.VALIDATE_ANNOTATIONS_FEATURE;
145
146 /** Feature identifier: honour all schemaLocations */
147 protected static final String HONOUR_ALL_SCHEMALOCATIONS =
148 Constants.XERCES_FEATURE_PREFIX + Constants.HONOUR_ALL_SCHEMALOCATIONS_FEATURE;
149
150 /** Feature identifier: use grammar pool only */
151 protected static final String USE_GRAMMAR_POOL_ONLY =
152 Constants.XERCES_FEATURE_PREFIX + Constants.USE_GRAMMAR_POOL_ONLY_FEATURE;
153
154 // feature identifiers
155
156 /** Feature identifier: validation. */
157 protected static final String VALIDATION =
158 Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
159
160 /** Feature identifier: namespaces. */
161 protected static final String NAMESPACES =
162 Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
163
164 /** Feature identifier: external general entities. */
165 protected static final String EXTERNAL_GENERAL_ENTITIES =
166 Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_GENERAL_ENTITIES_FEATURE;
167
168 /** Feature identifier: external parameter entities. */
169 protected static final String EXTERNAL_PARAMETER_ENTITIES =
170 Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_PARAMETER_ENTITIES_FEATURE;
171
172 /** Feature identifier: whether to ignore xsi:type attributes until a global element declaration is encountered */
173 protected static final String IGNORE_XSI_TYPE =
174 Constants.XERCES_FEATURE_PREFIX + Constants.IGNORE_XSI_TYPE_FEATURE;
175
176 /** Feature identifier: whether to ignore ID/IDREF errors */
177 protected static final String ID_IDREF_CHECKING =
178 Constants.XERCES_FEATURE_PREFIX + Constants.ID_IDREF_CHECKING_FEATURE;
179
180 /** Feature identifier: whether to ignore unparsed entity errors */
181 protected static final String UNPARSED_ENTITY_CHECKING =
182 Constants.XERCES_FEATURE_PREFIX + Constants.UNPARSED_ENTITY_CHECKING_FEATURE;
183
184 /** Feature identifier: whether to ignore identity constraint errors */
185 protected static final String IDENTITY_CONSTRAINT_CHECKING =
186 Constants.XERCES_FEATURE_PREFIX + Constants.IDC_CHECKING_FEATURE;
187
188
189
190 // property identifiers
191
192
193 /** Property identifier: xml string. */
194 protected static final String XML_STRING =
195 Constants.SAX_PROPERTY_PREFIX + Constants.XML_STRING_PROPERTY;
196
197 /** Property identifier: symbol table. */
198 protected static final String SYMBOL_TABLE =
199 Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
200
201 /** Property identifier: error handler. */
202 protected static final String ERROR_HANDLER =
203 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
204
205 /** Property identifier: entity resolver. */
206 protected static final String ENTITY_RESOLVER =
207 Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
208
209
210 /** Property identifier: XML Schema validator. */
211 protected static final String SCHEMA_VALIDATOR =
212 Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY;
213
214 /** Property identifier: schema location. */
215 protected static final String SCHEMA_LOCATION =
216 Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_LOCATION;
217
218 /** Property identifier: no namespace schema location. */
219 protected static final String SCHEMA_NONS_LOCATION =
220 Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_NONS_LOCATION;
221
222 // property identifiers
223
224 /** Property identifier: error reporter. */
225 protected static final String ERROR_REPORTER =
226 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
227
228 /** Property identifier: entity manager. */
229 protected static final String ENTITY_MANAGER =
230 Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
231
232 /** Property identifier document scanner: */
233 protected static final String DOCUMENT_SCANNER =
234 Constants.XERCES_PROPERTY_PREFIX + Constants.DOCUMENT_SCANNER_PROPERTY;
235
236 /** Property identifier: DTD scanner. */
237 protected static final String DTD_SCANNER =
238 Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_SCANNER_PROPERTY;
239
240 /** Property identifier: grammar pool. */
241 protected static final String XMLGRAMMAR_POOL =
242 Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
243
244 /** Property identifier: DTD loader. */
245 protected static final String DTD_PROCESSOR =
246 Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_PROCESSOR_PROPERTY;
247
248 /** Property identifier: DTD validator. */
249 protected static final String DTD_VALIDATOR =
250 Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY;
251
252 /** Property identifier: namespace binder. */
253 protected static final String NAMESPACE_BINDER =
254 Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_BINDER_PROPERTY;
255
256 /** Property identifier: datatype validator factory. */
257 protected static final String DATATYPE_VALIDATOR_FACTORY =
258 Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY;
259
260 protected static final String VALIDATION_MANAGER =
261 Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY;
262
263 /** Property identifier: JAXP schema language / DOM schema-type. */
264 protected static final String JAXP_SCHEMA_LANGUAGE =
265 Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE;
266
267 /** Property identifier: JAXP schema source/ DOM schema-location. */
268 protected static final String JAXP_SCHEMA_SOURCE =
269 Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE;
270
271 /** Property identifier: root type definition. */
272 protected static final String ROOT_TYPE_DEF =
273 Constants.XERCES_PROPERTY_PREFIX + Constants.ROOT_TYPE_DEFINITION_PROPERTY;
274
275 // debugging
276
277 /** Set to true and recompile to print exception stack trace. */
278 protected static final boolean PRINT_EXCEPTION_STACK_TRACE = false;
279
280 //
281 // Data
282 //
283
284 protected SymbolTable fSymbolTable;
285 protected XMLInputSource fInputSource;
286 protected ValidationManager fValidationManager;
287 protected XMLVersionDetector fVersionDetector;
288 protected XMLLocator fLocator;
289 protected Locale fLocale;
290
291 /** XML 1.0 Components. */
292 protected ArrayList fComponents;
293
294 /** XML 1.1. Components. */
295 protected ArrayList fXML11Components = null;
296
297 /** Common components: XMLEntityManager, XMLErrorReporter, XMLSchemaValidator */
298 protected ArrayList fCommonComponents = null;
299
300 /** The document handler. */
301 protected XMLDocumentHandler fDocumentHandler;
302
303 /** The DTD handler. */
304 protected XMLDTDHandler fDTDHandler;
305
306 /** The DTD content model handler. */
307 protected XMLDTDContentModelHandler fDTDContentModelHandler;
308
309 /** Last component in the document pipeline */
310 protected XMLDocumentSource fLastComponent;
311
312 /**
313 * True if a parse is in progress. This state is needed because
314 * some features/properties cannot be set while parsing (e.g.
315 * validation and namespaces).
316 */
317 protected boolean fParseInProgress = false;
318
319 /** fConfigUpdated is set to true if there has been any change to the configuration settings,
320 * i.e a feature or a property was changed.
321 */
322 protected boolean fConfigUpdated = false;
323
324 //
325 // XML 1.0 components
326 //
327
328 /** The XML 1.0 Datatype validator factory. */
329 protected DTDDVFactory fDatatypeValidatorFactory;
330
331 /** The XML 1.0 Document scanner that does namespace binding. */
332 protected XMLNSDocumentScannerImpl fNamespaceScanner;
333 /** The XML 1.0 Non-namespace implementation of scanner */
334 protected XMLDocumentScannerImpl fNonNSScanner;
335 /** The XML 1.0 DTD Validator: binds namespaces */
336 protected XMLDTDValidator fDTDValidator;
337 /** The XML 1.0 DTD Validator that does not bind namespaces */
338 protected XMLDTDValidator fNonNSDTDValidator;
339 /** The XML 1.0 DTD scanner. */
340 protected XMLDTDScanner fDTDScanner;
341 /** The XML 1.0 DTD Processor . */
342 protected XMLDTDProcessor fDTDProcessor;
343
344 //
345 // XML 1.1 components
346 //
347
348 /** The XML 1.1 datatype factory. **/
349 protected DTDDVFactory fXML11DatatypeFactory = null;
350
351 /** The XML 1.1 document scanner that does namespace binding. **/
352 protected XML11NSDocumentScannerImpl fXML11NSDocScanner = null;
353
354 /** The XML 1.1 document scanner that does not do namespace binding. **/
355 protected XML11DocumentScannerImpl fXML11DocScanner = null;
356
357 /** The XML 1.1 DTD validator that does namespace binding. **/
358 protected XML11NSDTDValidator fXML11NSDTDValidator = null;
359
360 /** The XML 1.1 DTD validator that does not do namespace binding. **/
361 protected XML11DTDValidator fXML11DTDValidator = null;
362
363 /** The XML 1.1 DTD scanner. **/
364 protected XML11DTDScannerImpl fXML11DTDScanner = null;
365 /** The XML 1.1 DTD processor. **/
366 protected XML11DTDProcessor fXML11DTDProcessor = null;
367
368 //
369 // Common components
370 //
371
372 /** Grammar pool. */
373 protected XMLGrammarPool fGrammarPool;
374
375 /** Error reporter. */
376 protected XMLErrorReporter fErrorReporter;
377
378 /** Entity manager. */
379 protected XMLEntityManager fEntityManager;
380
381 /** XML Schema Validator. */
382 protected XMLSchemaValidator fSchemaValidator;
383
384 /** Current scanner */
385 protected XMLDocumentScanner fCurrentScanner;
386 /** Current Datatype validator factory. */
387 protected DTDDVFactory fCurrentDVFactory;
388 /** Current DTD scanner. */
389 protected XMLDTDScanner fCurrentDTDScanner;
390
391 /** Flag indiciating whether XML11 components have been initialized. */
392 private boolean f11Initialized = false;
393
394 //
395 // Constructors
396 //
397
398 /** Default constructor. */
399 public XML11Configuration() {
400 this(null, null, null);
401 } // <init>()
402
403 /**
404 * Constructs a parser configuration using the specified symbol table.
405 *
406 * @param symbolTable The symbol table to use.
407 */
408 public XML11Configuration(SymbolTable symbolTable) {
409 this(symbolTable, null, null);
410 } // <init>(SymbolTable)
411
412 /**
413 * Constructs a parser configuration using the specified symbol table and
414 * grammar pool.
415 * <p>
416 * <strong>REVISIT:</strong>
417 * Grammar pool will be updated when the new validation engine is
418 * implemented.
419 *
420 * @param symbolTable The symbol table to use.
421 * @param grammarPool The grammar pool to use.
422 */
423 public XML11Configuration(SymbolTable symbolTable, XMLGrammarPool grammarPool) {
424 this(symbolTable, grammarPool, null);
425 } // <init>(SymbolTable,XMLGrammarPool)
426
427 /**
428 * Constructs a parser configuration using the specified symbol table,
429 * grammar pool, and parent settings.
430 * <p>
431 * <strong>REVISIT:</strong>
432 * Grammar pool will be updated when the new validation engine is
433 * implemented.
434 *
435 * @param symbolTable The symbol table to use.
436 * @param grammarPool The grammar pool to use.
437 * @param parentSettings The parent settings.
438 */
439 public XML11Configuration(
440 SymbolTable symbolTable,
441 XMLGrammarPool grammarPool,
442 XMLComponentManager parentSettings) {
443
444 super(parentSettings);
445
446 // create a vector to hold all the components in use
447 // XML 1.0 specialized components
448 fComponents = new ArrayList();
449 // XML 1.1 specialized components
450 fXML11Components = new ArrayList();
451 // Common components for XML 1.1. and XML 1.0
452 fCommonComponents = new ArrayList();
453
454 // create storage for recognized features and properties
455 fRecognizedFeatures = new ArrayList();
456 fRecognizedProperties = new ArrayList();
457
458 // create table for features and properties
459 fFeatures = new HashMap();
460 fProperties = new HashMap();
461
462 // add default recognized features
463 final String[] recognizedFeatures =
464 {
465 CONTINUE_AFTER_FATAL_ERROR, LOAD_EXTERNAL_DTD, // from XMLDTDScannerImpl
466 VALIDATION,
467 NAMESPACES,
468 NORMALIZE_DATA, SCHEMA_ELEMENT_DEFAULT, SCHEMA_AUGMENT_PSVI,
469 GENERATE_SYNTHETIC_ANNOTATIONS, VALIDATE_ANNOTATIONS,
470 HONOUR_ALL_SCHEMALOCATIONS, IGNORE_XSI_TYPE,
471 ID_IDREF_CHECKING, IDENTITY_CONSTRAINT_CHECKING,
472 UNPARSED_ENTITY_CHECKING, USE_GRAMMAR_POOL_ONLY,
473 // NOTE: These shouldn't really be here but since the XML Schema
474 // validator is constructed dynamically, its recognized
475 // features might not have been set and it would cause a
476 // not-recognized exception to be thrown. -Ac
477 XMLSCHEMA_VALIDATION, XMLSCHEMA_FULL_CHECKING,
478 EXTERNAL_GENERAL_ENTITIES,
479 EXTERNAL_PARAMETER_ENTITIES,
480 PARSER_SETTINGS,
481
482 };
483 addRecognizedFeatures(recognizedFeatures);
484 // set state for default features
485 fFeatures.put(VALIDATION, Boolean.FALSE);
486 fFeatures.put(NAMESPACES, Boolean.TRUE);
487 fFeatures.put(EXTERNAL_GENERAL_ENTITIES, Boolean.TRUE);
488 fFeatures.put(EXTERNAL_PARAMETER_ENTITIES, Boolean.TRUE);
489 fFeatures.put(CONTINUE_AFTER_FATAL_ERROR, Boolean.FALSE);
490 fFeatures.put(LOAD_EXTERNAL_DTD, Boolean.TRUE);
491 fFeatures.put(SCHEMA_ELEMENT_DEFAULT, Boolean.TRUE);
492 fFeatures.put(NORMALIZE_DATA, Boolean.TRUE);
493 fFeatures.put(SCHEMA_AUGMENT_PSVI, Boolean.TRUE);
494 fFeatures.put(GENERATE_SYNTHETIC_ANNOTATIONS, Boolean.FALSE);
495 fFeatures.put(VALIDATE_ANNOTATIONS, Boolean.FALSE);
496 fFeatures.put(HONOUR_ALL_SCHEMALOCATIONS, Boolean.FALSE);
497 fFeatures.put(IGNORE_XSI_TYPE, Boolean.FALSE);
498 fFeatures.put(ID_IDREF_CHECKING, Boolean.TRUE);
499 fFeatures.put(IDENTITY_CONSTRAINT_CHECKING, Boolean.TRUE);
500 fFeatures.put(UNPARSED_ENTITY_CHECKING, Boolean.TRUE);
501 fFeatures.put(USE_GRAMMAR_POOL_ONLY, Boolean.FALSE);
502 fFeatures.put(PARSER_SETTINGS, Boolean.TRUE);
503
504 // add default recognized properties
505 final String[] recognizedProperties =
506 {
507 SYMBOL_TABLE,
508 ERROR_HANDLER,
509 ENTITY_RESOLVER,
510 ERROR_REPORTER,
511 ENTITY_MANAGER,
512 DOCUMENT_SCANNER,
513 DTD_SCANNER,
514 DTD_PROCESSOR,
515 DTD_VALIDATOR,
516 DATATYPE_VALIDATOR_FACTORY,
517 VALIDATION_MANAGER,
518 SCHEMA_VALIDATOR,
519 XML_STRING,
520 XMLGRAMMAR_POOL,
521 JAXP_SCHEMA_SOURCE,
522 JAXP_SCHEMA_LANGUAGE,
523 // NOTE: These shouldn't really be here but since the XML Schema
524 // validator is constructed dynamically, its recognized
525 // properties might not have been set and it would cause a
526 // not-recognized exception to be thrown. -Ac
527 SCHEMA_LOCATION,
528 SCHEMA_NONS_LOCATION,
529 ROOT_TYPE_DEF,
530 };
531 addRecognizedProperties(recognizedProperties);
532
533 if (symbolTable == null) {
534 symbolTable = new SymbolTable();
535 }
536 fSymbolTable = symbolTable;
537 fProperties.put(SYMBOL_TABLE, fSymbolTable);
538
539 fGrammarPool = grammarPool;
540 if (fGrammarPool != null) {
541 fProperties.put(XMLGRAMMAR_POOL, fGrammarPool);
542 }
543
544 fEntityManager = new XMLEntityManager();
545 fProperties.put(ENTITY_MANAGER, fEntityManager);
546 addCommonComponent(fEntityManager);
547
548 fErrorReporter = new XMLErrorReporter();
549 fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
550 fProperties.put(ERROR_REPORTER, fErrorReporter);
551 addCommonComponent(fErrorReporter);
552
553 fNamespaceScanner = new XMLNSDocumentScannerImpl();
554 fProperties.put(DOCUMENT_SCANNER, fNamespaceScanner);
555 addComponent((XMLComponent) fNamespaceScanner);
556
557 fDTDScanner = new XMLDTDScannerImpl();
558 fProperties.put(DTD_SCANNER, fDTDScanner);
559 addComponent((XMLComponent) fDTDScanner);
560
561 fDTDProcessor = new XMLDTDProcessor();
562 fProperties.put(DTD_PROCESSOR, fDTDProcessor);
563 addComponent(fDTDProcessor);
564
565 fDTDValidator = new XMLNSDTDValidator();
566 fProperties.put(DTD_VALIDATOR, fDTDValidator);
567 addComponent(fDTDValidator);
568
569 fDatatypeValidatorFactory = DTDDVFactory.getInstance();
570 fProperties.put(DATATYPE_VALIDATOR_FACTORY, fDatatypeValidatorFactory);
571
572 fValidationManager = new ValidationManager();
573 fProperties.put(VALIDATION_MANAGER, fValidationManager);
574
575 fVersionDetector = new XMLVersionDetector();
576
577 // add message formatters
578 if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
579 XMLMessageFormatter xmft = new XMLMessageFormatter();
580 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft);
581 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft);
582 }
583
584 // set locale
585 try {
586 setLocale(Locale.getDefault());
587 } catch (XNIException e) {
588 // do nothing
589 // REVISIT: What is the right thing to do? -Ac
590 }
591
592 fConfigUpdated = false;
593
594 } // <init>(SymbolTable,XMLGrammarPool)
595
596 //
597 // Public methods
598 //
599 /**
600 * Sets the input source for the document to parse.
601 *
602 * @param inputSource The document's input source.
603 *
604 * @exception XMLConfigurationException Thrown if there is a
605 * configuration error when initializing the
606 * parser.
607 * @exception IOException Thrown on I/O error.
608 *
609 * @see #parse(boolean)
610 */
611 public void setInputSource(XMLInputSource inputSource)
612 throws XMLConfigurationException, IOException {
613
614 // REVISIT: this method used to reset all the components and
615 // construct the pipeline. Now reset() is called
616 // in parse (boolean) just before we parse the document
617 // Should this method still throw exceptions..?
618
619 fInputSource = inputSource;
620
621 } // setInputSource(XMLInputSource)
622
623 /**
624 * Set the locale to use for messages.
625 *
626 * @param locale The locale object to use for localization of messages.
627 *
628 * @exception XNIException Thrown if the parser does not support the
629 * specified locale.
630 */
631 public void setLocale(Locale locale) throws XNIException {
632 fLocale = locale;
633 fErrorReporter.setLocale(locale);
634 } // setLocale(Locale)
635 /**
636 * Sets the document handler on the last component in the pipeline
637 * to receive information about the document.
638 *
639 * @param documentHandler The document handler.
640 */
641 public void setDocumentHandler(XMLDocumentHandler documentHandler) {
642 fDocumentHandler = documentHandler;
643 if (fLastComponent != null) {
644 fLastComponent.setDocumentHandler(fDocumentHandler);
645 if (fDocumentHandler !=null){
646 fDocumentHandler.setDocumentSource(fLastComponent);
647 }
648 }
649 } // setDocumentHandler(XMLDocumentHandler)
650
651 /** Returns the registered document handler. */
652 public XMLDocumentHandler getDocumentHandler() {
653 return fDocumentHandler;
654 } // getDocumentHandler():XMLDocumentHandler
655
656 /**
657 * Sets the DTD handler.
658 *
659 * @param dtdHandler The DTD handler.
660 */
661 public void setDTDHandler(XMLDTDHandler dtdHandler) {
662 fDTDHandler = dtdHandler;
663 } // setDTDHandler(XMLDTDHandler)
664
665 /** Returns the registered DTD handler. */
666 public XMLDTDHandler getDTDHandler() {
667 return fDTDHandler;
668 } // getDTDHandler():XMLDTDHandler
669
670 /**
671 * Sets the DTD content model handler.
672 *
673 * @param handler The DTD content model handler.
674 */
675 public void setDTDContentModelHandler(XMLDTDContentModelHandler handler) {
676 fDTDContentModelHandler = handler;
677 } // setDTDContentModelHandler(XMLDTDContentModelHandler)
678
679 /** Returns the registered DTD content model handler. */
680 public XMLDTDContentModelHandler getDTDContentModelHandler() {
681 return fDTDContentModelHandler;
682 } // getDTDContentModelHandler():XMLDTDContentModelHandler
683
684 /**
685 * Sets the resolver used to resolve external entities. The EntityResolver
686 * interface supports resolution of public and system identifiers.
687 *
688 * @param resolver The new entity resolver. Passing a null value will
689 * uninstall the currently installed resolver.
690 */
691 public void setEntityResolver(XMLEntityResolver resolver) {
692 fProperties.put(ENTITY_RESOLVER, resolver);
693 } // setEntityResolver(XMLEntityResolver)
694
695 /**
696 * Return the current entity resolver.
697 *
698 * @return The current entity resolver, or null if none
699 * has been registered.
700 * @see #setEntityResolver
701 */
702 public XMLEntityResolver getEntityResolver() {
703 return (XMLEntityResolver)fProperties.get(ENTITY_RESOLVER);
704 } // getEntityResolver():XMLEntityResolver
705
706 /**
707 * Allow an application to register an error event handler.
708 *
709 * <p>If the application does not register an error handler, all
710 * error events reported by the SAX parser will be silently
711 * ignored; however, normal processing may not continue. It is
712 * highly recommended that all SAX applications implement an
713 * error handler to avoid unexpected bugs.</p>
714 *
715 * <p>Applications may register a new or different handler in the
716 * middle of a parse, and the SAX parser must begin using the new
717 * handler immediately.</p>
718 *
719 * @param errorHandler The error handler.
720 * @exception java.lang.NullPointerException If the handler
721 * argument is null.
722 * @see #getErrorHandler
723 */
724 public void setErrorHandler(XMLErrorHandler errorHandler) {
725 fProperties.put(ERROR_HANDLER, errorHandler);
726 } // setErrorHandler(XMLErrorHandler)
727
728 /**
729 * Return the current error handler.
730 *
731 * @return The current error handler, or null if none
732 * has been registered.
733 * @see #setErrorHandler
734 */
735 public XMLErrorHandler getErrorHandler() {
736 // REVISIT: Should this be a property?
737 return (XMLErrorHandler)fProperties.get(ERROR_HANDLER);
738 } // getErrorHandler():XMLErrorHandler
739
740
741 /**
742 * If the application decides to terminate parsing before the xml document
743 * is fully parsed, the application should call this method to free any
744 * resource allocated during parsing. For example, close all opened streams.
745 */
746 public void cleanup() {
747 fEntityManager.closeReaders();
748 }
749
750 /**
751 * Parses the specified input source.
752 *
753 * @param source The input source.
754 *
755 * @exception XNIException Throws exception on XNI error.
756 * @exception java.io.IOException Throws exception on i/o error.
757 */
758 public void parse(XMLInputSource source) throws XNIException, IOException {
759
760 if (fParseInProgress) {
761 // REVISIT - need to add new error message
762 throw new XNIException("FWK005 parse may not be called while parsing.");
763 }
764 fParseInProgress = true;
765
766 try {
767 setInputSource(source);
768 parse(true);
769 } catch (XNIException ex) {
770 if (PRINT_EXCEPTION_STACK_TRACE)
771 ex.printStackTrace();
772 throw ex;
773 } catch (IOException ex) {
774 if (PRINT_EXCEPTION_STACK_TRACE)
775 ex.printStackTrace();
776 throw ex;
777 } catch (RuntimeException ex) {
778 if (PRINT_EXCEPTION_STACK_TRACE)
779 ex.printStackTrace();
780 throw ex;
781 } catch (Exception ex) {
782 if (PRINT_EXCEPTION_STACK_TRACE)
783 ex.printStackTrace();
784 throw new XNIException(ex);
785 } finally {
786 fParseInProgress = false;
787 // close all streams opened by xerces
788 this.cleanup();
789 }
790
791 } // parse(InputSource)
792
793 public boolean parse(boolean complete) throws XNIException, IOException {
794 //
795 // reset and configure pipeline and set InputSource.
796 if (fInputSource != null) {
797 try {
798 fValidationManager.reset();
799 fVersionDetector.reset(this);
800 resetCommon();
801
802 short version = fVersionDetector.determineDocVersion(fInputSource);
803 // XML 1.0
804 if (version == Constants.XML_VERSION_1_0) {
805 configurePipeline();
806 reset();
807 }
808 // XML 1.1
809 else if (version == Constants.XML_VERSION_1_1) {
810 initXML11Components();
811 configureXML11Pipeline();
812 resetXML11();
813 }
814 // Unrecoverable error reported during version detection
815 else {
816 return false;
817 }
818
819 // mark configuration as fixed
820 fConfigUpdated = false;
821
822 // resets and sets the pipeline.
823 fVersionDetector.startDocumentParsing((XMLEntityHandler) fCurrentScanner, version);
824 fInputSource = null;
825 } catch (XNIException ex) {
826 if (PRINT_EXCEPTION_STACK_TRACE)
827 ex.printStackTrace();
828 throw ex;
829 } catch (IOException ex) {
830 if (PRINT_EXCEPTION_STACK_TRACE)
831 ex.printStackTrace();
832 throw ex;
833 } catch (RuntimeException ex) {
834 if (PRINT_EXCEPTION_STACK_TRACE)
835 ex.printStackTrace();
836 throw ex;
837 } catch (Exception ex) {
838 if (PRINT_EXCEPTION_STACK_TRACE)
839 ex.printStackTrace();
840 throw new XNIException(ex);
841 }
842 }
843
844 try {
845 return fCurrentScanner.scanDocument(complete);
846 } catch (XNIException ex) {
847 if (PRINT_EXCEPTION_STACK_TRACE)
848 ex.printStackTrace();
849 throw ex;
850 } catch (IOException ex) {
851 if (PRINT_EXCEPTION_STACK_TRACE)
852 ex.printStackTrace();
853 throw ex;
854 } catch (RuntimeException ex) {
855 if (PRINT_EXCEPTION_STACK_TRACE)
856 ex.printStackTrace();
857 throw ex;
858 } catch (Exception ex) {
859 if (PRINT_EXCEPTION_STACK_TRACE)
860 ex.printStackTrace();
861 throw new XNIException(ex);
862 }
863
864 } // parse(boolean):boolean
865
866 /**
867 * Returns the state of a feature.
868 *
869 * @param featureId The feature identifier.
870 * @return true if the feature is supported
871 *
872 * @throws XMLConfigurationException Thrown for configuration error.
873 * In general, components should
874 * only throw this exception if
875 * it is <strong>really</strong>
876 * a critical error.
877 */
878 public boolean getFeature(String featureId)
879 throws XMLConfigurationException {
880 // make this feature special
881 if (featureId.equals(PARSER_SETTINGS)){
882 return fConfigUpdated;
883 }
884 return super.getFeature(featureId);
885
886 } // getFeature(String):boolean
887
888 /**
889 * Set the state of a feature.
890 *
891 * Set the state of any feature in a SAX2 parser. The parser
892 * might not recognize the feature, and if it does recognize
893 * it, it might not be able to fulfill the request.
894 *
895 * @param featureId The unique identifier (URI) of the feature.
896 * @param state The requested state of the feature (true or false).
897 *
898 * @exception org.apache.xerces.xni.parser.XMLConfigurationException If the
899 * requested feature is not known.
900 */
901 public void setFeature(String featureId, boolean state)
902 throws XMLConfigurationException {
903 fConfigUpdated = true;
904 // forward to every XML 1.0 component
905 int count = fComponents.size();
906 for (int i = 0; i < count; i++) {
907 XMLComponent c = (XMLComponent) fComponents.get(i);
908 c.setFeature(featureId, state);
909 }
910 // forward it to common components
911 count = fCommonComponents.size();
912 for (int i = 0; i < count; i++) {
913 XMLComponent c = (XMLComponent) fCommonComponents.get(i);
914 c.setFeature(featureId, state);
915 }
916
917 // forward to every XML 1.1 component
918 count = fXML11Components.size();
919 for (int i = 0; i < count; i++) {
920 XMLComponent c = (XMLComponent) fXML11Components.get(i);
921 try{
922 c.setFeature(featureId, state);
923 }
924 catch (Exception e){
925 // no op
926 }
927 }
928 // save state if noone "objects"
929 super.setFeature(featureId, state);
930
931 } // setFeature(String,boolean)
932
933 /**
934 * setProperty
935 *
936 * @param propertyId
937 * @param value
938 */
939 public void setProperty(String propertyId, Object value)
940 throws XMLConfigurationException {
941 fConfigUpdated = true;
942 // forward to every XML 1.0 component
943 int count = fComponents.size();
944 for (int i = 0; i < count; i++) {
945 XMLComponent c = (XMLComponent) fComponents.get(i);
946 c.setProperty(propertyId, value);
947 }
948 // forward it to every common Component
949 count = fCommonComponents.size();
950 for (int i = 0; i < count; i++) {
951 XMLComponent c = (XMLComponent) fCommonComponents.get(i);
952 c.setProperty(propertyId, value);
953 }
954 // forward it to every XML 1.1 component
955 count = fXML11Components.size();
956 for (int i = 0; i < count; i++) {
957 XMLComponent c = (XMLComponent) fXML11Components.get(i);
958 try{
959 c.setProperty(propertyId, value);
960 }
961 catch (Exception e){
962 // ignore it
963 }
964 }
965
966 // store value if noone "objects"
967 super.setProperty(propertyId, value);
968
969 } // setProperty(String,Object)
970
971
972 /** Returns the locale. */
973 public Locale getLocale() {
974 return fLocale;
975 } // getLocale():Locale
976
977 /**
978 * reset all XML 1.0 components before parsing and namespace context
979 */
980 protected void reset() throws XNIException {
981 int count = fComponents.size();
982 for (int i = 0; i < count; i++) {
983 XMLComponent c = (XMLComponent) fComponents.get(i);
984 c.reset(this);
985 }
986
987 } // reset()
988
989 /**
990 * reset all common components before parsing
991 */
992 protected void resetCommon() throws XNIException {
993 // reset common components
994 int count = fCommonComponents.size();
995 for (int i = 0; i < count; i++) {
996 XMLComponent c = (XMLComponent) fCommonComponents.get(i);
997 c.reset(this);
998 }
999
1000 } // resetCommon()
1001
1002
1003 /**
1004 * reset all components before parsing and namespace context
1005 */
1006 protected void resetXML11() throws XNIException {
1007 // reset every component
1008 int count = fXML11Components.size();
1009 for (int i = 0; i < count; i++) {
1010 XMLComponent c = (XMLComponent) fXML11Components.get(i);
1011 c.reset(this);
1012 }
1013
1014 } // resetXML11()
1015
1016
1017 /**
1018 * Configures the XML 1.1 pipeline.
1019 * Note: this method also resets the new XML11 components.
1020 */
1021 protected void configureXML11Pipeline() {
1022 if (fCurrentDVFactory != fXML11DatatypeFactory) {
1023 fCurrentDVFactory = fXML11DatatypeFactory;
1024 setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory);
1025 }
1026 if (fCurrentDTDScanner != fXML11DTDScanner) {
1027 fCurrentDTDScanner = fXML11DTDScanner;
1028 setProperty(DTD_SCANNER, fCurrentDTDScanner);
1029 setProperty(DTD_PROCESSOR, fXML11DTDProcessor);
1030 }
1031
1032 fXML11DTDScanner.setDTDHandler(fXML11DTDProcessor);
1033 fXML11DTDProcessor.setDTDSource(fXML11DTDScanner);
1034 fXML11DTDProcessor.setDTDHandler(fDTDHandler);
1035 if (fDTDHandler != null) {
1036 fDTDHandler.setDTDSource(fXML11DTDProcessor);
1037 }
1038
1039 fXML11DTDScanner.setDTDContentModelHandler(fXML11DTDProcessor);
1040 fXML11DTDProcessor.setDTDContentModelSource(fXML11DTDScanner);
1041 fXML11DTDProcessor.setDTDContentModelHandler(fDTDContentModelHandler);
1042 if (fDTDContentModelHandler != null) {
1043 fDTDContentModelHandler.setDTDContentModelSource(fXML11DTDProcessor);
1044 }
1045
1046 // setup XML 1.1 document pipeline
1047 if (fFeatures.get(NAMESPACES) == Boolean.TRUE) {
1048 if (fCurrentScanner != fXML11NSDocScanner) {
1049 fCurrentScanner = fXML11NSDocScanner;
1050 setProperty(DOCUMENT_SCANNER, fXML11NSDocScanner);
1051 setProperty(DTD_VALIDATOR, fXML11NSDTDValidator);
1052 }
1053
1054 fXML11NSDocScanner.setDTDValidator(fXML11NSDTDValidator);
1055 fXML11NSDocScanner.setDocumentHandler(fXML11NSDTDValidator);
1056 fXML11NSDTDValidator.setDocumentSource(fXML11NSDocScanner);
1057 fXML11NSDTDValidator.setDocumentHandler(fDocumentHandler);
1058
1059 if (fDocumentHandler != null) {
1060 fDocumentHandler.setDocumentSource(fXML11NSDTDValidator);
1061 }
1062 fLastComponent = fXML11NSDTDValidator;
1063
1064 } else {
1065 // create components
1066 if (fXML11DocScanner == null) {
1067 // non namespace document pipeline
1068 fXML11DocScanner = new XML11DocumentScannerImpl();
1069 addXML11Component(fXML11DocScanner);
1070 fXML11DTDValidator = new XML11DTDValidator();
1071 addXML11Component(fXML11DTDValidator);
1072 }
1073 if (fCurrentScanner != fXML11DocScanner) {
1074 fCurrentScanner = fXML11DocScanner;
1075 setProperty(DOCUMENT_SCANNER, fXML11DocScanner);
1076 setProperty(DTD_VALIDATOR, fXML11DTDValidator);
1077 }
1078 fXML11DocScanner.setDocumentHandler(fXML11DTDValidator);
1079 fXML11DTDValidator.setDocumentSource(fXML11DocScanner);
1080 fXML11DTDValidator.setDocumentHandler(fDocumentHandler);
1081
1082 if (fDocumentHandler != null) {
1083 fDocumentHandler.setDocumentSource(fXML11DTDValidator);
1084 }
1085 fLastComponent = fXML11DTDValidator;
1086 }
1087
1088 // setup document pipeline
1089 if (fFeatures.get(XMLSCHEMA_VALIDATION) == Boolean.TRUE) {
1090 // If schema validator was not in the pipeline insert it.
1091 if (fSchemaValidator == null) {
1092 fSchemaValidator = new XMLSchemaValidator();
1093 // add schema component
1094 setProperty(SCHEMA_VALIDATOR, fSchemaValidator);
1095 addCommonComponent(fSchemaValidator);
1096 fSchemaValidator.reset(this);
1097 // add schema message formatter
1098 if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
1099 XSMessageFormatter xmft = new XSMessageFormatter();
1100 fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, xmft);
1101 }
1102 }
1103
1104 fLastComponent.setDocumentHandler(fSchemaValidator);
1105 fSchemaValidator.setDocumentSource(fLastComponent);
1106 fSchemaValidator.setDocumentHandler(fDocumentHandler);
1107 if (fDocumentHandler != null) {
1108 fDocumentHandler.setDocumentSource(fSchemaValidator);
1109 }
1110 fLastComponent = fSchemaValidator;
1111 }
1112
1113 } // configureXML11Pipeline()
1114
1115 /** Configures the pipeline. */
1116 protected void configurePipeline() {
1117 if (fCurrentDVFactory != fDatatypeValidatorFactory) {
1118 fCurrentDVFactory = fDatatypeValidatorFactory;
1119 // use XML 1.0 datatype library
1120 setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory);
1121 }
1122
1123 // setup DTD pipeline
1124 if (fCurrentDTDScanner != fDTDScanner) {
1125 fCurrentDTDScanner = fDTDScanner;
1126 setProperty(DTD_SCANNER, fCurrentDTDScanner);
1127 setProperty(DTD_PROCESSOR, fDTDProcessor);
1128 }
1129 fDTDScanner.setDTDHandler(fDTDProcessor);
1130 fDTDProcessor.setDTDSource(fDTDScanner);
1131 fDTDProcessor.setDTDHandler(fDTDHandler);
1132 if (fDTDHandler != null) {
1133 fDTDHandler.setDTDSource(fDTDProcessor);
1134 }
1135
1136 fDTDScanner.setDTDContentModelHandler(fDTDProcessor);
1137 fDTDProcessor.setDTDContentModelSource(fDTDScanner);
1138 fDTDProcessor.setDTDContentModelHandler(fDTDContentModelHandler);
1139 if (fDTDContentModelHandler != null) {
1140 fDTDContentModelHandler.setDTDContentModelSource(fDTDProcessor);
1141 }
1142
1143 // setup document pipeline
1144 if (fFeatures.get(NAMESPACES) == Boolean.TRUE) {
1145 if (fCurrentScanner != fNamespaceScanner) {
1146 fCurrentScanner = fNamespaceScanner;
1147 setProperty(DOCUMENT_SCANNER, fNamespaceScanner);
1148 setProperty(DTD_VALIDATOR, fDTDValidator);
1149 }
1150 fNamespaceScanner.setDTDValidator(fDTDValidator);
1151 fNamespaceScanner.setDocumentHandler(fDTDValidator);
1152 fDTDValidator.setDocumentSource(fNamespaceScanner);
1153 fDTDValidator.setDocumentHandler(fDocumentHandler);
1154 if (fDocumentHandler != null) {
1155 fDocumentHandler.setDocumentSource(fDTDValidator);
1156 }
1157 fLastComponent = fDTDValidator;
1158 } else {
1159 // create components
1160 if (fNonNSScanner == null) {
1161 fNonNSScanner = new XMLDocumentScannerImpl();
1162 fNonNSDTDValidator = new XMLDTDValidator();
1163 // add components
1164 addComponent((XMLComponent) fNonNSScanner);
1165 addComponent((XMLComponent) fNonNSDTDValidator);
1166 }
1167 if (fCurrentScanner != fNonNSScanner) {
1168 fCurrentScanner = fNonNSScanner;
1169 setProperty(DOCUMENT_SCANNER, fNonNSScanner);
1170 setProperty(DTD_VALIDATOR, fNonNSDTDValidator);
1171 }
1172
1173 fNonNSScanner.setDocumentHandler(fNonNSDTDValidator);
1174 fNonNSDTDValidator.setDocumentSource(fNonNSScanner);
1175 fNonNSDTDValidator.setDocumentHandler(fDocumentHandler);
1176 if (fDocumentHandler != null) {
1177 fDocumentHandler.setDocumentSource(fNonNSDTDValidator);
1178 }
1179 fLastComponent = fNonNSDTDValidator;
1180 }
1181
1182 // add XML Schema validator if needed
1183 if (fFeatures.get(XMLSCHEMA_VALIDATION) == Boolean.TRUE) {
1184 // If schema validator was not in the pipeline insert it.
1185 if (fSchemaValidator == null) {
1186 fSchemaValidator = new XMLSchemaValidator();
1187 // add schema component
1188 setProperty(SCHEMA_VALIDATOR, fSchemaValidator);
1189 addCommonComponent(fSchemaValidator);
1190 fSchemaValidator.reset(this);
1191 // add schema message formatter
1192 if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
1193 XSMessageFormatter xmft = new XSMessageFormatter();
1194 fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, xmft);
1195 }
1196
1197 }
1198 fLastComponent.setDocumentHandler(fSchemaValidator);
1199 fSchemaValidator.setDocumentSource(fLastComponent);
1200 fSchemaValidator.setDocumentHandler(fDocumentHandler);
1201 if (fDocumentHandler != null) {
1202 fDocumentHandler.setDocumentSource(fSchemaValidator);
1203 }
1204 fLastComponent = fSchemaValidator;
1205 }
1206 } // configurePipeline()
1207
1208
1209 // features and properties
1210
1211 /**
1212 * Check a feature. If feature is know and supported, this method simply
1213 * returns. Otherwise, the appropriate exception is thrown.
1214 *
1215 * @param featureId The unique identifier (URI) of the feature.
1216 *
1217 * @throws XMLConfigurationException Thrown for configuration error.
1218 * In general, components should
1219 * only throw this exception if
1220 * it is <strong>really</strong>
1221 * a critical error.
1222 */
1223 protected void checkFeature(String featureId) throws XMLConfigurationException {
1224
1225 //
1226 // Xerces Features
1227 //
1228
1229 if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
1230 final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
1231
1232 //
1233 // http://apache.org/xml/features/validation/dynamic
1234 // Allows the parser to validate a document only when it
1235 // contains a grammar. Validation is turned on/off based
1236 // on each document instance, automatically.
1237 //
1238 if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE.length() &&
1239 featureId.endsWith(Constants.DYNAMIC_VALIDATION_FEATURE)) {
1240 return;
1241 }
1242
1243 //
1244 // http://apache.org/xml/features/validation/default-attribute-values
1245 //
1246 if (suffixLength == Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE.length() &&
1247 featureId.endsWith(Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE)) {
1248 // REVISIT
1249 short type = XMLConfigurationException.NOT_SUPPORTED;
1250 throw new XMLConfigurationException(type, featureId);
1251 }
1252 //
1253 // http://apache.org/xml/features/validation/default-attribute-values
1254 //
1255 if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE.length() &&
1256 featureId.endsWith(Constants.VALIDATE_CONTENT_MODELS_FEATURE)) {
1257 // REVISIT
1258 short type = XMLConfigurationException.NOT_SUPPORTED;
1259 throw new XMLConfigurationException(type, featureId);
1260 }
1261 //
1262 // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar
1263 //
1264 if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE.length() &&
1265 featureId.endsWith(Constants.LOAD_DTD_GRAMMAR_FEATURE)) {
1266 return;
1267 }
1268 //
1269 // http://apache.org/xml/features/validation/nonvalidating/load-external-dtd
1270 //
1271 if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() &&
1272 featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
1273 return;
1274 }
1275
1276 //
1277 // http://apache.org/xml/features/validation/default-attribute-values
1278 //
1279 if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE.length() &&
1280 featureId.endsWith(Constants.VALIDATE_DATATYPES_FEATURE)) {
1281 short type = XMLConfigurationException.NOT_SUPPORTED;
1282 throw new XMLConfigurationException(type, featureId);
1283 }
1284
1285 //
1286 // http://apache.org/xml/features/validation/schema
1287 // Lets the user turn Schema validation support on/off.
1288 //
1289 if (suffixLength == Constants.SCHEMA_VALIDATION_FEATURE.length() &&
1290 featureId.endsWith(Constants.SCHEMA_VALIDATION_FEATURE)) {
1291 return;
1292 }
1293 // activate full schema checking
1294 if (suffixLength == Constants.SCHEMA_FULL_CHECKING.length() &&
1295 featureId.endsWith(Constants.SCHEMA_FULL_CHECKING)) {
1296 return;
1297 }
1298 // Feature identifier: expose schema normalized value
1299 // http://apache.org/xml/features/validation/schema/normalized-value
1300 if (suffixLength == Constants.SCHEMA_NORMALIZED_VALUE.length() &&
1301 featureId.endsWith(Constants.SCHEMA_NORMALIZED_VALUE)) {
1302 return;
1303 }
1304 // Feature identifier: send element default value via characters()
1305 // http://apache.org/xml/features/validation/schema/element-default
1306 if (suffixLength == Constants.SCHEMA_ELEMENT_DEFAULT.length() &&
1307 featureId.endsWith(Constants.SCHEMA_ELEMENT_DEFAULT)) {
1308 return;
1309 }
1310
1311 // special performance feature: only component manager is allowed to set it.
1312 if (suffixLength == Constants.PARSER_SETTINGS.length() &&
1313 featureId.endsWith(Constants.PARSER_SETTINGS)) {
1314 short type = XMLConfigurationException.NOT_SUPPORTED;
1315 throw new XMLConfigurationException(type, featureId);
1316 }
1317
1318 }
1319
1320 //
1321 // Not recognized
1322 //
1323
1324 super.checkFeature(featureId);
1325
1326 } // checkFeature(String)
1327
1328 /**
1329 * Check a property. If the property is know and supported, this method
1330 * simply returns. Otherwise, the appropriate exception is thrown.
1331 *
1332 * @param propertyId The unique identifier (URI) of the property
1333 * being set.
1334 *
1335 * @throws XMLConfigurationException Thrown for configuration error.
1336 * In general, components should
1337 * only throw this exception if
1338 * it is <strong>really</strong>
1339 * a critical error.
1340 */
1341 protected void checkProperty(String propertyId) throws XMLConfigurationException {
1342
1343 //
1344 // Xerces Properties
1345 //
1346
1347 if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
1348 final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();
1349
1350 if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() &&
1351 propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) {
1352 return;
1353 }
1354 if (suffixLength == Constants.SCHEMA_LOCATION.length() &&
1355 propertyId.endsWith(Constants.SCHEMA_LOCATION)) {
1356 return;
1357 }
1358 if (suffixLength == Constants.SCHEMA_NONS_LOCATION.length() &&
1359 propertyId.endsWith(Constants.SCHEMA_NONS_LOCATION)) {
1360 return;
1361 }
1362 }
1363
1364 if (propertyId.startsWith(Constants.JAXP_PROPERTY_PREFIX)) {
1365 final int suffixLength = propertyId.length() - Constants.JAXP_PROPERTY_PREFIX.length();
1366
1367 if (suffixLength == Constants.SCHEMA_SOURCE.length() &&
1368 propertyId.endsWith(Constants.SCHEMA_SOURCE)) {
1369 return;
1370 }
1371 }
1372
1373 // special cases
1374 if (propertyId.startsWith(Constants.SAX_PROPERTY_PREFIX)) {
1375 final int suffixLength = propertyId.length() - Constants.SAX_PROPERTY_PREFIX.length();
1376
1377 //
1378 // http://xml.org/sax/properties/xml-string
1379 // Value type: String
1380 // Access: read-only
1381 // Get the literal string of characters associated with the
1382 // current event. If the parser recognises and supports this
1383 // property but is not currently parsing text, it should return
1384 // null (this is a good way to check for availability before the
1385 // parse begins).
1386 //
1387 if (suffixLength == Constants.XML_STRING_PROPERTY.length() &&
1388 propertyId.endsWith(Constants.XML_STRING_PROPERTY)) {
1389 // REVISIT - we should probably ask xml-dev for a precise
1390 // definition of what this is actually supposed to return, and
1391 // in exactly which circumstances.
1392 short type = XMLConfigurationException.NOT_SUPPORTED;
1393 throw new XMLConfigurationException(type, propertyId);
1394 }
1395 }
1396
1397 //
1398 // Not recognized
1399 //
1400
1401 super.checkProperty(propertyId);
1402
1403 } // checkProperty(String)
1404
1405
1406 /**
1407 * Adds a component to the parser configuration. This method will
1408 * also add all of the component's recognized features and properties
1409 * to the list of default recognized features and properties.
1410 *
1411 * @param component The component to add.
1412 */
1413 protected void addComponent(XMLComponent component) {
1414
1415 // don't add a component more than once
1416 if (fComponents.contains(component)) {
1417 return;
1418 }
1419 fComponents.add(component);
1420 addRecognizedParamsAndSetDefaults(component);
1421
1422 } // addComponent(XMLComponent)
1423
1424 /**
1425 * Adds common component to the parser configuration. This method will
1426 * also add all of the component's recognized features and properties
1427 * to the list of default recognized features and properties.
1428 *
1429 * @param component The component to add.
1430 */
1431 protected void addCommonComponent(XMLComponent component) {
1432
1433 // don't add a component more than once
1434 if (fCommonComponents.contains(component)) {
1435 return;
1436 }
1437 fCommonComponents.add(component);
1438 addRecognizedParamsAndSetDefaults(component);
1439
1440 } // addCommonComponent(XMLComponent)
1441
1442 /**
1443 * Adds an XML 1.1 component to the parser configuration. This method will
1444 * also add all of the component's recognized features and properties
1445 * to the list of default recognized features and properties.
1446 *
1447 * @param component The component to add.
1448 */
1449 protected void addXML11Component(XMLComponent component) {
1450
1451 // don't add a component more than once
1452 if (fXML11Components.contains(component)) {
1453 return;
1454 }
1455 fXML11Components.add(component);
1456 addRecognizedParamsAndSetDefaults(component);
1457
1458 } // addXML11Component(XMLComponent)
1459
1460 /**
1461 * Adds all of the component's recognized features and properties
1462 * to the list of default recognized features and properties, and
1463 * sets default values on the configuration for features and
1464 * properties which were previously absent from the configuration.
1465 *
1466 * @param component The component whose recognized features
1467 * and properties will be added to the configuration
1468 */
1469 protected void addRecognizedParamsAndSetDefaults(XMLComponent component) {
1470
1471 // register component's recognized features
1472 String[] recognizedFeatures = component.getRecognizedFeatures();
1473 addRecognizedFeatures(recognizedFeatures);
1474
1475 // register component's recognized properties
1476 String[] recognizedProperties = component.getRecognizedProperties();
1477 addRecognizedProperties(recognizedProperties);
1478
1479 // set default values
1480 if (recognizedFeatures != null) {
1481 for (int i = 0; i < recognizedFeatures.length; ++i) {
1482 String featureId = recognizedFeatures[i];
1483 Boolean state = component.getFeatureDefault(featureId);
1484 if (state != null) {
1485 // Do not overwrite values already set on the configuration.
1486 if (!fFeatures.containsKey(featureId)) {
1487 fFeatures.put(featureId, state);
1488 // For newly added components who recognize this feature
1489 // but did not offer a default value, we need to make
1490 // sure these components will get an opportunity to read
1491 // the value before parsing begins.
1492 fConfigUpdated = true;
1493 }
1494 }
1495 }
1496 }
1497 if (recognizedProperties != null) {
1498 for (int i = 0; i < recognizedProperties.length; ++i) {
1499 String propertyId = recognizedProperties[i];
1500 Object value = component.getPropertyDefault(propertyId);
1501 if (value != null) {
1502 // Do not overwrite values already set on the configuration.
1503 if (!fProperties.containsKey(propertyId)) {
1504 fProperties.put(propertyId, value);
1505 // For newly added components who recognize this property
1506 // but did not offer a default value, we need to make
1507 // sure these components will get an opportunity to read
1508 // the value before parsing begins.
1509 fConfigUpdated = true;
1510 }
1511 }
1512 }
1513 }
1514 }
1515
1516 private void initXML11Components() {
1517 if (!f11Initialized) {
1518
1519 // create datatype factory
1520 fXML11DatatypeFactory = DTDDVFactory.getInstance(XML11_DATATYPE_VALIDATOR_FACTORY);
1521
1522 // setup XML 1.1 DTD pipeline
1523 fXML11DTDScanner = new XML11DTDScannerImpl();
1524 addXML11Component(fXML11DTDScanner);
1525 fXML11DTDProcessor = new XML11DTDProcessor();
1526 addXML11Component(fXML11DTDProcessor);
1527
1528 // setup XML 1.1. document pipeline - namespace aware
1529 fXML11NSDocScanner = new XML11NSDocumentScannerImpl();
1530 addXML11Component(fXML11NSDocScanner);
1531 fXML11NSDTDValidator = new XML11NSDTDValidator();
1532 addXML11Component(fXML11NSDTDValidator);
1533
1534 f11Initialized = true;
1535 }
1536 }
1537
1538 /**
1539 * Returns the state of a feature. This method calls getFeature()
1540 * on ParserConfigurationSettings, bypassing getFeature() on this
1541 * class.
1542 */
1543 boolean getFeature0(String featureId)
1544 throws XMLConfigurationException {
1545 return super.getFeature(featureId);
1546 }
1547
1548 } // class XML11Configuration