001package org.cache2k; 002 003/* 004 * #%L 005 * cache2k API only package 006 * %% 007 * Copyright (C) 2000 - 2016 headissue GmbH, Munich 008 * %% 009 * This program is free software: you can redistribute it and/or modify 010 * it under the terms of the GNU General Public License as 011 * published by the Free Software Foundation, either version 3 of the 012 * License, or (at your option) any later version. 013 * 014 * This program is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 * GNU General Public License for more details. 018 * 019 * You should have received a copy of the GNU General Public 020 * License along with this program. If not, see 021 * <http://www.gnu.org/licenses/gpl-3.0.html>. 022 * #L% 023 */ 024 025import org.cache2k.spi.Cache2kExtensionProvider; 026 027import java.io.Closeable; 028import java.lang.reflect.Constructor; 029import java.util.HashMap; 030import java.util.Iterator; 031import java.util.Map; 032import java.util.ServiceLoader; 033 034/** 035 * @author Jens Wilke; created: 2013-06-27 036 */ 037public abstract class CacheManager implements Iterable<Cache>, Closeable { 038 039 protected final static String DEFAULT_MANAGER_NAME = "default"; 040 041 private static CacheManager defaultManager; 042 private static String defaultName = DEFAULT_MANAGER_NAME; 043 private static Map<String, CacheManager> name2manager = new HashMap<String, CacheManager>(); 044 045 static { 046 ServiceLoader<Cache2kExtensionProvider> _loader = 047 ServiceLoader.load(Cache2kExtensionProvider.class, CacheManager.class.getClassLoader()); 048 for (Cache2kExtensionProvider p : _loader) { 049 p.register(); 050 } 051 } 052 053 /** 054 * Name of the default cache manager, which is "default" by default. It is also possible 055 * to set the default manager name via JNDI context "java:comp/env" and name 056 * "org.cache2k.CacheManager.defaultName". 057 */ 058 public static String getDefaultName() { 059 return defaultName; 060 } 061 062 /** 063 * Reset the manager name once on application startup. 064 */ 065 public static void setDefaultName(String defaultName) { 066 if (defaultManager != null) { 067 throw new IllegalStateException("default CacheManager already created"); 068 } 069 CacheManager.defaultName = defaultName; 070 } 071 072 /** 073 * Get the default cache manager for the current class loader 074 */ 075 public synchronized static CacheManager getInstance() { 076 if (defaultManager != null && !defaultManager.isDestroyed()) { 077 return defaultManager; 078 } 079 try { 080 defaultManager = (CacheManager) getManagerClass().newInstance(); 081 } catch (Exception e) { 082 return implNotFound(e); 083 } 084 name2manager.put(defaultManager.getName(), defaultManager); 085 return defaultManager; 086 } 087 088 private static CacheManager implNotFound(Exception e) { 089 throw new Error("cache2k implementation not found, cache2k-core.jar missing?", e); 090 } 091 092 private static Class<?> getManagerClass() throws ClassNotFoundException { 093 return Class.forName("org.cache2k.impl.CacheManagerImpl"); 094 } 095 096 public synchronized static CacheManager getInstance(String _name) { 097 if (defaultName.equals(_name)) { 098 return getInstance(); 099 } 100 CacheManager m = name2manager.get(_name); 101 if (m != null) { return m; } 102 try { 103 Class<?> c = getManagerClass(); 104 Constructor<?> cc = c.getConstructor(String.class); 105 m = (CacheManager) cc.newInstance(_name); 106 } catch (Exception e) { 107 return implNotFound(e); 108 } 109 name2manager.put(_name, m); 110 return m; 111 } 112 113 public abstract String getName(); 114 115 public abstract Iterator<Cache> iterator(); 116 117 public abstract Cache getCache(String name); 118 119 /** Clear all caches associated to this cache manager */ 120 public abstract void clear(); 121 122 /** 123 * @deprecated Use {@link #close()} 124 */ 125 public abstract void destroy(); 126 127 /** 128 * Free all resources from managed caches. If there is unwritten data, it is flushed, if needed. 129 * Same as calling all {@link org.cache2k.Cache#close()} methods. Calling this method is more effective, 130 * since it tries to close all caches concurrently as fast as possible. 131 */ 132 public abstract void close(); 133 134 public abstract boolean isDestroyed(); 135 136}