KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xerces > internal > util > XMLGrammarPoolImpl


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.util;
59
60 import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
61 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
62 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
63
64 /**
65  * Stores grammars in a pool associated to a specific key. This grammar pool
66  * implementation stores two types of grammars: those keyed by the root element
67  * name, and those keyed by the grammar's target namespace.
68  *
69  * This is the default implementation of the GrammarPool interface.
70  * As we move forward, this will become more function-rich and robust.
71  *
72  * @author Jeffrey Rodriguez, IBM
73  * @author Andy Clark, IBM
74  * @author Neil Graham, IBM
75  * @author Pavani Mukthipudi, Sun Microsystems
76  * @author Neeraj Bajaj, SUN Microsystems
77  *
78  * @version $Id: XMLGrammarPoolImpl.java,v 1.6 2003/07/30 21:30:04 elena Exp $
79  */

80 public class XMLGrammarPoolImpl implements XMLGrammarPool {
81
82     //
83
// Constants
84
//
85

86     /** Default size. */
87     protected static final int TABLE_SIZE = 11;
88
89     //
90
// Data
91
//
92

93     /** Grammars. */
94     protected Entry[] fGrammars = null;
95
96     // whether this pool is locked
97
protected boolean fPoolIsLocked;
98
99     // the number of grammars in the pool
100
protected int fGrammarCount = 0;
101
102     private static final boolean DEBUG = false ;
103
104     //
105
// Constructors
106
//
107

108     /** Constructs a grammar pool with a default number of buckets. */
109     public XMLGrammarPoolImpl() {
110         fGrammars = new Entry[TABLE_SIZE];
111         fPoolIsLocked = false;
112     } // <init>()
113

114     /** Constructs a grammar pool with a specified number of buckets. */
115     public XMLGrammarPoolImpl(int initialCapacity) {
116         fGrammars = new Entry[initialCapacity];
117         fPoolIsLocked = false;
118     }
119
120     //
121
// XMLGrammarPool methods
122
//
123

124     /* <p> Retrieve the initial known set of grammars. This method is
125      * called by a validator before the validation starts. The application
126      * can provide an initial set of grammars available to the current
127      * validation attempt. </p>
128      *
129      * @param grammarType The type of the grammar, from the
130      * <code>com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription</code>
131      * interface.
132      * @return The set of grammars the validator may put in its "bucket"
133      */

134     public Grammar [] retrieveInitialGrammarSet (String JavaDoc grammarType) {
135         synchronized (fGrammars) {
136             int grammarSize = fGrammars.length ;
137             Grammar [] tempGrammars = new Grammar[fGrammarCount];
138             int pos = 0;
139             for (int i = 0; i < grammarSize; i++) {
140                 for (Entry e = fGrammars[i]; e != null; e = e.next) {
141                     if (e.desc.getGrammarType().equals(grammarType)) {
142                         tempGrammars[pos++] = e.grammar;
143                     }
144                 }
145             }
146             Grammar[] toReturn = new Grammar[pos];
147             System.arraycopy(tempGrammars, 0, toReturn, 0, pos);
148             return toReturn;
149         }
150     } // retrieveInitialGrammarSet (String): Grammar[]
151

152     /* <p> Return the final set of grammars that the validator ended up
153      * with. This method is called after the validation finishes. The
154      * application may then choose to cache some of the returned grammars.</p>
155      * <p>In this implementation, we make our choice based on whether this object
156      * is "locked"--that is, whether the application has instructed
157      * us not to accept any new grammars.</p>
158      *
159      * @param grammarType The type of the grammars being returned;
160      * @param grammars An array containing the set of grammars being
161      * returned; order is not significant.
162      */

163     public void cacheGrammars(String JavaDoc grammarType, Grammar[] grammars) {
164         if(!fPoolIsLocked) {
165             for (int i = 0; i < grammars.length; i++) {
166                 if(DEBUG) {
167                     System.out.println("CACHED GRAMMAR " + (i+1) ) ;
168                     Grammar temp = grammars[i] ;
169                     //print(temp.getGrammarDescription());
170
}
171                 putGrammar(grammars[i]);
172             }
173         }
174     } // cacheGrammars(String, Grammar[]);
175

176     /* <p> This method requests that the application retrieve a grammar
177      * corresponding to the given GrammarIdentifier from its cache.
178      * If it cannot do so it must return null; the parser will then
179      * call the EntityResolver. </p>
180      * <strong>An application must not call its EntityResolver itself
181      * from this method; this may result in infinite recursions.</strong>
182      *
183      * This implementation chooses to use the root element name to identify a DTD grammar
184      * and the target namespace to identify a Schema grammar.
185      *
186      * @param desc The description of the Grammar being requested.
187      * @return The Grammar corresponding to this description or null if
188      * no such Grammar is known.
189      */

190     public Grammar retrieveGrammar(XMLGrammarDescription desc) {
191         if(DEBUG){
192             System.out.println("RETRIEVING GRAMMAR FROM THE APPLICATION WITH FOLLOWING DESCRIPTION :");
193             //print(desc);
194
}
195         return getGrammar(desc);
196     } // retrieveGrammar(XMLGrammarDescription): Grammar
197

198     //
199
// Public methods
200
//
201

202     /**
203      * Puts the specified grammar into the grammar pool and associates it to
204      * its root element name or its target namespace.
205      *
206      * @param grammar The Grammar.
207      */

208     public void putGrammar(Grammar grammar) {
209         if(!fPoolIsLocked) {
210             synchronized (fGrammars) {
211                 XMLGrammarDescription desc = grammar.getGrammarDescription();
212                 int hash = hashCode(desc);
213                 int index = (hash & 0x7FFFFFFF) % fGrammars.length;
214                 for (Entry entry = fGrammars[index]; entry != null; entry = entry.next) {
215                     if (entry.hash == hash && equals(entry.desc, desc)) {
216                         entry.grammar = grammar;
217                         return;
218                     }
219                 }
220                 // create a new entry
221
Entry entry = new Entry(hash, desc, grammar, fGrammars[index]);
222                 fGrammars[index] = entry;
223                 fGrammarCount++;
224             }
225         }
226     } // putGrammar(Grammar)
227

228     /**
229      * Returns the grammar associated to the specified grammar description.
230      * Currently, the root element name is used as the key for DTD grammars
231      * and the target namespace is used as the key for Schema grammars.
232      *
233      * @param desc The Grammar Description.
234      */

235     public Grammar getGrammar(XMLGrammarDescription desc) {
236         synchronized (fGrammars) {
237             int hash = hashCode(desc);
238         int index = (hash & 0x7FFFFFFF) % fGrammars.length;
239         for (Entry entry = fGrammars[index] ; entry != null ; entry = entry.next) {
240             if ((entry.hash == hash) && equals(entry.desc, desc)) {
241                 return entry.grammar;
242             }
243         }
244         return null;
245     }
246     } // getGrammar(XMLGrammarDescription):Grammar
247

248     /**
249      * Removes the grammar associated to the specified grammar description from the
250      * grammar pool and returns the removed grammar. Currently, the root element name
251      * is used as the key for DTD grammars and the target namespace is used
252      * as the key for Schema grammars.
253      *
254      * @param desc The Grammar Description.
255      * @return The removed grammar.
256      */

257     public Grammar removeGrammar(XMLGrammarDescription desc) {
258         synchronized (fGrammars) {
259             int hash = hashCode(desc);
260         int index = (hash & 0x7FFFFFFF) % fGrammars.length;
261         for (Entry entry = fGrammars[index], prev = null ; entry != null ; prev = entry, entry = entry.next) {
262             if ((entry.hash == hash) && equals(entry.desc, desc)) {
263                 if (prev != null) {
264                         prev.next = entry.next;
265             }
266             else {
267                 fGrammars[index] = entry.next;
268             }
269                 Grammar tempGrammar = entry.grammar;
270                 entry.grammar = null;
271                 fGrammarCount--;
272                 return tempGrammar;
273             }
274         }
275         return null;
276         }
277     } // removeGrammar(XMLGrammarDescription):Grammar
278

279     /**
280      * Returns true if the grammar pool contains a grammar associated
281      * to the specified grammar description. Currently, the root element name
282      * is used as the key for DTD grammars and the target namespace is used
283      * as the key for Schema grammars.
284      *
285      * @param desc The Grammar Description.
286      */

287     public boolean containsGrammar(XMLGrammarDescription desc) {
288         synchronized (fGrammars) {
289             int hash = hashCode(desc);
290         int index = (hash & 0x7FFFFFFF) % fGrammars.length;
291         for (Entry entry = fGrammars[index] ; entry != null ; entry = entry.next) {
292             if ((entry.hash == hash) && equals(entry.desc, desc)) {
293                 return true;
294             }
295         }
296         return false;
297     }
298     } // containsGrammar(XMLGrammarDescription):boolean
299

300     /* <p> Sets this grammar pool to a "locked" state--i.e.,
301      * no new grammars will be added until it is "unlocked".
302      */

303     public void lockPool() {
304         fPoolIsLocked = true;
305     } // lockPool()
306

307     /* <p> Sets this grammar pool to an "unlocked" state--i.e.,
308      * new grammars will be added when putGrammar or cacheGrammars
309      * are called.
310      */

311     public void unlockPool() {
312         fPoolIsLocked = false;
313     } // unlockPool()
314

315     /*
316      * <p>This method clears the pool-i.e., removes references
317      * to all the grammars in it.</p>
318      */

319     public void clear() {
320         for (int i=0; i<fGrammars.length; i++) {
321             if(fGrammars[i] != null) {
322                 fGrammars[i].clear();
323                 fGrammars[i] = null;
324             }
325         }
326         fGrammarCount = 0;
327     } // clear()
328

329     /**
330      * This method checks whether two grammars are the same. Currently, we compare
331      * the root element names for DTD grammars and the target namespaces for Schema grammars.
332      * The application can override this behaviour and add its own logic.
333      *
334      * @param gDesc1 The grammar description
335      * @param gDesc2 The grammar description of the grammar to be compared to
336      * @return True if the grammars are equal, otherwise false
337      */

338     public boolean equals(XMLGrammarDescription desc1, XMLGrammarDescription desc2) {
339         return desc1.equals(desc2);
340     }
341
342     /**
343      * Returns the hash code value for the given grammar description.
344      *
345      * @param desc The grammar description
346      * @return The hash code value
347      */

348     public int hashCode(XMLGrammarDescription desc) {
349         return desc.hashCode();
350     }
351
352     /**
353      * This class is a grammar pool entry. Each entry acts as a node
354      * in a linked list.
355      */

356     protected static final class Entry {
357         public int hash;
358         public XMLGrammarDescription desc;
359         public Grammar grammar;
360         public Entry next;
361
362         protected Entry(int hash, XMLGrammarDescription desc, Grammar grammar, Entry next) {
363             this.hash = hash;
364             this.desc = desc;
365             this.grammar = grammar;
366             this.next = next;
367         }
368
369         // clear this entry; useful to promote garbage collection
370
// since reduces reference count of objects to be destroyed
371
protected void clear () {
372             desc = null;
373             grammar = null;
374             if(next != null) {
375                 next.clear();
376                 next = null;
377             }
378         } // clear()
379
} // class Entry
380

381     /* For DTD build we can't import here XSDDescription. Thus, this method is commented out.. */
382     /* public void print(XMLGrammarDescription description){
383         if(description.getGrammarType().equals(XMLGrammarDescription.XML_DTD)){
384
385         }
386         else if(description.getGrammarType().equals(XMLGrammarDescription.XML_SCHEMA)){
387             XSDDescription schema = (XSDDescription)description ;
388             System.out.println("Context = " + schema.getContextType());
389             System.out.println("TargetNamespace = " + schema.getTargetNamespace());
390             String [] temp = schema.getLocationHints();
391
392             for (int i = 0 ; (temp != null && i < temp.length) ; i++){
393                 System.out.println("LocationHint " + i + " = "+ temp[i]);
394             }
395
396             System.out.println("Triggering Component = " + schema.getTriggeringComponent());
397             System.out.println("EnclosingElementName =" + schema.getEnclosingElementName());
398
399         }
400
401     }//print
402     */

403
404 } // class XMLGrammarPoolImpl
405
Popular Tags