
net.sf.aguacate.config.impl.ConfigurationImpl Maven / Gradle / Ivy
package net.sf.aguacate.config.impl;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import net.sf.aguacate.config.Configuration;
import net.sf.aguacate.config.spi.PathInfoCompiler;
import net.sf.aguacate.context.ContextProcessor;
import net.sf.aguacate.context.ContextValidator;
import net.sf.aguacate.model.EntityInfo;
import net.sf.aguacate.model.FieldType;
import net.sf.aguacate.util.codec.bridge.CodecCoupling;
import net.sf.aguacate.util.filesystem.EventHandler;
import net.sf.aguacate.util.filesystem.FileSystemObserver;
import net.sf.aguacate.util.formatter.OutputFormater;
import net.sf.aguacate.util.resource.ResourceLocator;
import net.sf.aguacate.util.resource.impl.ResourceLocatorClassImpl;
import net.sf.aguacate.util.resource.impl.ResourceLocatorFileImpl;
import net.sf.aguacate.validator.InputValidator;
import net.sf.aguacate.validator.ValidatorConverter;
public class ConfigurationImpl implements Configuration, EventHandler {
private static final Logger LOGGER = LogManager.getLogger(ConfigurationImpl.class);
private static final String SUFFIX = ".json";
private static final int SUFFIX_LENGTH = 5;
private static final String ENVIRONMENT = "DIRECTORY_CONFIGURATION";
private static final File DIRECTORY;
private final ResourceLocator locator;
private final PathInfoCompiler compiler;
private final ValidatorConverter validatorConverter;
private Map cache;
static {
assert SUFFIX_LENGTH == SUFFIX.length();
String temp = System.getProperty(ENVIRONMENT);
if (temp == null || temp.isEmpty()) {
temp = System.getenv(ENVIRONMENT);
if (temp == null || temp.isEmpty()) {
LOGGER.info("No " + ENVIRONMENT + " defined, using default");
DIRECTORY = null;
} else {
LOGGER.info("using " + ENVIRONMENT + " (env): {}", temp);
DIRECTORY = new File(temp);
}
} else {
LOGGER.info("using " + ENVIRONMENT + " (prop): {}", temp);
DIRECTORY = new File(temp);
}
}
public ConfigurationImpl(PathInfoCompiler compiler, ValidatorConverter validatorConverter) {
if (DIRECTORY == null) {
this.locator = new ResourceLocatorClassImpl(ConfigurationImpl.class);
} else {
this.locator = new ResourceLocatorFileImpl(DIRECTORY);
FileSystemObserver.watch(DIRECTORY.toPath(), this);
}
this.compiler = compiler;
this.validatorConverter = validatorConverter;
this.cache = new HashMap<>();
}
@Override
public boolean accepts(String entity, String method) {
return get(entity).accepts(method);
}
@Override
public InputValidator inputValidator(String entity, String method) {
return get(entity).getValidatorConverter(method);
}
@Override
public ContextValidator contextValidator(String entity, String method) {
return get(entity).getContextValidator();
}
@Override
public ContextProcessor contextProcessor(String entity, String method) {
return get(entity).getContextProcessor();
}
@Override
public OutputFormater outputFormater(String entity, String method) {
return get(entity).getOutputFormater();
}
@Override
public Map outputFields(String entity, String method) {
return get(entity).getOutputFields().get(method);
}
EntityInfo get(String entity) {
EntityInfo info = cache.get(entity);
if (info == null) {
synchronized (this) {
info = cache.get(entity);
if (info == null) {
String resource = entity.concat(SUFFIX);
info = load0(resource);
if (info != null) {
LOGGER.trace("original: {}", cache);
Map temp = new HashMap<>(cache);
temp.put(entity, info);
LOGGER.trace("new: {}", temp);
cache = temp;
}
}
}
}
return info;
}
EntityInfo load0(String file) {
try {
EntityInfo info;
InputStream inputStream = locator.open(file);
if (inputStream == null) {
LOGGER.warn("Not Found: {}", file);
info = null;
} else {
Map data;
try {
data = CodecCoupling.jsonCodecBridge()
.decodeMap(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
} finally {
try {
inputStream.close();
} catch (IOException e) {
LOGGER.warn("when closing a resource", e);
}
}
LOGGER.trace("decoded: {}", data);
info = compiler.compile(validatorConverter, data);
}
return info;
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
@Override
public String[] methods(String entity) {
return get(entity).methods();
}
@Override
public ResourceLocator getLocator() {
return locator;
}
@Override
public void onDelete(Path directory, Path deleted) {
String file = deleted.toString();
if (file.endsWith(SUFFIX)) {
String name = removeSufix(file);
synchronized (this) {
if (cache.containsKey(name)) {
Map temp = new HashMap<>(cache);
temp.remove(name);
cache = temp;
}
}
} else {
LOGGER.debug("ignore deleted file: {}", deleted);
}
}
@Override
public void onUpdate(Path directory, Path updated) {
String file = updated.toString();
if (file.endsWith(SUFFIX)) {
String name = removeSufix(file);
synchronized (this) {
if (cache.containsKey(name)) {
Map temp = new HashMap<>(cache);
temp.put(name, load0(file));
cache = temp;
}
}
} else {
LOGGER.debug("ignore updated file: {}", updated);
}
}
String removeSufix(String name) {
return name.substring(0, name.length() - SUFFIX_LENGTH);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy