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


001:        /*
002:         * $Id: UtilCache.java,v 1.2 2004/02/26 16:22:09 jonesde Exp $
003:         *
004:         *  Copyright (c) 2001-2004 The Open For Business Project - www.ofbiz.org
005:         *
006:         *  Permission is hereby granted, free of charge, to any person obtaining a
007:         *  copy of this software and associated documentation files (the "Software"),
008:         *  to deal in the Software without restriction, including without limitation
009:         *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
010:         *  and/or sell copies of the Software, and to permit persons to whom the
011:         *  Software is furnished to do so, subject to the following conditions:
012:         *
013:         *  The above copyright notice and this permission notice shall be included
014:         *  in all copies or substantial portions of the Software.
015:         *
016:         *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
017:         *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
018:         *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
019:         *  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
020:         *  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
021:         *  OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
022:         *  THE USE OR OTHER DEALINGS IN THE SOFTWARE.
023:         */
024:        package org.ofbiz.base.util;
025:
026:        import java.util.HashMap;
027:        import java.util.Iterator;
028:        import java.util.LinkedList;
029:        import java.util.Map;
030:        import java.util.ResourceBundle;
031:
032:        /**
033:         * Generalized caching utility. Provides a number of caching features:
034:         * <ul>
035:         *   <li>Limited or unlimited element capacity
036:         *   <li>If limited, removes elements with the LRU (Least Recently Used) algorithm
037:         *   <li>Keeps track of when each element was loaded into the cache
038:         *   <li>Using the expireTime can report whether a given element has expired
039:         *   <li>Counts misses and hits
040:         * </ul>
041:         *
042:         * @author     <a href="mailto:jonesde@ofbiz.org">David E. Jones</a>
043:         * @version    $Revision: 1.2 $
044:         * @since      2.0
045:         */
046:        public class UtilCache {
047:
048:            /** A static Map to keep track of all of the UtilCache instances. */
049:            public static Map utilCacheTable = new HashMap();
050:
051:            /** An index number appended to utilCacheTable names when there are conflicts. */
052:            protected static Map defaultIndices = new HashMap();
053:
054:            /** The name of the UtilCache instance, is also the key for the instance in utilCacheTable. */
055:            protected String name;
056:
057:            /** A list of the elements order by Least Recent Use */
058:            public LinkedList keyLRUList = new LinkedList();
059:
060:            /** A hashtable containing a CacheLine object with a value and a loadTime for each element. */
061:            public Map cacheLineTable = new HashMap();
062:
063:            /** A count of the number of cache hits */
064:            protected long hitCount = 0;
065:
066:            /** A count of the number of cache misses */
067:            protected long missCount = 0;
068:
069:            /** The maximum number of elements in the cache.
070:             * If set to 0, there will be no limit on the number of elements in the cache.
071:             */
072:            protected long maxSize = 0;
073:
074:            /** Specifies the amount of time since initial loading before an element will be reported as expired.
075:             * If set to 0, elements will never expire.
076:             */
077:            protected long expireTime = 0;
078:
079:            /** Specifies whether or not to use soft references for this cache, defaults to false */
080:            protected boolean useSoftReference = false;
081:
082:            /** Constructor which specifies the cacheName as well as the maxSize, expireTime and useSoftReference.
083:             * The passed maxSize, expireTime and useSoftReference will be overridden by values from cache.properties if found.
084:             * @param maxSize The maxSize member is set to this value
085:             * @param expireTime The expireTime member is set to this value
086:             * @param cacheName The name of the cache.
087:             * @param useSoftReference Specifies whether or not to use soft references for this cache.
088:             */
089:            public UtilCache(String cacheName, long maxSize, long expireTime,
090:                    boolean useSoftReference) {
091:                this .useSoftReference = useSoftReference;
092:                this .maxSize = maxSize;
093:                this .expireTime = expireTime;
094:                setPropertiesParams(cacheName);
095:
096:                name = cacheName + this .getNextDefaultIndex(cacheName);
097:                utilCacheTable.put(name, this );
098:            }
099:
100:            /** Constructor which specifies the cacheName as well as the maxSize and expireTime.
101:             * The passed maxSize and expireTime will be overridden by values from cache.properties if found.
102:             * @param maxSize The maxSize member is set to this value
103:             * @param expireTime The expireTime member is set to this value
104:             * @param cacheName The name of the cache.
105:             */
106:            public UtilCache(String cacheName, long maxSize, long expireTime) {
107:                this (cacheName, maxSize, expireTime, false);
108:            }
109:
110:            /** Constructor which specifies the maxSize and expireTime.
111:             * @param maxSize The maxSize member is set to this value
112:             * @param expireTime The expireTime member is set to this value
113:             */
114:            public UtilCache(long maxSize, long expireTime) {
115:                this .useSoftReference = false;
116:                this .maxSize = maxSize;
117:                this .expireTime = expireTime;
118:                String name = "specified"
119:                        + this .getNextDefaultIndex("specified");
120:
121:                setPropertiesParams(name);
122:                utilCacheTable.put(name, this );
123:            }
124:
125:            /** This constructor takes a name for the cache, puts itself in the utilCacheTable.
126:             * It also uses the cacheName to lookup the initialization parameters from cache.properties.
127:             * @param cacheName The name of the cache.
128:             */
129:            public UtilCache(String cacheName) {
130:                setPropertiesParams("default");
131:                setPropertiesParams(cacheName);
132:
133:                name = cacheName + this .getNextDefaultIndex(cacheName);
134:                utilCacheTable.put(name, this );
135:            }
136:
137:            /** 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. */
138:            public UtilCache() {
139:                setPropertiesParams("default");
140:
141:                name = "default" + this .getNextDefaultIndex("default");
142:                utilCacheTable.put(name, this );
143:            }
144:
145:            protected String getNextDefaultIndex(String cacheName) {
146:                Integer curInd = (Integer) UtilCache.defaultIndices
147:                        .get(cacheName);
148:
149:                if (curInd == null) {
150:                    UtilCache.defaultIndices.put(cacheName, new Integer(1));
151:                    return "";
152:                } else {
153:                    UtilCache.defaultIndices.put(cacheName, new Integer(curInd
154:                            .intValue() + 1));
155:                    return Integer.toString(curInd.intValue() + 1);
156:                }
157:            }
158:
159:            protected void setPropertiesParams(String cacheName) {
160:                ResourceBundle res = ResourceBundle.getBundle("cache");
161:
162:                if (res != null) {
163:                    try {
164:                        String value = res.getString(cacheName + ".maxSize");
165:                        Long longValue = new Long(value);
166:
167:                        if (longValue != null) {
168:                            maxSize = longValue.longValue();
169:                        }
170:                    } catch (Exception e) {
171:                    }
172:                    try {
173:                        String value = res.getString(cacheName + ".expireTime");
174:                        Long longValue = new Long(value);
175:
176:                        if (longValue != null) {
177:                            expireTime = longValue.longValue();
178:                        }
179:                    } catch (Exception e) {
180:                    }
181:
182:                    try {
183:                        String value = res.getString(cacheName
184:                                + ".useSoftReference");
185:
186:                        if (value != null) {
187:                            useSoftReference = "true".equals(value);
188:                        }
189:                    } catch (Exception e) {
190:                    }
191:                }
192:            }
193:
194:            /** Puts or loads the passed element into the cache
195:             * @param key The key for the element, used to reference it in the hastables and LRU linked list
196:             * @param value The value of the element
197:             */
198:            public synchronized void put(Object key, Object value) {
199:                if (key == null)
200:                    return;
201:
202:                if (maxSize > 0) {
203:                    // when maxSize is changed, the setter will take care of filling the LRU list
204:                    if (cacheLineTable.containsKey(key)) {
205:                        keyLRUList.remove(key);
206:                        keyLRUList.addFirst(key);
207:                    } else {
208:                        keyLRUList.addFirst(key);
209:                    }
210:                }
211:
212:                if (expireTime > 0) {
213:                    cacheLineTable.put(key, new UtilCache.CacheLine(value,
214:                            useSoftReference, System.currentTimeMillis()));
215:                } else {
216:                    cacheLineTable.put(key, new UtilCache.CacheLine(value,
217:                            useSoftReference));
218:                }
219:                if (maxSize > 0 && cacheLineTable.size() > maxSize) {
220:                    Object lastKey = keyLRUList.getLast();
221:                    remove(lastKey);
222:                }
223:            }
224:
225:            /** Gets an element from the cache according to the specified key.
226:             * If the requested element hasExpired, it is removed before it is looked up which causes the function to return null.
227:             * @param key The key for the element, used to reference it in the hastables and LRU linked list
228:             * @return The value of the element specified by the key
229:             */
230:            public Object get(Object key) {
231:                if (key == null) {
232:                    missCount++;
233:                    return null;
234:                }
235:                UtilCache.CacheLine line = (UtilCache.CacheLine) cacheLineTable
236:                        .get(key);
237:
238:                if (hasExpired(line)) {
239:                    // note that print.info in debug.properties cannot be checked through UtilProperties here, it would cause infinite recursion...
240:                    // if (Debug.infoOn()) Debug.logInfo("Element has expired with key " + key, module);
241:                    remove(key);
242:                    line = null;
243:                }
244:
245:                if (line == null) {
246:                    // if (Debug.infoOn()) Debug.logInfo("Element not found with key " + key, module);
247:                    missCount++;
248:                    return null;
249:                }
250:                // if (Debug.infoOn()) Debug.logInfo("Element found with key " + key, module);
251:                hitCount++;
252:
253:                if (maxSize > 0) {
254:                    synchronized (this ) {
255:                        keyLRUList.remove(key);
256:                        keyLRUList.addFirst(key);
257:                    }
258:                }
259:                return line.getValue();
260:            }
261:
262:            /** Removes an element from the cache according to the specified key
263:             * @param key The key for the element, used to reference it in the hastables and LRU linked list
264:             * @return The value of the removed element specified by the key
265:             */
266:            public synchronized Object remove(Object key) {
267:                if (key == null) {
268:                    missCount++;
269:                    return null;
270:                }
271:
272:                UtilCache.CacheLine line = (UtilCache.CacheLine) cacheLineTable
273:                        .remove(key);
274:                if (line != null) {
275:                    if (maxSize > 0)
276:                        keyLRUList.remove(key);
277:                    return line.getValue();
278:                } else {
279:                    missCount++;
280:                    return null;
281:                }
282:            }
283:
284:            /** Removes all elements from this cache */
285:            public synchronized void clear() {
286:                cacheLineTable.clear();
287:                keyLRUList.clear();
288:                clearCounters();
289:            }
290:
291:            /** Removes all elements from this cache */
292:            public static void clearAllCaches() {
293:                Iterator entries = utilCacheTable.entrySet().iterator();
294:                while (entries.hasNext()) {
295:                    Map.Entry entry = (Map.Entry) entries.next();
296:                    UtilCache utilCache = (UtilCache) entry.getValue();
297:                    utilCache.clear();
298:                }
299:            }
300:
301:            /** Getter for the name of the UtilCache instance.
302:             * @return The name of the instance
303:             */
304:            public String getName() {
305:                return name;
306:            }
307:
308:            /** Returns the number of successful hits on the cache
309:             * @return The number of successful cache hits
310:             */
311:            public long getHitCount() {
312:                return hitCount;
313:            }
314:
315:            /** Returns the number of cache misses
316:             * @return The number of cache misses
317:             */
318:            public long getMissCount() {
319:                return missCount;
320:            }
321:
322:            /** Clears the hit and miss counters
323:             */
324:            public void clearCounters() {
325:                hitCount = 0;
326:                missCount = 0;
327:            }
328:
329:            /** Sets the maximum number of elements in the cache.
330:             * If 0, there is no maximum.
331:             * @param maxSize The maximum number of elements in the cache
332:             */
333:            public void setMaxSize(long maxSize) {
334:                // if the new maxSize is <= 0, clear keyLRUList
335:                if (maxSize <= 0) {
336:                    keyLRUList.clear();
337:                } else if (maxSize > 0 && this .maxSize <= 0) {
338:                    // if the new maxSize > 0 and the old is <= 0, fill in LRU list - order will be meaningless for now
339:                    Iterator keys = cacheLineTable.keySet().iterator();
340:
341:                    while (keys.hasNext()) {
342:                        keyLRUList.add(keys.next());
343:                    }
344:                }
345:
346:                // if the new maxSize is less than the current cache size, shrink the cache.
347:                if (maxSize > 0 && cacheLineTable.size() > maxSize) {
348:                    while (cacheLineTable.size() > maxSize) {
349:                        Object lastKey = keyLRUList.getLast();
350:
351:                        remove(lastKey);
352:                    }
353:                }
354:
355:                this .maxSize = maxSize;
356:            }
357:
358:            /** Returns the current maximum number of elements in the cache
359:             * @return The maximum number of elements in the cache
360:             */
361:            public long getMaxSize() {
362:                return maxSize;
363:            }
364:
365:            /** Sets the expire time for the cache elements.
366:             * If 0, elements never expire.
367:             * @param expireTime The expire time for the cache elements
368:             */
369:            public void setExpireTime(long expireTime) {
370:                // if expire time was <= 0 and is now greater, fill expire table now
371:                if (this .expireTime <= 0 && expireTime > 0) {
372:                    long currentTime = System.currentTimeMillis();
373:                    Iterator values = cacheLineTable.values().iterator();
374:                    while (values.hasNext()) {
375:                        UtilCache.CacheLine line = (UtilCache.CacheLine) values
376:                                .next();
377:                        line.loadTime = currentTime;
378:                    }
379:                } else if (this .expireTime <= 0 && expireTime > 0) {// if expire time was > 0 and is now <=, do nothing, just leave the load times in place, won't hurt anything...
380:                }
381:
382:                this .expireTime = expireTime;
383:            }
384:
385:            /** return the current expire time for the cache elements
386:             * @return The expire time for the cache elements
387:             */
388:            public long getExpireTime() {
389:                return expireTime;
390:            }
391:
392:            /** Set whether or not the cache lines should use a soft reference to the data */
393:            public void setUseSoftReference(boolean useSoftReference) {
394:                if (this .useSoftReference != useSoftReference) {
395:                    this .useSoftReference = useSoftReference;
396:                    Iterator values = cacheLineTable.values().iterator();
397:                    while (values.hasNext()) {
398:                        UtilCache.CacheLine line = (UtilCache.CacheLine) values
399:                                .next();
400:                        line.setUseSoftReference(useSoftReference);
401:                    }
402:                }
403:            }
404:
405:            /** Return whether or not the cache lines should use a soft reference to the data */
406:            public boolean getUseSoftReference() {
407:                return this .useSoftReference;
408:            }
409:
410:            /** Returns the number of elements currently in the cache
411:             * @return The number of elements currently in the cache
412:             */
413:            public long size() {
414:                return cacheLineTable.size();
415:            }
416:
417:            /** Returns a boolean specifying whether or not an element with the specified key is in the cache.
418:             * If the requested element hasExpired, it is removed before it is looked up which causes the function to return false.
419:             * @param key The key for the element, used to reference it in the hastables and LRU linked list
420:             * @return True is the cache contains an element corresponding to the specified key, otherwise false
421:             */
422:            public boolean containsKey(Object key) {
423:                UtilCache.CacheLine line = (UtilCache.CacheLine) cacheLineTable
424:                        .get(key);
425:
426:                if (hasExpired(line)) {
427:                    remove(key);
428:                    line = null;
429:                }
430:                if (line != null) {
431:                    return true;
432:                } else {
433:                    return false;
434:                }
435:            }
436:
437:            /** Returns a boolean specifying whether or not the element corresponding to the key has expired.
438:             * Only returns true if element is in cache and has expired. Error conditions return false, if no expireTable entry, returns true.
439:             * Always returns false if expireTime <= 0.
440:             * Also, if SoftReference in the CacheLine object has been cleared by the gc return true.
441:             *
442:             * @param key The key for the element, used to reference it in the hastables and LRU linked list
443:             * @return True is the element corresponding to the specified key has expired, otherwise false
444:             */
445:            public boolean hasExpired(Object key) {
446:                if (key == null)
447:                    return false;
448:
449:                UtilCache.CacheLine line = (UtilCache.CacheLine) cacheLineTable
450:                        .get(key);
451:
452:                return hasExpired(line);
453:            }
454:
455:            protected boolean hasExpired(UtilCache.CacheLine line) {
456:                if (line == null)
457:                    return false;
458:                // check this BEFORE checking to see if expireTime <= 0, ie if time expiration is enabled
459:                // check to see if we are using softReference first, slight performance increase
460:                if (this .useSoftReference && line.getValue() == null)
461:                    return true;
462:                if (expireTime <= 0)
463:                    return false;
464:
465:                if (line.loadTime <= 0)
466:                    return true;
467:                if ((line.loadTime + expireTime) < System.currentTimeMillis()) {
468:                    return true;
469:                } else {
470:                    return false;
471:                }
472:            }
473:
474:            /** Clears all expired cache entries; also clear any cache entries where the SoftReference in the CacheLine object has been cleared by the gc */
475:            public void clearExpired() {
476:                Iterator keys = cacheLineTable.keySet().iterator();
477:                while (keys.hasNext()) {
478:                    Object key = keys.next();
479:                    if (hasExpired(key)) {
480:                        remove(key);
481:                    }
482:                }
483:            }
484:
485:            /** Clears all expired cache entries from all caches */
486:            public static void clearExpiredFromAllCaches() {
487:                Iterator entries = utilCacheTable.entrySet().iterator();
488:                while (entries.hasNext()) {
489:                    Map.Entry entry = (Map.Entry) entries.next();
490:                    UtilCache utilCache = (UtilCache) entry.getValue();
491:                    utilCache.clearExpired();
492:                }
493:            }
494:
495:            /** Checks for a non-expired key in a specific cache */
496:            public static boolean validKey(String cacheName, Object key) {
497:                UtilCache cache = (UtilCache) utilCacheTable.get(cacheName);
498:                if (cache != null) {
499:                    if (cache.containsKey(key))
500:                        return true;
501:                }
502:                return false;
503:            }
504:
505:            public static class CacheLine {
506:                public Object valueRef = null;
507:                public long loadTime = 0;
508:                public boolean useSoftReference = false;
509:
510:                public CacheLine(Object value, boolean useSoftReference) {
511:                    if (useSoftReference) {
512:                        this .valueRef = new java.lang.ref.SoftReference(value);
513:                    } else {
514:                        this .valueRef = value;
515:                    }
516:                    this .useSoftReference = useSoftReference;
517:                }
518:
519:                public CacheLine(Object value, boolean useSoftReference,
520:                        long loadTime) {
521:                    this (value, useSoftReference);
522:                    this .loadTime = loadTime;
523:                }
524:
525:                public Object getValue() {
526:                    if (valueRef == null)
527:                        return null;
528:                    if (useSoftReference) {
529:                        return ((java.lang.ref.SoftReference) valueRef).get();
530:                    } else {
531:                        return valueRef;
532:                    }
533:                }
534:
535:                public void setUseSoftReference(boolean useSoftReference) {
536:                    if (this .useSoftReference != useSoftReference) {
537:                        synchronized (this ) {
538:                            this .useSoftReference = useSoftReference;
539:                            if (useSoftReference) {
540:                                this .valueRef = new java.lang.ref.SoftReference(
541:                                        this .valueRef);
542:                            } else {
543:                                this .valueRef = ((java.lang.ref.SoftReference) this.valueRef)
544:                                        .get();
545:                            }
546:                        }
547:                    }
548:                }
549:            }
550:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.