1 10 package org.mmbase.cache; 11 12 import java.util.*; 13 14 import org.mmbase.util.*; 15 import org.mmbase.util.logging.Logger; 16 import org.mmbase.util.logging.Logging; 17 import org.mmbase.util.xml.DocumentReader; 18 import org.w3c.dom.Element ; 19 20 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap; 21 22 23 24 30 public class CacheManager { 31 32 private static final Logger log = Logging.getLoggerInstance(CacheManager.class); 33 34 37 private static final Map caches = new ConcurrentHashMap(); 38 39 46 public static Cache getCache(String name) { 47 return (Cache) caches.get(name); 48 } 49 50 55 public static Set getCaches() { 56 return Collections.unmodifiableSet(caches.keySet()); 57 } 58 59 60 67 protected static Cache putCache(Cache cache) { 68 Cache old = (Cache) caches.put(cache.getName(), cache); 69 configure(configReader, cache.getName()); 70 return old; 71 } 72 73 78 79 private static void configure(DocumentReader file) { 80 configure(file, null); 81 } 82 83 private static DocumentReader configReader = null; 84 85 89 private static void configure(DocumentReader xmlReader, String only) { 90 if (xmlReader == null) { 91 return; } 93 94 if (only == null) { 95 log.service("Configuring caches with " + xmlReader.getSystemId()); 96 } else { 97 if (log.isDebugEnabled()) log.debug("Configuring cache " + only + " with file " + xmlReader.getSystemId()); 98 } 99 100 Iterator e = xmlReader.getChildElements("caches", "cache"); 101 while (e.hasNext()) { 102 Element cacheElement = (Element ) e.next(); 103 String cacheName = cacheElement.getAttribute("name"); 104 if (only != null && ! only.equals(cacheName)) { 105 continue; 106 } 107 Cache cache = getCache(cacheName); 108 if (cache == null) { 109 log.service("No cache " + cacheName + " is present (perhaps not used yet?)"); 110 } else { 111 String clazz = xmlReader.getElementValue(xmlReader.getElementByPath(cacheElement, "cache.implementation.class")); 112 if(!"".equals(clazz)) { 113 Element cacheImpl = xmlReader.getElementByPath(cacheElement, "cache.implementation"); 114 Iterator it = xmlReader.getChildElements(cacheImpl, "param"); 115 Map configValues = new HashMap(); 116 while (it.hasNext()) { 117 Element attrNode = (Element )it.next(); 118 String paramName = xmlReader.getElementAttributeValue(attrNode, "name"); 119 String paramValue = xmlReader.getElementValue(attrNode); 120 configValues.put(paramName, paramValue); 121 } 122 cache.setImplementation(clazz, configValues); 123 } 124 String status = xmlReader.getElementValue(xmlReader.getElementByPath(cacheElement, "cache.status")); 125 cache.setActive(status.equalsIgnoreCase("active")); 126 try { 127 Integer size = new Integer (xmlReader.getElementValue(xmlReader.getElementByPath(cacheElement, "cache.size"))); 128 cache.setMaxSize(size.intValue()); 129 log.service("Setting " + cacheName + " " + status + " with size " + size); 130 } catch (NumberFormatException nfe) { 131 log.error("Could not configure cache " + cacheName + " because the size was wrong: " + nfe.toString()); 132 } 133 String maxSize = xmlReader.getElementValue(xmlReader.getElementByPath(cacheElement, "cache.maxEntrySize")); 134 if (!"".equals(maxSize)) { 135 try { 136 cache.maxEntrySize = Integer.parseInt(maxSize); 137 log.service("Setting maximum entry size on " + cacheName + ": " + cache.maxEntrySize + " bytes "); 138 } catch (NumberFormatException nfe2) { 139 log.error("Could not set max entry size cache of " + cacheName + " because " + nfe2.toString()); 140 } 141 } else { 142 if (cache.getDefaultMaxEntrySize() > 0) { 143 log.service("No max entry size specified for this cache taking default " + cache.getDefaultMaxEntrySize() + " bytes"); 144 } 145 cache.maxEntrySize = cache.getDefaultMaxEntrySize(); 146 if(cache instanceof QueryResultCache){ 148 QueryResultCache queryCache = (QueryResultCache) cache; 149 queryCache.getReleaseStrategy().removeAllStrategies(); 151 log.debug("found a SearchQueryCache: " + cacheName); 152 List strategies = findReleaseStrategies(xmlReader, xmlReader.getElementByPath("caches")); 154 if(strategies != null){ 155 log.debug("found " + strategies.size() + " globally configured strategies"); 156 queryCache.addReleaseStrategies(strategies); 157 } 158 159 strategies = findReleaseStrategies(xmlReader, cacheElement); 161 if(strategies != null){ 162 log.debug("found " + strategies.size() + " strategies for cache " + cache.getName()); 163 queryCache.addReleaseStrategies(strategies); 164 } 165 if (queryCache.getReleaseStrategy().size() == 0) { 166 log.warn("No release-strategies configured for cache " + queryCache + " (nor globally configured); falling back to basic release strategy"); 167 queryCache.addReleaseStrategy(new BasicReleaseStrategy()); 168 } 169 } 170 } 171 } 172 } 173 } 174 175 181 private static List findReleaseStrategies(DocumentReader reader, Element parentElement) { 182 List result = new ArrayList(); 183 Iterator strategyParentIterator = reader.getChildElements(parentElement, "releaseStrategies"); 184 if(!strategyParentIterator.hasNext()){ 185 return null; 186 }else{ 187 parentElement = (Element ) strategyParentIterator.next(); 188 189 Iterator strategyIterator = reader.getChildElements(parentElement, "strategy"); 191 while(strategyIterator.hasNext()){ 192 String strategyClassName = 193 reader.getElementValue((Element )strategyIterator.next()); 194 log.debug("found strategy in configuration: "+ strategyClassName); 195 try { 196 ReleaseStrategy releaseStrategy = getStrategyInstance(strategyClassName); 197 log.debug("still there after trying to get a strategy instance... Instance is " + releaseStrategy==null ? "null" : "not null"); 198 199 if(releaseStrategy != null){ 201 202 result.add(releaseStrategy); 203 log.debug("Successfully created and added "+releaseStrategy.getName() + " instance"); 204 }else{ 205 log.error("release strategy instance is null."); 206 } 207 208 } catch (CacheConfigurationException e1) { 209 throw new RuntimeException ("Cache configuration error: " + e1.toString(), e1); 212 } 213 } 214 } 215 return result; 216 } 217 218 225 private static ReleaseStrategy getStrategyInstance(String strategyClassName) throws CacheConfigurationException { 226 log.debug("getStrategyInstance()"); 227 Class strategyClass; 228 ReleaseStrategy strategy = null; 229 try { 230 strategyClass = Class.forName(strategyClassName); 231 strategy = (ReleaseStrategy) strategyClass.newInstance(); 232 log.debug("created strategy instance: "+strategyClassName); 233 234 } catch (ClassCastException e){ 235 log.debug(strategyClassName + " can not be cast to strategy"); 236 throw new CacheConfigurationException(strategyClassName + " can not be cast to strategy"); 237 } catch (ClassNotFoundException e) { 238 log.debug("exception getStrategyInstance()"); 239 throw new CacheConfigurationException("Class "+strategyClassName + 240 "was not found"); 241 } catch (InstantiationException e) { 242 log.debug("exception getStrategyInstance()"); 243 throw new CacheConfigurationException("A new instance of " + strategyClassName + 244 "could not be created: " + e.toString()); 245 } catch (IllegalAccessException e) { 246 log.debug("exception getStrategyInstance()"); 247 throw new CacheConfigurationException("A new instance of " + strategyClassName + 248 "could not be created: " + e.toString()); 249 } 250 log.debug("exit getStrategyInstance()"); 251 return strategy; 252 } 253 254 258 private static ResourceWatcher configWatcher = new ResourceWatcher () { 259 public void onChange(String resource) { 260 try { 261 configReader = new DocumentReader(ResourceLoader.getConfigurationRoot().getInputSource(resource), Cache.class); 262 } catch (Exception e) { 263 log.error(e); 264 return; 265 } 266 configure(configReader); 267 } 268 }; 269 270 static { log.debug("Static init of Caches"); 272 configWatcher.add("caches.xml"); 273 configWatcher.onChange("caches.xml"); 274 configWatcher.setDelay(10 * 1000); configWatcher.start(); 276 277 } 278 279 280 public static int getTotalByteSize() { 281 Iterator i = caches.entrySet().iterator(); 282 int len = 0; 283 SizeOf sizeof = new SizeOf(); 284 while (i.hasNext()) { 285 Map.Entry entry = (Map.Entry) i.next(); 286 len += sizeof.sizeof(entry.getKey()) + sizeof.sizeof(entry.getValue()); 287 } 288 return len; 289 } 290 291 295 public static void shutdown() { 296 log.info("Clearing all caches"); 297 Iterator i = caches.values().iterator(); 298 while (i.hasNext()) { 299 Cache cache = (Cache) i.next(); 300 cache.clear(); 301 i.remove(); 302 } 303 } 304 305 } 306 | Popular Tags |