Source Code Cross Referenced for UtilCache.java in  » ERP-CRM-Financial » ofbiz » org » ofbiz » base » util » cache » 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 » ERP CRM Financial » ofbiz » org.ofbiz.base.util.cache 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Licensed to the Apache Software Foundation (ASF) under one
003:         * or more contributor license agreements.  See the NOTICE file
004:         * distributed with this work for additional information
005:         * regarding copyright ownership.  The ASF licenses this file
006:         * to you under the Apache License, Version 2.0 (the
007:         * "License"); you may not use this file except in compliance
008:         * with the License.  You may obtain a copy of the License at
009:         * 
010:         * http://www.apache.org/licenses/LICENSE-2.0
011:         * 
012:         * Unless required by applicable law or agreed to in writing,
013:         * software distributed under the License is distributed on an
014:         * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015:         * KIND, either express or implied.  See the License for the
016:         * specific language governing permissions and limitations
017:         * under the License.
018:         *******************************************************************************/package org.ofbiz.base.util.cache;
019:
020:        import java.io.Serializable;
021:        import java.util.Collection;
022:        import java.util.Iterator;
023:        import java.util.List;
024:        import java.util.Map;
025:        import java.util.MissingResourceException;
026:        import java.util.ResourceBundle;
027:        import java.util.Set;
028:        import java.util.WeakHashMap;
029:
030:        import javolution.util.FastList;
031:        import javolution.util.FastMap;
032:        import javolution.util.FastSet;
033:
034:        import org.ofbiz.base.util.Debug;
035:        import org.ofbiz.base.util.ObjectType;
036:        import org.ofbiz.base.util.UtilValidate;
037:
038:        /**
039:         * Generalized caching utility. Provides a number of caching features:
040:         * <ul>
041:         *   <li>Limited or unlimited element capacity
042:         *   <li>If limited, removes elements with the LRU (Least Recently Used) algorithm
043:         *   <li>Keeps track of when each element was loaded into the cache
044:         *   <li>Using the expireTime can report whether a given element has expired
045:         *   <li>Counts misses and hits
046:         * </ul>
047:         *
048:         */
049:        public class UtilCache implements  Serializable {
050:
051:            public static final String module = UtilCache.class.getName();
052:
053:            /** A static Map to keep track of all of the UtilCache instances. */
054:            public static Map utilCacheTable = new WeakHashMap();
055:
056:            /** An index number appended to utilCacheTable names when there are conflicts. */
057:            protected static Map defaultIndices = FastMap.newInstance();
058:
059:            /** The name of the UtilCache instance, is also the key for the instance in utilCacheTable. */
060:            protected String name = null;
061:
062:            /** A hashtable containing a CacheLine object with a value and a loadTime for each element. */
063:            public CacheLineTable cacheLineTable = null;
064:
065:            /** A count of the number of cache hits */
066:            protected long hitCount = 0;
067:
068:            /** A count of the number of cache misses because it is not found in the cache */
069:            protected long missCountNotFound = 0;
070:            /** A count of the number of cache misses because it expired */
071:            protected long missCountExpired = 0;
072:            /** A count of the number of cache misses because it was cleared from the Soft Reference (ie garbage collection, etc) */
073:            protected long missCountSoftRef = 0;
074:
075:            /** A count of the number of cache hits on removes */
076:            protected long removeHitCount = 0;
077:            /** A count of the number of cache misses on removes */
078:            protected long removeMissCount = 0;
079:
080:            /** The maximum number of elements in the cache.
081:             * If set to 0, there will be no limit on the number of elements in the cache.
082:             */
083:            protected int maxSize = 0;
084:            protected int maxInMemory = 0;
085:
086:            /** Specifies the amount of time since initial loading before an element will be reported as expired.
087:             * If set to 0, elements will never expire.
088:             */
089:            protected long expireTime = 0;
090:
091:            /** Specifies whether or not to use soft references for this cache, defaults to false */
092:            protected boolean useSoftReference = false;
093:
094:            /** Specifies whether or not to use file base stored for this cache, defautls to false */
095:            protected boolean useFileSystemStore = false;
096:            private String fileStore = "runtime/data/utilcache";
097:
098:            /** The set of listeners to receive notifcations when items are modidfied(either delibrately or because they were expired). */
099:            protected Set listeners = FastSet.newInstance();
100:
101:            /** Constructor which specifies the cacheName as well as the maxSize, expireTime and useSoftReference.
102:             * The passed maxSize, expireTime and useSoftReference will be overridden by values from cache.properties if found.
103:             * @param maxSize The maxSize member is set to this value
104:             * @param expireTime The expireTime member is set to this value
105:             * @param cacheName The name of the cache.
106:             * @param useSoftReference Specifies whether or not to use soft references for this cache.
107:             */
108:            public UtilCache(String cacheName, int maxSize, int maxInMemory,
109:                    long expireTime, boolean useSoftReference,
110:                    boolean useFileSystemStore) {
111:                this .maxSize = maxSize;
112:                this .maxInMemory = maxInMemory;
113:                this .expireTime = expireTime;
114:                this .useSoftReference = useSoftReference;
115:                this .useFileSystemStore = useFileSystemStore;
116:                name = cacheName + this .getNextDefaultIndex(cacheName);
117:
118:                setPropertiesParams(cacheName);
119:
120:                utilCacheTable.put(name, this );
121:            }
122:
123:            public UtilCache(String cacheName, int maxSize, long expireTime,
124:                    boolean useSoftReference) {
125:                this (cacheName, maxSize, maxSize, expireTime, useSoftReference,
126:                        false);
127:            }
128:
129:            /** Constructor which specifies the cacheName as well as the maxSize and expireTime.
130:             * The passed maxSize and expireTime will be overridden by values from cache.properties if found.
131:             * @param maxSize The maxSize member is set to this value
132:             * @param expireTime The expireTime member is set to this value
133:             * @param cacheName The name of the cache.
134:             */
135:            public UtilCache(String cacheName, int maxSize, long expireTime) {
136:                this (cacheName, maxSize, expireTime, false);
137:            }
138:
139:            /** Constructor which specifies the maxSize and expireTime.
140:             * @param maxSize The maxSize member is set to this value
141:             * @param expireTime The expireTime member is set to this value
142:             */
143:            public UtilCache(int maxSize, long expireTime) {
144:                this .useSoftReference = false;
145:                this .maxSize = maxSize;
146:                this .expireTime = expireTime;
147:                String name = "specified"
148:                        + this .getNextDefaultIndex("specified");
149:
150:                setPropertiesParams(name);
151:
152:                utilCacheTable.put(name, this );
153:            }
154:
155:            /** This constructor takes a name for the cache, puts itself in the utilCacheTable.
156:             * It also uses the cacheName to lookup the initialization parameters from cache.properties.
157:             * @param cacheName The name of the cache.
158:             */
159:            public UtilCache(String cacheName, boolean useSoftReference) {
160:                name = cacheName + this .getNextDefaultIndex(cacheName);
161:                this .useSoftReference = useSoftReference;
162:
163:                setPropertiesParams("default");
164:                setPropertiesParams(cacheName);
165:
166:                utilCacheTable.put(name, this );
167:            }
168:
169:            /** This constructor takes a name for the cache, puts itself in the utilCacheTable.
170:             * It also uses the cacheName to lookup the initialization parameters from cache.properties.
171:             * @param cacheName The name of the cache.
172:             */
173:            public UtilCache(String cacheName) {
174:                name = cacheName + this .getNextDefaultIndex(cacheName);
175:
176:                setPropertiesParams("default");
177:                setPropertiesParams(cacheName);
178:
179:                utilCacheTable.put(name, this );
180:            }
181:
182:            /** Default constructor, all members stay at default values as defined in cache.properties, or the defaults in this file if cache.properties is not found, or there are no 'default' entries in it. */
183:            public UtilCache() {
184:                setPropertiesParams("default");
185:
186:                name = "default" + this .getNextDefaultIndex("default");
187:                utilCacheTable.put(name, this );
188:            }
189:
190:            protected String getNextDefaultIndex(String cacheName) {
191:                Integer curInd = (Integer) UtilCache.defaultIndices
192:                        .get(cacheName);
193:
194:                if (curInd == null) {
195:                    UtilCache.defaultIndices.put(cacheName, new Integer(1));
196:                    return "";
197:                } else {
198:                    UtilCache.defaultIndices.put(cacheName, new Integer(curInd
199:                            .intValue() + 1));
200:                    return Integer.toString(curInd.intValue() + 1);
201:                }
202:            }
203:
204:            public static String getPropertyParam(ResourceBundle res,
205:                    String[] propNames, String parameter) {
206:                String value = null;
207:                for (int i = 0; i < propNames.length && value == null; i++) {
208:                    try {
209:                        value = res.getString(propNames[i] + '.' + parameter);
210:                    } catch (MissingResourceException e) {
211:                    }
212:                }
213:                // don't need this, just return null
214:                //if (value == null) {
215:                //    throw new MissingResourceException("Can't find resource for bundle", res.getClass().getName(), Arrays.asList(propNames) + "." + parameter);
216:                //}
217:                return value;
218:            }
219:
220:            protected void setPropertiesParams(String cacheName) {
221:                setPropertiesParams(new String[] { cacheName });
222:            }
223:
224:            public void setPropertiesParams(String[] propNames) {
225:                ResourceBundle res = ResourceBundle.getBundle("cache");
226:
227:                if (res != null) {
228:                    try {
229:                        String value = getPropertyParam(res, propNames,
230:                                "maxSize");
231:                        if (UtilValidate.isNotEmpty(value)) {
232:                            Integer intValue = new Integer(value);
233:                            if (intValue != null) {
234:                                this .maxSize = intValue.intValue();
235:                            }
236:                        }
237:                    } catch (Exception e) {
238:                        Debug.logWarning(e,
239:                                "Error getting maxSize value from cache.properties file for propNames: "
240:                                        + propNames, module);
241:                    }
242:                    try {
243:                        String value = getPropertyParam(res, propNames,
244:                                "maxInMemory");
245:                        if (UtilValidate.isNotEmpty(value)) {
246:                            Integer intValue = new Integer(value);
247:                            if (intValue != null) {
248:                                this .maxInMemory = intValue.intValue();
249:                            }
250:                        }
251:                    } catch (Exception e) {
252:                        Debug.logWarning(e,
253:                                "Error getting maxInMemory value from cache.properties file for propNames: "
254:                                        + propNames, module);
255:                    }
256:                    try {
257:                        String value = getPropertyParam(res, propNames,
258:                                "expireTime");
259:                        if (UtilValidate.isNotEmpty(value)) {
260:                            Long longValue = new Long(value);
261:                            if (longValue != null) {
262:                                this .expireTime = longValue.longValue();
263:                            }
264:                        }
265:                    } catch (Exception e) {
266:                        Debug.logWarning(e,
267:                                "Error getting expireTime value from cache.properties file for propNames: "
268:                                        + propNames, module);
269:                    }
270:                    try {
271:                        String value = getPropertyParam(res, propNames,
272:                                "useSoftReference");
273:                        if (value != null) {
274:                            useSoftReference = "true".equals(value);
275:                        }
276:                    } catch (Exception e) {
277:                        Debug
278:                                .logWarning(
279:                                        e,
280:                                        "Error getting useSoftReference value from cache.properties file for propNames: "
281:                                                + propNames, module);
282:                    }
283:                    try {
284:                        String value = getPropertyParam(res, propNames,
285:                                "useFileSystemStore");
286:                        if (value != null) {
287:                            useFileSystemStore = "true".equals(value);
288:                        }
289:                    } catch (Exception e) {
290:                        Debug
291:                                .logWarning(
292:                                        e,
293:                                        "Error getting useFileSystemStore value from cache.properties file for propNames: "
294:                                                + propNames, module);
295:                    }
296:                    try {
297:                        String value = res.getString("cache.file.store");
298:                        if (value != null) {
299:                            fileStore = value;
300:                        }
301:                    } catch (Exception e) {
302:                        Debug
303:                                .logWarning(
304:                                        e,
305:                                        "Error getting cache.file.store value from cache.properties file for propNames: "
306:                                                + propNames, module);
307:                    }
308:                }
309:
310:                int maxMemSize = this .maxInMemory;
311:                if (maxMemSize == 0)
312:                    maxMemSize = maxSize;
313:                this .cacheLineTable = new CacheLineTable(this .fileStore,
314:                        this .name, this .useFileSystemStore, maxMemSize);
315:            }
316:
317:            /** Puts or loads the passed element into the cache
318:             * @param key The key for the element, used to reference it in the hastables and LRU linked list
319:             * @param value The value of the element
320:             */
321:            public synchronized Object put(Object key, Object value) {
322:                return put(key, value, expireTime);
323:            }
324:
325:            /** Puts or loads the passed element into the cache
326:             * @param key The key for the element, used to reference it in the hastables and LRU linked list
327:             * @param value The value of the element
328:             * @param expireTime how long to keep this key in the cache
329:             */
330:            public synchronized Object put(Object key, Object value,
331:                    long expireTime) {
332:                if (key == null) {
333:                    if (Debug.verboseOn())
334:                        Debug.logVerbose(
335:                                "In UtilCache tried to put with null key, using NullObject for cache "
336:                                        + this .getName(), module);
337:                    key = ObjectType.NULL;
338:                }
339:                CacheLine oldCacheLine;
340:                if (expireTime > 0) {
341:                    oldCacheLine = (CacheLine) cacheLineTable.put(key,
342:                            new CacheLine(value, useSoftReference, System
343:                                    .currentTimeMillis(), expireTime));
344:                } else {
345:                    oldCacheLine = (CacheLine) cacheLineTable.put(key,
346:                            new CacheLine(value, useSoftReference, expireTime));
347:                }
348:
349:                if (oldCacheLine == null) {
350:                    noteAddition(key, value);
351:                    return null;
352:                } else {
353:                    noteUpdate(key, value, oldCacheLine.getValue());
354:                    return oldCacheLine.getValue();
355:                }
356:
357:            }
358:
359:            /** Gets an element from the cache according to the specified key.
360:             * If the requested element hasExpired, it is removed before it is looked up which causes the function to return null.
361:             * @param key The key for the element, used to reference it in the hastables and LRU linked list
362:             * @return The value of the element specified by the key
363:             */
364:            public Object get(Object key) {
365:                CacheLine line = getInternal(key, true);
366:                if (line == null) {
367:                    return null;
368:                } else {
369:                    return line.getValue();
370:                }
371:            }
372:
373:            protected CacheLine getInternalNoCheck(Object key) {
374:                if (key == null) {
375:                    if (Debug.verboseOn())
376:                        Debug.logVerbose(
377:                                "In UtilCache tried to get with null key, using NullObject for cache "
378:                                        + this .getName(), module);
379:                    key = ObjectType.NULL;
380:                }
381:                CacheLine line = (CacheLine) cacheLineTable.get(key);
382:                return line;
383:            }
384:
385:            protected CacheLine getInternal(Object key, boolean countGet) {
386:                CacheLine line = getInternalNoCheck(key);
387:                if (line == null) {
388:                    if (countGet)
389:                        missCountNotFound++;
390:                } else if (line.softReferenceCleared()) {
391:                    removeInternal(key, false);
392:                    if (countGet)
393:                        missCountSoftRef++;
394:                    line = null;
395:                } else if (this .hasExpired(line)) {
396:                    // note that print.info in debug.properties cannot be checked through UtilProperties here, it would cause infinite recursion...
397:                    // if (Debug.infoOn()) Debug.logInfo("Element has expired with key " + key, module);
398:                    removeInternal(key, false);
399:                    if (countGet)
400:                        missCountExpired++;
401:                    line = null;
402:                } else {
403:                    if (countGet)
404:                        hitCount++;
405:                }
406:                return line;
407:            }
408:
409:            public List values() {
410:                if (cacheLineTable == null) {
411:                    return null;
412:                }
413:
414:                List valuesList = FastList.newInstance();
415:                Iterator i = cacheLineTable.keySet().iterator();
416:                while (i.hasNext()) {
417:                    Object key = i.next();
418:                    valuesList.add(this .get(key));
419:                }
420:
421:                return valuesList;
422:            }
423:
424:            public long getSizeInBytes() {
425:                long totalSize = 0;
426:                Iterator i = cacheLineTable.values().iterator();
427:                while (i.hasNext()) {
428:                    totalSize += ((CacheLine) i.next()).getSizeInBytes();
429:                }
430:                return totalSize;
431:            }
432:
433:            /** Removes an element from the cache according to the specified key
434:             * @param key The key for the element, used to reference it in the hastables and LRU linked list
435:             * @return The value of the removed element specified by the key
436:             */
437:            public synchronized Object remove(Object key) {
438:                return this .removeInternal(key, true);
439:            }
440:
441:            /** This is used for internal remove calls because we only want to count external calls */
442:            protected synchronized Object removeInternal(Object key,
443:                    boolean countRemove) {
444:                if (key == null) {
445:                    if (Debug.verboseOn())
446:                        Debug.logVerbose(
447:                                "In UtilCache tried to remove with null key, using NullObject for cache "
448:                                        + this .getName(), module);
449:                    key = ObjectType.NULL;
450:                }
451:                CacheLine line = (CacheLine) cacheLineTable.remove(key);
452:                if (line != null) {
453:                    noteRemoval(key, line.getValue());
454:                    if (countRemove)
455:                        this .removeHitCount++;
456:                    return line.getValue();
457:                } else {
458:                    if (countRemove)
459:                        this .removeMissCount++;
460:                    return null;
461:                }
462:            }
463:
464:            /** Removes all elements from this cache */
465:            public synchronized void clear() {
466:                Iterator it = cacheLineTable.keySet().iterator();
467:                while (it.hasNext()) {
468:                    Object key = it.next();
469:                    CacheLine line = getInternalNoCheck(key);
470:                    noteRemoval(key, line == null ? null : line.getValue());
471:                }
472:                cacheLineTable.clear();
473:                clearCounters();
474:            }
475:
476:            /** Removes all elements from this cache */
477:            public static void clearAllCaches() {
478:                Iterator entries = utilCacheTable.entrySet().iterator();
479:                while (entries.hasNext()) {
480:                    Map.Entry entry = (Map.Entry) entries.next();
481:                    UtilCache utilCache = (UtilCache) entry.getValue();
482:                    utilCache.clear();
483:                }
484:            }
485:
486:            /** Getter for the name of the UtilCache instance.
487:             * @return The name of the instance
488:             */
489:            public String getName() {
490:                return this .name;
491:            }
492:
493:            /** Returns the number of successful hits on the cache
494:             * @return The number of successful cache hits
495:             */
496:            public long getHitCount() {
497:                return this .hitCount;
498:            }
499:
500:            /** Returns the number of cache misses from entries that are not found in the cache
501:             * @return The number of cache misses
502:             */
503:            public long getMissCountNotFound() {
504:                return this .missCountNotFound;
505:            }
506:
507:            /** Returns the number of cache misses from entries that are expired
508:             * @return The number of cache misses
509:             */
510:            public long getMissCountExpired() {
511:                return this .missCountExpired;
512:            }
513:
514:            /** Returns the number of cache misses from entries that are have had the soft reference cleared out (by garbage collector and such)
515:             * @return The number of cache misses
516:             */
517:            public long getMissCountSoftRef() {
518:                return this .missCountSoftRef;
519:            }
520:
521:            /** Returns the number of cache misses caused by any reason
522:             * @return The number of cache misses
523:             */
524:            public long getMissCountTotal() {
525:                return this .missCountSoftRef + this .missCountNotFound
526:                        + this .missCountExpired;
527:            }
528:
529:            public long getRemoveHitCount() {
530:                return this .removeHitCount;
531:            }
532:
533:            public long getRemoveMissCount() {
534:                return this .removeMissCount;
535:            }
536:
537:            /** Clears the hit and miss counters
538:             */
539:            public void clearCounters() {
540:                this .hitCount = 0;
541:                this .missCountNotFound = 0;
542:                this .missCountExpired = 0;
543:                this .missCountSoftRef = 0;
544:                this .removeHitCount = 0;
545:                this .removeMissCount = 0;
546:            }
547:
548:            /** Sets the maximum number of elements in the cache.
549:             * If 0, there is no maximum.
550:             * @param maxSize The maximum number of elements in the cache
551:             */
552:            public void setMaxSize(int maxSize) {
553:                cacheLineTable.setLru(maxSize);
554:                this .maxSize = maxSize;
555:            }
556:
557:            /** Returns the current maximum number of elements in the cache
558:             * @return The maximum number of elements in the cache
559:             */
560:            public long getMaxSize() {
561:                return maxSize;
562:            }
563:
564:            /** Sets the expire time for the cache elements.
565:             * If 0, elements never expire.
566:             * @param expireTime The expire time for the cache elements
567:             */
568:            public void setExpireTime(long expireTime) {
569:                // if expire time was <= 0 and is now greater, fill expire table now
570:                if (this .expireTime <= 0 && expireTime > 0) {
571:                    long currentTime = System.currentTimeMillis();
572:                    Iterator values = cacheLineTable.values().iterator();
573:                    while (values.hasNext()) {
574:                        CacheLine line = (CacheLine) values.next();
575:                        line.loadTime = currentTime;
576:                    }
577:                } else if (this .expireTime <= 0 && expireTime > 0) {
578:                    // if expire time was > 0 and is now <=, do nothing, just leave the load times in place, won't hurt anything...
579:                }
580:
581:                this .expireTime = expireTime;
582:            }
583:
584:            /** return the current expire time for the cache elements
585:             * @return The expire time for the cache elements
586:             */
587:            public long getExpireTime() {
588:                return expireTime;
589:            }
590:
591:            /** Set whether or not the cache lines should use a soft reference to the data */
592:            public void setUseSoftReference(boolean useSoftReference) {
593:                if (this .useSoftReference != useSoftReference) {
594:                    this .useSoftReference = useSoftReference;
595:                    Iterator values = cacheLineTable.values().iterator();
596:                    while (values.hasNext()) {
597:                        CacheLine line = (CacheLine) values.next();
598:                        line.setUseSoftReference(useSoftReference);
599:                    }
600:                }
601:            }
602:
603:            /** Return whether or not the cache lines should use a soft reference to the data */
604:            public boolean getUseSoftReference() {
605:                return this .useSoftReference;
606:            }
607:
608:            public boolean getUseFileSystemStore() {
609:                return this .useFileSystemStore;
610:            }
611:
612:            /** Returns the number of elements currently in the cache
613:             * @return The number of elements currently in the cache
614:             */
615:            public long size() {
616:                return cacheLineTable.size();
617:            }
618:
619:            /** Returns a boolean specifying whether or not an element with the specified key is in the cache.
620:             * If the requested element hasExpired, it is removed before it is looked up which causes the function to return false.
621:             * @param key The key for the element, used to reference it in the hastables and LRU linked list
622:             * @return True is the cache contains an element corresponding to the specified key, otherwise false
623:             */
624:            public boolean containsKey(Object key) {
625:                CacheLine line = getInternal(key, false);
626:                if (line != null) {
627:                    return true;
628:                } else {
629:                    return false;
630:                }
631:            }
632:
633:            /** 
634:             * NOTE: this returns an unmodifiable copy of the keySet, so removing from here won't have an effect, 
635:             * and calling a remove while iterating through the set will not cause a concurrent modification exception.
636:             * This behavior is necessary for now for the persisted cache feature. 
637:             */
638:            public Set getCacheLineKeys() {
639:                return cacheLineTable.keySet();
640:            }
641:
642:            public Collection getCacheLineValues() {
643:                return cacheLineTable.values();
644:            }
645:
646:            /** Returns a boolean specifying whether or not the element corresponding to the key has expired.
647:             * Only returns true if element is in cache and has expired. Error conditions return false, if no expireTable entry, returns true.
648:             * Always returns false if expireTime <= 0.
649:             * Also, if SoftReference in the CacheLine object has been cleared by the gc return true.
650:             *
651:             * @param key The key for the element, used to reference it in the hastables and LRU linked list
652:             * @return True is the element corresponding to the specified key has expired, otherwise false
653:             */
654:            public boolean hasExpired(Object key) {
655:                CacheLine line = getInternalNoCheck(key);
656:                return hasExpired(line);
657:            }
658:
659:            protected boolean hasExpired(CacheLine line) {
660:                if (line == null)
661:                    return false;
662:
663:                // check this BEFORE checking to see if expireTime <= 0, ie if time expiration is enabled
664:                // check to see if we are using softReference first, slight performance increase
665:                if (line.softReferenceCleared())
666:                    return true;
667:
668:                // check if expireTime <= 0, ie if time expiration is not enabled
669:                if (line.expireTime <= 0)
670:                    return false;
671:
672:                // check if the time was saved for this; if the time was not saved, but expire time is > 0, then we don't know when it was saved so expire it to be safe
673:                if (line.loadTime <= 0)
674:                    return true;
675:
676:                if ((line.loadTime + line.expireTime) < System
677:                        .currentTimeMillis()) {
678:                    return true;
679:                } else {
680:                    return false;
681:                }
682:            }
683:
684:            /** Clears all expired cache entries; also clear any cache entries where the SoftReference in the CacheLine object has been cleared by the gc */
685:            public void clearExpired() {
686:                Iterator keys = cacheLineTable.keySet().iterator();
687:                while (keys.hasNext()) {
688:                    Object key = keys.next();
689:                    if (hasExpired(key)) {
690:                        removeInternal(key, false);
691:                    }
692:                }
693:            }
694:
695:            /** Send a key addition event to all registered listeners */
696:            protected void noteAddition(Object key, Object newValue) {
697:                synchronized (listeners) {
698:                    Iterator it = listeners.iterator();
699:                    while (it.hasNext()) {
700:                        CacheListener listener = (CacheListener) it.next();
701:                        listener.noteKeyAddition(this , key, newValue);
702:                    }
703:                }
704:            }
705:
706:            /** Send a key removal event to all registered listeners */
707:            protected void noteRemoval(Object key, Object oldValue) {
708:                synchronized (listeners) {
709:                    Iterator it = listeners.iterator();
710:                    while (it.hasNext()) {
711:                        CacheListener listener = (CacheListener) it.next();
712:                        listener.noteKeyRemoval(this , key, oldValue);
713:                    }
714:                }
715:            }
716:
717:            /** Send a key update event to all registered listeners */
718:            protected void noteUpdate(Object key, Object newValue,
719:                    Object oldValue) {
720:                synchronized (listeners) {
721:                    Iterator it = listeners.iterator();
722:                    while (it.hasNext()) {
723:                        CacheListener listener = (CacheListener) it.next();
724:                        listener.noteKeyUpdate(this , key, newValue, oldValue);
725:                    }
726:                }
727:            }
728:
729:            /** Adds an event listener for key removals */
730:            public void addListener(CacheListener listener) {
731:                synchronized (listeners) {
732:                    listeners.add(listener);
733:                }
734:            }
735:
736:            /** Removes an event listener for key removals */
737:            public void removeListener(CacheListener listener) {
738:                synchronized (listeners) {
739:                    listeners.remove(listener);
740:                }
741:            }
742:
743:            /** Clears all expired cache entries from all caches */
744:            public static void clearExpiredFromAllCaches() {
745:                Iterator entries = utilCacheTable.entrySet().iterator();
746:                while (entries.hasNext()) {
747:                    Map.Entry entry = (Map.Entry) entries.next();
748:                    UtilCache utilCache = (UtilCache) entry.getValue();
749:                    utilCache.clearExpired();
750:                }
751:            }
752:
753:            /** Checks for a non-expired key in a specific cache */
754:            public static boolean validKey(String cacheName, Object key) {
755:                UtilCache cache = (UtilCache) utilCacheTable.get(cacheName);
756:                if (cache != null) {
757:                    if (cache.containsKey(key))
758:                        return true;
759:                }
760:                return false;
761:            }
762:
763:            public static void clearCachesThatStartWith(String startsWith) {
764:                synchronized (utilCacheTable) {
765:                    Iterator it = utilCacheTable.entrySet().iterator();
766:                    while (it.hasNext()) {
767:                        Map.Entry entry = (Map.Entry) it.next();
768:                        String name = (String) entry.getKey();
769:                        if (name.startsWith(startsWith)) {
770:                            UtilCache cache = (UtilCache) entry.getValue();
771:                            cache.clear();
772:                        }
773:                    }
774:                }
775:            }
776:
777:            public static void clearCache(String cacheName) {
778:                synchronized (UtilCache.utilCacheTable) {
779:                    UtilCache cache = (UtilCache) UtilCache.utilCacheTable
780:                            .get(cacheName);
781:                    if (cache == null)
782:                        return;
783:                    cache.clear();
784:                }
785:            }
786:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.