/** * */ package org.gcube.common.metadataprofilediscovery; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import org.gcube.common.metadataprofilediscovery.jaxb.NamespaceCategories; import org.gcube.common.metadataprofilediscovery.reader.NamespaceCategoryReader; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.impl.ScopeBean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.common.cache.RemovalListener; import com.google.common.cache.RemovalNotification; /** * The Class NamespaceCategoriesCache. * * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it * * Mar 3, 2022 */ public class NamespaceCategoriesCache { private static Logger LOG = LoggerFactory.getLogger(NamespaceCategoriesCache.class); private static LoadingCache namespaces; static { CacheLoader loader = new CacheLoader() { @Override public NamespaceCategories load(String scope) throws Exception { LOG.info("Loading the NamespaceCategories cache for scope: {}", scope); NamespaceCategories namespacesCat = loadNamespaces(scope); if (namespacesCat != null) LOG.info("Returning {} for the scope name: {}", NamespaceCategories.class.getSimpleName(), scope); else { LOG.info("No NamespaceCategories obj for scope {}", scope); } return namespacesCat; } }; RemovalListener removalListener = new RemovalListener() { @Override public void onRemoval(RemovalNotification arg0) { LOG.debug("cache expired"); } }; namespaces = CacheBuilder.newBuilder().maximumSize(300).expireAfterWrite(30, TimeUnit.MINUTES) .removalListener(removalListener).build(loader); } /** * Populate the cache. * * @param scope the scope */ private static void populateTheCache(ScopeBean scope) { String origScope = null; String instScope = scope.toString(); try { origScope = ScopeProvider.instance.get(); // Populating the cache by using the detachedres-library ScopeProvider.instance.set(scope.toString()); LOG.info("Trying to populate the Namespaces cache in the scope: "+instScope); NamespaceCategoryReader rd = new NamespaceCategoryReader(scope); namespaces.put(instScope, rd.getNamespaces()); } catch (Exception e) { // SILENT } finally { if (origScope != null && !origScope.equals(scope.toString())) { // Setting original scope ScopeProvider.instance.set(scope.toString()); } } } /** * Gets the VRE obj for input VRE name. * * @param scope the scope * @return the vre * @throws ExecutionException the execution exception */ public static NamespaceCategories get(String scope) throws ExecutionException { try { return namespaces.get(scope); } catch (Exception e) { LOG.info("Error on getting NamespaceCategories obj for scope {}. Is the key {} not found in the cache?", scope, namespaces); throw e; } } /** * Load VRE obj for VRE name. * * @param scope the scope * @return the vre */ protected static NamespaceCategories loadNamespaces(String scope) { NamespaceCategories namespacesCategories = namespaces.getIfPresent(scope); // THIS CHECK SHOULD NOT BE NEEDED if (namespacesCategories == null) { LOG.info("loading Catalogue Namespaces for scope: {}",scope); ScopeBean scopeB = new ScopeBean(scope); populateTheCache(scopeB); namespacesCategories = namespaces.getIfPresent(scope); LOG.info("NamespaceCategories populated correclty with scope: {}",scope); }else { LOG.info("NamespaceCategories cache already populated with scope: {}, returning cached NamespaceCategories",scope); } return namespacesCategories; } /** * Gets the cache. * * @return the cache */ public LoadingCache getCache() { return namespaces; } }