KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xerces > internal > parsers > BasicParserConfiguration


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2001-2004 The Apache Software Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package com.sun.org.apache.xerces.internal.parsers;
59
60 import java.io.IOException JavaDoc;
61 import java.util.ArrayList JavaDoc;
62 import java.util.HashMap JavaDoc;
63 import java.util.Locale JavaDoc;
64
65 import com.sun.org.apache.xerces.internal.impl.Constants;
66 import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings;
67 import com.sun.org.apache.xerces.internal.util.SymbolTable;
68 import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler;
69 import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
70 import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
71 import com.sun.org.apache.xerces.internal.xni.XNIException;
72 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
73 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
74 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
75 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
76 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
77 import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
78 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
79 import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
80
81 /**
82  * A very basic parser configuration. This configuration class can
83  * be used as a base class for custom parser configurations. The
84  * basic parser configuration creates the symbol table (if not
85  * specified at construction time) and manages all of the recognized
86  * features and properties.
87  * <p>
88  * The basic parser configuration does <strong>not</strong> mandate
89  * any particular pipeline configuration or the use of specific
90  * components except for the symbol table. If even this is too much
91  * for a basic parser configuration, the programmer can create a new
92  * configuration class that implements the
93  * <code>XMLParserConfiguration</code> interface.
94  * <p>
95  * Subclasses of the basic parser configuration can add their own
96  * recognized features and properties by calling the
97  * <code>addRecognizedFeature</code> and
98  * <code>addRecognizedProperty</code> methods, respectively.
99  * <p>
100  * The basic parser configuration assumes that the configuration
101  * will be made up of various parser components that implement the
102  * <code>XMLComponent</code> interface. If subclasses of this
103  * configuration create their own components for use in the
104  * parser configuration, then each component should be added to
105  * the list of components by calling the <code>addComponent</code>
106  * method. The basic parser configuration will make sure to call
107  * the <code>reset</code> method of each registered component
108  * before parsing an instance document.
109  * <p>
110  * This class recognizes the following features and properties:
111  * <ul>
112  * <li>Features
113  * <ul>
114  * <li>http://xml.org/sax/features/validation</li>
115  * <li>http://xml.org/sax/features/namespaces</li>
116  * <li>http://xml.org/sax/features/external-general-entities</li>
117  * <li>http://xml.org/sax/features/external-parameter-entities</li>
118  * </ul>
119  * <li>Properties
120  * <ul>
121  * <li>http://xml.org/sax/properties/xml-string</li>
122  * <li>http://apache.org/xml/properties/internal/symbol-table</li>
123  * <li>http://apache.org/xml/properties/internal/error-handler</li>
124  * <li>http://apache.org/xml/properties/internal/entity-resolver</li>
125  * </ul>
126  * </ul>
127  *
128  * @author Arnaud Le Hors, IBM
129  * @author Andy Clark, IBM
130  *
131  * @version $Id: BasicParserConfiguration.java,v 1.24 2004/04/12 21:56:02 mrglavas Exp $
132  */

