Source Code Cross Referenced for AbstractCacheAdministrator.java in  » Cache » OSCache » com » opensymphony » oscache » base » 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
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Cache » OSCache » com.opensymphony.oscache.base 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright (c) 2002-2003 by OpenSymphony
003:         * All rights reserved.
004:         */
005:        package com.opensymphony.oscache.base;
006:
007:        import com.opensymphony.oscache.base.algorithm.AbstractConcurrentReadCache;
008:        import com.opensymphony.oscache.base.events.*;
009:        import com.opensymphony.oscache.base.persistence.PersistenceListener;
010:        import com.opensymphony.oscache.util.StringUtil;
011:
012:        import org.apache.commons.logging.Log;
013:        import org.apache.commons.logging.LogFactory;
014:
015:        import java.util.*;
016:
017:        import javax.swing.event.EventListenerList;
018:
019:        /**
020:         * An AbstractCacheAdministrator defines an abstract cache administrator, implementing all
021:         * the basic operations related to the configuration of a cache, including assigning
022:         * any configured event handlers to cache objects.<p>
023:         *
024:         * Extend this class to implement a custom cache administrator.
025:         *
026:         * @version        $Revision: 425 $
027:         * @author        a href="mailto:mike@atlassian.com">Mike Cannon-Brookes</a>
028:         * @author <a href="mailto:fbeauregard@pyxis-tech.com">Francois Beauregard</a>
029:         * @author <a href="mailto:abergevin@pyxis-tech.com">Alain Bergevin</a>
030:         * @author <a href="mailto:fabian.crabus@gurulogic.de">Fabian Crabus</a>
031:         * @author <a href="&#109;a&#105;&#108;&#116;&#111;:chris&#64;swebtec.&#99;&#111;&#109;">Chris Miller</a>
032:         */
033:        public abstract class AbstractCacheAdministrator implements 
034:                java.io.Serializable {
035:            private static transient final Log log = LogFactory
036:                    .getLog(AbstractCacheAdministrator.class);
037:
038:            /**
039:             * A boolean cache configuration property that indicates whether the cache
040:             * should cache objects in memory. Set this property to <code>false</code>
041:             * to disable in-memory caching.
042:             */
043:            public final static String CACHE_MEMORY_KEY = "cache.memory";
044:
045:            /**
046:             * An integer cache configuration property that specifies the maximum number
047:             * of objects to hold in the cache. Setting this to a negative value will
048:             * disable the capacity functionality - there will be no limit to the number
049:             * of objects that are held in cache.
050:             */
051:            public final static String CACHE_CAPACITY_KEY = "cache.capacity";
052:
053:            /**
054:             * A String cache configuration property that specifies the classname of
055:             * an alternate caching algorithm. This class must extend
056:             * {@link com.opensymphony.oscache.base.algorithm.AbstractConcurrentReadCache}
057:             * By default caches will use {@link com.opensymphony.oscache.base.algorithm.LRUCache} as
058:             * the default algorithm if the cache capacity is set to a postive value, or
059:             * {@link com.opensymphony.oscache.base.algorithm.UnlimitedCache} if the
060:             * capacity is negative (ie, disabled).
061:             */
062:            public final static String CACHE_ALGORITHM_KEY = "cache.algorithm";
063:
064:            /**
065:             * A boolean cache configuration property that indicates whether the persistent
066:             * cache should be unlimited in size, or should be restricted to the same size
067:             * as the in-memory cache. Set this property to <code>true</code> to allow the
068:             * persistent cache to grow without bound.
069:             */
070:            public final static String CACHE_DISK_UNLIMITED_KEY = "cache.unlimited.disk";
071:
072:            /**
073:             * The configuration key that specifies whether we should block waiting for new
074:             * content to be generated, or just serve the old content instead. The default
075:             * behaviour is to serve the old content since that provides the best performance
076:             * (at the cost of serving slightly stale data).
077:             */
078:            public final static String CACHE_BLOCKING_KEY = "cache.blocking";
079:
080:            /**
081:             * A String cache configuration property that specifies the classname that will
082:             * be used to provide cache persistence. This class must extend {@link PersistenceListener}.
083:             */
084:            public static final String PERSISTENCE_CLASS_KEY = "cache.persistence.class";
085:
086:            /**
087:             * A String cache configuration property that specifies if the cache persistence
088:             * will only be used in overflow mode, that is, when the memory cache capacity has been reached.
089:             */
090:            public static final String CACHE_PERSISTENCE_OVERFLOW_KEY = "cache.persistence.overflow.only";
091:
092:            /**
093:             * A String cache configuration property that holds a comma-delimited list of
094:             * classnames. These classes specify the event handlers that are to be applied
095:             * to the cache.
096:             */
097:            public static final String CACHE_ENTRY_EVENT_LISTENERS_KEY = "cache.event.listeners";
098:            protected Config config = null;
099:
100:            /**
101:             * Holds a list of all the registered event listeners. Event listeners are specified
102:             * using the {@link #CACHE_ENTRY_EVENT_LISTENERS_KEY} configuration key.
103:             */
104:            protected EventListenerList listenerList = new EventListenerList();
105:
106:            /**
107:             * The algorithm class being used, as specified by the {@link #CACHE_ALGORITHM_KEY}
108:             * configuration property.
109:             */
110:            protected String algorithmClass = null;
111:
112:            /**
113:             * The cache capacity (number of entries), as specified by the {@link #CACHE_CAPACITY_KEY}
114:             * configuration property.
115:             */
116:            protected int cacheCapacity = -1;
117:
118:            /**
119:             * Whether the cache blocks waiting for content to be build, or serves stale
120:             * content instead. This value can be specified using the {@link #CACHE_BLOCKING_KEY}
121:             * configuration property.
122:             */
123:            private boolean blocking = false;
124:
125:            /**
126:             * Whether or not to store the cache entries in memory. This is configurable using the
127:             * {@link com.opensymphony.oscache.base.AbstractCacheAdministrator#CACHE_MEMORY_KEY} property.
128:             */
129:            private boolean memoryCaching = true;
130:
131:            /**
132:             * Whether the persistent cache should be used immediately or only when the memory capacity
133:             * has been reached, ie. overflow only.
134:             * This can be set via the {@link #CACHE_PERSISTENCE_OVERFLOW_KEY} configuration property.
135:             */
136:            private boolean overflowPersistence;
137:
138:            /**
139:             * Whether the disk cache should be unlimited in size, or matched 1-1 to the memory cache.
140:             * This can be set via the {@link #CACHE_DISK_UNLIMITED_KEY} configuration property.
141:             */
142:            private boolean unlimitedDiskCache;
143:
144:            /**
145:             * Create the AbstractCacheAdministrator.
146:             * This will initialize all values and load the properties from oscache.properties.
147:             */
148:            protected AbstractCacheAdministrator() {
149:                this (null);
150:            }
151:
152:            /**
153:             * Create the AbstractCacheAdministrator.
154:             *
155:             * @param p the configuration properties for this cache.
156:             */
157:            protected AbstractCacheAdministrator(Properties p) {
158:                loadProps(p);
159:                initCacheParameters();
160:
161:                if (log.isDebugEnabled()) {
162:                    log.debug("Constructed AbstractCacheAdministrator()");
163:                }
164:            }
165:
166:            /**
167:             * Sets the algorithm to use for the cache.
168:             *
169:             * @see com.opensymphony.oscache.base.algorithm.LRUCache
170:             * @see com.opensymphony.oscache.base.algorithm.FIFOCache
171:             * @see com.opensymphony.oscache.base.algorithm.UnlimitedCache
172:             * @param newAlgorithmClass The class to use (eg.
173:             * <code>"com.opensymphony.oscache.base.algorithm.LRUCache"</code>)
174:             */
175:            public void setAlgorithmClass(String newAlgorithmClass) {
176:                algorithmClass = newAlgorithmClass;
177:            }
178:
179:            /**
180:             * Indicates whether the cache will block waiting for new content to
181:             * be built, or serve stale content instead of waiting. Regardless of this
182:             * setting, the cache will <em>always</em> block if new content is being
183:             * created, ie, there's no stale content in the cache that can be served.
184:             */
185:            public boolean isBlocking() {
186:                return blocking;
187:            }
188:
189:            /**
190:             * Sets the cache capacity (number of items). Administrator implementations
191:             * should override this method to ensure that their {@link Cache} objects
192:             * are updated correctly (by calling {@link AbstractConcurrentReadCache#setMaxEntries(int)}}}.
193:             *
194:             * @param newCacheCapacity The new capacity
195:             */
196:            protected void setCacheCapacity(int newCacheCapacity) {
197:                cacheCapacity = newCacheCapacity;
198:            }
199:
200:            /**
201:             * Whether entries are cached in memory or not.
202:             * Default is true.
203:             * Set by the <code>cache.memory</code> property.
204:             *
205:             * @return Status whether or not memory caching is used.
206:             */
207:            public boolean isMemoryCaching() {
208:                return memoryCaching;
209:            }
210:
211:            /**
212:             * Retrieves the value of one of the configuration properties.
213:             *
214:             * @param key The key assigned to the property
215:             * @return Property value, or <code>null</code> if the property could not be found.
216:             */
217:            public String getProperty(String key) {
218:                return config.getProperty(key);
219:            }
220:
221:            /**
222:             * Indicates whether the unlimited disk cache is enabled or not.
223:             */
224:            public boolean isUnlimitedDiskCache() {
225:                return unlimitedDiskCache;
226:            }
227:
228:            /**
229:             * Check if we use overflowPersistence
230:             *
231:             * @return Returns the overflowPersistence.
232:             */
233:            public boolean isOverflowPersistence() {
234:                return this .overflowPersistence;
235:            }
236:
237:            /**
238:             * Sets the overflowPersistence flag
239:             *
240:             * @param overflowPersistence The overflowPersistence to set.
241:             */
242:            public void setOverflowPersistence(boolean overflowPersistence) {
243:                this .overflowPersistence = overflowPersistence;
244:            }
245:
246:            /**
247:             * Retrieves an array containing instances all of the {@link CacheEventListener}
248:             * classes that are specified in the OSCache configuration file.
249:             */
250:            protected CacheEventListener[] getCacheEventListeners() {
251:                List classes = StringUtil.split(config
252:                        .getProperty(CACHE_ENTRY_EVENT_LISTENERS_KEY), ',');
253:                CacheEventListener[] listeners = new CacheEventListener[classes
254:                        .size()];
255:
256:                for (int i = 0; i < classes.size(); i++) {
257:                    String className = (String) classes.get(i);
258:
259:                    try {
260:                        Class clazz = Class.forName(className);
261:
262:                        if (!CacheEventListener.class.isAssignableFrom(clazz)) {
263:                            log
264:                                    .error("Specified listener class '"
265:                                            + className
266:                                            + "' does not implement CacheEventListener. Ignoring this listener.");
267:                        } else {
268:                            listeners[i] = (CacheEventListener) clazz
269:                                    .newInstance();
270:                        }
271:                    } catch (ClassNotFoundException e) {
272:                        log.error("CacheEventListener class '" + className
273:                                + "' not found. Ignoring this listener.", e);
274:                    } catch (InstantiationException e) {
275:                        log
276:                                .error(
277:                                        "CacheEventListener class '"
278:                                                + className
279:                                                + "' could not be instantiated because it is not a concrete class. Ignoring this listener.",
280:                                        e);
281:                    } catch (IllegalAccessException e) {
282:                        log
283:                                .error(
284:                                        "CacheEventListener class '"
285:                                                + className
286:                                                + "' could not be instantiated because it is not public. Ignoring this listener.",
287:                                        e);
288:                    }
289:                }
290:
291:                return listeners;
292:            }
293:
294:            /**
295:             * If there is a <code>PersistenceListener</code> in the configuration
296:             * it will be instantiated and applied to the given cache object. If the
297:             * <code>PersistenceListener</code> cannot be found or instantiated, an
298:             * error will be logged but the cache will not have a persistence listener
299:             * applied to it and no exception will be thrown.<p>
300:             *
301:             * A cache can only have one <code>PersistenceListener</code>.
302:             *
303:             * @param cache the cache to apply the <code>PersistenceListener</code> to.
304:             *
305:             * @return the same cache object that was passed in.
306:             */
307:            protected Cache setPersistenceListener(Cache cache) {
308:                String persistenceClassname = config
309:                        .getProperty(PERSISTENCE_CLASS_KEY);
310:
311:                try {
312:                    Class clazz = Class.forName(persistenceClassname);
313:                    PersistenceListener persistenceListener = (PersistenceListener) clazz
314:                            .newInstance();
315:
316:                    cache.setPersistenceListener(persistenceListener
317:                            .configure(config));
318:                } catch (ClassNotFoundException e) {
319:                    log.error("PersistenceListener class '"
320:                            + persistenceClassname
321:                            + "' not found. Check your configuration.", e);
322:                } catch (Exception e) {
323:                    log.error("Error instantiating class '"
324:                            + persistenceClassname + "'", e);
325:                }
326:
327:                return cache;
328:            }
329:
330:            /**
331:             * Applies all of the recognised listener classes to the supplied
332:             * cache object. Recognised classes are {@link CacheEntryEventListener}
333:             * and {@link CacheMapAccessEventListener}.<p>
334:             *
335:             * @param cache The cache to apply the configuration to.
336:             * @return cache The configured cache object.
337:             */
338:            protected Cache configureStandardListeners(Cache cache) {
339:                if (config.getProperty(PERSISTENCE_CLASS_KEY) != null) {
340:                    cache = setPersistenceListener(cache);
341:                }
342:
343:                if (config.getProperty(CACHE_ENTRY_EVENT_LISTENERS_KEY) != null) {
344:                    // Grab all the specified listeners and add them to the cache's
345:                    // listener list. Note that listeners that implement more than
346:                    // one of the event interfaces will be added multiple times.
347:                    CacheEventListener[] listeners = getCacheEventListeners();
348:
349:                    for (int i = 0; i < listeners.length; i++) {
350:                        // Pass through the configuration to those listeners that require it
351:                        if (listeners[i] instanceof  LifecycleAware) {
352:                            try {
353:                                ((LifecycleAware) listeners[i]).initialize(
354:                                        cache, config);
355:                            } catch (InitializationException e) {
356:                                log.error("Could not initialize listener '"
357:                                        + listeners[i].getClass().getName()
358:                                        + "'. Listener ignored.", e);
359:
360:                                continue;
361:                            }
362:                        }
363:
364:                        if (listeners[i] instanceof  CacheEntryEventListener) {
365:                            cache.addCacheEventListener(listeners[i]);
366:                        } else if (listeners[i] instanceof  CacheMapAccessEventListener) {
367:                            cache.addCacheEventListener(listeners[i]);
368:                        }
369:                    }
370:                }
371:
372:                return cache;
373:            }
374:
375:            /**
376:             * Finalizes all the listeners that are associated with the given cache object.
377:             * Any <code>FinalizationException</code>s that are thrown by the listeners will
378:             * be caught and logged.
379:             */
380:            protected void finalizeListeners(Cache cache) {
381:                // It's possible for cache to be null if getCache() was never called (CACHE-63)
382:                if (cache == null) {
383:                    return;
384:                }
385:
386:                Object[] listeners = cache.listenerList.getListenerList();
387:
388:                for (int i = listeners.length - 2; i >= 0; i -= 2) {
389:                    if (listeners[i + 1] instanceof  LifecycleAware) {
390:                        try {
391:                            ((LifecycleAware) listeners[i + 1]).finialize();
392:                        } catch (FinalizationException e) {
393:                            log.error("Listener could not be finalized", e);
394:                        }
395:                    }
396:                }
397:            }
398:
399:            /**
400:             * Initialize the core cache parameters from the configuration properties.
401:             * The parameters that are initialized are:
402:             * <ul>
403:             * <li>the algorithm class ({@link #CACHE_ALGORITHM_KEY})</li>
404:             * <li>the cache size ({@link #CACHE_CAPACITY_KEY})</li>
405:             * <li>whether the cache is blocking or non-blocking ({@link #CACHE_BLOCKING_KEY})</li>
406:             * <li>whether caching to memory is enabled ({@link #CACHE_MEMORY_KEY})</li>
407:             * <li>whether the persistent cache is unlimited in size ({@link #CACHE_DISK_UNLIMITED_KEY})</li>
408:             * </ul>
409:             */
410:            private void initCacheParameters() {
411:                algorithmClass = getProperty(CACHE_ALGORITHM_KEY);
412:
413:                blocking = "true"
414:                        .equalsIgnoreCase(getProperty(CACHE_BLOCKING_KEY));
415:
416:                String cacheMemoryStr = getProperty(CACHE_MEMORY_KEY);
417:
418:                if ((cacheMemoryStr != null)
419:                        && cacheMemoryStr.equalsIgnoreCase("false")) {
420:                    memoryCaching = false;
421:                }
422:
423:                unlimitedDiskCache = Boolean.valueOf(
424:                        config.getProperty(CACHE_DISK_UNLIMITED_KEY))
425:                        .booleanValue();
426:                overflowPersistence = Boolean.valueOf(
427:                        config.getProperty(CACHE_PERSISTENCE_OVERFLOW_KEY))
428:                        .booleanValue();
429:
430:                String cacheSize = getProperty(CACHE_CAPACITY_KEY);
431:
432:                try {
433:                    if ((cacheSize != null) && (cacheSize.length() > 0)) {
434:                        cacheCapacity = Integer.parseInt(cacheSize);
435:                    }
436:                } catch (NumberFormatException e) {
437:                    log
438:                            .error("The value supplied for the cache capacity, '"
439:                                    + cacheSize
440:                                    + "', is not a valid number. The cache capacity setting is being ignored.");
441:                }
442:            }
443:
444:            /**
445:             * Load the properties file from the classpath.
446:             */
447:            private void loadProps(Properties p) {
448:                config = new Config(p);
449:            }
450:        }
www.java2java.com | Contact Us
Copyright 2010 - 2030 Java Source and Support. All rights reserved.
All other trademarks are property of their respective owners.