Source Code Cross Referenced for SoftReferenceGrammarPool.java in  » XML » xerces-2_9_1 » org » apache » xerces » jaxp » validation » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » xerces 2_9_1 » org.apache.xerces.jaxp.validation 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Licensed to the Apache Software Foundation (ASF) under one or more
003:         * contributor license agreements.  See the NOTICE file distributed with
004:         * this work for additional information regarding copyright ownership.
005:         * The ASF licenses this file to You under the Apache License, Version 2.0
006:         * (the "License"); you may not use this file except in compliance with
007:         * the License.  You may obtain a copy of the License at
008:         * 
009:         *      http://www.apache.org/licenses/LICENSE-2.0
010:         * 
011:         * Unless required by applicable law or agreed to in writing, software
012:         * distributed under the License is distributed on an "AS IS" BASIS,
013:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:         * See the License for the specific language governing permissions and
015:         * limitations under the License.
016:         */
017:
018:        package org.apache.xerces.jaxp.validation;
019:
020:        import java.lang.ref.Reference;
021:        import java.lang.ref.ReferenceQueue;
022:        import java.lang.ref.SoftReference;
023:
024:        import org.apache.xerces.xni.grammars.Grammar;
025:        import org.apache.xerces.xni.grammars.XMLGrammarDescription;
026:        import org.apache.xerces.xni.grammars.XMLSchemaDescription;
027:        import org.apache.xerces.xni.grammars.XMLGrammarPool;
028:
029:        /**
030:         * <p>This grammar pool is a memory sensitive cache. The grammars
031:         * stored in the pool are softly reachable and may be cleared by
032:         * the garbage collector in response to memory demand. Equality
033:         * of <code>XMLSchemaDescription</code>s is determined using both
034:         * the target namespace for the schema and schema location.</p>
035:         * 
036:         * @author Michael Glavassevich, IBM
037:         * @version $Id: SoftReferenceGrammarPool.java 447235 2006-09-18 05:01:44Z mrglavas $
038:         */
039:        final class SoftReferenceGrammarPool implements  XMLGrammarPool {
040:
041:            //
042:            // Constants
043:            //
044:
045:            /** Default size. */
046:            protected static final int TABLE_SIZE = 11;
047:
048:            /** Zero length grammar array. */
049:            protected static final Grammar[] ZERO_LENGTH_GRAMMAR_ARRAY = new Grammar[0];
050:
051:            //
052:            // Data
053:            //
054:
055:            /** Grammars. */
056:            protected Entry[] fGrammars = null;
057:
058:            /** Flag indicating whether this pool is locked */
059:            protected boolean fPoolIsLocked;
060:
061:            /** The number of grammars in the pool */
062:            protected int fGrammarCount = 0;
063:
064:            /** Reference queue for cleared grammar references */
065:            protected final ReferenceQueue fReferenceQueue = new ReferenceQueue();
066:
067:            //
068:            // Constructors
069:            //
070:
071:            /** Constructs a grammar pool with a default number of buckets. */
072:            public SoftReferenceGrammarPool() {
073:                fGrammars = new Entry[TABLE_SIZE];
074:                fPoolIsLocked = false;
075:            } // <init>()
076:
077:            /** Constructs a grammar pool with a specified number of buckets. */
078:            public SoftReferenceGrammarPool(int initialCapacity) {
079:                fGrammars = new Entry[initialCapacity];
080:                fPoolIsLocked = false;
081:            }
082:
083:            //
084:            // XMLGrammarPool methods
085:            //
086:
087:            /* <p> Retrieve the initial known set of grammars. This method is
088:             * called by a validator before the validation starts. The application
089:             * can provide an initial set of grammars available to the current
090:             * validation attempt. </p>
091:             *
092:             * @param grammarType The type of the grammar, from the
093:             *  		  <code>org.apache.xerces.xni.grammars.XMLGrammarDescription</code>
094:             *  		  interface.
095:             * @return 		  The set of grammars the validator may put in its "bucket"
096:             */
097:            public Grammar[] retrieveInitialGrammarSet(String grammarType) {
098:                synchronized (fGrammars) {
099:                    clean();
100:                    // Return no grammars. This allows the garbage collector to sift
101:                    // out grammars which are not in use when memory demand is high.
102:                    // It also allows the pool to return the "right" schema grammar
103:                    // based on schema locations.
104:                    return ZERO_LENGTH_GRAMMAR_ARRAY;
105:                }
106:            } // retrieveInitialGrammarSet (String): Grammar[]
107:
108:            /* <p> Return the final set of grammars that the validator ended up
109:             * with. This method is called after the validation finishes. The
110:             * application may then choose to cache some of the returned grammars.</p>
111:             * <p>In this implementation, we make our choice based on whether this object
112:             * is "locked"--that is, whether the application has instructed
113:             * us not to accept any new grammars.</p>
114:             *
115:             * @param grammarType The type of the grammars being returned;
116:             * @param grammars 	  An array containing the set of grammars being
117:             *  		  returned; order is not significant.
118:             */
119:            public void cacheGrammars(String grammarType, Grammar[] grammars) {
120:                if (!fPoolIsLocked) {
121:                    for (int i = 0; i < grammars.length; ++i) {
122:                        putGrammar(grammars[i]);
123:                    }
124:                }
125:            } // cacheGrammars(String, Grammar[]);
126:
127:            /* <p> This method requests that the application retrieve a grammar
128:             * corresponding to the given GrammarIdentifier from its cache.
129:             * If it cannot do so it must return null; the parser will then
130:             * call the EntityResolver. </p>
131:             * <strong>An application must not call its EntityResolver itself
132:             * from this method; this may result in infinite recursions.</strong>
133:             *
134:             * This implementation chooses to use the root element name to identify a DTD grammar
135:             * and the target namespace to identify a Schema grammar.
136:             *
137:             * @param desc The description of the Grammar being requested.
138:             * @return     The Grammar corresponding to this description or null if
139:             *  	   no such Grammar is known.
140:             */
141:            public Grammar retrieveGrammar(XMLGrammarDescription desc) {
142:                return getGrammar(desc);
143:            } // retrieveGrammar(XMLGrammarDescription):  Grammar
144:
145:            //
146:            // Public methods
147:            //
148:
149:            /**
150:             * Puts the specified grammar into the grammar pool and associates it to
151:             * its root element name or its target namespace.
152:             *
153:             * @param grammar The Grammar.
154:             */
155:            public void putGrammar(Grammar grammar) {
156:                if (!fPoolIsLocked) {
157:                    synchronized (fGrammars) {
158:                        clean();
159:                        XMLGrammarDescription desc = grammar
160:                                .getGrammarDescription();
161:                        int hash = hashCode(desc);
162:                        int index = (hash & 0x7FFFFFFF) % fGrammars.length;
163:                        for (Entry entry = fGrammars[index]; entry != null; entry = entry.next) {
164:                            if (entry.hash == hash && equals(entry.desc, desc)) {
165:                                if (entry.grammar.get() != grammar) {
166:                                    entry.grammar = new SoftGrammarReference(
167:                                            entry, grammar, fReferenceQueue);
168:                                }
169:                                return;
170:                            }
171:                        }
172:                        // create a new entry
173:                        Entry entry = new Entry(hash, index, desc, grammar,
174:                                fGrammars[index], fReferenceQueue);
175:                        fGrammars[index] = entry;
176:                        fGrammarCount++;
177:                    }
178:                }
179:            } // putGrammar(Grammar)
180:
181:            /**
182:             * Returns the grammar associated to the specified grammar description.
183:             * Currently, the root element name is used as the key for DTD grammars
184:             * and the target namespace  is used as the key for Schema grammars.
185:             *
186:             * @param desc The Grammar Description.
187:             */
188:            public Grammar getGrammar(XMLGrammarDescription desc) {
189:                synchronized (fGrammars) {
190:                    clean();
191:                    int hash = hashCode(desc);
192:                    int index = (hash & 0x7FFFFFFF) % fGrammars.length;
193:                    for (Entry entry = fGrammars[index]; entry != null; entry = entry.next) {
194:                        Grammar tempGrammar = (Grammar) entry.grammar.get();
195:                        /** If the soft reference has been cleared, remove this entry from the pool. */
196:                        if (tempGrammar == null) {
197:                            removeEntry(entry);
198:                        } else if ((entry.hash == hash)
199:                                && equals(entry.desc, desc)) {
200:                            return tempGrammar;
201:                        }
202:                    }
203:                    return null;
204:                }
205:            } // getGrammar(XMLGrammarDescription):Grammar
206:
207:            /**
208:             * Removes the grammar associated to the specified grammar description from the
209:             * grammar pool and returns the removed grammar. Currently, the root element name
210:             * is used as the key for DTD grammars and the target namespace  is used
211:             * as the key for Schema grammars.
212:             *
213:             * @param desc The Grammar Description.
214:             * @return     The removed grammar.
215:             */
216:            public Grammar removeGrammar(XMLGrammarDescription desc) {
217:                synchronized (fGrammars) {
218:                    clean();
219:                    int hash = hashCode(desc);
220:                    int index = (hash & 0x7FFFFFFF) % fGrammars.length;
221:                    for (Entry entry = fGrammars[index]; entry != null; entry = entry.next) {
222:                        if ((entry.hash == hash) && equals(entry.desc, desc)) {
223:                            return removeEntry(entry);
224:                        }
225:                    }
226:                    return null;
227:                }
228:            } // removeGrammar(XMLGrammarDescription):Grammar
229:
230:            /**
231:             * Returns true if the grammar pool contains a grammar associated
232:             * to the specified grammar description. Currently, the root element name
233:             * is used as the key for DTD grammars and the target namespace  is used
234:             * as the key for Schema grammars.
235:             *
236:             * @param desc The Grammar Description.
237:             */
238:            public boolean containsGrammar(XMLGrammarDescription desc) {
239:                synchronized (fGrammars) {
240:                    clean();
241:                    int hash = hashCode(desc);
242:                    int index = (hash & 0x7FFFFFFF) % fGrammars.length;
243:                    for (Entry entry = fGrammars[index]; entry != null; entry = entry.next) {
244:                        Grammar tempGrammar = (Grammar) entry.grammar.get();
245:                        /** If the soft reference has been cleared, remove this entry from the pool. */
246:                        if (tempGrammar == null) {
247:                            removeEntry(entry);
248:                        } else if ((entry.hash == hash)
249:                                && equals(entry.desc, desc)) {
250:                            return true;
251:                        }
252:                    }
253:                    return false;
254:                }
255:            } // containsGrammar(XMLGrammarDescription):boolean
256:
257:            /* <p> Sets this grammar pool to a "locked" state--i.e.,
258:             * no new grammars will be added until it is "unlocked".
259:             */
260:            public void lockPool() {
261:                fPoolIsLocked = true;
262:            } // lockPool()
263:
264:            /* <p> Sets this grammar pool to an "unlocked" state--i.e.,
265:             * new grammars will be added when putGrammar or cacheGrammars
266:             * are called.
267:             */
268:            public void unlockPool() {
269:                fPoolIsLocked = false;
270:            } // unlockPool()
271:
272:            /*
273:             * <p>This method clears the pool-i.e., removes references
274:             * to all the grammars in it.</p>
275:             */
276:            public void clear() {
277:                for (int i = 0; i < fGrammars.length; i++) {
278:                    if (fGrammars[i] != null) {
279:                        fGrammars[i].clear();
280:                        fGrammars[i] = null;
281:                    }
282:                }
283:                fGrammarCount = 0;
284:            } // clear()
285:
286:            /**
287:             * This method checks whether two grammars are the same. Currently, we compare
288:             * the root element names for DTD grammars and the target namespaces for Schema grammars.
289:             * The application can override this behaviour and add its own logic.
290:             *
291:             * @param desc1 The grammar description
292:             * @param desc2 The grammar description of the grammar to be compared to
293:             * @return      True if the grammars are equal, otherwise false
294:             */
295:            public boolean equals(XMLGrammarDescription desc1,
296:                    XMLGrammarDescription desc2) {
297:                if (desc1 instanceof  XMLSchemaDescription) {
298:                    if (!(desc2 instanceof  XMLSchemaDescription)) {
299:                        return false;
300:                    }
301:                    final XMLSchemaDescription sd1 = (XMLSchemaDescription) desc1;
302:                    final XMLSchemaDescription sd2 = (XMLSchemaDescription) desc2;
303:                    final String targetNamespace = sd1.getTargetNamespace();
304:                    if (targetNamespace != null) {
305:                        if (!targetNamespace.equals(sd2.getTargetNamespace())) {
306:                            return false;
307:                        }
308:                    } else if (sd2.getTargetNamespace() != null) {
309:                        return false;
310:                    }
311:                    // The JAXP 1.3 spec says that the implementation can assume that
312:                    // if two schema location hints are the same they always resolve
313:                    // to the same document. In the default grammar pool implementation
314:                    // we only look at the target namespaces. Here we also compare
315:                    // location hints.
316:                    final String expandedSystemId = sd1.getExpandedSystemId();
317:                    if (expandedSystemId != null) {
318:                        if (!expandedSystemId.equals(sd2.getExpandedSystemId())) {
319:                            return false;
320:                        }
321:                    } else if (sd2.getExpandedSystemId() != null) {
322:                        return false;
323:                    }
324:                    return true;
325:                }
326:                return desc1.equals(desc2);
327:            }
328:
329:            /**
330:             * Returns the hash code value for the given grammar description.
331:             *
332:             * @param desc The grammar description
333:             * @return     The hash code value
334:             */
335:            public int hashCode(XMLGrammarDescription desc) {
336:                if (desc instanceof  XMLSchemaDescription) {
337:                    final XMLSchemaDescription sd = (XMLSchemaDescription) desc;
338:                    final String targetNamespace = sd.getTargetNamespace();
339:                    final String expandedSystemId = sd.getExpandedSystemId();
340:                    int hash = (targetNamespace != null) ? targetNamespace
341:                            .hashCode() : 0;
342:                    hash ^= (expandedSystemId != null) ? expandedSystemId
343:                            .hashCode() : 0;
344:                    return hash;
345:                }
346:                return desc.hashCode();
347:            }
348:
349:            /**
350:             * Removes the given entry from the pool
351:             * 
352:             * @param entry the entry to remove
353:             * @return The grammar attached to this entry
354:             */
355:            private Grammar removeEntry(Entry entry) {
356:                if (entry.prev != null) {
357:                    entry.prev.next = entry.next;
358:                } else {
359:                    fGrammars[entry.bucket] = entry.next;
360:                }
361:                if (entry.next != null) {
362:                    entry.next.prev = entry.prev;
363:                }
364:                --fGrammarCount;
365:                entry.grammar.entry = null;
366:                return (Grammar) entry.grammar.get();
367:            }
368:
369:            /**
370:             * Removes stale entries from the pool.
371:             */
372:            private void clean() {
373:                Reference ref = fReferenceQueue.poll();
374:                while (ref != null) {
375:                    Entry entry = ((SoftGrammarReference) ref).entry;
376:                    if (entry != null) {
377:                        removeEntry(entry);
378:                    }
379:                    ref = fReferenceQueue.poll();
380:                }
381:            }
382:
383:            /**
384:             * This class is a grammar pool entry. Each entry acts as a node
385:             * in a doubly linked list.
386:             */
387:            static final class Entry {
388:
389:                public int hash;
390:                public int bucket;
391:                public Entry prev;
392:                public Entry next;
393:                public XMLGrammarDescription desc;
394:                public SoftGrammarReference grammar;
395:
396:                protected Entry(int hash, int bucket,
397:                        XMLGrammarDescription desc, Grammar grammar,
398:                        Entry next, ReferenceQueue queue) {
399:                    this .hash = hash;
400:                    this .bucket = bucket;
401:                    this .prev = null;
402:                    this .next = next;
403:                    if (next != null) {
404:                        next.prev = this ;
405:                    }
406:                    this .desc = desc;
407:                    this .grammar = new SoftGrammarReference(this , grammar,
408:                            queue);
409:                }
410:
411:                // clear this entry; useful to promote garbage collection
412:                // since reduces reference count of objects to be destroyed
413:                protected void clear() {
414:                    desc = null;
415:                    grammar = null;
416:                    if (next != null) {
417:                        next.clear();
418:                        next = null;
419:                    }
420:                } // clear()
421:
422:            } // class Entry
423:
424:            /**
425:             * This class stores a soft reference to a grammar object. It keeps a reference
426:             * to its associated entry, so that it can be easily removed from the pool.
427:             */
428:            static final class SoftGrammarReference extends SoftReference {
429:
430:                public Entry entry;
431:
432:                protected SoftGrammarReference(Entry entry, Grammar grammar,
433:                        ReferenceQueue queue) {
434:                    super (grammar, queue);
435:                    this .entry = entry;
436:                }
437:
438:            } // class SoftGrammarReference
439:
440:        } // class SoftReferenceGrammarPool
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.