resource-registry/src/main/java/org/gcube/informationsystem/resourceregistry/contexts/ServerContextCache.java

243 lines
8.4 KiB
Java

package org.gcube.informationsystem.resourceregistry.contexts;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.UUID;
import org.gcube.com.fasterxml.jackson.core.JsonProcessingException;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode;
import org.gcube.com.fasterxml.jackson.databind.node.TextNode;
import org.gcube.informationsystem.contexts.impl.entities.ContextImpl;
import org.gcube.informationsystem.contexts.impl.relations.IsParentOfImpl;
import org.gcube.informationsystem.contexts.reference.entities.Context;
import org.gcube.informationsystem.contexts.reference.relations.IsParentOf;
import org.gcube.informationsystem.model.reference.properties.Metadata;
import org.gcube.informationsystem.resourceregistry.api.contexts.ContextCache;
import org.gcube.informationsystem.resourceregistry.api.contexts.ContextCacheRenewal;
import org.gcube.informationsystem.resourceregistry.api.exceptions.ResourceRegistryException;
import org.gcube.informationsystem.resourceregistry.contexts.entities.ContextManagement;
import org.gcube.informationsystem.resourceregistry.instances.base.ElementManagement;
import org.gcube.informationsystem.resourceregistry.requests.RequestUtility;
import org.gcube.informationsystem.resourceregistry.requests.ServerRequestInfo;
import org.gcube.informationsystem.serialization.ElementMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class ServerContextCache extends ContextCache {
private static Logger logger = LoggerFactory.getLogger(ServerContextCache.class);
protected List<Context> contextsMetaPrivacy;
protected Map<UUID, Context> uuidToContextMetaPrivacy;
protected List<Context> contextsNoMeta;
protected Map<UUID, Context> uuidToContextNoMeta;
protected boolean includeMeta;
protected static ServerContextCache singleton;
public synchronized static ServerContextCache getInstance() {
if(singleton==null) {
singleton = new ServerContextCache();
}
return singleton;
}
@Override
public void cleanCache() {
cleanCache(Calendar.getInstance());
}
@Override
protected void cleanCache(Calendar now) {
super.cleanCache(now);
contextsMetaPrivacy = null;
uuidToContextMetaPrivacy = null;
contextsNoMeta = null;
uuidToContextNoMeta = null;
}
public ServerContextCache() {
Calendar now = Calendar.getInstance();
cleanCache(now);
initContextCacheRenewal();
}
public boolean isIncludeMeta() {
return includeMeta;
}
public void setIncludeMeta(boolean includeMeta) {
this.includeMeta = includeMeta;
}
public void initContextCacheRenewal() {
ContextCacheRenewal contextCacheRenewal = new ContextCacheRenewal() {
@Override
public List<Context> renew() throws ResourceRegistryException {
ContextManagement contextManagement = new ContextManagement();
contextManagement.setForceOffset(0);
contextManagement.setForceLimit(-1);
String contextsJsonString = contextManagement.allFromDatabase(false);
List<Context> contexts = null;
try {
contexts = ElementMapper.unmarshalList(contextsJsonString);
} catch (IOException e) {
logger.error("Unable to read contexts from DB", e);
}
return contexts;
}
};
setContextCacheRenewal(contextCacheRenewal);
}
protected boolean isUserAllowedToGetPrivacyMeta() {
return ElementManagement.isUserAllowedToGetPrivacyMeta();
}
@Override
public synchronized List<Context> getContexts() throws ResourceRegistryException {
refreshContextsIfNeeded();
ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get();
if(requestInfo.getUriInfo()!=null && !requestInfo.includeMeta()){
return contextsNoMeta;
}
if(isUserAllowedToGetPrivacyMeta()) {
return contexts;
}else {
return contextsMetaPrivacy;
}
}
@Override
public synchronized Context getContextByUUID(UUID uuid) throws ResourceRegistryException {
refreshContextsIfNeeded();
ServerRequestInfo requestInfo = RequestUtility.getRequestInfo().get();
if(requestInfo.getUriInfo()!=null && !requestInfo.includeMeta()){
return uuidToContextNoMeta.get(uuid);
}
if(isUserAllowedToGetPrivacyMeta()) {
return uuidToContext.get(uuid);
}else {
return uuidToContextMetaPrivacy.get(uuid);
}
}
protected Metadata getMetadataForPrivacy(ObjectMapper objectMapper, Metadata metadata) {
ObjectNode objectNode = objectMapper.valueToTree(metadata);
objectNode.replace(Metadata.CREATED_BY_PROPERTY, new TextNode(Metadata.HIDDEN_FOR_PRIVACY_USER));
objectNode.replace(Metadata.LAST_UPDATE_BY_PROPERTY, new TextNode(Metadata.HIDDEN_FOR_PRIVACY_USER));
try {
Metadata metadataWithPrivacy = objectMapper.treeToValue(objectNode, Metadata.class);
return metadataWithPrivacy;
} catch (JsonProcessingException e) {
return metadata;
}
}
@Override
protected void setContexts(Calendar calendar, List<Context> contexts) {
this.contexts = new ArrayList<>();
this.uuidToContext = new LinkedHashMap<>();
this.contextsMetaPrivacy = new ArrayList<>();
this.uuidToContextMetaPrivacy = new LinkedHashMap<>();
this.contextsNoMeta = new ArrayList<>();
this.uuidToContextNoMeta = new LinkedHashMap<>();
ObjectMapper objectMapper = ElementMapper.getObjectMapper();
for(Context c : contexts) {
UUID uuid = c.getID();
Context contextWithMeta = new ContextImpl(c.getName());
contextWithMeta.setMetadata(c.getMetadata());
contextWithMeta.setID(uuid);
this.contexts.add(contextWithMeta);
this.uuidToContext.put(uuid, contextWithMeta);
Context contextMetaPrivacy = new ContextImpl(c.getName());
Metadata metadataWithPrivacy = getMetadataForPrivacy(objectMapper, c.getMetadata());
contextMetaPrivacy.setMetadata(metadataWithPrivacy);
contextMetaPrivacy.setID(uuid);
this.contextsMetaPrivacy.add(contextMetaPrivacy);
this.uuidToContextMetaPrivacy.put(uuid, contextMetaPrivacy);
Context contextNoMeta = new ContextImpl(c.getName());
contextNoMeta.setMetadata(null);
contextNoMeta.setID(uuid);
this.contextsNoMeta.add(contextNoMeta);
this.uuidToContextNoMeta.put(uuid, contextNoMeta);
}
for(Context c : contexts) {
UUID uuid = c.getID();
Context contextMeta = this.uuidToContext.get(uuid);
Context contextMetaPrivacy = this.uuidToContextMetaPrivacy.get(uuid);
Context contextNoMeta = this.uuidToContextNoMeta.get(uuid);
if(c.getParent()!=null) {
IsParentOf ipo = c.getParent();
UUID isParentOfParentUUID = ipo.getID();
UUID contextParentUUID = ipo.getSource().getID();
Context parentWithMeta = this.uuidToContext.get(contextParentUUID);
IsParentOf isParentOfWithMeta = new IsParentOfImpl(parentWithMeta, contextMeta);
isParentOfWithMeta.setID(isParentOfParentUUID);
isParentOfWithMeta.setMetadata(ipo.getMetadata());
parentWithMeta.addChild(isParentOfWithMeta);
contextMeta.setParent(isParentOfWithMeta);
Context parentWithMetaPrivacy = this.uuidToContextMetaPrivacy.get(contextParentUUID);
IsParentOf isParentOfMetaPrivacy = new IsParentOfImpl(parentWithMetaPrivacy, contextMetaPrivacy);
isParentOfMetaPrivacy.setID(isParentOfParentUUID);
Metadata metadataWithPrivacy = getMetadataForPrivacy(objectMapper, ipo.getMetadata());
isParentOfMetaPrivacy.setMetadata(metadataWithPrivacy);
parentWithMetaPrivacy.addChild(isParentOfMetaPrivacy);
contextMetaPrivacy.setParent(isParentOfMetaPrivacy);
Context parentNoMeta = this.uuidToContextNoMeta.get(contextParentUUID);
IsParentOf isParentOfNoMeta = new IsParentOfImpl(parentNoMeta, contextNoMeta);
isParentOfNoMeta.setMetadata(null);
isParentOfNoMeta.setID(isParentOfParentUUID);
parentNoMeta.addChild(isParentOfNoMeta);
contextNoMeta.setParent(isParentOfNoMeta);
}
}
for(Context context : contexts) {
UUID uuid = context.getID();
String fullName = getContextFullName(context);
this.uuidToContextFullName.put(uuid, fullName);
this.contextFullNameToUUID.put(fullName, uuid);
}
SortedSet<String> contextFullNames = new TreeSet<String>(contextFullNameToUUID.keySet());
for(String contextFullName : contextFullNames) {
UUID uuid = contextFullNameToUUID.get(contextFullName);
Context context = uuidToContext.get(uuid);
contextsTree.addNode(context);
}
}
}