KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xerces > impl > dtd > XMLDTDLoader


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.xerces.impl.dtd;
18
19 import org.apache.xerces.impl.Constants;
20 import org.apache.xerces.impl.XMLDTDScannerImpl;
21 import org.apache.xerces.impl.XMLErrorReporter;
22 import org.apache.xerces.impl.XMLEntityManager;
23 import org.apache.xerces.impl.msg.XMLMessageFormatter;
24
25 import org.apache.xerces.util.SymbolTable;
26 import org.apache.xerces.util.DefaultErrorHandler;
27
28 import org.apache.xerces.xni.XNIException;
29 import org.apache.xerces.xni.grammars.XMLGrammarPool;
30 import org.apache.xerces.xni.grammars.XMLGrammarLoader;
31 import org.apache.xerces.xni.grammars.Grammar;
32 import org.apache.xerces.xni.parser.XMLConfigurationException;
33 import org.apache.xerces.xni.parser.XMLErrorHandler;
34 import org.apache.xerces.xni.parser.XMLEntityResolver;
35 import org.apache.xerces.xni.parser.XMLInputSource;
36
37 import java.util.Locale JavaDoc;
38 import java.io.IOException JavaDoc;
39 import java.io.EOFException JavaDoc;
40
41 /**
42  * The DTD loader. The loader knows how to build grammars from XMLInputSources.
43  * It extends the DTD processor in order to do this; it's
44  * a separate class because DTD processors don't need to know how
45  * to talk to the outside world in their role as instance-document
46  * helpers.
47  * <p>
48  * This component requires the following features and properties. It
49  * know ho to set them if no one else does:from the
50  * <ul>
51  * <li>http://xml.org/sax/features/namespaces</li>
52  * <li>http://apache.org/xml/properties/internal/symbol-table</li>
53  * <li>http://apache.org/xml/properties/internal/error-reporter</li>
54  * <li>http://apache.org/xml/properties/internal/grammar-pool</li>
55  * <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li>
56  * </ul>
57  *
58  * @xerces.internal
59  *
60  * @author Neil Graham, IBM
61  *
62  * @version $Id: XMLDTDLoader.java,v 1.11 2004/10/04 21:57:30 mrglavas Exp $
63  */

64 public class XMLDTDLoader
65         extends XMLDTDProcessor
66         implements XMLGrammarLoader {
67
68     //
69
// Constants
70
//
71

72     // feature identifiers
73

74     /** Feature identifier: standard uri conformant feature. */
75     protected static final String JavaDoc STANDARD_URI_CONFORMANT_FEATURE =
76         Constants.XERCES_FEATURE_PREFIX + Constants.STANDARD_URI_CONFORMANT_FEATURE;
77
78     // recognized features:
79
private static final String JavaDoc[] RECOGNIZED_FEATURES = {
80         VALIDATION,
81         WARN_ON_DUPLICATE_ATTDEF,
82         NOTIFY_CHAR_REFS,
83         STANDARD_URI_CONFORMANT_FEATURE
84     };
85
86     // property identifiers
87

88     /** Property identifier: error handler. */
89     protected static final String JavaDoc ERROR_HANDLER =
90         Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
91
92     /** Property identifier: entity resolver. */
93     public static final String JavaDoc ENTITY_RESOLVER =
94         Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
95
96     /** Recognized properties. */
97     private static final String JavaDoc[] LOADER_RECOGNIZED_PROPERTIES = {
98         SYMBOL_TABLE,
99         ERROR_REPORTER,
100         ERROR_HANDLER,
101         ENTITY_RESOLVER,
102         GRAMMAR_POOL,
103         DTD_VALIDATOR,
104     };
105
106     // enforcing strict uri?
107
private boolean fStrictURI = false;
108
109     /** Entity resolver . */
110     protected XMLEntityResolver fEntityResolver;
111
112     // the scanner we use to actually read the DTD
113
protected XMLDTDScannerImpl fDTDScanner;
114
115     // the entity manager the scanner needs.
116
protected XMLEntityManager fEntityManager;
117
118     // what's our Locale?
119
protected Locale JavaDoc fLocale;
120
121     //
122
// Constructors
123
//
124

125     /** Deny default construction; we need a SymtolTable! */
126     public XMLDTDLoader() {
127         this(new SymbolTable());
128     } // <init>()
129

130     public XMLDTDLoader(SymbolTable symbolTable) {
131         this(symbolTable, null);
132     } // init(SymbolTable)
133

134     public XMLDTDLoader(SymbolTable symbolTable,
135                 XMLGrammarPool grammarPool) {
136         this(symbolTable, grammarPool, null, new XMLEntityManager());
137     } // init(SymbolTable, XMLGrammarPool)
138

139     XMLDTDLoader(SymbolTable symbolTable,
140                 XMLGrammarPool grammarPool, XMLErrorReporter errorReporter,
141                 XMLEntityResolver entityResolver) {
142         fSymbolTable = symbolTable;
143         fGrammarPool = grammarPool;
144         if(errorReporter == null) {
145             errorReporter = new XMLErrorReporter();
146             errorReporter.setProperty(ERROR_HANDLER, new DefaultErrorHandler());
147         }
148         fErrorReporter = errorReporter;
149         // Add XML message formatter if there isn't one.
150
if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
151             XMLMessageFormatter xmft = new XMLMessageFormatter();
152             fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft);
153             fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft);
154         }
155         fEntityResolver = entityResolver;
156         if(fEntityResolver instanceof XMLEntityManager) {
157             fEntityManager = (XMLEntityManager)fEntityResolver;
158         } else {
159             fEntityManager = new XMLEntityManager();
160         }
161         fEntityManager.setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY, errorReporter);
162         fDTDScanner = new XMLDTDScannerImpl(fSymbolTable, fErrorReporter, fEntityManager);
163         fDTDScanner.setDTDHandler(this);
164         fDTDScanner.setDTDContentModelHandler(this);
165         reset();
166     } // init(SymbolTable, XMLGrammarPool, XMLErrorReporter, XMLEntityResolver)
167

