1 17 18 package com.whirlycott.cache; 19 20 import java.io.InputStream ; 21 import java.util.HashMap ; 22 import java.util.Iterator ; 23 import java.util.LinkedList ; 24 import java.util.Map ; 25 26 import javax.xml.parsers.DocumentBuilderFactory ; 27 28 import org.apache.commons.logging.Log; 29 import org.apache.commons.logging.LogFactory; 30 import org.w3c.dom.Document ; 31 import org.w3c.dom.Element ; 32 import org.w3c.dom.NodeList ; 33 34 39 public class CacheManager { 40 41 44 protected final static Map configuration = new HashMap (); 45 46 static String defaultCacheName = null; 47 48 51 private final static Log log = LogFactory.getLog(CacheManager.class); 52 53 57 protected final static CacheManager singleton = new CacheManager(); 58 59 62 public static Map getConfiguration() { 63 return configuration; 64 } 65 66 71 public static CacheManager getInstance() { 72 return singleton; 73 } 74 75 78 protected final Map namedCaches = new HashMap (); 79 80 84 private CacheManager() { 85 log.info(Messages.getString("CacheManager.creating_new_cache_manager_singleton")); 87 try { 88 configure(); 89 90 } catch (final CacheException e) { 91 log.fatal(e.getMessage(), e); 93 } 94 } 95 96 102 protected void configure() throws CacheException { 103 log.debug(Messages.getString("CacheManager.configuring_the_whirlycache")); 105 Document doc; 107 108 doc = loadConfigFile(Constants.CONFIG_FILE); 110 111 if (doc == null) { 112 log.warn("Could not load " + Constants.CONFIG_FILE + " file. Falling back to defaults."); 114 doc = loadConfigFile(Constants.DEFAULT_CONFIG_FILE); 116 117 if (doc == null) { 119 final String msg = Messages.getString("CacheManager.cannot_load_default_config_file"); throw new CacheException(msg); 122 } 123 } 124 125 130 final Element root = doc.getDocumentElement(); 131 132 defaultCacheName = root.getElementsByTagName("default-cache").item(0).getFirstChild().getNodeValue(); log.debug(Messages.getString("CacheManager.default_cache_name") + defaultCacheName); 135 final NodeList caches = root.getElementsByTagName(Constants.CONFIG_CACHE); 136 for (int i = 0; i < caches.getLength(); i++) { 137 final CacheConfiguration configuration = new CacheConfiguration(); 138 final Element elementCache = (Element ) caches.item(i); 139 final String cacheName = elementCache.getAttribute(Constants.CONFIG_NAME); 140 log.debug(Messages.getString("CacheManager.cache_name") + cacheName); configuration.setName(cacheName); 142 143 final NodeList elementCacheAttributes = elementCache.getElementsByTagName("*"); for (int j = 0; j < elementCacheAttributes.getLength(); j++) { 145 final Element att = (Element ) elementCacheAttributes.item(j); 146 147 final String nodeName = att.getNodeName(); 148 final String nodeValue = att.getFirstChild().getNodeValue(); 149 log.debug("Node name: " + nodeName + "; Node value: " + nodeValue); 150 151 if (Constants.CONFIG_BACKEND.equals(nodeName)) { 152 configuration.setBackend(nodeValue); 153 154 } else if (Constants.CONFIG_TUNER_SLEEPTIME.equals(nodeName)) { 155 configuration.setTunerSleepTime(new Integer (nodeValue).intValue()); 156 157 } else if (Constants.CONFIG_POLICY.equals(nodeName)) { 158 configuration.setPolicy(nodeValue); 159 160 } else if (Constants.CONFIG_MAXSIZE.equals(nodeName)) { 161 configuration.setMaxSize(new Integer (nodeValue).intValue()); 162 163 } else { 164 configuration.setAttribute(nodeName, nodeValue); 166 } 167 168 log.debug(" - " + nodeName + "=" + nodeValue); } 170 171 log.debug(Messages.getString("CacheManager.making_named_caches")); createCache(configuration); 174 175 CacheManager.configuration.put(elementCache.getAttribute(Constants.CONFIG_NAME), configuration); 177 } 178 179 if (namedCaches.get(defaultCacheName) == null) { 181 final Object [] args = { defaultCacheName }; 182 throw new CacheException(Messages.getCompoundString("CacheManager.nonexistent_default_cache", args)); } 184 185 } 186 187 196 public Cache createCache(final CacheConfiguration _configuration) throws CacheException { 197 if (_configuration == null || _configuration.getName() == null) { 198 final String msg = Messages.getString("CacheManager.cache_name_cannot_be_null"); log.error(msg); 200 throw new CacheException(msg); 201 } 202 203 log.debug("Creating cache: " + _configuration.getName()); 204 205 final Cache c; 206 207 final Object o = namedCaches.get(_configuration.getName()); 209 210 if (o == null) { 212 try { 213 final String backend = _configuration.getBackend(); 214 log.debug("Cache backend is " + backend); 216 final Object possiblyC = Class.forName(backend).newInstance(); 217 218 if (!(possiblyC instanceof ManagedCache)) 219 throw new CacheException("Problem creating an instance of " + backend + " because it does not implement the ManagedCache interface."); 221 final ManagedCache managedCache = (ManagedCache) possiblyC; 222 final CacheMaintenancePolicy policy = createPolicy(managedCache, _configuration); 223 224 c = new CacheDecorator(managedCache, _configuration, new CacheMaintenancePolicy[] { policy }); 225 226 } catch (final Exception e) { 227 log.fatal(Messages.getString("CacheManager.cannot_create_instance_of_impl"), e); throw new CacheException(e); 229 } 230 namedCaches.put(_configuration.getName(), c); 231 } else { 232 c = (Cache) o; 234 } 235 return c; 236 } 237 238 246 private CacheMaintenancePolicy createPolicy(final ManagedCache managedCache, final CacheConfiguration configuration) throws CacheException { 247 final String policyClass = configuration.getPolicy(); 249 250 if (null == policyClass) 251 throw new IllegalArgumentException (Messages.getString("CacheManager.cache_config_get_policy_cannot_be_null")); 253 final CacheMaintenancePolicy policy; 254 try { 255 policy = (CacheMaintenancePolicy) Class.forName(policyClass).newInstance(); 256 } catch (Exception e) { 257 throw new CacheException("Cannot make an instance of policy class " + policyClass, e); } 259 if (policy != null) { 260 policy.setCache(managedCache); 261 policy.setConfiguration(configuration); 262 } 263 264 return policy; 265 } 266 267 272 public void destroy() throws CacheException { 273 destroy(defaultCacheName); 274 } 275 276 284 public void destroy(final String _cacheName) throws CacheException { 285 final CacheDecorator c = (CacheDecorator) getCache(_cacheName); 287 c.clear(); 288 c.shutdown(); 289 namedCaches.remove(_cacheName); 290 } 291 292 298 public Cache getCache() throws CacheException { 299 return getCache(defaultCacheName); 300 } 301 302 310 public Cache getCache(final String _name) throws CacheException { 311 if (_name == null) 313 throw new IllegalArgumentException (Messages.getString("CacheManager.cannot_get_cache_with_null_name")); 315 final Cache c = (Cache) namedCaches.get(_name); 316 317 if (c == null) 318 throw new CacheException("There is no cache called '" + _name + "'"); 320 return c; 321 } 322 323 330 protected Document loadConfigFile(final String _filename) throws CacheException { 331 if (_filename == null) { 332 throw new CacheException(Messages.getString("CacheManager.cannot_load_null_config_file")); } 334 335 final InputStream is = getClass().getResourceAsStream(_filename); 336 if (is != null) { 337 try { 338 return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is); 339 } catch (final Exception e) { 340 log.error("Problem loading " + _filename); } 342 } 343 344 return null; 346 } 347 348 355 public void shutdown() throws CacheException { 356 synchronized (namedCaches) { 357 final Iterator cacheNames = new LinkedList (namedCaches.keySet()).iterator(); 358 while (cacheNames.hasNext()) { 360 try { 361 destroy((String ) cacheNames.next()); 362 } catch (CacheException e) { 363 throw new CacheException(Messages.getString("CacheManager.problem_shutting_down")); } 365 } 366 } 367 } 368 369 375 public String [] getCacheNames() { 376 final Object [] caches = namedCaches.keySet().toArray(); 377 final int size = caches.length; 378 final String [] names = new String [size]; 379 for (int i = 0; i < size; i++) { 380 names[i] = (String ) caches[i]; 381 } 382 return names; 383 } 384 } | Popular Tags |