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.Locale;
22
23 import org.apache.xerces.impl.Constants;
24 import org.apache.xerces.impl.XMLDTDScannerImpl;
25 import org.apache.xerces.impl.XMLDocumentScannerImpl;
26 import org.apache.xerces.impl.XMLEntityManager;
27 import org.apache.xerces.impl.XMLErrorReporter;
28 import org.apache.xerces.impl.XMLNamespaceBinder;
29 import org.apache.xerces.impl.dtd.XMLDTDProcessor;
30 import org.apache.xerces.impl.dtd.XMLDTDValidator;
31 import org.apache.xerces.impl.dv.DTDDVFactory;
32 import org.apache.xerces.impl.msg.XMLMessageFormatter;
33 import org.apache.xerces.impl.validation.ValidationManager;
34 import org.apache.xerces.util.SymbolTable;
35 import org.apache.xerces.xni.XMLLocator;
36 import org.apache.xerces.xni.XNIException;
37 import org.apache.xerces.xni.grammars.XMLGrammarPool;
38 import org.apache.xerces.xni.parser.XMLComponent;
39 import org.apache.xerces.xni.parser.XMLComponentManager;
40 import org.apache.xerces.xni.parser.XMLConfigurationException;
41 import org.apache.xerces.xni.parser.XMLDTDScanner;
42 import org.apache.xerces.xni.parser.XMLDocumentScanner;
43 import org.apache.xerces.xni.parser.XMLInputSource;
44 import org.apache.xerces.xni.parser.XMLPullParserConfiguration;
45
46 /**
47 * This is the DTD-only parser configuration. It extends the basic
48 * configuration with a standard set of parser components appropriate
49 * to DTD-centric validation. Since
50 * the Xerces2 reference implementation document and DTD scanner
51 * implementations are capable of acting as pull parsers, this
52 * configuration implements the
53 * <code>XMLPullParserConfiguration</code> interface.
54 * <p>
55 * In addition to the features and properties recognized by the base
56 * parser configuration, this class recognizes these additional
57 * features and properties:
58 * <ul>
59 * <li>Features
60 * <ul>
61 * <li>http://apache.org/xml/features/validation/warn-on-duplicate-attdef</li>
62 * <li>http://apache.org/xml/features/validation/warn-on-undeclared-elemdef</li>
63 * <li>http://apache.org/xml/features/allow-java-encodings</li>
64 * <li>http://apache.org/xml/features/continue-after-fatal-error</li>
65 * <li>http://apache.org/xml/features/load-external-dtd</li>
66 * </ul>
67 * <li>Properties
68 * <ul>
69 * <li>http://apache.org/xml/properties/internal/error-reporter</li>
70 * <li>http://apache.org/xml/properties/internal/entity-manager</li>
71 * <li>http://apache.org/xml/properties/internal/document-scanner</li>
72 * <li>http://apache.org/xml/properties/internal/dtd-scanner</li>
73 * <li>http://apache.org/xml/properties/internal/grammar-pool</li>
74 * <li>http://apache.org/xml/properties/internal/validator/dtd</li>
75 * <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li>
76 * </ul>
77 * </ul>
78 *
79 * @author Arnaud Le Hors, IBM
80 * @author Andy Clark, IBM
81 * @author Neil Graham, IBM
82 *
83 * @version $Id: DTDConfiguration.java 548192 2007-06-18 03:34:19Z mrglavas $
84 */
85 public class DTDConfiguration
86 extends BasicParserConfiguration
87 implements XMLPullParserConfiguration {
88
89 //
90 // Constants
91 //
92
93 // feature identifiers
94
95 /** Feature identifier: warn on duplicate attribute definition. */
96 protected static final String WARN_ON_DUPLICATE_ATTDEF =
97 Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE;
98
99 /** Feature identifier: warn on duplicate entity definition. */
100 protected static final String WARN_ON_DUPLICATE_ENTITYDEF =
101 Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE;
102
103 /** Feature identifier: warn on undeclared element definition. */
104 protected static final String WARN_ON_UNDECLARED_ELEMDEF =
105 Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE;
106
107 /** Feature identifier: allow Java encodings. */
108 protected static final String ALLOW_JAVA_ENCODINGS =
109 Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE;
110
111 /** Feature identifier: continue after fatal error. */
112 protected static final String CONTINUE_AFTER_FATAL_ERROR =
113 Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
114
115 /** Feature identifier: load external DTD. */
116 protected static final String LOAD_EXTERNAL_DTD =
117 Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE;
118
119 /** Feature identifier: notify built-in refereces. */
120 protected static final String NOTIFY_BUILTIN_REFS =
121 Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_BUILTIN_REFS_FEATURE;
122
123 /** Feature identifier: notify character refereces. */
124 protected static final String NOTIFY_CHAR_REFS =
125 Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_CHAR_REFS_FEATURE;
126
127
128 // property identifiers
129
130 /** Property identifier: error reporter. */
131 protected static final String ERROR_REPORTER =
132 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
133
134 /** Property identifier: entity manager. */
135 protected static final String ENTITY_MANAGER =
136 Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
137
138 /** Property identifier document scanner: */
139 protected static final String DOCUMENT_SCANNER =
140 Constants.XERCES_PROPERTY_PREFIX + Constants.DOCUMENT_SCANNER_PROPERTY;
141
142 /** Property identifier: DTD scanner. */
143 protected static final String DTD_SCANNER =
144 Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_SCANNER_PROPERTY;
145
146 /** Property identifier: grammar pool. */
147 protected static final String XMLGRAMMAR_POOL =
148 Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
149
150 /** Property identifier: DTD loader. */
151 protected static final String DTD_PROCESSOR =
152 Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_PROCESSOR_PROPERTY;
153
154 /** Property identifier: DTD validator. */
155 protected static final String DTD_VALIDATOR =
156 Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY;
157
158 /** Property identifier: namespace binder. */
159 protected static final String NAMESPACE_BINDER =
160 Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_BINDER_PROPERTY;
161
162 /** Property identifier: datatype validator factory. */
163 protected static final String DATATYPE_VALIDATOR_FACTORY =
164 Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY;
165
166 protected static final String VALIDATION_MANAGER =
167 Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY;
168
169 /** Property identifier: JAXP schema language / DOM schema-type. */
170 protected static final String JAXP_SCHEMA_LANGUAGE =
171 Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE;
172
173 /** Property identifier: JAXP schema source/ DOM schema-location. */
174 protected static final String JAXP_SCHEMA_SOURCE =
175 Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE;
176
177
178 // debugging
179
180 /** Set to true and recompile to print exception stack trace. */
181 protected static final boolean PRINT_EXCEPTION_STACK_TRACE = false;
182
183 //
184 // Data
185 //
186
187 // components (non-configurable)
188
189 /** Grammar pool. */
190 protected XMLGrammarPool fGrammarPool;
191
192 /** Datatype validator factory. */
193 protected DTDDVFactory fDatatypeValidatorFactory;
194
195 // components (configurable)
196
197 /** Error reporter. */
198 protected XMLErrorReporter fErrorReporter;
199
200 /** Entity manager. */
201 protected XMLEntityManager fEntityManager;
202
203 /** Document scanner. */
204 protected XMLDocumentScanner fScanner;
205
206 /** Input Source */
207 protected XMLInputSource fInputSource;
208
209 /** DTD scanner. */
210 protected XMLDTDScanner fDTDScanner;
211
212 /** DTD Processor . */
213 protected XMLDTDProcessor fDTDProcessor;
214
215 /** DTD Validator. */
216 protected XMLDTDValidator fDTDValidator;
217
218 /** Namespace binder. */
219 protected XMLNamespaceBinder fNamespaceBinder;
220
221 protected ValidationManager fValidationManager;
222 // state
223
224 /** Locator */
225 protected XMLLocator fLocator;
226
227 /**
228 * True if a parse is in progress. This state is needed because
229 * some features/properties cannot be set while parsing (e.g.
230 * validation and namespaces).
231 */
232 protected boolean fParseInProgress = false;
233
234 //
235 // Constructors
236 //
237
238 /** Default constructor. */
239 public DTDConfiguration() {
240 this(null, null, null);
241 } // <init>()
242
243 /**
244 * Constructs a parser configuration using the specified symbol table.
245 *
246 * @param symbolTable The symbol table to use.
247 */
248 public DTDConfiguration(SymbolTable symbolTable) {
249 this(symbolTable, null, null);
250 } // <init>(SymbolTable)
251
252 /**
253 * Constructs a parser configuration using the specified symbol table and
254 * grammar pool.
255 * <p>
256 * <strong>REVISIT:</strong>
257 * Grammar pool will be updated when the new validation engine is
258 * implemented.
259 *
260 * @param symbolTable The symbol table to use.
261 * @param grammarPool The grammar pool to use.
262 */
263 public DTDConfiguration(SymbolTable symbolTable,
264 XMLGrammarPool grammarPool) {
265 this(symbolTable, grammarPool, null);
266 } // <init>(SymbolTable,XMLGrammarPool)
267
268 /**
269 * Constructs a parser configuration using the specified symbol table,
270 * grammar pool, and parent settings.
271 * <p>
272 * <strong>REVISIT:</strong>
273 * Grammar pool will be updated when the new validation engine is
274 * implemented.
275 *
276 * @param symbolTable The symbol table to use.
277 * @param grammarPool The grammar pool to use.
278 * @param parentSettings The parent settings.
279 */
280 public DTDConfiguration(SymbolTable symbolTable,
281 XMLGrammarPool grammarPool,
282 XMLComponentManager parentSettings) {
283 super(symbolTable, parentSettings);
284
285 // add default recognized features
286 final String[] recognizedFeatures = {
287 //WARN_ON_DUPLICATE_ATTDEF, // from XMLDTDScannerImpl
288 //WARN_ON_UNDECLARED_ELEMDEF, // from XMLDTDScannerImpl
289 //ALLOW_JAVA_ENCODINGS, // from XMLEntityManager
290 CONTINUE_AFTER_FATAL_ERROR,
291 LOAD_EXTERNAL_DTD, // from XMLDTDScannerImpl
292 //NOTIFY_BUILTIN_REFS, // from XMLDocumentFragmentScannerImpl
293 //NOTIFY_CHAR_REFS, // from XMLDocumentFragmentScannerImpl
294 //WARN_ON_DUPLICATE_ENTITYDEF, // from XMLEntityManager
295 };
296 addRecognizedFeatures(recognizedFeatures);
297
298 // set state for default features
299 //setFeature(WARN_ON_DUPLICATE_ATTDEF, false); // from XMLDTDScannerImpl
300 //setFeature(WARN_ON_UNDECLARED_ELEMDEF, false); // from XMLDTDScannerImpl
301 //setFeature(ALLOW_JAVA_ENCODINGS, false); // from XMLEntityManager
302 setFeature(CONTINUE_AFTER_FATAL_ERROR, false);
303 setFeature(LOAD_EXTERNAL_DTD, true); // from XMLDTDScannerImpl
304 //setFeature(NOTIFY_BUILTIN_REFS, false); // from XMLDocumentFragmentScannerImpl
305 //setFeature(NOTIFY_CHAR_REFS, false); // from XMLDocumentFragmentScannerImpl
306 //setFeature(WARN_ON_DUPLICATE_ENTITYDEF, false); // from XMLEntityManager
307
308 // add default recognized properties
309 final String[] recognizedProperties = {
310 ERROR_REPORTER,
311 ENTITY_MANAGER,
312 DOCUMENT_SCANNER,
313 DTD_SCANNER,
314 DTD_PROCESSOR,
315 DTD_VALIDATOR,
316 NAMESPACE_BINDER,
317 XMLGRAMMAR_POOL,
318 DATATYPE_VALIDATOR_FACTORY,
319 VALIDATION_MANAGER,
320 JAXP_SCHEMA_SOURCE,
321 JAXP_SCHEMA_LANGUAGE
322 };
323 addRecognizedProperties(recognizedProperties);
324
325 fGrammarPool = grammarPool;
326 if(fGrammarPool != null){
327 setProperty(XMLGRAMMAR_POOL, fGrammarPool);
328 }
329
330 fEntityManager = createEntityManager();
331 setProperty(ENTITY_MANAGER, fEntityManager);
332 addComponent(fEntityManager);
333
334 fErrorReporter = createErrorReporter();
335 fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
336 setProperty(ERROR_REPORTER, fErrorReporter);
337 addComponent(fErrorReporter);
338
339 fScanner = createDocumentScanner();
340 setProperty(DOCUMENT_SCANNER, fScanner);
341 if (fScanner instanceof XMLComponent) {
342 addComponent((XMLComponent)fScanner);
343 }
344
345 fDTDScanner = createDTDScanner();
346 if (fDTDScanner != null) {
347 setProperty(DTD_SCANNER, fDTDScanner);
348 if (fDTDScanner instanceof XMLComponent) {
349 addComponent((XMLComponent)fDTDScanner);
350 }
351 }
352
353 fDTDProcessor = createDTDProcessor();
354 if (fDTDProcessor != null) {
355 setProperty(DTD_PROCESSOR, fDTDProcessor);
356 addComponent(fDTDProcessor);
357 }
358
359 fDTDValidator = createDTDValidator();
360 if (fDTDValidator != null) {
361 setProperty(DTD_VALIDATOR, fDTDValidator);
362 addComponent(fDTDValidator);
363 }
364
365 fNamespaceBinder = createNamespaceBinder();
366 if (fNamespaceBinder != null) {
367 setProperty(NAMESPACE_BINDER, fNamespaceBinder);
368 addComponent(fNamespaceBinder);
369 }
370
371 fDatatypeValidatorFactory = createDatatypeValidatorFactory();
372 if (fDatatypeValidatorFactory != null) {
373 setProperty(DATATYPE_VALIDATOR_FACTORY,
374 fDatatypeValidatorFactory);
375 }
376 fValidationManager = createValidationManager();
377
378 if (fValidationManager != null) {
379 setProperty (VALIDATION_MANAGER, fValidationManager);
380 }
381 // add message formatters
382 if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
383 XMLMessageFormatter xmft = new XMLMessageFormatter();
384 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft);
385 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft);
386 }
387
388 // set locale
389 try {
390 setLocale(Locale.getDefault());
391 }
392 catch (XNIException e) {
393 // do nothing
394 // REVISIT: What is the right thing to do? -Ac
395 }
396
397 } // <init>(SymbolTable,XMLGrammarPool)
398
399 //
400 // Public methods
401 //
402
403 /**
404 * Set the locale to use for messages.
405 *
406 * @param locale The locale object to use for localization of messages.
407 *
408 * @exception XNIException Thrown if the parser does not support the
409 * specified locale.
410 */
411 public void setLocale(Locale locale) throws XNIException {
412 super.setLocale(locale);
413 fErrorReporter.setLocale(locale);
414 } // setLocale(Locale)
415
416 //
417 // XMLPullParserConfiguration methods
418 //
419
420 // parsing
421
422 /**
423 * Sets the input source for the document to parse.
424 *
425 * @param inputSource The document's input source.
426 *
427 * @exception XMLConfigurationException Thrown if there is a
428 * configuration error when initializing the
429 * parser.
430 * @exception IOException Thrown on I/O error.
431 *
432 * @see #parse(boolean)
433 */
434 public void setInputSource(XMLInputSource inputSource)
435 throws XMLConfigurationException, IOException {
436
437 // REVISIT: this method used to reset all the components and
438 // construct the pipeline. Now reset() is called
439 // in parse (boolean) just before we parse the document
440 // Should this method still throw exceptions..?
441
442 fInputSource = inputSource;
443
444 } // setInputSource(XMLInputSource)
445
446 /**
447 * Parses the document in a pull parsing fashion.
448 *
449 * @param complete True if the pull parser should parse the
450 * remaining document completely.
451 *
452 * @return True if there is more document to parse.
453 *
454 * @exception XNIException Any XNI exception, possibly wrapping
455 * another exception.
456 * @exception IOException An IO exception from the parser, possibly
457 * from a byte stream or character stream
458 * supplied by the parser.
459 *
460 * @see #setInputSource
461 */
462 public boolean parse(boolean complete) throws XNIException, IOException {
463 //
464 // reset and configure pipeline and set InputSource.
465 if (fInputSource !=null) {
466 try {
467 // resets and sets the pipeline.
468 reset();
469 fScanner.setInputSource(fInputSource);
470 fInputSource = null;
471 }
472 catch (XNIException ex) {
473 if (PRINT_EXCEPTION_STACK_TRACE)
474 ex.printStackTrace();
475 throw ex;
476 }
477 catch (IOException ex) {
478 if (PRINT_EXCEPTION_STACK_TRACE)
479 ex.printStackTrace();
480 throw ex;
481 }
482 catch (RuntimeException ex) {
483 if (PRINT_EXCEPTION_STACK_TRACE)
484 ex.printStackTrace();
485 throw ex;
486 }
487 catch (Exception ex) {
488 if (PRINT_EXCEPTION_STACK_TRACE)
489 ex.printStackTrace();
490 throw new XNIException(ex);
491 }
492 }
493
494 try {
495 return fScanner.scanDocument(complete);
496 }
497 catch (XNIException ex) {
498 if (PRINT_EXCEPTION_STACK_TRACE)
499 ex.printStackTrace();
500 throw ex;
501 }
502 catch (IOException ex) {
503 if (PRINT_EXCEPTION_STACK_TRACE)
504 ex.printStackTrace();
505 throw ex;
506 }
507 catch (RuntimeException ex) {
508 if (PRINT_EXCEPTION_STACK_TRACE)
509 ex.printStackTrace();
510 throw ex;
511 }
512 catch (Exception ex) {
513 if (PRINT_EXCEPTION_STACK_TRACE)
514 ex.printStackTrace();
515 throw new XNIException(ex);
516 }
517
518 } // parse(boolean):boolean
519
520 /**
521 * If the application decides to terminate parsing before the xml document
522 * is fully parsed, the application should call this method to free any
523 * resource allocated during parsing. For example, close all opened streams.
524 */
525 public void cleanup() {
526 fEntityManager.closeReaders();
527 }
528
529 //
530 // XMLParserConfiguration methods
531 //
532
533 /**
534 * Parses the specified input source.
535 *
536 * @param source The input source.
537 *
538 * @exception XNIException Throws exception on XNI error.
539 * @exception java.io.IOException Throws exception on i/o error.
540 */
541 public void parse(XMLInputSource source) throws XNIException, IOException {
542
543 if (fParseInProgress) {
544 // REVISIT - need to add new error message
545 throw new XNIException("FWK005 parse may not be called while parsing.");
546 }
547 fParseInProgress = true;
548
549 try {
550 setInputSource(source);
551 parse(true);
552 }
553 catch (XNIException ex) {
554 if (PRINT_EXCEPTION_STACK_TRACE)
555 ex.printStackTrace();
556 throw ex;
557 }
558 catch (IOException ex) {
559 if (PRINT_EXCEPTION_STACK_TRACE)
560 ex.printStackTrace();
561 throw ex;
562 }
563 catch (RuntimeException ex) {
564 if (PRINT_EXCEPTION_STACK_TRACE)
565 ex.printStackTrace();
566 throw ex;
567 }
568 catch (Exception ex) {
569 if (PRINT_EXCEPTION_STACK_TRACE)
570 ex.printStackTrace();
571 throw new XNIException(ex);
572 }
573 finally {
574 fParseInProgress = false;
575 // close all streams opened by xerces
576 this.cleanup();
577 }
578
579 } // parse(InputSource)
580
581 //
582 // Protected methods
583 //
584
585 /**
586 * Reset all components before parsing.
587 *
588 * @throws XNIException Thrown if an error occurs during initialization.
589 */
590 protected void reset() throws XNIException {
591
592 if (fValidationManager != null)
593 fValidationManager.reset();
594 // configure the pipeline and initialize the components
595 configurePipeline();
596 super.reset();
597 } // reset()
598
599 /** Configures the pipeline. */
600 protected void configurePipeline() {
601
602 // REVISIT: This should be better designed. In other words, we
603 // need to figure out what is the best way for people to
604 // re-use *most* of the standard configuration but do
605 // things common things such as remove a component (e.g.
606 // the validator), insert a new component (e.g. XInclude),
607 // etc... -Ac
608
609 // setup document pipeline
610 if (fDTDValidator != null) {
611 fScanner.setDocumentHandler(fDTDValidator);
612 if (fFeatures.get(NAMESPACES) == Boolean.TRUE) {
613
614 // filters
615 fDTDValidator.setDocumentHandler(fNamespaceBinder);
616 fDTDValidator.setDocumentSource(fScanner);
617 fNamespaceBinder.setDocumentHandler(fDocumentHandler);
618 fNamespaceBinder.setDocumentSource(fDTDValidator);
619 fLastComponent = fNamespaceBinder;
620 }
621 else {
622 fDTDValidator.setDocumentHandler(fDocumentHandler);
623 fDTDValidator.setDocumentSource(fScanner);
624 fLastComponent = fDTDValidator;
625 }
626 }
627 else {
628 if (fFeatures.get(NAMESPACES) == Boolean.TRUE) {
629 fScanner.setDocumentHandler(fNamespaceBinder);
630 fNamespaceBinder.setDocumentHandler(fDocumentHandler);
631 fNamespaceBinder.setDocumentSource(fScanner);
632 fLastComponent = fNamespaceBinder;
633 }
634 else {
635 fScanner.setDocumentHandler(fDocumentHandler);
636 fLastComponent = fScanner;
637 }
638 }
639
640 configureDTDPipeline();
641 } // configurePipeline()
642
643 protected void configureDTDPipeline (){
644
645 // setup dtd pipeline
646 if (fDTDScanner != null) {
647 fProperties.put(DTD_SCANNER, fDTDScanner);
648 if (fDTDProcessor != null) {
649 fProperties.put(DTD_PROCESSOR, fDTDProcessor);
650 fDTDScanner.setDTDHandler(fDTDProcessor);
651 fDTDProcessor.setDTDSource(fDTDScanner);
652 fDTDProcessor.setDTDHandler(fDTDHandler);
653 if (fDTDHandler != null) {
654 fDTDHandler.setDTDSource(fDTDProcessor);
655 }
656
657 fDTDScanner.setDTDContentModelHandler(fDTDProcessor);
658 fDTDProcessor.setDTDContentModelSource(fDTDScanner);
659 fDTDProcessor.setDTDContentModelHandler(fDTDContentModelHandler);
660 if (fDTDContentModelHandler != null) {
661 fDTDContentModelHandler.setDTDContentModelSource(fDTDProcessor);
662 }
663 }
664 else {
665 fDTDScanner.setDTDHandler(fDTDHandler);
666 if (fDTDHandler != null) {
667 fDTDHandler.setDTDSource(fDTDScanner);
668 }
669 fDTDScanner.setDTDContentModelHandler(fDTDContentModelHandler);
670 if (fDTDContentModelHandler != null) {
671 fDTDContentModelHandler.setDTDContentModelSource(fDTDScanner);
672 }
673 }
674 }
675
676
677 }
678
679 // features and properties
680
681 /**
682 * Check a feature. If feature is know and supported, this method simply
683 * returns. Otherwise, the appropriate exception is thrown.
684 *
685 * @param featureId The unique identifier (URI) of the feature.
686 *
687 * @throws XMLConfigurationException Thrown for configuration error.
688 * In general, components should
689 * only throw this exception if
690 * it is <strong>really</strong>
691 * a critical error.
692 */
693 protected void checkFeature(String featureId)
694 throws XMLConfigurationException {
695
696 //
697 // Xerces Features
698 //
699
700 if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
701 final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
702
703 //
704 // http://apache.org/xml/features/validation/dynamic
705 // Allows the parser to validate a document only when it
706 // contains a grammar. Validation is turned on/off based
707 // on each document instance, automatically.
708 //
709 if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE.length() &&
710 featureId.endsWith(Constants.DYNAMIC_VALIDATION_FEATURE)) {
711 return;
712 }
713
714 //
715 // http://apache.org/xml/features/validation/default-attribute-values
716 //
717 if (suffixLength == Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE.length() &&
718 featureId.endsWith(Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE)) {
719 // REVISIT
720 short type = XMLConfigurationException.NOT_SUPPORTED;
721 throw new XMLConfigurationException(type, featureId);
722 }
723 //
724 // http://apache.org/xml/features/validation/default-attribute-values
725 //
726 if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE.length() &&
727 featureId.endsWith(Constants.VALIDATE_CONTENT_MODELS_FEATURE)) {
728 // REVISIT
729 short type = XMLConfigurationException.NOT_SUPPORTED;
730 throw new XMLConfigurationException(type, featureId);
731 }
732 //
733 // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar
734 //
735 if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE.length() &&
736 featureId.endsWith(Constants.LOAD_DTD_GRAMMAR_FEATURE)) {
737 return;
738 }
739 //
740 // http://apache.org/xml/features/validation/nonvalidating/load-external-dtd
741 //
742 if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() &&
743 featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
744 return;
745 }
746
747 //
748 // http://apache.org/xml/features/validation/default-attribute-values
749 //
750 if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE.length() &&
751 featureId.endsWith(Constants.VALIDATE_DATATYPES_FEATURE)) {
752 short type = XMLConfigurationException.NOT_SUPPORTED;
753 throw new XMLConfigurationException(type, featureId);
754 }
755 }
756
757 //
758 // Not recognized
759 //
760
761 super.checkFeature(featureId);
762
763 } // checkFeature(String)
764
765 /**
766 * Check a property. If the property is know and supported, this method
767 * simply returns. Otherwise, the appropriate exception is thrown.
768 *
769 * @param propertyId The unique identifier (URI) of the property
770 * being set.
771 *
772 * @throws XMLConfigurationException Thrown for configuration error.
773 * In general, components should
774 * only throw this exception if
775 * it is <strong>really</strong>
776 * a critical error.
777 */
778 protected void checkProperty(String propertyId)
779 throws XMLConfigurationException {
780
781 //
782 // Xerces Properties
783 //
784
785 if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
786 final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();
787
788 if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() &&
789 propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) {
790 return;
791 }
792 }
793
794 //
795 // Not recognized
796 //
797
798 super.checkProperty(propertyId);
799
800 } // checkProperty(String)
801
802 // factory methods
803
804 /** Creates an entity manager. */
805 protected XMLEntityManager createEntityManager() {
806 return new XMLEntityManager();
807 } // createEntityManager():XMLEntityManager
808
809 /** Creates an error reporter. */
810 protected XMLErrorReporter createErrorReporter() {
811 return new XMLErrorReporter();
812 } // createErrorReporter():XMLErrorReporter
813
814 /** Create a document scanner. */
815 protected XMLDocumentScanner createDocumentScanner() {
816 return new XMLDocumentScannerImpl();
817 } // createDocumentScanner():XMLDocumentScanner
818
819 /** Create a DTD scanner. */
820 protected XMLDTDScanner createDTDScanner() {
821 return new XMLDTDScannerImpl();
822 } // createDTDScanner():XMLDTDScanner
823
824 /** Create a DTD loader . */
825 protected XMLDTDProcessor createDTDProcessor() {
826 return new XMLDTDProcessor();
827 } // createDTDProcessor():XMLDTDProcessor
828
829 /** Create a DTD validator. */
830 protected XMLDTDValidator createDTDValidator() {
831 return new XMLDTDValidator();
832 } // createDTDValidator():XMLDTDValidator
833
834 /** Create a namespace binder. */
835 protected XMLNamespaceBinder createNamespaceBinder() {
836 return new XMLNamespaceBinder();
837 } // createNamespaceBinder():XMLNamespaceBinder
838
839 /** Create a datatype validator factory. */
840 protected DTDDVFactory createDatatypeValidatorFactory() {
841 return DTDDVFactory.getInstance();
842 } // createDatatypeValidatorFactory():DatatypeValidatorFactory
843 protected ValidationManager createValidationManager(){
844 return new ValidationManager();
845 }
846
847 } // class DTDConfiguration