diff --git a/src/main/java/org/gcube/informationsystem/resourceregistry/api/utils/ContextCache.java b/src/main/java/org/gcube/informationsystem/resourceregistry/api/utils/ContextCache.java new file mode 100644 index 0000000..7fe5a20 --- /dev/null +++ b/src/main/java/org/gcube/informationsystem/resourceregistry/api/utils/ContextCache.java @@ -0,0 +1,157 @@ +package org.gcube.informationsystem.resourceregistry.api.utils; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import org.gcube.informationsystem.context.impl.entities.ContextImpl; +import org.gcube.informationsystem.context.impl.relations.IsParentOfImpl; +import org.gcube.informationsystem.context.reference.entities.Context; +import org.gcube.informationsystem.context.reference.relations.IsParentOf; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ContextCache { + + private static Logger logger = LoggerFactory.getLogger(ContextCache.class); + + // in millisec + public static final long DEFAULT_EXPIRING_TIMEOUT; + public static int expiringTimeout; + + static { + DEFAULT_EXPIRING_TIMEOUT = TimeUnit.HOURS.toMillis(6); + expiringTimeout = (int) DEFAULT_EXPIRING_TIMEOUT; + } + + public static void setExpiringTimeout(int expiringTimeout) { + ContextCache.expiringTimeout = expiringTimeout; + } + + protected static ContextCache singleton; + + public synchronized static ContextCache getInstance() { + Calendar now = Calendar.getInstance(); + + if(singleton!=null && now.after(singleton.expiringTime)) { + logger.debug("Context Cache has been expired. It must be renewed."); + singleton = null; + } + + if(singleton==null) { + singleton = new ContextCache(); + singleton.creationTime = Calendar.getInstance(); + singleton.creationTime.setTimeInMillis(now.getTimeInMillis()); + singleton.expiringTime = Calendar.getInstance(); + singleton.expiringTime.setTimeInMillis(now.getTimeInMillis()); + singleton.expiringTime.add(Calendar.MILLISECOND, expiringTimeout); + } + + return singleton; + } + + // in millisec used for logging purposes only + protected Calendar creationTime; + // in millisec + protected Calendar expiringTime; + + protected List contexts; + protected Map uuidToContext; + protected Map uuidToContextFullName; + protected Map contextFullNameToUUID; + + public ContextCache() { + contexts = null; + uuidToContext = null; + uuidToContextFullName = null; + contextFullNameToUUID = null; + } + + public synchronized List getContexts() { + return contexts; + } + + public synchronized void setContexts(List contexts) { + this.contexts = new ArrayList<>(); + this.uuidToContext = new HashMap<>(); + + for(Context c : contexts) { + UUID uuid = c.getHeader().getUUID(); + Context context = new ContextImpl(c.getName()); + context.setHeader(c.getHeader()); + this.contexts.add(context); + this.uuidToContext.put(uuid, context); + } + + for(Context c : contexts) { + UUID uuid = c.getHeader().getUUID(); + Context context = this.uuidToContext.get(uuid); + if(c.getParent()!=null) { + IsParentOf ipo = c.getParent(); + UUID parentUUID = ipo.getSource().getHeader().getUUID(); + Context parent = this.uuidToContext.get(parentUUID); + IsParentOf isParentOf = new IsParentOfImpl(parent, context); + isParentOf.setHeader(ipo.getHeader()); + parent.addChild(isParentOf); + context.setParent(isParentOf); + } + } + + this.uuidToContextFullName = new HashMap<>(); + this.contextFullNameToUUID = new HashMap<>(); + + for(Context context : contexts) { + UUID uuid = context.getHeader().getUUID(); + String fullName = getContextFullName(context); + this.uuidToContextFullName.put(uuid, fullName); + this.contextFullNameToUUID.put(fullName, uuid); + } + + } + + private String getContextFullName(Context context) { + StringBuilder stringBuilder = new StringBuilder(); + IsParentOf ipo = context.getParent(); + if(ipo!=null) { + Context c = ipo.getSource(); + c = uuidToContext.get(c.getHeader().getUUID()); + String parentFullName = getContextFullName(c); + stringBuilder.append(parentFullName); + } + stringBuilder.append("/"); + stringBuilder.append(context.getName()); + return stringBuilder.toString(); + } + + + public String getContextFullNameByUUID(UUID uuid) { + return uuidToContextFullName.get(uuid); + } + + public UUID getUUIDByFullName(String fullName) { + return contextFullNameToUUID.get(fullName); + } + + public Context getContextByUUID(UUID uuid) { + return uuidToContext.get(uuid); + } + + /** + * @return an Map containing UUID to Context FullName association + */ + public Map getUUIDToContextFullNameAssociation() { + return new HashMap<>(uuidToContextFullName); + } + + /** + * @return an Map containing Context FullName to UUID association + */ + public Map getContextFullNameToUUIDAssociation() { + return new HashMap<>(contextFullNameToUUID); + } + +}