All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.jasminb.jsonapi.ResourceCache Maven / Gradle / Ivy

Go to download

JSONAPI-Converter is a library that provides means for integrating with services using JSON API specification.

There is a newer version: 0.14
Show newest version
package com.github.jasminb.jsonapi;

import java.util.HashMap;
import java.util.Map;

/**
 * Resource caching provider.
 * 

* Cache implementation is based on thread-local variables. In order to use cache in a thread, init() * method must be called. When cache is no longer needed, clear() method should be used to perform * thread local cleanup. *

*

* Cache can be locked by invoking lock(), after cache is locked, no items will be cached, and calling * any cache method will be a no-op. To unlock cache and make it accept cache calls again, unlock() * method must be invoked. *

*

* If cache is used in recursive calls, it is safe to call init() and clear() * multiple times. Init call will not purge current cache state in case it is called recursively. Clear call will * clear cache state only if recursion exited (initDepth == 0). *

* * * @author jbegic */ public class ResourceCache { private ThreadLocal> resourceCache; private ThreadLocal initDepth; private ThreadLocal cacheLocked; public ResourceCache() { resourceCache = new ThreadLocal<>(); initDepth = new ThreadLocal<>(); cacheLocked = new ThreadLocal<>(); } /** * Initialises cache for current thread-scope. */ public void init() { if (initDepth.get() == null) { initDepth.set(1); } else { initDepth.set(initDepth.get() + 1); } if (resourceCache.get() == null) { resourceCache.set(new HashMap()); } if (cacheLocked.get() == null) { cacheLocked.set(Boolean.FALSE); } } /** * Clears current thread scope state. * @throws IllegalStateException in case init() was not called */ public void clear() { verifyState(); initDepth.set(initDepth.get() - 1); if (initDepth.get() == 0) { resourceCache.set(null); cacheLocked.set(null); initDepth.set(null); } } /** * Adds multiple resources to cache. * @param resources items to add * @throws IllegalStateException in case init() was not called */ public void cache(Map resources) { verifyState(); if (!cacheLocked.get()) { resourceCache.get().putAll(resources); } } /** * Adds resource to cache. * @param identifier resource identifier * @param resource resource * @throws IllegalStateException in case init() was not called */ public void cache(String identifier, Object resource) { verifyState(); if (!cacheLocked.get()) { resourceCache.get().put(identifier, resource); } } /** * Returns cached resource or null if resource was not found in cache. * @param identifier resource identifier * @return cached resource or null */ public Object get(String identifier) { verifyState(); return resourceCache.get().get(identifier); } /** * Checks if resource with given identifier is cached. * @param identifier resource identifier * @return true if resource is cached, else false * @throws IllegalStateException in case init() was not called */ public boolean contains(String identifier) { verifyState(); return resourceCache.get().containsKey(identifier); } /** * Locks this cache instance for thread scope that method was invoked in. *

* After invoking this method, all cache attempts will be no-op. *

* @throws IllegalStateException in case init() was not called */ public void lock() { verifyState(); cacheLocked.set(true); } /** * Unlocks this cache instance for thread scope that method was invoked in. *

* After invoking this method. Cache calls will cache items accordingly. *

*/ public void unlock() { verifyState(); cacheLocked.set(false); } private void verifyState() { if (resourceCache.get() == null) { throw new IllegalStateException("Cache not initialised, call init() first"); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy