KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xerces > parsers > BasicParserConfiguration


1 /*
2  * Copyright 2001-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.parsers;
18
19 import java.io.IOException JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Locale JavaDoc;
23
24 import org.apache.xerces.impl.Constants;
25 import org.apache.xerces.util.ParserConfigurationSettings;
26 import org.apache.xerces.util.SymbolTable;
27 import org.apache.xerces.xni.XMLDTDContentModelHandler;
28 import org.apache.xerces.xni.XMLDTDHandler;
29 import org.apache.xerces.xni.XMLDocumentHandler;
30 import org.apache.xerces.xni.XNIException;
31 import org.apache.xerces.xni.parser.XMLComponent;
32 import org.apache.xerces.xni.parser.XMLComponentManager;
33 import org.apache.xerces.xni.parser.XMLConfigurationException;
34 import org.apache.xerces.xni.parser.XMLDocumentSource;
35 import org.apache.xerces.xni.parser.XMLEntityResolver;
36 import org.apache.xerces.xni.parser.XMLErrorHandler;
37 import org.apache.xerces.xni.parser.XMLInputSource;
38 import org.apache.xerces.xni.parser.XMLParserConfiguration;
39
40 /**
41  * A very basic parser configuration. This configuration class can
42  * be used as a base class for custom parser configurations. The
43  * basic parser configuration creates the symbol table (if not
44  * specified at construction time) and manages all of the recognized
45  * features and properties.
46  * <p>
47  * The basic parser configuration does <strong>not</strong> mandate
48  * any particular pipeline configuration or the use of specific
49  * components except for the symbol table. If even this is too much
50  * for a basic parser configuration, the programmer can create a new
51  * configuration class that implements the
52  * <code>XMLParserConfiguration</code> interface.
53  * <p>
54  * Subclasses of the basic parser configuration can add their own
55  * recognized features and properties by calling the
56  * <code>addRecognizedFeature</code> and
57  * <code>addRecognizedProperty</code> methods, respectively.
58  * <p>
59  * The basic parser configuration assumes that the configuration
60  * will be made up of various parser components that implement the
61  * <code>XMLComponent</code> interface. If subclasses of this
62  * configuration create their own components for use in the
63  * parser configuration, then each component should be added to
64  * the list of components by calling the <code>addComponent</code>
65  * method. The basic parser configuration will make sure to call
66  * the <code>reset</code> method of each registered component
67  * before parsing an instance document.
68  * <p>
69  * This class recognizes the following features and properties:
70  * <ul>
71  * <li>Features
72  * <ul>
73  * <li>http://xml.org/sax/features/validation</li>
74  * <li>http://xml.org/sax/features/namespaces</li>
75  * <li>http://xml.org/sax/features/external-general-entities</li>
76  * <li>http://xml.org/sax/features/external-parameter-entities</li>
77  * </ul>
78  * <li>Properties
79  * <ul>
80  * <li>http://xml.org/sax/properties/xml-string</li>
81  * <li>http://apache.org/xml/properties/internal/symbol-table</li>
82  * <li>http://apache.org/xml/properties/internal/error-handler</li>
83  * <li>http://apache.org/xml/properties/internal/entity-resolver</li>
84  * </ul>
85  * </ul>
86  *
87  * @author Arnaud Le Hors, IBM
88  * @author Andy Clark, IBM
89  *
90  * @version $Id: BasicParserConfiguration.java,v 1.24 2004/04/12 21:56:02 mrglavas Exp $
91  */

