KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999-2002 The Apache Software Foundation. All rights
6  * 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 com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
61 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
62 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
63 import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl;
64
65 import com.sun.org.apache.xerces.internal.util.ShadowedSymbolTable;
66 import com.sun.org.apache.xerces.internal.util.SymbolTable;
67 import com.sun.org.apache.xerces.internal.util.SynchronizedSymbolTable;
68
69 /**
70  * A parser pool that enables caching of grammars. The caching parser
71  * pool is constructed with a specific symbol table and grammar pool
72  * that has already been populated with the grammars used by the
73  * application.
74  * <p>
75  * Once the caching parser pool is constructed, specific parser
76  * instances are created by calling the appropriate factory method
77  * on the parser pool.
78  * <p>
79  * <strong>Note:</strong> There is a performance penalty for using
80  * a caching parser pool due to thread safety. Access to the symbol
81  * table and grammar pool must be synchronized to ensure the safe
82  * operation of the symbol table and grammar pool.
83  * <p>
84  * <strong>Note:</strong> If performance is critical, then another
85  * mechanism needs to be used instead of the caching parser pool.
86  * One approach would be to create parser instances that do not
87  * share these structures. Instead, each instance would get its
88  * own copy to use while parsing. This avoids the synchronization
89  * overhead at the expense of more memory and the time required
90  * to copy the structures for each new parser instance. And even
91  * when a parser instance is re-used, there is a potential for a
92  * memory leak due to new symbols being added to the symbol table
93  * over time. In other words, always take caution to make sure
94  * that your application is thread-safe and avoids leaking memory.
95  *
96  * @author Andy Clark, IBM
97  *
98  * @version $Id: CachingParserPool.java,v 1.11 2002/06/01 16:36:36 elena Exp $
99  */

