metadata-profile-discovery/src/main/java/org/gcube/common/metadataprofilediscovery/NamespaceCategoriesCache.java

146 lines
4.1 KiB
Java

/**
*
*/
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<String, NamespaceCategories> namespaces;
static {
CacheLoader<String, NamespaceCategories> loader = new CacheLoader<String, NamespaceCategories>() {
@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<String, NamespaceCategories> removalListener = new RemovalListener<String, NamespaceCategories>() {
@Override
public void onRemoval(RemovalNotification<String, NamespaceCategories> 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<String, NamespaceCategories> getCache() {
return namespaces;
}
}