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