Use Guice to create core classes
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 9 May 2015 14:50:11 +0000 (16:50 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Sat, 9 May 2015 14:50:11 +0000 (16:50 +0200)
src/main/java/net/pterodactylus/rhynodge/engine/Starter.java
src/main/java/net/pterodactylus/rhynodge/loader/ChainWatcher.java
src/main/java/net/pterodactylus/rhynodge/states/StateManager.java
src/main/java/net/pterodactylus/util/inject/ObjectBinding.java [new file with mode: 0644]
src/test/java/net/pterodactylus/rhynodge/states/StateManagerTest.java
src/test/java/net/pterodactylus/util/inject/ObjectBindingTest.java [new file with mode: 0644]

index d824eb8..bed4935 100644 (file)
 package net.pterodactylus.rhynodge.engine;
 
 import java.io.IOException;
+import java.util.Arrays;
 
 import net.pterodactylus.rhynodge.actions.EmailAction;
 import net.pterodactylus.rhynodge.loader.ChainWatcher;
-import net.pterodactylus.rhynodge.states.StateManager;
-import net.pterodactylus.rhynodge.states.StateManager.Directory;
+import net.pterodactylus.rhynodge.loader.ChainWatcher.ChainDirectory;
+import net.pterodactylus.rhynodge.states.StateManager.StateDirectory;
 import net.pterodactylus.util.envopt.Parser;
+import net.pterodactylus.util.inject.ObjectBinding;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
 
 /**
  * Rhynodge main starter class.
@@ -39,17 +44,18 @@ public class Starter {
         *            Command-line arguments
         */
        public static void main(String... arguments) throws IOException {
-
                Options options = Parser.fromSystemEnvironment().parseEnvironment(Options::new);
+               EmailAction errorEmailAction =
+                               createErrorEmailAction(options.smtpHostname, options.errorEmailSender, options.errorEmailRecipient);
 
-               /* create the state manager. */
-               StateManager stateManager = new StateManager(Directory.of(options.stateDirectory));
-
-               /* create the engine. */
-               Engine engine = new Engine(stateManager, createErrorEmailAction(options.smtpHostname, options.errorEmailSender, options.errorEmailRecipient));
+               Injector injector = Guice.createInjector(Arrays.asList(
+                               ObjectBinding.forClass(StateDirectory.class).is(StateDirectory.of(options.stateDirectory)),
+                               ObjectBinding.forClass(ChainDirectory.class).is(ChainDirectory.of(options.chainDirectory)),
+                               ObjectBinding.forClass(EmailAction.class).is(errorEmailAction)
+               ));
 
                /* start a watcher. */
-               ChainWatcher chainWatcher = new ChainWatcher(engine, options.chainDirectory);
+               ChainWatcher chainWatcher = injector.getInstance(ChainWatcher.class);
                chainWatcher.start();
        }
 
index 71320ff..69faf8b 100644 (file)
@@ -27,6 +27,9 @@ import java.util.Map.Entry;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
 import net.pterodactylus.rhynodge.Reaction;
 import net.pterodactylus.rhynodge.engine.Engine;
 import net.pterodactylus.rhynodge.loader.Chain.Parameter;
@@ -48,6 +51,7 @@ import com.google.common.util.concurrent.Uninterruptibles;
  *
  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
  */
+@Singleton
 public class ChainWatcher extends AbstractExecutionThreadService {
 
        /** The logger. */
@@ -73,9 +77,10 @@ public class ChainWatcher extends AbstractExecutionThreadService {
         * @param directory
         *            The directory to watch
         */
-       public ChainWatcher(Engine engine, String directory) {
+       @Inject
+       public ChainWatcher(Engine engine, ChainDirectory directory) {
                this.engine = engine;
-               this.directory = directory;
+               this.directory = directory.getDirectory();
        }
 
        //
@@ -235,4 +240,22 @@ public class ChainWatcher extends AbstractExecutionThreadService {
                return (filename.lastIndexOf(".") > -1) ? filename.substring(0, filename.lastIndexOf(".")) : filename;
        }
 
+       public static class ChainDirectory {
+
+               private final String directory;
+
+               private ChainDirectory(String directory) {
+                       this.directory = directory;
+               }
+
+               public String getDirectory() {
+                       return directory;
+               }
+
+               public static ChainDirectory of(String directory) {
+                       return new ChainDirectory(directory);
+               }
+
+       }
+
 }
index bb8aff5..8e0c72e 100644 (file)
@@ -56,12 +56,12 @@ public class StateManager {
        /**
         * Creates a new state manager. The given directory is assumed to exist.
         *
-        * @param directory
+        * @param stateDirectory
         *            The directory to store states in
         */
        @Inject
-       public StateManager(Directory directory) {
-               this.directory = directory.getDirectory();
+       public StateManager(StateDirectory stateDirectory) {
+               this.directory = stateDirectory.getDirectory();
        }
 
        //
@@ -164,11 +164,11 @@ public class StateManager {
                return empty();
        }
 
-       public static class Directory {
+       public static class StateDirectory {
 
                private final String directory;
 
-               private Directory(String directory) {
+               private StateDirectory(String directory) {
                        this.directory = directory;
                }
 
@@ -176,8 +176,8 @@ public class StateManager {
                        return directory;
                }
 
-               public static Directory of(String directory) {
-                       return new Directory(directory);
+               public static StateDirectory of(String directory) {
+                       return new StateDirectory(directory);
                }
 
        }
diff --git a/src/main/java/net/pterodactylus/util/inject/ObjectBinding.java b/src/main/java/net/pterodactylus/util/inject/ObjectBinding.java
new file mode 100644 (file)
index 0000000..5bf2864
--- /dev/null
@@ -0,0 +1,30 @@
+package net.pterodactylus.util.inject;
+
+import com.google.inject.Module;
+
+/**
+ * Helper class for Guice configuration.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class ObjectBinding {
+
+       public static <T> $1<T> forClass(Class<T> requestedClass) {
+               return new $1<>(requestedClass);
+       }
+
+       public static class $1<T> {
+
+               private final Class<T> requestedClass;
+
+               private $1(Class<T> requestedClass) {
+                       this.requestedClass = requestedClass;
+               }
+
+               public Module is(T instance) {
+                       return (binder) -> binder.bind(requestedClass).toInstance(instance);
+               }
+
+       }
+
+}
index 0821b68..839b389 100644 (file)
@@ -12,7 +12,7 @@ import java.io.IOException;
 import java.util.Optional;
 
 import net.pterodactylus.rhynodge.State;
-import net.pterodactylus.rhynodge.states.StateManager.Directory;
+import net.pterodactylus.rhynodge.states.StateManager.StateDirectory;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.google.common.io.Files;
@@ -42,7 +42,7 @@ public class StateManagerTest {
        public StateManagerTest() throws IOException {
                tempFolder.create();
                statePath = tempFolder.newFolder();
-               stateManager = new StateManager(Directory.of(statePath.getPath()));
+               stateManager = new StateManager(StateDirectory.of(statePath.getPath()));
        }
 
        @Test
diff --git a/src/test/java/net/pterodactylus/util/inject/ObjectBindingTest.java b/src/test/java/net/pterodactylus/util/inject/ObjectBindingTest.java
new file mode 100644 (file)
index 0000000..df32585
--- /dev/null
@@ -0,0 +1,32 @@
+package net.pterodactylus.util.inject;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.Matchers;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link ObjectBinding}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class ObjectBindingTest {
+
+       @Test
+       public void constructorCanBeCalled() {
+               new ObjectBinding();
+       }
+
+       @Test
+       public void objectIsBound() {
+               TestClass testObject = new TestClass();
+               Injector injector = Guice.createInjector(ObjectBinding.forClass(TestInterface.class).is(testObject));
+               MatcherAssert.assertThat(injector.getInstance(TestInterface.class), Matchers.sameInstance(testObject));
+       }
+
+       public interface TestInterface { }
+
+       public static class TestClass implements TestInterface { }
+
+}