168     // XMLGrammarLoader methods
169

170     /**
171      * Sets the state of a feature. This method is called by the component
172      * manager any time after reset when a feature changes state.
173      * <p>
174      * <strong>Note:</strong> Components should silently ignore features
175      * that do not affect the operation of the component.
176      *
177      * @param featureId The feature identifier.
178      * @param state The state of the feature.
179      *
180      * @throws SAXNotRecognizedException The component should not throw
181      * this exception.
182      * @throws SAXNotSupportedException The component should not throw
183      * this exception.
184      */

185     public void setFeature(String JavaDoc featureId, boolean state)
186             throws XMLConfigurationException {
187         if(featureId.equals(VALIDATION)) {
188             fValidation = state;
189         } else if(featureId.equals(WARN_ON_DUPLICATE_ATTDEF)) {
190             fWarnDuplicateAttdef = state;
191         } else if(featureId.equals(NOTIFY_CHAR_REFS)) {
192             fDTDScanner.setFeature(featureId, state);
193         } else if(featureId.equals(STANDARD_URI_CONFORMANT_FEATURE)) {
194             fStrictURI = state;
195         } else {
196             throw new XMLConfigurationException(XMLConfigurationException.NOT_RECOGNIZED, featureId);
197         }
198     } // setFeature(String,boolean)
199

200     /**
201      * Returns a list of property identifiers that are recognized by
202      * this component. This method may return null if no properties
203      * are recognized by this component.
204      */

205     public String JavaDoc[] getRecognizedProperties() {
206         return (String JavaDoc[])(LOADER_RECOGNIZED_PROPERTIES.clone());
207     } // getRecognizedProperties():String[]
208

209     /**
210      * Returns the state of a property.
211      *
212      * @param propertyId The property identifier.
213      *
214      * @throws XMLConfigurationException Thrown on configuration error.
215      */

216     public Object JavaDoc getProperty(String JavaDoc propertyId)
217             throws XMLConfigurationException {
218         if(propertyId.equals( SYMBOL_TABLE)) {
219             return fSymbolTable;
220         } else if(propertyId.equals( ERROR_REPORTER)) {
221             return fErrorReporter;
222         } else if(propertyId.equals( ERROR_HANDLER)) {
223             return fErrorReporter.getErrorHandler();
224         } else if(propertyId.equals( ENTITY_RESOLVER)) {
225             return fEntityResolver;
226         } else if(propertyId.equals( GRAMMAR_POOL)) {
227             return fGrammarPool;
228         } else if(propertyId.equals( DTD_VALIDATOR)) {
229             return fValidator;
230         }
231         throw new XMLConfigurationException(XMLConfigurationException.NOT_RECOGNIZED, propertyId);
232     } // getProperty(String): Object
233

234     /**
235      * Sets the value of a property. This method is called by the component
236      * manager any time after reset when a property changes value.
237      * <p>
238      * <strong>Note:</strong> Components should silently ignore properties
239      * that do not affect the operation of the component.
240      *
241      * @param propertyId The property identifier.
242      * @param value The value of the property.
243      *
244      * @throws SAXNotRecognizedException The component should not throw
245      * this exception.
246      * @throws SAXNotSupportedException The component should not throw
247      * this exception.
248      */

249     public void setProperty(String JavaDoc propertyId, Object JavaDoc value)
250             throws XMLConfigurationException {
251         if(propertyId.equals( SYMBOL_TABLE)) {
252             fSymbolTable = (SymbolTable)value;
253             fDTDScanner.setProperty(propertyId, value);
254             fEntityManager.setProperty(propertyId, value);
255         } else if(propertyId.equals( ERROR_REPORTER)) {
256             fErrorReporter = (XMLErrorReporter)value;
257             // Add XML message formatter if there isn't one.
258
if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
259                 XMLMessageFormatter xmft = new XMLMessageFormatter();
260                 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft);
261                 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft);
262             }
263             fDTDScanner.setProperty(propertyId, value);
264             fEntityManager.setProperty(propertyId, value);
265         } else if(propertyId.equals( ERROR_HANDLER)) {
266             fErrorReporter.setProperty(propertyId, value);
267         } else if(propertyId.equals( ENTITY_RESOLVER)) {
268             fEntityResolver = (XMLEntityResolver)value;
269         } else if(propertyId.equals( GRAMMAR_POOL)) {
270             fGrammarPool = (XMLGrammarPool)value;
271         } else {
272             throw new XMLConfigurationException(XMLConfigurationException.NOT_RECOGNIZED, propertyId);
273         }
274     } // setProperty(String,Object)
275

