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 javax.naming.Context;
028import javax.naming.InitialContext;
029import java.io.Closeable;
030import java.lang.reflect.Constructor;
031import java.util.HashMap;
032import java.util.Iterator;
033import java.util.Map;
034import java.util.ServiceLoader;
035
036/**
037 * @author Jens Wilke; created: 2013-06-27
038 */
039public abstract class CacheManager implements Iterable<Cache>, Closeable {
040
041  protected final static String DEFAULT_MANAGER_NAME = "default";
042
043  private static CacheManager defaultManager;
044  private static String defaultName = DEFAULT_MANAGER_NAME;
045  private static Map<String, CacheManager> name2manager = new HashMap<String, CacheManager>();
046
047  static {
048    ServiceLoader<Cache2kExtensionProvider> _loader =
049        ServiceLoader.load(Cache2kExtensionProvider.class);
050    for (Cache2kExtensionProvider p : _loader) {
051      p.register();
052    }
053  }
054
055  /**
056   * Name of the default cache manager, which is "default" by default. It is also possible
057   * to set the default manager name via JNDI context "java:comp/env" and name
058   * "org.cache2k.CacheManager.defaultName".
059   */
060  public static String getDefaultName() {
061    return defaultName;
062  }
063
064  /**
065   * Reset the manager name once on application startup.
066   */
067  public static void setDefaultName(String defaultName) {
068    if (defaultManager != null) {
069      throw new IllegalStateException("default CacheManager already created");
070    }
071    CacheManager.defaultName = defaultName;
072  }
073
074  /**
075   * Get the default cache manager for the current class loader
076   */
077  public synchronized static CacheManager getInstance() {
078    if (defaultManager != null && !defaultManager.isDestroyed()) {
079      return defaultManager;
080    }
081    try {
082      defaultManager = (CacheManager) getManagerClass().newInstance();
083    } catch (Exception e) {
084      return implNotFound(e);
085    }
086    name2manager.put(defaultManager.getName(), defaultManager);
087    return defaultManager;
088  }
089
090  private static CacheManager implNotFound(Exception e) {
091    throw new Error("cache2k implementation not found, cache2k-core.jar missing?", e);
092  }
093
094  private static Class<?> getManagerClass() throws ClassNotFoundException {
095    return Class.forName("org.cache2k.impl.CacheManagerImpl");
096  }
097
098  public synchronized static CacheManager getInstance(String _name) {
099    if (defaultName.equals(_name)) {
100      return getInstance();
101    }
102    CacheManager m = name2manager.get(_name);
103    if (m != null) { return m; }
104    try {
105      Class<?> c = getManagerClass();
106      Constructor<?> cc = c.getConstructor(String.class);
107        m = (CacheManager) cc.newInstance(_name);
108    } catch (Exception e) {
109      return implNotFound(e);
110    }
111    name2manager.put(_name, m);
112    return m;
113  }
114
115  public abstract String getName();
116
117  public abstract Iterator<Cache> iterator();
118
119  public abstract Cache getCache(String name);
120
121  /** Clear all caches associated to this cache manager */
122  public abstract void clear();
123
124  /**
125   * @deprecated Use {@link #close()}
126   */
127  public abstract void destroy();
128
129  /**
130   * Free all resources from managed caches. If there is unwritten data, it is flushed, if needed.
131   * Same as calling all {@link org.cache2k.Cache#close()} methods. Calling this method is more effective,
132   * since it tries to close all caches concurrently as fast as possible.
133   */
134  public abstract void close();
135
136  public abstract boolean isDestroyed();
137
138}