Use JSON for configuration files, remove all references to XML.
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sun, 6 Jan 2013 14:46:20 +0000 (15:46 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sun, 6 Jan 2013 14:46:20 +0000 (15:46 +0100)
pom.xml
src/main/java/net/pterodactylus/reactor/loader/Chain.java
src/main/java/net/pterodactylus/reactor/loader/ChainWatcher.java
src/main/resources/chains/kickasstorrents-example.json [new file with mode: 0644]
src/main/resources/chains/kickasstorrents-example.xml [deleted file]

diff --git a/pom.xml b/pom.xml
index 28d464d..6f917fb 100644 (file)
--- a/pom.xml
+++ b/pom.xml
                        <version>3.1</version>
                </dependency>
                <dependency>
-                       <groupId>com.sun.xml.bind</groupId>
-                       <artifactId>jaxb</artifactId>
-                       <version>2.1.9</version>
-               </dependency>
-               <dependency>
                        <groupId>com.fasterxml.jackson.core</groupId>
                        <artifactId>jackson-core</artifactId>
                        <version>2.1.2</version>
index b018859..c367da0 100644 (file)
@@ -20,16 +20,13 @@ package net.pterodactylus.reactor.loader;
 import java.util.ArrayList;
 import java.util.List;
 
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlRootElement;
+import com.fasterxml.jackson.annotation.JsonProperty;
 
 /**
  * Model for chain definitions.
  *
  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
  */
-@XmlRootElement
 public class Chain {
 
        /**
@@ -40,11 +37,11 @@ public class Chain {
        public static class Parameter {
 
                /** The name of the parameter. */
-               @XmlElement(required = true)
+               @JsonProperty
                private String name;
 
                /** The value of the parameter. */
-               @XmlElement(required = true)
+               @JsonProperty
                private String value;
 
                /**
@@ -104,12 +101,11 @@ public class Chain {
        public static class Part {
 
                /** The class name of the part. */
-               @XmlElement(required = true, name = "class")
+               @JsonProperty(value = "class")
                private String name;
 
                /** The parameters of the part. */
-               @XmlElement(name = "parameter")
-               @XmlElementWrapper(name = "parameters")
+               @JsonProperty
                private List<Parameter> parameters = new ArrayList<Parameter>();
 
                /**
@@ -169,28 +165,27 @@ public class Chain {
        }
 
        /** Whether this chain is enabled. */
-       @XmlElement(required = true)
+       @JsonProperty
        private boolean enabled;
 
        /** The query of the chain. */
-       @XmlElement(required = true)
+       @JsonProperty
        private Part query;
 
        /** The filters of the chain. */
-       @XmlElement(name = "filter")
-       @XmlElementWrapper(name = "filters")
+       @JsonProperty
        private List<Part> filters = new ArrayList<Part>();
 
        /** The trigger of the chain. */
-       @XmlElement(required = true)
+       @JsonProperty
        private Part trigger;
 
        /** The action of the chain. */
-       @XmlElement(required = true)
+       @JsonProperty
        private Part action;
 
        /** Interval between updates (in seconds). */
-       @XmlElement(required = true)
+       @JsonProperty
        private int updateInterval;
 
        /**
index a6a5004..9daf262 100644 (file)
@@ -19,15 +19,12 @@ package net.pterodactylus.reactor.loader;
 
 import java.io.File;
 import java.io.FilenameFilter;
+import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.concurrent.TimeUnit;
 
-import javax.xml.bind.JAXBContext;
-import javax.xml.bind.JAXBException;
-import javax.xml.bind.Unmarshaller;
-
 import net.pterodactylus.reactor.Reaction;
 import net.pterodactylus.reactor.engine.Engine;
 import net.pterodactylus.reactor.loader.Chain.Parameter;
@@ -35,13 +32,16 @@ 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 XML files and loads and unloads
+ * Watches a directory for chain configuration files and loads and unloads
  * {@link Reaction}s from the {@link Engine}.
  *
  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
@@ -51,13 +51,16 @@ 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 XML files. */
+       /** The directory to watch for chain configuration files. */
        private final String directory;
 
        /**
@@ -95,23 +98,27 @@ public class ChainWatcher extends AbstractExecutionThreadService {
                                continue;
                        }
 
-                       /* list all files, scan for XMLs. */
+                       /* list all files, scan for configuration files. */
                        logger.debug(String.format("Scanning %s...", directory));
-                       File[] xmlFiles = directoryFile.listFiles(new FilenameFilter() {
+                       File[] configurationFiles = directoryFile.listFiles(new FilenameFilter() {
 
                                @Override
                                public boolean accept(File dir, String name) {
-                                       return name.endsWith(".xml");
+                                       return name.endsWith(".json");
                                }
                        });
-                       logger.debug(String.format("Found %d XML file(s), parsing...", xmlFiles.length));
+                       logger.debug(String.format("Found %d configuration file(s), parsing...", configurationFiles.length));
 
                        /* now parse all XML files. */
                        Map<String, Chain> chains = new HashMap<String, Chain>();
-                       for (File xmlFile : xmlFiles) {
+                       for (File configurationFile : configurationFiles) {
 
                                /* parse XML file. */
-                               Chain chain = parseXmlFile(xmlFile);
+                               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()));
@@ -135,7 +142,7 @@ public class ChainWatcher extends AbstractExecutionThreadService {
                                        logger.debug(String.format("  Parameter: %s=%s", parameter.name(), parameter.value()));
                                }
 
-                               chains.put(xmlFile.getName(), chain);
+                               chains.put(configurationFile.getName(), chain);
                        }
 
                        /* filter enabled chains. */
@@ -186,22 +193,23 @@ public class ChainWatcher extends AbstractExecutionThreadService {
        //
 
        /**
-        * Parses the given XML file into a {@link Chain}.
+        * Parses the given configuration file into a {@link Chain}.
         *
-        * @param xmlFile
-        *            The XML file to parse
+        * @param configurationFile
+        *            The configuration file to parse
         * @return The parsed chain
         */
-       private static Chain parseXmlFile(File xmlFile) {
+       private static Chain parseConfigurationFile(File configurationFile) {
                try {
-                       JAXBContext context = JAXBContext.newInstance(Chain.class);
-                       Unmarshaller unmarshaller = context.createUnmarshaller();
-                       logger.debug(String.format("Reading %s...", xmlFile.getPath()));
-                       return (Chain) unmarshaller.unmarshal(xmlFile);
-               } catch (JAXBException e) {
-                       e.printStackTrace();
-                       return null;
+                       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;
        }
 
 }
diff --git a/src/main/resources/chains/kickasstorrents-example.json b/src/main/resources/chains/kickasstorrents-example.json
new file mode 100644 (file)
index 0000000..1628c73
--- /dev/null
@@ -0,0 +1,49 @@
+{
+       "enabled": true,
+
+       "query":
+               {
+                       "class": "HttpQuery",
+                       "parameters": [
+                               {
+                                       "name": "url",
+                                       "value": "http://kat.ph/usearch/example%20words/?field=time_add&sorder=desc"
+                               }
+                       ]
+               },
+
+       "filters": [
+               {
+                       "class": "HtmlFilter"
+               },
+               {
+                       "class": "KickAssTorrentsFilter"
+               }
+       ],
+
+       "trigger":
+               {
+                       "class": "NewTorrentTrigger"
+               },
+
+       "action":
+               {
+                       "class": "EmailAction",
+                       "parameters": [
+                               {
+                                       "name": "smtpHostname",
+                                       "value": "smtp"
+                               },
+                               {
+                                       "name": "sender",
+                                       "value": "reactor@reactor.de"
+                               },
+                               {
+                                       "name": "recipient",
+                                       "value": "recipient@recipient.de"
+                               }
+                       ]
+               },
+
+       "updateInterval": 3600
+}
diff --git a/src/main/resources/chains/kickasstorrents-example.xml b/src/main/resources/chains/kickasstorrents-example.xml
deleted file mode 100644 (file)
index af77816..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<chain>
-
-       <enabled>false</enabled>
-
-       <query>
-               <class>HttpQuery</class>
-               <parameters>
-                       <parameter>
-                               <name>url</name>
-                               <value>http://kat.ph/usearch/example%20words/?field=time_add&amp;sorder=desc</value>
-                       </parameter>
-               </parameters>
-       </query>
-
-       <filters>
-               <filter>
-                       <class>HtmlFilter</class>
-               </filter>
-               <filter>
-                       <class>KickAssTorrentsFilter</class>
-               </filter>
-       </filters>
-
-       <trigger>
-               <class>NewTorrentTrigger</class>
-       </trigger>
-
-       <action>
-               <class>EmailAction</class>
-               <parameters>
-                       <parameter>
-                               <name>smtpHostname</name>
-                               <value>smtp</value>
-                       </parameter>
-                       <parameter>
-                               <name>sender</name>
-                               <value>reactor@reactor.de</value>
-                       </parameter>
-                       <parameter>
-                               <name>recipient</name>
-                               <value>recipient@recipient.de</value>
-                       </parameter>
-               </parameters>
-       </action>
-
-       <updateInterval>3600</updateInterval>
-
-</chain>