133 public abstract class BasicParserConfiguration
134     extends ParserConfigurationSettings
135     implements XMLParserConfiguration {
136
137     //
138
// Constants
139
//
140

141     // feature identifiers
142

143     /** Feature identifier: validation. */
144     protected static final String JavaDoc VALIDATION =
145         Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
146     
147     /** Feature identifier: namespaces. */
148     protected static final String JavaDoc NAMESPACES =
149         Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
150     
151     /** Feature identifier: external general entities. */
152     protected static final String JavaDoc EXTERNAL_GENERAL_ENTITIES =
153         Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_GENERAL_ENTITIES_FEATURE;
154     
155     /** Feature identifier: external parameter entities. */
156     protected static final String JavaDoc EXTERNAL_PARAMETER_ENTITIES =
157         Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_PARAMETER_ENTITIES_FEATURE;
158     
159     // property identifiers
160

161     /** Property identifier: xml string. */
162     protected static final String JavaDoc XML_STRING =
163         Constants.SAX_PROPERTY_PREFIX + Constants.XML_STRING_PROPERTY;
164
165     /** Property identifier: symbol table. */
166     protected static final String JavaDoc SYMBOL_TABLE =
167         Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
168
169     /** Property identifier: error handler. */
170     protected static final String JavaDoc ERROR_HANDLER =
171         Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
172
173     /** Property identifier: entity resolver. */
174     protected static final String JavaDoc ENTITY_RESOLVER =
175         Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
176
177     //
178
// Data
179
//
180

181     // components (non-configurable)
182

183     /** Symbol table. */
184     protected SymbolTable fSymbolTable;
185
186
187     // data
188

189     /** Locale. */
190     protected Locale JavaDoc fLocale;
191
192     /** Components. */
193     protected ArrayList JavaDoc fComponents;
194
195     // handlers
196

197     /** The document handler. */
198     protected XMLDocumentHandler fDocumentHandler;
199
200     /** The DTD handler. */
201     protected XMLDTDHandler fDTDHandler;
202
203     /** The DTD content model handler. */
204     protected XMLDTDContentModelHandler fDTDContentModelHandler;
205
206     /** Last component in the document pipeline */
207     protected XMLDocumentSource fLastComponent;
208
209     //
210
// Constructors
211
//
212

213     /** Default Constructor. */
214     protected BasicParserConfiguration() {
215         this(null, null);
216     } // <init>()
217

218     /**
219      * Constructs a parser configuration using the specified symbol table.
220      *
221      * @param symbolTable The symbol table to use.
222      */

223     protected BasicParserConfiguration(SymbolTable symbolTable) {
224         this(symbolTable, null);
225     } // <init>(SymbolTable)
226

227     /**
228      * Constructs a parser configuration using the specified symbol table
229      * and parent settings.
230      *
231      * @param symbolTable The symbol table to use.
232      * @param parentSettings The parent settings.
233      */

234     protected BasicParserConfiguration(SymbolTable symbolTable,
235                                        XMLComponentManager parentSettings) {
236         super(parentSettings);
237
238         // create a vector to hold all the components in use
239
fComponents = new ArrayList JavaDoc();
240
241         // create storage for recognized features and properties
242
fRecognizedFeatures = new ArrayList JavaDoc();
243         fRecognizedProperties = new ArrayList JavaDoc();
244
245         // create table for features and properties
246
fFeatures = new HashMap JavaDoc();
247         fProperties = new HashMap JavaDoc();
248
249         // add default recognized features
250
final String JavaDoc[] recognizedFeatures = {
251             PARSER_SETTINGS,
252             VALIDATION,
253             NAMESPACES,
254             EXTERNAL_GENERAL_ENTITIES,
255             EXTERNAL_PARAMETER_ENTITIES,
256         };
257         addRecognizedFeatures(recognizedFeatures);
258         fFeatures.put(PARSER_SETTINGS, Boolean.TRUE);
259         // set state for default features
260
fFeatures.put(VALIDATION, Boolean.FALSE);
261         fFeatures.put(NAMESPACES, Boolean.TRUE);
262         fFeatures.put(EXTERNAL_GENERAL_ENTITIES, Boolean.TRUE);
263         fFeatures.put(EXTERNAL_PARAMETER_ENTITIES, Boolean.TRUE);
264
265         // add default recognized properties
266
final String JavaDoc[] recognizedProperties = {
267             XML_STRING,
268             SYMBOL_TABLE,
269             ERROR_HANDLER,
270             ENTITY_RESOLVER,
271         };
272         addRecognizedProperties(recognizedProperties);
273
274         if (symbolTable == null) {
275             symbolTable = new SymbolTable();
276         }
277         fSymbolTable = symbolTable;
278         fProperties.put(SYMBOL_TABLE, fSymbolTable);
279
280     } // <init>(SymbolTable)
281

282     /**
283      * Adds a component to the parser configuration. This method will
284      * also add all of the component's recognized features and properties
285      * to the list of default recognized features and properties.
286      *
287      * @param component The component to add.
288      */

289     protected void addComponent(XMLComponent component) {
290
291         // don't add a component more than once
292
if (fComponents.contains(component)) {
293             return;
294         }
295         fComponents.add(component);
296
297         // register component's recognized features
298
String JavaDoc[] recognizedFeatures = component.getRecognizedFeatures();
299         addRecognizedFeatures(recognizedFeatures);
300         
301         // register component's recognized properties
302
String JavaDoc[] recognizedProperties = component.getRecognizedProperties();
303         addRecognizedProperties(recognizedProperties);
304
305         // set default values
306
if (recognizedFeatures != null) {
307             for (int i = 0; i < recognizedFeatures.length; i++) {
308                 String JavaDoc featureId = recognizedFeatures[i];
309                 Boolean JavaDoc state = component.getFeatureDefault(featureId);
310                 if (state != null) {
311                     super.setFeature(featureId, state.booleanValue());
312                 }
313             }
314         }
315         if (recognizedProperties != null) {
316             for (int i = 0; i < recognizedProperties.length; i++) {
317                 String JavaDoc propertyId = recognizedProperties[i];
318                 Object JavaDoc value = component.getPropertyDefault(propertyId);
319                 if (value != null) {
320                     super.setProperty(propertyId, value);
321                 }
322             }
323         }
324
325     } // addComponent(XMLComponent)
326

327     //
328
// XMLParserConfiguration methods
329
//
330

331     /**
332      * Parse an XML document.
333      * <p>
334      * The parser can use this method to instruct this configuration
335      * to begin parsing an XML document from any valid input source
336      * (a character stream, a byte stream, or a URI).
337      * <p>
338      * Parsers may not invoke this method while a parse is in progress.
339      * Once a parse is complete, the parser may then parse another XML
340      * document.
341      * <p>
342      * This method is synchronous: it will not return until parsing
343      * has ended. If a client application wants to terminate
344      * parsing early, it should throw an exception.
345      *
346      * @param inputSource The input source for the top-level of the
347      * XML document.
348      *
349      * @exception XNIException Any XNI exception, possibly wrapping
350      * another exception.
351      * @exception IOException An IO exception from the parser, possibly
352      * from a byte stream or character stream
353      * supplied by the parser.
354      */

355     public abstract void parse(XMLInputSource inputSource)
356         throws XNIException, IOException JavaDoc;
357
358     /**
359      * Sets the document handler on the last component in the pipeline
360      * to receive information about the document.
361      *
362      * @param documentHandler The document handler.
363      */

364     public void setDocumentHandler(XMLDocumentHandler documentHandler) {
365         fDocumentHandler = documentHandler;
366         if (fLastComponent != null) {
367             fLastComponent.setDocumentHandler(fDocumentHandler);
368             if (fDocumentHandler !=null){
369                 fDocumentHandler.setDocumentSource(fLastComponent);
370             }
371         }
372     } // setDocumentHandler(XMLDocumentHandler)
373

374     /** Returns the registered document handler. */
375     public XMLDocumentHandler getDocumentHandler() {
376         return fDocumentHandler;
377     } // getDocumentHandler():XMLDocumentHandler
378

379     /**
380      * Sets the DTD handler.
381      *
382      * @param dtdHandler The DTD handler.
383      */

384     public void setDTDHandler(XMLDTDHandler dtdHandler) {
385         fDTDHandler = dtdHandler;
386     } // setDTDHandler(XMLDTDHandler)
387

388     /** Returns the registered DTD handler. */
389     public XMLDTDHandler getDTDHandler() {
390         return fDTDHandler;
391     } // getDTDHandler():XMLDTDHandler
392

393     /**
394      * Sets the DTD content model handler.
395      *
396      * @param handler The DTD content model handler.
397      */

398     public void setDTDContentModelHandler(XMLDTDContentModelHandler handler) {
399         fDTDContentModelHandler = handler;
400     } // setDTDContentModelHandler(XMLDTDContentModelHandler)
401

402     /** Returns the registered DTD content model handler. */
403     public XMLDTDContentModelHandler getDTDContentModelHandler() {
404         return fDTDContentModelHandler;
405     } // getDTDContentModelHandler():XMLDTDContentModelHandler
406

407     /**
408      * Sets the resolver used to resolve external entities. The EntityResolver
409      * interface supports resolution of public and system identifiers.
410      *
411      * @param resolver The new entity resolver. Passing a null value will
412      * uninstall the currently installed resolver.
413      */

414     public void setEntityResolver(XMLEntityResolver resolver) {
415         // REVISIT: Should this be a property?
416
fProperties.put(ENTITY_RESOLVER, resolver);
417     } // setEntityResolver(XMLEntityResolver)
418

419     /**
420      * Return the current entity resolver.
421      *
422      * @return The current entity resolver, or null if none
423      * has been registered.
424      * @see #setEntityResolver
425      */

426     public XMLEntityResolver getEntityResolver() {
427         // REVISIT: Should this be a property?
428
return (XMLEntityResolver)fProperties.get(ENTITY_RESOLVER);
429     } // getEntityResolver():XMLEntityResolver
430

431     /**
432      * Allow an application to register an error event handler.
433      *
434      * <p>If the application does not register an error handler, all
435      * error events reported by the SAX parser will be silently
436      * ignored; however, normal processing may not continue. It is
437      * highly recommended that all SAX applications implement an
438      * error handler to avoid unexpected bugs.</p>
439      *
440      * <p>Applications may register a new or different handler in the
441      * middle of a parse, and the SAX parser must begin using the new
442      * handler immediately.</p>
443      *
444      * @param errorHandler The error handler.
445      * @exception java.lang.NullPointerException If the handler
446      * argument is null.
447      * @see #getErrorHandler
448      */

449     public void setErrorHandler(XMLErrorHandler errorHandler) {
450         // REVISIT: Should this be a property?
451
fProperties.put(ERROR_HANDLER, errorHandler);
452     } // setErrorHandler(XMLErrorHandler)
453

454     /**
455      * Return the current error handler.
456      *
457      * @return The current error handler, or null if none
458      * has been registered.
459      * @see #setErrorHandler
460      */

461     public XMLErrorHandler getErrorHandler() {
462         // REVISIT: Should this be a property?
463
return (XMLErrorHandler)fProperties.get(ERROR_HANDLER);
464     } // getErrorHandler():XMLErrorHandler
465

466     /**
467      * Set the state of a feature.
468      *
469      * Set the state of any feature in a SAX2 parser. The parser
470      * might not recognize the feature, and if it does recognize
471      * it, it might not be able to fulfill the request.
472      *
473      * @param featureId The unique identifier (URI) of the feature.
474      * @param state The requested state of the feature (true or false).
475      *
476      * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the
477      * requested feature is not known.
478      */

479     public void setFeature(String JavaDoc featureId, boolean state)
480         throws XMLConfigurationException {
481
482         // forward to every component
483
int count = fComponents.size();
484         for (int i = 0; i < count; i++) {
485             XMLComponent c = (XMLComponent) fComponents.get(i);
486             c.setFeature(featureId, state);
487         }
488         // save state if noone "objects"
489
super.setFeature(featureId, state);
490
491     } // setFeature(String,boolean)
492

493     /**
494      * setProperty
495      *
496      * @param propertyId
497      * @param value
498      */

499     public void setProperty(String JavaDoc propertyId, Object JavaDoc value)
500         throws XMLConfigurationException {
501
502         // forward to every component
503
int count = fComponents.size();
504         for (int i = 0; i < count; i++) {
505             XMLComponent c = (XMLComponent) fComponents.get(i);
506             c.setProperty(propertyId, value);
507         }
508
509         // store value if noone "objects"
510
super.setProperty(propertyId, value);
511
512     } // setProperty(String,Object)
513

514     /**
515      * Set the locale to use for messages.
516      *
517      * @param locale The locale object to use for localization of messages.
518      *
519      * @exception XNIException Thrown if the parser does not support the
520      * specified locale.
521      */

522     public void setLocale(Locale JavaDoc locale) throws XNIException {
523         fLocale = locale;
524     } // setLocale(Locale)
525

526     /** Returns the locale. */
527     public Locale JavaDoc getLocale() {
528         return fLocale;
529     } // getLocale():Locale
530

531     //
532
// Protected methods
533
//
534

535     /**
536      * reset all components before parsing and namespace context
537      */

538     protected void reset() throws XNIException {
539
540         // reset every component
541
int count = fComponents.size();
542         for (int i = 0; i < count; i++) {
543             XMLComponent c = (XMLComponent) fComponents.get(i);
544             c.reset(this);
545         }
546
547     } // reset()
548

549     /**
550      * Check a property. If the property is known and supported, this method
551      * simply returns. Otherwise, the appropriate exception is thrown.
552      *
553      * @param propertyId The unique identifier (URI) of the property
554      * being set.
555      * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the
556      * requested feature is not known or supported.
557      */

558     protected void checkProperty(String JavaDoc propertyId)
559         throws XMLConfigurationException {
560
561         // special cases
562
if (propertyId.startsWith(Constants.SAX_PROPERTY_PREFIX)) {
563             final int suffixLength = propertyId.length() - Constants.SAX_PROPERTY_PREFIX.length();
564             
565             //
566
// http://xml.org/sax/properties/xml-string
567
// Value type: String
568
// Access: read-only
569
// Get the literal string of characters associated with the
570
// current event. If the parser recognises and supports this
571
// property but is not currently parsing text, it should return
572
// null (this is a good way to check for availability before the
573
// parse begins).
574
//
575
if (suffixLength == Constants.XML_STRING_PROPERTY.length() &&
576                 propertyId.endsWith(Constants.XML_STRING_PROPERTY)) {
577                 // REVISIT - we should probably ask xml-dev for a precise
578
// definition of what this is actually supposed to return, and
579
// in exactly which circumstances.
580
short type = XMLConfigurationException.NOT_SUPPORTED;
581                 throw new XMLConfigurationException(type, propertyId);
582             }
583         }
584
585         // check property
586
super.checkProperty(propertyId);
587
588     } // checkProperty(String)
589

590     
591     /**
592      * Check a feature. If feature is know and supported, this method simply
593      * returns. Otherwise, the appropriate exception is thrown.
594      *
595      * @param featureId The unique identifier (URI) of the feature.
596      *
597      * @throws XMLConfigurationException Thrown for configuration error.
598      * In general, components should
599      * only throw this exception if
600      * it is <strong>really</strong>
601      * a critical error.
602      */

603     protected void checkFeature(String JavaDoc featureId)
604         throws XMLConfigurationException {
605
606         //
607
// Xerces Features
608
//
609
if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
610             final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
611
612             //
613
// special performance feature: no one by component manager is allowed to set it
614
//
615
if (suffixLength == Constants.PARSER_SETTINGS.length() &&
616                 featureId.endsWith(Constants.PARSER_SETTINGS)) {
617                 short type = XMLConfigurationException.NOT_SUPPORTED;
618                 throw new XMLConfigurationException(type, featureId);
619             }
620         }
621
622         super.checkFeature(featureId);
623
624      } // checkFeature(String)
625

626
627 } // class BasicParserConfiguration
628
Popular Tags