KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Copyright 1999-2002,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 org.apache.xerces.xni.grammars.Grammar;
20 import org.apache.xerces.xni.grammars.XMLGrammarPool;
21 import org.apache.xerces.xni.grammars.XMLGrammarDescription;
22 import org.apache.xerces.util.XMLGrammarPoolImpl;
23
24 import org.apache.xerces.util.ShadowedSymbolTable;
25 import org.apache.xerces.util.SymbolTable;
26 import org.apache.xerces.util.SynchronizedSymbolTable;
27
28 /**
29  * A parser pool that enables caching of grammars. The caching parser
30  * pool is constructed with a specific symbol table and grammar pool
31  * that has already been populated with the grammars used by the
32  * application.
33  * <p>
34  * Once the caching parser pool is constructed, specific parser
35  * instances are created by calling the appropriate factory method
36  * on the parser pool.
37  * <p>
38  * <strong>Note:</strong> There is a performance penalty for using
39  * a caching parser pool due to thread safety. Access to the symbol
40  * table and grammar pool must be synchronized to ensure the safe
41  * operation of the symbol table and grammar pool.
42  * <p>
43  * <strong>Note:</strong> If performance is critical, then another
44  * mechanism needs to be used instead of the caching parser pool.
45  * One approach would be to create parser instances that do not
46  * share these structures. Instead, each instance would get its
47  * own copy to use while parsing. This avoids the synchronization
48  * overhead at the expense of more memory and the time required
49  * to copy the structures for each new parser instance. And even
50  * when a parser instance is re-used, there is a potential for a
51  * memory leak due to new symbols being added to the symbol table
52  * over time. In other words, always take caution to make sure
53  * that your application is thread-safe and avoids leaking memory.
54  *
55  * @author Andy Clark, IBM
56  *
57  * @version $Id: CachingParserPool.java,v 1.12 2004/02/24 23:15:56 mrglavas Exp $
58  */

