X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Freactor%2Floader%2FChainWatcher.java;fp=src%2Fmain%2Fjava%2Fnet%2Fpterodactylus%2Freactor%2Floader%2FChainWatcher.java;h=0000000000000000000000000000000000000000;hb=6f69aff66ba5617d0bb27874014b4274bc551ab8;hp=3d30f2615edfc140405d9237064e891134b05cdd;hpb=13a4fe6bece23b3dd561de657cf9bb7ea307e2b6;p=rhynodge.git diff --git a/src/main/java/net/pterodactylus/reactor/loader/ChainWatcher.java b/src/main/java/net/pterodactylus/reactor/loader/ChainWatcher.java deleted file mode 100644 index 3d30f26..0000000 --- a/src/main/java/net/pterodactylus/reactor/loader/ChainWatcher.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Reactor - ChainWatcher.java - Copyright © 2013 David Roden - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package net.pterodactylus.reactor.loader; - -import java.io.File; -import java.io.FilenameFilter; -import java.io.IOException; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import net.pterodactylus.reactor.Reaction; -import net.pterodactylus.reactor.engine.Engine; -import net.pterodactylus.reactor.loader.Chain.Parameter; -import net.pterodactylus.reactor.loader.Chain.Part; - -import org.apache.log4j.Logger; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.base.Predicate; -import com.google.common.collect.Maps; -import com.google.common.util.concurrent.AbstractExecutionThreadService; -import com.google.common.util.concurrent.Uninterruptibles; - -/** - * Watches a directory for chain configuration files and loads and unloads - * {@link Reaction}s from the {@link Engine}. - * - * @author David ‘Bombe’ Roden - */ -public class ChainWatcher extends AbstractExecutionThreadService { - - /** The logger. */ - private static final Logger logger = Logger.getLogger(ChainWatcher.class); - - /** The JSON object mapper. */ - private static final ObjectMapper objectMapper = new ObjectMapper(); - - /** The reaction loader. */ - private final ReactionLoader reactionLoader = new ReactionLoader(); - - /** The engine to load reactions with. */ - private final Engine engine; - - /** The directory to watch for chain configuration files. */ - private final String directory; - - /** - * Creates a new chain watcher. - * - * @param engine - * The engine to load reactions with - * @param directory - * The directory to watch - */ - public ChainWatcher(Engine engine, String directory) { - this.engine = engine; - this.directory = directory; - } - - // - // ABSTRACTEXECUTIONTHREADSERVICE METHODS - // - - /** - * {@inheritDoc} - */ - @Override - protected void run() throws Exception { - - /* loaded chains. */ - final Map loadedChains = new HashMap(); - - while (isRunning()) { - - /* check if directory is there. */ - File directoryFile = new File(directory); - if (!directoryFile.exists() || !directoryFile.isDirectory() || !directoryFile.canRead()) { - Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS); - continue; - } - - /* list all files, scan for configuration files. */ - logger.debug(String.format("Scanning %s...", directory)); - File[] configurationFiles = directoryFile.listFiles(new FilenameFilter() { - - @Override - public boolean accept(File dir, String name) { - return name.endsWith(".json"); - } - }); - logger.debug(String.format("Found %d configuration file(s), parsing...", configurationFiles.length)); - - /* now parse all XML files. */ - Map chains = new HashMap(); - for (File configurationFile : configurationFiles) { - - /* parse XML file. */ - Chain chain = parseConfigurationFile(configurationFile); - if (chain == null) { - logger.warn(String.format("Could not parse %s.", configurationFile)); - continue; - } - - /* dump chain */ - logger.debug(String.format(" Enabled: %s", chain.enabled())); - - logger.debug(String.format(" Query: %s", chain.query().name())); - for (Parameter parameter : chain.query().parameters()) { - logger.debug(String.format(" Parameter: %s=%s", parameter.name(), parameter.value())); - } - for (Part filter : chain.filters()) { - logger.debug(String.format(" Filter: %s", filter.name())); - for (Parameter parameter : filter.parameters()) { - logger.debug(String.format(" Parameter: %s=%s", parameter.name(), parameter.value())); - } - } - logger.debug(String.format(" Trigger: %s", chain.trigger().name())); - for (Parameter parameter : chain.trigger().parameters()) { - logger.debug(String.format(" Parameter: %s=%s", parameter.name(), parameter.value())); - } - logger.debug(String.format(" Action: %s", chain.action().name())); - for (Parameter parameter : chain.action().parameters()) { - logger.debug(String.format(" Parameter: %s=%s", parameter.name(), parameter.value())); - } - - chains.put(getReactionName(configurationFile.getName()), chain); - } - - /* filter enabled chains. */ - Map enabledChains = Maps.filterEntries(chains, new Predicate>() { - - @Override - public boolean apply(Entry chainEntry) { - return chainEntry.getValue().enabled(); - } - }); - logger.debug(String.format("Found %d enabled Chain(s).", enabledChains.size())); - - /* check for removed chains. */ - Set chainsToRemove = new HashSet(); - for (Entry loadedChain : loadedChains.entrySet()) { - - /* skip chains that still exist. */ - if (enabledChains.containsKey(loadedChain.getKey())) { - continue; - } - - logger.info(String.format("Removing Chain: %s", loadedChain.getKey())); - engine.removeReaction(loadedChain.getKey()); - chainsToRemove.add(loadedChain.getKey()); - } - - /* remove removed chains from loaded chains. */ - for (String reactionName : chainsToRemove) { - loadedChains.remove(reactionName); - } - - /* check for new chains. */ - for (Entry enabledChain : enabledChains.entrySet()) { - - /* skip already loaded chains. */ - if (loadedChains.containsValue(enabledChain.getValue())) { - continue; - } - - logger.info(String.format("Loading new Chain: %s", enabledChain.getKey())); - - Reaction reaction = reactionLoader.loadReaction(enabledChain.getValue()); - engine.addReaction(enabledChain.getKey(), reaction); - loadedChains.put(enabledChain.getKey(), enabledChain.getValue()); - } - - /* wait before checking again. */ - Uninterruptibles.sleepUninterruptibly(5, TimeUnit.SECONDS); - } - } - - // - // STATIC METHODS - // - - /** - * Parses the given configuration file into a {@link Chain}. - * - * @param configurationFile - * The configuration file to parse - * @return The parsed chain - */ - private static Chain parseConfigurationFile(File configurationFile) { - try { - return objectMapper.readValue(configurationFile, Chain.class); - } catch (JsonParseException jpe1) { - logger.warn(String.format("Could not parse %s.", configurationFile), jpe1); - } catch (JsonMappingException jme1) { - logger.warn(String.format("Could not parse %s.", configurationFile), jme1); - } catch (IOException ioe1) { - logger.info(String.format("Could not read %s.", configurationFile)); - } - return null; - } - - /** - * Extracts the name of the reaction from the given filename. - * - * @param filename - * The filename to extract the reaction name from - * @return The name of the reaction - */ - private static String getReactionName(String filename) { - return (filename.lastIndexOf(".") > -1) ? filename.substring(0, filename.lastIndexOf(".")) : filename; - } - -}