100 public class CachingParserPool {
101
102     //
103
// Constants
104
//
105

106     /** Default shadow symbol table (false). */
107     public static final boolean DEFAULT_SHADOW_SYMBOL_TABLE = false;
108
109     /** Default shadow grammar pool (false). */
110     public static final boolean DEFAULT_SHADOW_GRAMMAR_POOL = false;
111
112     //
113
// Data
114
//
115

116     /**
117      * Symbol table. The symbol table that the caching parser pool is
118      * constructed with is automatically wrapped in a synchronized
119      * version for thread-safety.
120      */

121     protected SymbolTable fSynchronizedSymbolTable;
122
123     /**
124      * Grammar pool. The grammar pool that the caching parser pool is
125      * constructed with is automatically wrapped in a synchronized
126      * version for thread-safety.
127      */

128     protected XMLGrammarPool fSynchronizedGrammarPool;
129
130     /**
131      * Shadow the symbol table for new parser instances. If true,
132      * new parser instances use shadow copies of the main symbol
133      * table and are not allowed to add new symbols to the main
134      * symbol table. New symbols are added to the shadow symbol
135      * table and are local to the parser instance.
136      */

137     protected boolean fShadowSymbolTable = DEFAULT_SHADOW_SYMBOL_TABLE;
138
139     /**
140      * Shadow the grammar pool for new parser instances. If true,
141      * new parser instances use shadow copies of the main grammar
142      * pool and are not allowed to add new grammars to the main
143      * grammar pool. New grammars are added to the shadow grammar
144      * pool and are local to the parser instance.
145      */

146     protected boolean fShadowGrammarPool = DEFAULT_SHADOW_GRAMMAR_POOL;
147
148     //
149
// Constructors
150
//
151

152     /** Default constructor. */
153     public CachingParserPool() {
154         this(new SymbolTable(), new XMLGrammarPoolImpl());
155     } // <init>()
156

157     /**
158      * Constructs a caching parser pool with the specified symbol table
159      * and grammar pool.
160      *
161      * @param symbolTable The symbol table.
162      * @param grammarPool The grammar pool.
163      */

164     public CachingParserPool(SymbolTable symbolTable, XMLGrammarPool grammarPool) {
165         fSynchronizedSymbolTable = new SynchronizedSymbolTable(symbolTable);
166         fSynchronizedGrammarPool = new SynchronizedGrammarPool(grammarPool);
167     } // <init>(SymbolTable,XMLGrammarPool)
168

169     //
170
// Public methods
171
//
172

173     /** Returns the symbol table. */
174     public SymbolTable getSymbolTable() {
175         return fSynchronizedSymbolTable;
176     } // getSymbolTable():SymbolTable
177

178     /** Returns the grammar pool. */
179     public XMLGrammarPool getXMLGrammarPool() {
180         return fSynchronizedGrammarPool;
181     } // getXMLGrammarPool():XMLGrammarPool
182

183     // setters and getters
184

185     /**
186      * Sets whether new parser instance receive shadow copies of the
187      * main symbol table.
188      *
189      * @param shadow If true, new parser instances use shadow copies
190      * of the main symbol table and are not allowed to
191      * add new symbols to the main symbol table. New
192      * symbols are added to the shadow symbol table and
193      * are local to the parser instance. If false, new
194      * parser instances are allowed to add new symbols
195      * to the main symbol table.
196      */

197     public void setShadowSymbolTable(boolean shadow) {
198         fShadowSymbolTable = shadow;
199     } // setShadowSymbolTable(boolean)
200

201     // factory methods
202

203     /** Creates a new DOM parser. */
204     public DOMParser createDOMParser() {
205         SymbolTable symbolTable = fShadowSymbolTable
206                                 ? new ShadowedSymbolTable(fSynchronizedSymbolTable)
207                                 : fSynchronizedSymbolTable;
208         XMLGrammarPool grammarPool = fShadowGrammarPool
209                                 ? new ShadowedGrammarPool(fSynchronizedGrammarPool)
210                                 : fSynchronizedGrammarPool;
211         return new DOMParser(symbolTable, grammarPool);
212     } // createDOMParser():DOMParser
213

214     /** Creates a new SAX parser. */
215     public SAXParser createSAXParser() {
216         SymbolTable symbolTable = fShadowSymbolTable
217                                 ? new ShadowedSymbolTable(fSynchronizedSymbolTable)
218                                 : fSynchronizedSymbolTable;
219         XMLGrammarPool grammarPool = fShadowGrammarPool
220                                 ? new ShadowedGrammarPool(fSynchronizedGrammarPool)
221                                 : fSynchronizedGrammarPool;
222         return new SAXParser(symbolTable, grammarPool);
223     } // createSAXParser():SAXParser
224

225     //
226
// Classes
227
//
228

229     /**
230      * Synchronized grammar pool.
231      *
232      * @author Andy Clark, IBM
233      */

234     public static final class SynchronizedGrammarPool
235         implements XMLGrammarPool {
236
237         //
238
// Data
239
//
240

241         /** Main grammar pool. */
242         private XMLGrammarPool fGrammarPool;
243
244         //
245
// Constructors
246
//
247

248         /** Constructs a synchronized grammar pool. */
249         public SynchronizedGrammarPool(XMLGrammarPool grammarPool) {
250             fGrammarPool = grammarPool;
251         } // <init>(XMLGrammarPool)
252

253         //
254
// GrammarPool methods
255
//
256

257         // retrieve the initial set of grammars for the validator
258
// to work with.
259
// REVISIT: does this need to be synchronized since it's just reading?
260
// @param grammarType type of the grammars to be retrieved.
261
// @return the initial grammar set the validator may place in its "bucket"
262
public Grammar [] retrieveInitialGrammarSet(String JavaDoc grammarType ) {
263             synchronized (fGrammarPool) {
264                 return fGrammarPool.retrieveInitialGrammarSet(grammarType);
265             }
266         } // retrieveInitialGrammarSet(String): Grammar[]
267

268         // retrieve a particular grammar.
269
// REVISIT: does this need to be synchronized since it's just reading?
270
// @param gDesc description of the grammar to be retrieved
271
// @return Grammar corresponding to gDesc, or null if none exists.
272
public Grammar retrieveGrammar(XMLGrammarDescription gDesc) {
273             synchronized (fGrammarPool) {
274                 return fGrammarPool.retrieveGrammar(gDesc);
275             }
276         } // retrieveGrammar(XMLGrammarDesc): Grammar
277

278         // give the grammarPool the option of caching these grammars.
279
// This certainly must be synchronized.
280
// @param grammarType The type of the grammars to be cached.
281
// @param grammars the Grammars that may be cached (unordered, Grammars previously
282
// given to the validator may be included).
283
public void cacheGrammars(String JavaDoc grammarType, Grammar[] grammars) {
284             synchronized (fGrammarPool) {
285                 fGrammarPool.cacheGrammars(grammarType, grammars);
286             }
287         } // cacheGrammars(String, Grammar[]);
288

289         /** lock the grammar pool */
290         public void lockPool() {
291             synchronized (fGrammarPool) {
292                 fGrammarPool.lockPool();
293             }
294         } // lockPool()
295

296         /** clear the grammar pool */
297         public void clear() {
298             synchronized (fGrammarPool) {
299                 fGrammarPool.clear();
300             }
301         } // lockPool()
302

303         /** unlock the grammar pool */
304         public void unlockPool() {
305             synchronized (fGrammarPool) {
306                 fGrammarPool.unlockPool();
307             }
308         } // unlockPool()
309

310         /***
311          * Methods corresponding to original (pre Xerces2.0.0final)
312          * grammarPool have been commented out.
313          */

314         /**
315          * Puts the specified grammar into the grammar pool.
316          *
317          * @param key Key to associate with grammar.
318          * @param grammar Grammar object.
319          */

320         /******
321         public void putGrammar(String key, Grammar grammar) {
322             synchronized (fGrammarPool) {
323                 fGrammarPool.putGrammar(key, grammar);
324             }
325         } // putGrammar(String,Grammar)
326         *******/

327
328         /**
329          * Returns the grammar associated to the specified key.
330          *
331          * @param key The key of the grammar.
332          */

333         /**********
334         public Grammar getGrammar(String key) {
335             synchronized (fGrammarPool) {
336                 return fGrammarPool.getGrammar(key);
337             }
338         } // getGrammar(String):Grammar
339         ***********/

340
341         /**
342          * Removes the grammar associated to the specified key from the
343          * grammar pool and returns the removed grammar.
344          *
345          * @param key The key of the grammar.
346          */

347         /**********
348         public Grammar removeGrammar(String key) {
349             synchronized (fGrammarPool) {
350                 return fGrammarPool.removeGrammar(key);
351             }
352         } // removeGrammar(String):Grammar
353         ******/

354
355         /**
356          * Returns true if the grammar pool contains a grammar associated
357          * to the specified key.
358          *
359          * @param key The key of the grammar.
360          */

361         /**********
362         public boolean containsGrammar(String key) {
363             synchronized (fGrammarPool) {
364                 return fGrammarPool.containsGrammar(key);
365             }
366         } // containsGrammar(String):boolean
367         ********/

368
369     } // class SynchronizedGrammarPool
370

371     /**
372      * Shadowed grammar pool.
373      * This class is predicated on the existence of a concrete implementation;
374      * so using our own doesn't seem to bad an idea.
375      *
376      * @author Andy Clark, IBM
377      * @author Neil Graham, IBM
378      */

379     public static final class ShadowedGrammarPool
380         extends XMLGrammarPoolImpl {
381
382         //
383
// Data
384
//
385

386         /** Main grammar pool. */
387         private XMLGrammarPool fGrammarPool;
388
389         //
390
// Constructors
391
//
392

393         /** Constructs a shadowed grammar pool. */
394         public ShadowedGrammarPool(XMLGrammarPool grammarPool) {
395             fGrammarPool = grammarPool;
396         } // <init>(GrammarPool)
397

398         //
399
// GrammarPool methods
400
//
401

402         /**
403          * Retrieve the initial set of grammars for the validator to work with.
404          * REVISIT: does this need to be synchronized since it's just reading?
405          *
406          * @param grammarType Type of the grammars to be retrieved.
407          * @return The initial grammar set the validator may place in its "bucket"
408          */

409         public Grammar [] retrieveInitialGrammarSet(String JavaDoc grammarType ) {
410             Grammar [] grammars = super.retrieveInitialGrammarSet(grammarType);
411             if (grammars != null) return grammars;
412             return fGrammarPool.retrieveInitialGrammarSet(grammarType);
413         } // retrieveInitialGrammarSet(String): Grammar[]
414

415         /**
416          * Retrieve a particular grammar.
417          * REVISIT: does this need to be synchronized since it's just reading?
418          *
419          * @param gDesc Description of the grammar to be retrieved
420          * @return Grammar corresponding to gDesc, or null if none exists.
421          */

422         public Grammar retrieveGrammar(XMLGrammarDescription gDesc) {
423             Grammar g = super.retrieveGrammar(gDesc);
424             if(g != null) return g;
425             return fGrammarPool.retrieveGrammar(gDesc);
426         } // retrieveGrammar(XMLGrammarDesc): Grammar
427

428         /**
429          * Give the grammarPool the option of caching these grammars.
430          * This certainly must be synchronized.
431          *
432          * @param grammarType The type of the grammars to be cached.
433          * @param grammars The Grammars that may be cached (unordered, Grammars previously
434          * given to the validator may be included).
435          */

436         public void cacheGrammars(String JavaDoc grammarType, Grammar[] grammars) {
437            // better give both grammars a shot...
438
super.cacheGrammars(grammarType, grammars);
439            fGrammarPool.cacheGrammars(grammarType, grammars);
440         } // cacheGrammars(grammarType, Grammar[]);
441

442         /**
443          * Returns the grammar associated to the specified description.
444          *
445          * @param desc The description of the grammar.
446          */

447         public Grammar getGrammar(XMLGrammarDescription desc) {
448
449             if (super.containsGrammar(desc)) {
450                 return super.getGrammar(desc);
451             }
452             return null;
453
454         } // getGrammar(XMLGrammarDescription):Grammar
455

456         /**
457          * Returns true if the grammar pool contains a grammar associated
458          * to the specified description.
459          *
460          * @param desc The description of the grammar.
461          */

462         public boolean containsGrammar(XMLGrammarDescription desc) {
463             return super.containsGrammar(desc);
464         } // containsGrammar(XMLGrammarDescription):boolean
465

466     } // class ShadowedGrammarPool
467

468 } // class CachingParserPool
469
Popular Tags