All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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