92 public abstract class BasicParserConfiguration
93     extends ParserConfigurationSettings
94     implements XMLParserConfiguration {
95
96     //
97
// Constants
98
//
99

100     // feature identifiers
101

102     /** Feature identifier: validation. */
103     protected static final String JavaDoc VALIDATION =
104         Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
105     
106     /** Feature identifier: namespaces. */
107     protected static final String JavaDoc NAMESPACES =
108         Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
109     
110     /** Feature identifier: external general entities. */
111     protected static final String JavaDoc EXTERNAL_GENERAL_ENTITIES =
112         Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_GENERAL_ENTITIES_FEATURE;
113     
114     /** Feature identifier: external parameter entities. */
115     protected static final String JavaDoc EXTERNAL_PARAMETER_ENTITIES =
116         Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_PARAMETER_ENTITIES_FEATURE;
117     
118     // property identifiers
119

120     /** Property identifier: xml string. */
121     protected static final String JavaDoc XML_STRING =
122         Constants.SAX_PROPERTY_PREFIX + Constants.XML_STRING_PROPERTY;
123
124     /** Property identifier: symbol table. */
125     protected static final String JavaDoc SYMBOL_TABLE =
126         Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
127
128     /** Property identifier: error handler. */
129     protected static final String JavaDoc ERROR_HANDLER =
130         Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
131
132     /** Property identifier: entity resolver. */
133     protected static final String JavaDoc ENTITY_RESOLVER =
134         Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
135
136     //
137
// Data
138
//
139

140     // components (non-configurable)
141

142     /** Symbol table. */
143     protected SymbolTable fSymbolTable;
144
145
146     // data
147

148     /** Locale. */
149     protected Locale JavaDoc fLocale;
150
151     /** Components. */
152     protected ArrayList JavaDoc fComponents;
153
154     // handlers
155

156     /** The document handler. */
157     protected XMLDocumentHandler fDocumentHandler;
158
159     /** The DTD handler. */
160     protected XMLDTDHandler fDTDHandler;
161
162     /** The DTD content model handler. */
163     protected XMLDTDContentModelHandler fDTDContentModelHandler;
164
165     /** Last component in the document pipeline */
166     protected XMLDocumentSource fLastComponent;
167
168     //
169
// Constructors
170
//
171

172     /** Default Constructor. */
173     protected BasicParserConfiguration() {
174         this(null, null);
175     } // <init>()
176

177     /**
178      * Constructs a parser configuration using the specified symbol table.
179      *
180      * @param symbolTable The symbol table to use.
181      */

182     protected BasicParserConfiguration(SymbolTable symbolTable) {
183         this(symbolTable, null);
184     } // <init>(SymbolTable)
185

186     /**
187      * Constructs a parser configuration using the specified symbol table
188      * and parent settings.
189      *
190      * @param symbolTable The symbol table to use.
191      * @param parentSettings The parent settings.
192      */

193     protected BasicParserConfiguration(SymbolTable symbolTable,
194                                        XMLComponentManager parentSettings) {
195         super(parentSettings);
196
197         // create a vector to hold all the components in use
198
fComponents = new ArrayList JavaDoc();
199
200         // create storage for recognized features and properties
201
fRecognizedFeatures = new ArrayList JavaDoc();
202         fRecognizedProperties = new ArrayList JavaDoc();
203
204         // create table for features and properties
205
fFeatures = new HashMap JavaDoc();
206         fProperties = new HashMap JavaDoc();
207
208         // add default recognized features
209
final String JavaDoc[] recognizedFeatures = {
210             PARSER_SETTINGS,
211             VALIDATION,
212             NAMESPACES,
213             EXTERNAL_GENERAL_ENTITIES,
214             EXTERNAL_PARAMETER_ENTITIES,
215         };
216         addRecognizedFeatures(recognizedFeatures);
217         fFeatures.put(PARSER_SETTINGS, Boolean.TRUE);
218         // set state for default features
219
fFeatures.put(VALIDATION, Boolean.FALSE);
220         fFeatures.put(NAMESPACES, Boolean.TRUE);
221         fFeatures.put(EXTERNAL_GENERAL_ENTITIES, Boolean.TRUE);
222         fFeatures.put(EXTERNAL_PARAMETER_ENTITIES, Boolean.TRUE);
223
224         // add default recognized properties
225
final String JavaDoc[] recognizedProperties = {
226             XML_STRING,
227             SYMBOL_TABLE,
228             ERROR_HANDLER,
229             ENTITY_RESOLVER,
230         };
231         addRecognizedProperties(recognizedProperties);
232
233         if (symbolTable == null) {
234             symbolTable = new SymbolTable();
235         }
236         fSymbolTable = symbolTable;
237         fProperties.put(SYMBOL_TABLE, fSymbolTable);
238
239     } // <init>(SymbolTable)
240

241     /**
242      * Adds a component to the parser configuration. This method will
243      * also add all of the component's recognized features and properties
244      * to the list of default recognized features and properties.
245      *
246      * @param component The component to add.
247      */

248     protected void addComponent(XMLComponent component) {
249
250         // don't add a component more than once
251
if (fComponents.contains(component)) {
252             return;
253         }
254         fComponents.add(component);
255
256         // register component's recognized features
257
String JavaDoc[] recognizedFeatures = component.getRecognizedFeatures();
258         addRecognizedFeatures(recognizedFeatures);
259         
260         // register component's recognized properties
261
String JavaDoc[] recognizedProperties = component.getRecognizedProperties();
262         addRecognizedProperties(recognizedProperties);
263
264         // set default values
265
if (recognizedFeatures != null) {
266             for (int i = 0; i < recognizedFeatures.length; i++) {
267                 String JavaDoc featureId = recognizedFeatures[i];
268                 Boolean JavaDoc state = component.getFeatureDefault(featureId);
269                 if (state != null) {
270                     super.setFeature(featureId, state.booleanValue());
271                 }
272             }
273         }
274         if (recognizedProperties != null) {
275             for (int i = 0; i < recognizedProperties.length; i++) {
276                 String JavaDoc propertyId = recognizedProperties[i];
277                 Object JavaDoc value = component.getPropertyDefault(propertyId);
278                 if (value != null) {
279                     super.setProperty(propertyId, value);
280                 }
281             }
282         }
283
284     } // addComponent(XMLComponent)
285

286     //
287
// XMLParserConfiguration methods
288
//
289

290     /**
291      * Parse an XML document.
292      * <p>
293      * The parser can use this method to instruct this configuration
294      * to begin parsing an XML document from any valid input source
295      * (a character stream, a byte stream, or a URI).
296      * <p>
297      * Parsers may not invoke this method while a parse is in progress.
298      * Once a parse is complete, the parser may then parse another XML
299      * document.
300      * <p>
301      * This method is synchronous: it will not return until parsing
302      * has ended. If a client application wants to terminate
303      * parsing early, it should throw an exception.
304      *
305      * @param inputSource The input source for the top-level of the
306      * XML document.
307      *
308      * @exception XNIException Any XNI exception, possibly wrapping
309      * another exception.
310      * @exception IOException An IO exception from the parser, possibly
311      * from a byte stream or character stream
312      * supplied by the parser.
313      */

314     public abstract void parse(XMLInputSource inputSource)
315         throws XNIException, IOException JavaDoc;
316
317     /**
318      * Sets the document handler on the last component in the pipeline
319      * to receive information about the document.
320      *
321      * @param documentHandler The document handler.
322      */

323     public void setDocumentHandler(XMLDocumentHandler documentHandler) {
324         fDocumentHandler = documentHandler;
325         if (fLastComponent != null) {
326             fLastComponent.setDocumentHandler(fDocumentHandler);
327             if (fDocumentHandler !=null){
328                 fDocumentHandler.setDocumentSource(fLastComponent);
329             }
330         }
331     } // setDocumentHandler(XMLDocumentHandler)
332

333     /** Returns the registered document handler. */
334     public XMLDocumentHandler getDocumentHandler() {
335         return fDocumentHandler;
336     } // getDocumentHandler():XMLDocumentHandler
337

338     /**
339      * Sets the DTD handler.
340      *
341      * @param dtdHandler The DTD handler.
342      */

343     public void setDTDHandler(XMLDTDHandler dtdHandler) {
344         fDTDHandler = dtdHandler;
345     } // setDTDHandler(XMLDTDHandler)
346

347     /** Returns the registered DTD handler. */
348     public XMLDTDHandler getDTDHandler() {
349         return fDTDHandler;
350     } // getDTDHandler():XMLDTDHandler
351

352     /**
353      * Sets the DTD content model handler.
354      *
355      * @param handler The DTD content model handler.
356      */

357     public void setDTDContentModelHandler(XMLDTDContentModelHandler handler) {
358         fDTDContentModelHandler = handler;
359     } // setDTDContentModelHandler(XMLDTDContentModelHandler)
360

361     /** Returns the registered DTD content model handler. */
362     public XMLDTDContentModelHandler getDTDContentModelHandler() {
363         return fDTDContentModelHandler;
364     } // getDTDContentModelHandler():XMLDTDContentModelHandler
365

366     /**
367      * Sets the resolver used to resolve external entities. The EntityResolver
368      * interface supports resolution of public and system identifiers.
369      *
370      * @param resolver The new entity resolver. Passing a null value will
371      * uninstall the currently installed resolver.
372      */

373     public void setEntityResolver(XMLEntityResolver resolver) {
374         // REVISIT: Should this be a property?
375
fProperties.put(ENTITY_RESOLVER, resolver);
376     } // setEntityResolver(XMLEntityResolver)
377

378     /**
379      * Return the current entity resolver.
380      *
381      * @return The current entity resolver, or null if none
382      * has been registered.
383      * @see #setEntityResolver
384      */

385     public XMLEntityResolver getEntityResolver() {
386         // REVISIT: Should this be a property?
387
return (XMLEntityResolver)fProperties.get(ENTITY_RESOLVER);
388     } // getEntityResolver():XMLEntityResolver
389

390     /**
391      * Allow an application to register an error event handler.
392      *
393      * <p>If the application does not register an error handler, all
394      * error events reported by the SAX parser will be silently
395      * ignored; however, normal processing may not continue. It is
396      * highly recommended that all SAX applications implement an
397      * error handler to avoid unexpected bugs.</p>
398      *
399      * <p>Applications may register a new or different handler in the
400      * middle of a parse, and the SAX parser must begin using the new
401      * handler immediately.</p>
402      *
403      * @param errorHandler The error handler.
404      * @exception java.lang.NullPointerException If the handler
405      * argument is null.
406      * @see #getErrorHandler
407      */

408     public void setErrorHandler(XMLErrorHandler errorHandler) {
409         // REVISIT: Should this be a property?
410
fProperties.put(ERROR_HANDLER, errorHandler);
411     } // setErrorHandler(XMLErrorHandler)
412

413     /**
414      * Return the current error handler.
415      *
416      * @return The current error handler, or null if none
417      * has been registered.
418      * @see #setErrorHandler
419      */

420     public XMLErrorHandler getErrorHandler() {
421         // REVISIT: Should this be a property?
422
return (XMLErrorHandler)fProperties.get(ERROR_HANDLER);
423     } // getErrorHandler():XMLErrorHandler
424

425     /**
426      * Set the state of a feature.
427      *
428      * Set the state of any feature in a SAX2 parser. The parser
429      * might not recognize the feature, and if it does recognize
430      * it, it might not be able to fulfill the request.
431      *
432      * @param featureId The unique identifier (URI) of the feature.
433      * @param state The requested state of the feature (true or false).
434      *
435      * @exception org.apache.xerces.xni.parser.XMLConfigurationException If the
436      * requested feature is not known.
437      */

438     public void setFeature(String JavaDoc featureId, boolean state)
439         throws XMLConfigurationException {
440
441         // forward to every component
442
int count = fComponents.size();
443         for (int i = 0; i < count; i++) {
444             XMLComponent c = (XMLComponent) fComponents.get(i);
445             c.setFeature(featureId, state);
446         }
447         // save state if noone "objects"
448
super.setFeature(featureId, state);
449
450     } // setFeature(String,boolean)
451

452     /**
453      * setProperty
454      *
455      * @param propertyId
456      * @param value
457      */

458     public void setProperty(String JavaDoc propertyId, Object JavaDoc value)
459         throws XMLConfigurationException {
460
461         // forward to every component
462
int count = fComponents.size();
463         for (int i = 0; i < count; i++) {
464             XMLComponent c = (XMLComponent) fComponents.get(i);
465             c.setProperty(propertyId, value);
466         }
467
468         // store value if noone "objects"
469
super.setProperty(propertyId, value);
470
471     } // setProperty(String,Object)
472

473     /**
474      * Set the locale to use for messages.
475      *
476      * @param locale The locale object to use for localization of messages.
477      *
478      * @exception XNIException Thrown if the parser does not support the
479      * specified locale.
480      */

481     public void setLocale(Locale JavaDoc locale) throws XNIException {
482         fLocale = locale;
483     } // setLocale(Locale)
484

485     /** Returns the locale. */
486     public Locale JavaDoc getLocale() {
487         return fLocale;
488     } // getLocale():Locale
489

490     //
491
// Protected methods
492
//
493

494     /**
495      * reset all components before parsing and namespace context
496      */

497     protected void reset() throws XNIException {
498
499         // reset every component
500
int count = fComponents.size();
501         for (int i = 0; i < count; i++) {
502             XMLComponent c = (XMLComponent) fComponents.get(i);
503             c.reset(this);
504         }
505
506     } // reset()
507

508     /**
509      * Check a property. If the property is known and supported, this method
510      * simply returns. Otherwise, the appropriate exception is thrown.
511      *
512      * @param propertyId The unique identifier (URI) of the property
513      * being set.
514      * @exception org.apache.xerces.xni.parser.XMLConfigurationException If the
515      * requested feature is not known or supported.
516      */

517     protected void checkProperty(String JavaDoc propertyId)
518         throws XMLConfigurationException {
519
520         // special cases
521
if (propertyId.startsWith(Constants.SAX_PROPERTY_PREFIX)) {
522             final int suffixLength = propertyId.length() - Constants.SAX_PROPERTY_PREFIX.length();
523             
524             //
525
// http://xml.org/sax/properties/xml-string
526
// Value type: String
527
// Access: read-only
528
// Get the literal string of characters associated with the
529
// current event. If the parser recognises and supports this
530
// property but is not currently parsing text, it should return
531
// null (this is a good way to check for availability before the
532
// parse begins).
533
//
534
if (suffixLength == Constants.XML_STRING_PROPERTY.length() &&
535                 propertyId.endsWith(Constants.XML_STRING_PROPERTY)) {
536                 // REVISIT - we should probably ask xml-dev for a precise
537
// definition of what this is actually supposed to return, and
538
// in exactly which circumstances.
539
short type = XMLConfigurationException.NOT_SUPPORTED;
540                 throw new XMLConfigurationException(type, propertyId);
541             }
542         }
543
544         // check property
545
super.checkProperty(propertyId);
546
547     } // checkProperty(String)
548

549     
550     /**
551      * Check a feature. If feature is know and supported, this method simply
552      * returns. Otherwise, the appropriate exception is thrown.
553      *
554      * @param featureId The unique identifier (URI) of the feature.
555      *
556      * @throws XMLConfigurationException Thrown for configuration error.
557      * In general, components should
558      * only throw this exception if
559      * it is <strong>really</strong>
560      * a critical error.
561      */

562     protected void checkFeature(String JavaDoc featureId)
563         throws XMLConfigurationException {
564
565         //
566
// Xerces Features
567
//
568
if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
569             final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
570
571             //
572
// special performance feature: no one by component manager is allowed to set it
573
//
574
if (suffixLength == Constants.PARSER_SETTINGS.length() &&
575                 featureId.endsWith(Constants.PARSER_SETTINGS)) {
576                 short type = XMLConfigurationException.NOT_SUPPORTED;
577                 throw new XMLConfigurationException(type, featureId);
578             }
579         }
580
581         super.checkFeature(featureId);
582
583      } // checkFeature(String)
584

585
586 } // class BasicParserConfiguration
587
Popular Tags