276     /**
277      * Returns the state of a feature.
278      *
279      * @param featureId The feature identifier.
280      *
281      * @throws XMLConfigurationException Thrown on configuration error.
282      */

283     public boolean getFeature(String JavaDoc featureId)
284             throws XMLConfigurationException {
285         if(featureId.equals( VALIDATION)) {
286             return fValidation;
287         } else if(featureId.equals( WARN_ON_DUPLICATE_ATTDEF)) {
288             return fWarnDuplicateAttdef;
289         } else if(featureId.equals( NOTIFY_CHAR_REFS)) {
290             return fDTDScanner.getFeature(featureId);
291         }
292         throw new XMLConfigurationException(XMLConfigurationException.NOT_RECOGNIZED, featureId);
293     } //getFeature(String): boolean
294

295     /**
296      * Set the locale to use for messages.
297      *
298      * @param locale The locale object to use for localization of messages.
299      *
300      * @exception XNIException Thrown if the parser does not support the
301      * specified locale.
302      */

303     public void setLocale(Locale JavaDoc locale) {
304         fLocale = locale;
305     } // setLocale(Locale)
306

307     /** Return the Locale the XMLGrammarLoader is using. */
308     public Locale JavaDoc getLocale() {
309         return fLocale;
310     } // getLocale(): Locale
311

312
313     /**
314      * Sets the error handler.
315      *
316      * @param errorHandler The error handler.
317      */

318     public void setErrorHandler(XMLErrorHandler errorHandler) {
319         fErrorReporter.setProperty(ERROR_HANDLER, errorHandler);
320     } // setErrorHandler(XMLErrorHandler)
321

322     /** Returns the registered error handler. */
323     public XMLErrorHandler getErrorHandler() {
324         return fErrorReporter.getErrorHandler();
325     } // getErrorHandler(): XMLErrorHandler
326

327     /**
328      * Sets the entity resolver.
329      *
330      * @param entityResolver The new entity resolver.
331      */

332     public void setEntityResolver(XMLEntityResolver entityResolver) {
333         fEntityResolver = entityResolver;
334     } // setEntityResolver(XMLEntityResolver)
335

336     /** Returns the registered entity resolver. */
337     public XMLEntityResolver getEntityResolver() {
338         return fEntityResolver;
339     } // getEntityResolver(): XMLEntityResolver
340

341     /**
342      * Returns a Grammar object by parsing the contents of the
343      * entity pointed to by source.
344      *
345      * @param source the location of the entity which forms
346      * the starting point of the grammar to be constructed.
347      * @throws IOException When a problem is encountered reading the entity
348      * XNIException When a condition arises (such as a FatalError) that requires parsing
349      * of the entity be terminated.
350      */

351     public Grammar loadGrammar(XMLInputSource source)
352             throws IOException JavaDoc, XNIException {
353         reset();
354         // First chance checking strict URI
355
String JavaDoc eid = XMLEntityManager.expandSystemId(source.getSystemId(), source.getBaseSystemId(), fStrictURI);
356         fDTDGrammar = new DTDGrammar(fSymbolTable, new XMLDTDDescription(source.getPublicId(), source.getSystemId(), source.getBaseSystemId(), eid, null));
357         fGrammarBucket = new DTDGrammarBucket();
358         fGrammarBucket.setStandalone(false);
359         fGrammarBucket.setActiveGrammar(fDTDGrammar);
360         // no reason to use grammar bucket's "put" method--we
361
// know which grammar it is, and we don't know the root name anyway...
362

363         // actually start the parsing!
364
try {
365             fDTDScanner.setInputSource(source);
366             fDTDScanner.scanDTDExternalSubset(true);
367         } catch (EOFException JavaDoc e) {
368             // expected behaviour...
369
}
370         finally {
371             // Close all streams opened by the parser.
372
fEntityManager.closeReaders();
373         }
374         if(fDTDGrammar != null && fGrammarPool != null) {
375             fGrammarPool.cacheGrammars(XMLDTDDescription.XML_DTD, new Grammar[] {fDTDGrammar});
376         }
377         return fDTDGrammar;
378     } // loadGrammar(XMLInputSource): Grammar
379

380     // reset all the components that we rely upon
381
protected void reset() {
382         super.reset();
383         fDTDScanner.reset();
384         fEntityManager.reset();
385         fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
386     }
387
388 } // class XMLDTDLoader
389
Popular Tags