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}