com.davidbracewell.cache.CacheManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mango Show documentation
Show all versions of mango Show documentation
A set of utilities and tools to speed up and ease programming in Java.
/*
* (c) 2005 David B. Bracewell
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.davidbracewell.cache;
import com.davidbracewell.config.Config;
import com.davidbracewell.conversion.Cast;
import com.davidbracewell.reflection.Reflect;
import com.davidbracewell.reflection.ReflectionException;
import com.davidbracewell.string.StringUtils;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* Manages the creation and retrieval of caches. Caches are defined as specification {@link CacheSpec}. Additionally,
* there can be cacheSpecClass configuration setting if a special CacheSpec needs to be used
* to parse the string specification.
*
* @author David Bracewell
*/
public final class CacheManager {
/**
* The name of the global cache.
*/
public static final String GLOBAL_CACHE = "com.davidbracewell.cache.globalCache";
private static volatile CacheManager INSTANCE = null;
private volatile Map> caches = new ConcurrentHashMap<>();
private CacheManager() {
}
/**
* Creates an object that automatically caches results for methods annotated with the @Cached
* annotation.
*
* @param The type of the object
* @param object The object, which must implement an interface, that we are wrapping
* @return The Proxy object
*/
public static T cacheObject(T object) {
return CacheProxy.cache(object);
}
/**
* Gets instance.
*
* @return The CacheManager instance
*/
public static CacheManager getInstance() {
if (INSTANCE == null) {
synchronized (CacheManager.class) {
if (INSTANCE == null) {
INSTANCE = new CacheManager();
}
}
}
return INSTANCE;
}
/**
* Determines if a cache with a given name has been created
*
* @param name The cache name
* @return True if the cache has been created, false if not.
*/
public boolean contains(String name) {
return caches.containsKey(name);
}
/**
* Gets the cache associated with the given name. If the name is not known, i.e. the associated cache has not been
* defined, a no operation cache (no cache) is returned.
*
* @param the type parameter
* @param the type parameter
* @param name The name of the cache
* @return A cache
*/
public Cache get(String name) {
if (StringUtils.isNullOrBlank(name)) {
throw new IllegalArgumentException("Cache name must not be null or blank.");
}
if (GLOBAL_CACHE.equals(name)) {
return Cast.as(getGlobalCache());
} else if (caches.containsKey(name)) {
return Cast.as(caches.get(name));
} else if (Config.hasProperty(name) && caches.containsKey(Config.get(name).asString())) {
return Cast.as(caches.get(Config.get(name).asString()));
}
return register(this.getCacheSpec(name));
}
/**
* Gets cache names.
*
* @return The names of all of the initialized caches.
*/
public Set getCacheNames() {
return caches.keySet();
}
private CacheSpec getCacheSpec(String property) {
//Sanity check for the global cache. If one is not defined in the configuration create a default with max size 1,000
if (GLOBAL_CACHE.equals(property) && !Config.hasProperty(property)) {
return new CacheSpec().name(GLOBAL_CACHE).maxSize(1000);
}
String specString = Config.get(property).asString();
//Make sure the cache is defined
if (Strings.isNullOrEmpty(specString)) {
throw new IllegalArgumentException(property + " is not a known cache and is not defined via a config file.");
}
CacheSpec spec;
//See if there is special implementation of the cache spec class
if (Config.hasProperty(property + ".cacheSpecClass")) {
try {
spec = Reflect.onClass(Config.get(property + ".cacheSpecClass").asClass()).create().get();
} catch (ReflectionException e) {
throw Throwables.propagate(e);
}
} else {
spec = new CacheSpec<>();
}
try {
spec.fromString(specString);
if (!specString.contains("name:")) {
spec.name(property);
}
} catch (Exception e) {
throw new IllegalStateException(specString + " is an invalid specification string.");
}
return spec;
}
/**
* Gets global cache.
*
* @return The global cache
*/
public Cache getGlobalCache() {
if (caches.containsKey(GLOBAL_CACHE)) {
return Cast.as(caches.get(GLOBAL_CACHE));
}
Cache cache = Cast.as(register(getCacheSpec(GLOBAL_CACHE)));
caches.put(GLOBAL_CACHE, cache);
return cache;
}
/**
* Creates a cache for a given cache specification. If the name in the specification is a known cache, then
* it will return that cache.
*
* @param The key type
* @param The value type
* @param specification The specification
* @return A cache for the specification
*/
public Cache register(CacheSpec, ?> specification) {
if (!caches.containsKey(specification.getName())) {
Cache, ?> cache = specification.getEngine().create(specification);
caches.putIfAbsent(cache.getName(), cache);
}
return Cast.as(caches.get(specification.getName()));
}
}//END OF CacheManager
© 2015 - 2025 Weber Informatics LLC | Privacy Policy