APLCache.java
Home
/
src /
main /
java /
br /
ufrgs /
inf /
prosoft /
aplcache /
caching /
APLCache.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package br.ufrgs.inf.prosoft.aplcache.caching;
import br.ufrgs.inf.prosoft.jsonserialiser.JSONSerialiser;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
*
* @author romulo
*/
public class APLCache {
private static final Logger LOGGER = Logger.getLogger(APLCache.class.getName());
private static String APLCACHE_CACHEABLE_PARAMETERS = System.getenv("APLCACHE_CACHEABLE_PARAMETERS");
private static final Map<String, Collection<String>> APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS = new HashMap<>();
private static final String APLCACHE_LOG = System.getenv("APLCACHE_LOG");
private static void loadCacheableParameters() {
if (APLCACHE_CACHEABLE_PARAMETERS == null) {
return;
}
try (FileReader fileReader = new FileReader(APLCACHE_CACHEABLE_PARAMETERS)) {
JsonParser jsonParser = new JsonParser();
JsonObject jsonObject = jsonParser.parse(fileReader).getAsJsonObject();
jsonObject.entrySet().forEach(entry -> {
Collection<String> parameters = new ArrayList<>();
entry.getValue().getAsJsonArray().forEach(parameter -> {
parameters.add(parameter.getAsString());
});
APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS.put(entry.getKey(), parameters);
});
LOGGER.log(Level.INFO, "cache file loaded");
} catch (FileNotFoundException ex) {
LOGGER.log(Level.SEVERE, "invalid cache file");
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, "invalid cache file");
}
APLCACHE_CACHEABLE_PARAMETERS = null;
}
public static boolean isCacheable(Thread currentThread, Object... parameters) {
StackTraceElement[] stackTrace = currentThread.getStackTrace();
StackTraceElement stackTraceElement = null;
try {
stackTraceElement = stackTrace[2];
} catch (ArrayIndexOutOfBoundsException ex) {
stackTraceElement = stackTrace[0];
}
return isCacheable(stackTraceElement, parameters);
}
public static boolean isCacheable(StackTraceElement stackTraceElement, Object... parameters) {
try {
String methodName = stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName();
return isCacheable(methodName, parameters);
} catch (Exception ex) {
return false;
}
}
public static boolean isCacheable(String method, Object... parameters) {
loadCacheableParameters();
if (APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS.isEmpty()) {
LOGGER.log(Level.WARNING, "no method is cacheable");
return false;
}
Collection<String> cacheableParameters = APLCACHE_METHOD_HAS_CACHEABLE_PARAMETERS.get(method);
if (cacheableParameters == null) {
LOGGER.log(Level.WARNING, "method not cacheable: {0}", method);
return false;
}
String serialisedParameters = Stream.of(parameters).map(JSONSerialiser::serialise)
.collect(Collectors.joining(",", "[", "]"));
if (cacheableParameters.contains(serialisedParameters)) {
return true;
}
log("uncacheable " + method + " : " + serialisedParameters);
return false;
}
private static void log(String message) {
if (APLCACHE_LOG == null) {
return;
}
try (FileWriter fileWriter = new FileWriter(APLCACHE_LOG, true)) {
fileWriter.write(message + "\n");
} catch (IOException ex) {
}
}
}