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