59 public class CachingParserPool {
60
61     //
62
// Constants
63
//
64

65     /** Default shadow symbol table (false). */
66     public static final boolean DEFAULT_SHADOW_SYMBOL_TABLE = false;
67
68     /** Default shadow grammar pool (false). */
69     public static final boolean DEFAULT_SHADOW_GRAMMAR_POOL = false;
70
71     //
72
// Data
73
//
74

75     /**
76      * Symbol table. The symbol table that the caching parser pool is
77      * constructed with is automatically wrapped in a synchronized
78      * version for thread-safety.
79      */

80     protected SymbolTable fSynchronizedSymbolTable;
81
82     /**
83      * Grammar pool. The grammar pool that the caching parser pool is
84      * constructed with is automatically wrapped in a synchronized
85      * version for thread-safety.
86      */

87     protected XMLGrammarPool fSynchronizedGrammarPool;
88
89     /**
90      * Shadow the symbol table for new parser instances. If true,
91      * new parser instances use shadow copies of the main symbol
92      * table and are not allowed to add new symbols to the main
93      * symbol table. New symbols are added to the shadow symbol
94      * table and are local to the parser instance.
95      */

96     protected boolean fShadowSymbolTable = DEFAULT_SHADOW_SYMBOL_TABLE;
97
98     /**
99      * Shadow the grammar pool for new parser instances. If true,
100      * new parser instances use shadow copies of the main grammar
101      * pool and are not allowed to add new grammars to the main
102      * grammar pool. New grammars are added to the shadow grammar
103      * pool and are local to the parser instance.
104      */

105     protected boolean fShadowGrammarPool = DEFAULT_SHADOW_GRAMMAR_POOL;
106
107     //
108
// Constructors
109
//
110

111     /** Default constructor. */
112     public CachingParserPool() {
113         this(new SymbolTable(), new XMLGrammarPoolImpl());
114     } // <init>()
115

116     /**
117      * Constructs a caching parser pool with the specified symbol table
118      * and grammar pool.
119      *
120      * @param symbolTable The symbol table.
121      * @param grammarPool The grammar pool.
122      */

123     public CachingParserPool(SymbolTable symbolTable, XMLGrammarPool grammarPool) {
124         fSynchronizedSymbolTable = new SynchronizedSymbolTable(symbolTable);
125         fSynchronizedGrammarPool = new SynchronizedGrammarPool(grammarPool);
126     } // <init>(SymbolTable,XMLGrammarPool)
127

128     //
129
// Public methods
130
//
131

132     /** Returns the symbol table. */
133     public SymbolTable getSymbolTable() {
134         return fSynchronizedSymbolTable;
135     } // getSymbolTable():SymbolTable
136

137     /** Returns the grammar pool. */
138     public XMLGrammarPool getXMLGrammarPool() {
139         return fSynchronizedGrammarPool;
140     } // getXMLGrammarPool():XMLGrammarPool
141

142     // setters and getters
143

144     /**
145      * Sets whether new parser instance receive shadow copies of the
146      * main symbol table.
147      *
148      * @param shadow If true, new parser instances use shadow copies
149      * of the main symbol table and are not allowed to
150      * add new symbols to the main symbol table. New
151      * symbols are added to the shadow symbol table and
152      * are local to the parser instance. If false, new
153      * parser instances are allowed to add new symbols
154      * to the main symbol table.
155      */

156     public void setShadowSymbolTable(boolean shadow) {
157         fShadowSymbolTable = shadow;
158     } // setShadowSymbolTable(boolean)
159

160     // factory methods
161

162     /** Creates a new DOM parser. */
163     public DOMParser createDOMParser() {
164         SymbolTable symbolTable = fShadowSymbolTable
165                                 ? new ShadowedSymbolTable(fSynchronizedSymbolTable)
166                                 : fSynchronizedSymbolTable;
167         XMLGrammarPool grammarPool = fShadowGrammarPool
168                                 ? new ShadowedGrammarPool(fSynchronizedGrammarPool)
169                                 : fSynchronizedGrammarPool;
170         return new DOMParser(symbolTable, grammarPool);
171     } // createDOMParser():DOMParser
172

173     /** Creates a new SAX parser. */
174     public SAXParser createSAXParser() {
175         SymbolTable symbolTable = fShadowSymbolTable
176                                 ? new ShadowedSymbolTable(fSynchronizedSymbolTable)
177                                 : fSynchronizedSymbolTable;
178         XMLGrammarPool grammarPool = fShadowGrammarPool
179                                 ? new ShadowedGrammarPool(fSynchronizedGrammarPool)
180                                 : fSynchronizedGrammarPool;
181         return new SAXParser(symbolTable, grammarPool);
182     } // createSAXParser():SAXParser
183

184     //
185
// Classes
186
//
187

188     /**
189      * Synchronized grammar pool.
190      *
191      * @author Andy Clark, IBM
192      */

193     public static final class SynchronizedGrammarPool
194         implements XMLGrammarPool {
195
196         //
197
// Data
198
//
199

200         /** Main grammar pool. */
201         private XMLGrammarPool fGrammarPool;
202
203         //
204
// Constructors
205
//
206

207         /** Constructs a synchronized grammar pool. */
208         public SynchronizedGrammarPool(XMLGrammarPool grammarPool) {
209             fGrammarPool = grammarPool;
210         } // <init>(XMLGrammarPool)
211

212         //
213
// GrammarPool methods
214
//
215

216         // retrieve the initial set of grammars for the validator
217
// to work with.
218
// REVISIT: does this need to be synchronized since it's just reading?
219
// @param grammarType type of the grammars to be retrieved.
220
// @return the initial grammar set the validator may place in its "bucket"
221
public Grammar [] retrieveInitialGrammarSet(String JavaDoc grammarType ) {
222             synchronized (fGrammarPool) {
223                 return fGrammarPool.retrieveInitialGrammarSet(grammarType);
224             }
225         } // retrieveInitialGrammarSet(String): Grammar[]
226

227         // retrieve a particular grammar.
228
// REVISIT: does this need to be synchronized since it's just reading?
229
// @param gDesc description of the grammar to be retrieved
230
// @return Grammar corresponding to gDesc, or null if none exists.
231
public Grammar retrieveGrammar(XMLGrammarDescription gDesc) {
232             synchronized (fGrammarPool) {
233                 return fGrammarPool.retrieveGrammar(gDesc);
234             }
235         } // retrieveGrammar(XMLGrammarDesc): Grammar
236

237         // give the grammarPool the option of caching these grammars.
238
// This certainly must be synchronized.
239
// @param grammarType The type of the grammars to be cached.
240
// @param grammars the Grammars that may be cached (unordered, Grammars previously
241
// given to the validator may be included).
242
public void cacheGrammars(String JavaDoc grammarType, Grammar[] grammars) {
243             synchronized (fGrammarPool) {
244                 fGrammarPool.cacheGrammars(grammarType, grammars);
245             }
246         } // cacheGrammars(String, Grammar[]);
247

248         /** lock the grammar pool */
249         public void lockPool() {
250             synchronized (fGrammarPool) {
251                 fGrammarPool.lockPool();
252             }
253         } // lockPool()
254

255         /** clear the grammar pool */
256         public void clear() {
257             synchronized (fGrammarPool) {
258                 fGrammarPool.clear();
259             }
260         } // lockPool()
261

262         /** unlock the grammar pool */
263         public void unlockPool() {
264             synchronized (fGrammarPool) {
265                 fGrammarPool.unlockPool();
266             }
267         } // unlockPool()
268

269         /***
270          * Methods corresponding to original (pre Xerces2.0.0final)
271          * grammarPool have been commented out.
272          */

273         /**
274          * Puts the specified grammar into the grammar pool.
275          *
276          * @param key Key to associate with grammar.
277          * @param grammar Grammar object.
278          */

279         /******
280         public void putGrammar(String key, Grammar grammar) {
281             synchronized (fGrammarPool) {
282                 fGrammarPool.putGrammar(key, grammar);
283             }
284         } // putGrammar(String,Grammar)
285         *******/

286
287         /**
288          * Returns the grammar associated to the specified key.
289          *
290          * @param key The key of the grammar.
291          */

292         /**********
293         public Grammar getGrammar(String key) {
294             synchronized (fGrammarPool) {
295                 return fGrammarPool.getGrammar(key);
296             }
297         } // getGrammar(String):Grammar
298         ***********/

299
300         /**
301          * Removes the grammar associated to the specified key from the
302          * grammar pool and returns the removed grammar.
303          *
304          * @param key The key of the grammar.
305          */

306         /**********
307         public Grammar removeGrammar(String key) {
308             synchronized (fGrammarPool) {
309                 return fGrammarPool.removeGrammar(key);
310             }
311         } // removeGrammar(String):Grammar
312         ******/

313
314         /**
315          * Returns true if the grammar pool contains a grammar associated
316          * to the specified key.
317          *
318          * @param key The key of the grammar.
319          */

320         /**********
321         public boolean containsGrammar(String key) {
322             synchronized (fGrammarPool) {
323                 return fGrammarPool.containsGrammar(key);
324             }
325         } // containsGrammar(String):boolean
326         ********/

327
328     } // class SynchronizedGrammarPool
329

330     /**
331      * Shadowed grammar pool.
332      * This class is predicated on the existence of a concrete implementation;
333      * so using our own doesn't seem to bad an idea.
334      *
335      * @author Andy Clark, IBM
336      * @author Neil Graham, IBM
337      */

338     public static final class ShadowedGrammarPool
339         extends XMLGrammarPoolImpl {
340
341         //
342
// Data
343
//
344

345         /** Main grammar pool. */
346         private XMLGrammarPool fGrammarPool;
347
348         //
349
// Constructors
350
//
351

352         /** Constructs a shadowed grammar pool. */
353         public ShadowedGrammarPool(XMLGrammarPool grammarPool) {
354             fGrammarPool = grammarPool;
355         } // <init>(GrammarPool)
356

357         //
358
// GrammarPool methods
359
//
360

361         /**
362          * Retrieve the initial set of grammars for the validator to work with.
363          * REVISIT: does this need to be synchronized since it's just reading?
364          *
365          * @param grammarType Type of the grammars to be retrieved.
366          * @return The initial grammar set the validator may place in its "bucket"
367          */

368         public Grammar [] retrieveInitialGrammarSet(String JavaDoc grammarType ) {
369             Grammar [] grammars = super.retrieveInitialGrammarSet(grammarType);
370             if (grammars != null) return grammars;
371             return fGrammarPool.retrieveInitialGrammarSet(grammarType);
372         } // retrieveInitialGrammarSet(String): Grammar[]
373

374         /**
375          * Retrieve a particular grammar.
376          * REVISIT: does this need to be synchronized since it's just reading?
377          *
378          * @param gDesc Description of the grammar to be retrieved
379          * @return Grammar corresponding to gDesc, or null if none exists.
380          */

381         public Grammar retrieveGrammar(XMLGrammarDescription gDesc) {
382             Grammar g = super.retrieveGrammar(gDesc);
383             if(g != null) return g;
384             return fGrammarPool.retrieveGrammar(gDesc);
385         } // retrieveGrammar(XMLGrammarDesc): Grammar
386

387         /**
388          * Give the grammarPool the option of caching these grammars.
389          * This certainly must be synchronized.
390          *
391          * @param grammarType The type of the grammars to be cached.
392          * @param grammars The Grammars that may be cached (unordered, Grammars previously
393          * given to the validator may be included).
394          */

395         public void cacheGrammars(String JavaDoc grammarType, Grammar[] grammars) {
396            // better give both grammars a shot...
397
super.cacheGrammars(grammarType, grammars);
398            fGrammarPool.cacheGrammars(grammarType, grammars);
399         } // cacheGrammars(grammarType, Grammar[]);
400

401         /**
402          * Returns the grammar associated to the specified description.
403          *
404          * @param desc The description of the grammar.
405          */

406         public Grammar getGrammar(XMLGrammarDescription desc) {
407
408             if (super.containsGrammar(desc)) {
409                 return super.getGrammar(desc);
410             }
411             return null;
412
413         } // getGrammar(XMLGrammarDescription):Grammar
414

415         /**
416          * Returns true if the grammar pool contains a grammar associated
417          * to the specified description.
418          *
419          * @param desc The description of the grammar.
420          */

421         public boolean containsGrammar(XMLGrammarDescription desc) {
422             return super.containsGrammar(desc);
423         } // containsGrammar(XMLGrammarDescription):boolean
424

425     } // class ShadowedGrammarPool
426

427 } // class CachingParserPool
428
Popular Tags