Coverage Summary for Class: RequestScopeCacheHelper (org.kitodo.production.helper.cache)

Class Class, % Method, % Line, %
RequestScopeCacheHelper 0% (0/1) 0% (0/3) 0% (0/14)


 /*
  * (c) Kitodo. Key to digital objects e. V. <contact@kitodo.org>
  *
  * This file is part of the Kitodo project.
  *
  * It is licensed under GNU General Public License version 3 or later.
  *
  * For the full copyright and license information, please read the
  * GPL3-License.txt file that was distributed with this source code.
  */
 
 package org.kitodo.production.helper.cache;
 
 import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Supplier;
 
 import javax.faces.context.FacesContext;
 
 /**
  * Caches arbitrary objects while processing a request.
  * 
  * <p>Stores objects in a simple hash map inside FacesContext.getAttributes(). After each request, 
  * a new FacesContext will be created, which means cached objects are not available any more.</p>
  * 
  * <p>Usually, such caching is not necessary when implementing Beans annotated with @RequestScope
  * and getters that store processed values in local variables. However, a lot of beans do not 
  * follow this pattern, which means that some common methods, e.g., getting the current locale of 
  * a user (which requires a database lookup), are re-evaluated many times during processing of 
  * a request.</p>
  * 
  * <p>Therefore, this class provides the possibility to inject a request scoped cache.</p>
  * 
  * <p>If this cache is used outside of a JSF request context, it will simply re-evaluate the supplier 
  * function upon every request.</p>
  * 
  */
 public class RequestScopeCacheHelper {
 
     private static final String ATTRIBUTE_NAME = "RequestScopeCacheHelper";
 
     /**
      * Load or create a simple hash map in the FacesContext.getAttributes() map.
      * @return the cache
      */
     @SuppressWarnings("unchecked")
     private static Map<String, Object> getCache() {
         FacesContext ctx = FacesContext.getCurrentInstance();
         if (Objects.nonNull(ctx)) {
             if (!ctx.getAttributes().containsKey(ATTRIBUTE_NAME)) {
                 ctx.getAttributes().put(ATTRIBUTE_NAME, new ConcurrentHashMap<String, Object>());
             }
             return (ConcurrentHashMap<String, Object>)ctx.getAttributes().get(ATTRIBUTE_NAME);
         }
         return null;
     }
 
     /**
      * Returns a cached object if it has been previously requested within the scope of a request,
      * otherwise it will evaluate the supplier function.
      * 
      * @param <T> the type of the object that is cached
      * @param key the key that is used to cache an object (needs to be unique application wide)
      * @param supplier a supplier function that is evaluated if the object is not found in cache 
      *                 and whose result is then stored in the cache
      * @param clazz the class of the object type
      * @return the cached object or the object provided by supplier if it was not cached before
      */
     public static <T> T getFromCache(String key, Supplier<T> supplier, Class<T> clazz) {
         Map<String, Object> cache = getCache();
         if (Objects.nonNull(cache)) {
             // save value if it does not yet exist
             if (!cache.containsKey(key)) {
                 T value = supplier.get();
                 cache.put(key, value);
             };
             return clazz.cast(cache.get(key));
         }
         // cache not available, e.g., when called outside of request scope (in a background process)
         return supplier.get();
     }
 }