package fi.nls.oskari.cache;

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Supplier;

/**
 * Generic cache factory for Oskari.
 * TODO: make Cache implementation parametrizable via PropertyUtil. Same as logger and UserService.
 * Usage:
 * <pre>
 * {@code
 *  private Cache<String> cache = CacheManager.getCache("MyCacheName");
 *  final String response = getUrl("http://www.paikkatietoikkuna.fi");
 *
 *  public String getUrl(final String url) {
 *      String response = cache.get(propertyName);
 *      if(response != null) {
 *          return response;
 *      }
 *      response = IOHelper.getURL(url);
 *      cache.put(url, response);
 *      return response;
 *  }
 * }
 * </pre>
 */
public class CacheManager {

    private static ConcurrentMap<String, Cache> CACHE_STORE = new ConcurrentHashMap<String, Cache>();

    /**
     * Returns a cache matching name or creates one if it doesn't exist.
     *
     * @param name name of the cache
     * @param <T>  type mapping for cache
     * @return
     */
    public static <T> Cache<T> getCache(final String name) {
        return getCache(name, () -> new Cache<>());
    }

    public static <T> Cache<T> getCache(final String name, final Supplier<? extends Cache<T>> supplier) {
        final Cache existing = CACHE_STORE.get(name);
        if (existing != null) {
            return existing;
        }

        // create a new one
        final Cache<T> cache = supplier.get();
        cache.setName(name);
        CACHE_STORE.put(name, cache);
        return cache;
    }

    /**
     * Returns names of registered caches
     */
    public static Set<String> getCacheNames() {
        return CACHE_STORE.keySet();
    }

    /**
     * Registers cache manually to manager.
     * @return true if successful, false if params missing or a cache already exists with same name
     */
    public static boolean addCache(final String name, final Cache cache) {
        if (null == name || null == cache || CACHE_STORE.containsKey(name)) {
            return false;
        }
        cache.setName(name);
        CACHE_STORE.put(name, cache);
        return true;
    }

}

@@ -23,16 +23,42 @@
 cache;%0A%0A
+import java.util.Objects;%0A
 import j
@@ -853,16 +853,22 @@
  static 
+final 
 Concurre
@@ -924,29 +924,16 @@
 HashMap%3C
-String, Cache
 %3E();%0A%0A  
@@ -1248,277 +1248,635 @@
     
-public static %3CT%3E Cache%3CT%3E getCache(final String name, final Supplier%3C? extends Cache%3CT%3E%3E supplier) %7B%0A        final Cache existing = CACHE_STORE.get(name);%0A        if (existing != null) %7B%0A            return existing;%0A        %7D%0A%0A        // create a new one%0A        final
+/**%0A     * Returns a cache matching name or creates one if it doesn't exist%0A     * by calling the provided supplier function.%0A     *%0A     * @param name name of the cache%0A     * @param supplier function which creates a new cache if one doesn't exists for the key%0A     * @param %3CT%3E  type mapping for cache%0A     * @return%0A     */%0A    @SuppressWarnings(%22unchecked%22)%0A    public static %3CT%3E Cache%3CT%3E getCache(final String name, final Supplier%3C? extends Cache%3CT%3E%3E supplier) %7B%0A        Objects.requireNonNull(name);%0A        Objects.requireNonNull(supplier);%0A        return (Cache%3CT%3E) CACHE_STORE.computeIfAbsent(name, __ -%3E %7B%0A           
  Cac
@@ -1905,32 +1905,36 @@
 .get();%0A        
+    
 cache.setName(na
@@ -1950,36 +1950,24 @@
     
-CACHE_STORE.put(name,
+    return
  cache
-)
 ;%0A  
@@ -1968,36 +1968,26 @@
 he;%0A        
-return cache
+%7D)
 ;%0A    %7D%0A%0A   
@@ -2133,32 +2133,103 @@
 %0A    %7D%0A%0A    /**%0A
+     * @deprecated to be removed, use %7B@link #getCache(String)%7D%0A     *%0A
      * Registers
@@ -2381,16 +2381,20 @@
 c static
+ %3CT%3E
  boolean
@@ -2433,16 +2433,19 @@
 al Cache
+%3CT%3E
  cache) 

Modify how CacheManager works internally, deprecate CacheManager.addCache