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

net.sf.aguacate.script.spi.DynamicCacheSpi Maven / Gradle / Ivy

There is a newer version: 0.10.9
Show newest version
package net.sf.aguacate.script.spi;

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.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import net.sf.aguacate.script.DynamicCache;
import net.sf.aguacate.util.dynamic.bridge.Dynamic;
import net.sf.aguacate.util.dynamic.bridge.DynamicFactoryCoupling;
import net.sf.aguacate.util.filesystem.EventHandler;
import net.sf.aguacate.util.filesystem.FileSystemObserver;
import net.sf.aguacate.util.resource.ResourceLocator;
import net.sf.aguacate.util.resource.impl.ResourceLocatorClassImpl;
import net.sf.aguacate.util.resource.impl.ResourceLocatorFileImpl;

public class DynamicCacheSpi implements DynamicCache, EventHandler {

	private static final Logger LOGGER = LogManager.getLogger(DynamicCacheSpi.class);

	private static final Logger LOGGER2 = LogManager.getLogger("aguacate.file.script");

	private static final String ENVIRONMENT = "DIRECTORY_SCRIPT";

	private static final File DIRECTORY;

	private static final String EXTENSION = "js";

	private static final String SUFFIX = "." + EXTENSION;

	private static final int SUFFIX_LENGTH = 3;

	private final ResourceLocator locator;

	private Map cache;

	static {
		assert SUFFIX.equals("." + EXTENSION);
		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 DynamicCacheSpi() {
		cache = Collections.emptyMap();
		assert cache != null && cache.isEmpty();
		if (DIRECTORY == null) {
			locator = new ResourceLocatorClassImpl(DynamicCache.class);
		} else {
			locator = new ResourceLocatorFileImpl(DIRECTORY);
			FileSystemObserver.watch(DIRECTORY.toPath(), this);
		}
	}

	@Override
	public Dynamic get(String scriptName) {
		Dynamic dynamic = cache.get(scriptName);
		if (dynamic == null) {
			synchronized (this) {
				dynamic = cache.get(scriptName);
				if (dynamic == null) {
					Map temp = new HashMap<>(cache);
					dynamic = load0(scriptName.concat(SUFFIX));
					temp.put(scriptName, dynamic);
					cache = temp;
				}
			}
		}
		return dynamic;
	}

	Dynamic load0(String filename) {
		LOGGER.debug(filename);
		LOGGER2.info("Loading script: {}", filename);
		try {
			InputStream inputStream = locator.open(filename);
			if (inputStream == null) {
				throw new IllegalArgumentException(filename);
			} else {
				try {
					return DynamicFactoryCoupling.getByExtension(EXTENSION)
							.createFrom(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
				} finally {
					try {
						inputStream.close();
					} catch (IOException e) {
						LOGGER.warn("On closing resource", e);
					}
				}
			}
		} catch (IOException e) {
			throw new IllegalStateException(filename, e);
		}
	}

	@Override
	public void onDelete(Path directory, Path deleted) {
		String file = deleted.toString();
		if (file.endsWith(SUFFIX)) {
			LOGGER2.warn("Removing script definition: {}", deleted);
			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)) {
			LOGGER2.info("Change detected on script: {}", updated);
			String name = removeSufix(file);
			synchronized (this) {
				if (cache.containsKey(name)) {
					Map temp = new HashMap<>(cache);
					temp.put(name, load0(file));
					cache = temp;
				}
			}
		} else {
			LOGGER2.warn("Ignored : {}", updated);
			LOGGER.debug("ignore updated file: {}", updated);
		}
	}

	String removeSufix(String name) {
		return name.substring(0, name.length() - SUFFIX_LENGTH);
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy