Move preferences loading and saving out of the core.
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Tue, 30 Sep 2014 05:12:43 +0000 (07:12 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Tue, 30 Sep 2014 05:12:43 +0000 (07:12 +0200)
src/main/java/net/pterodactylus/sone/core/Core.java
src/main/java/net/pterodactylus/sone/core/Preferences.java
src/main/java/net/pterodactylus/sone/core/PreferencesLoader.java [new file with mode: 0644]
src/test/java/net/pterodactylus/sone/core/PreferencesLoaderTest.java [new file with mode: 0644]
src/test/java/net/pterodactylus/sone/core/PreferencesTest.java

index c10408a..f3927d9 100644 (file)
@@ -89,8 +89,6 @@ import net.pterodactylus.sone.freenet.wot.event.IdentityUpdatedEvent;
 import net.pterodactylus.sone.freenet.wot.event.OwnIdentityAddedEvent;
 import net.pterodactylus.sone.freenet.wot.event.OwnIdentityRemovedEvent;
 import net.pterodactylus.sone.main.SonePlugin;
-import net.pterodactylus.sone.utils.DefaultOption;
-import net.pterodactylus.sone.utils.IntegerRangePredicate;
 import net.pterodactylus.util.config.Configuration;
 import net.pterodactylus.util.config.ConfigurationException;
 import net.pterodactylus.util.logging.Logging;
@@ -100,7 +98,6 @@ import net.pterodactylus.util.thread.NamedThreadFactory;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Optional;
-import com.google.common.base.Predicates;
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
@@ -124,9 +121,6 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
        /** The start time. */
        private final long startupTime = System.currentTimeMillis();
 
-       /** The options. */
-       private final Options options = new Options();
-
        /** The preferences. */
        private final Preferences preferences;
 
@@ -228,7 +222,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                this.webOfTrustUpdater = webOfTrustUpdater;
                this.eventBus = eventBus;
                this.database = database;
-               preferences = new Preferences(this.eventBus, options);
+               preferences = new Preferences(eventBus);
        }
 
        @VisibleForTesting
@@ -243,7 +237,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
                this.webOfTrustUpdater = webOfTrustUpdater;
                this.eventBus = eventBus;
                this.database = database;
-               preferences = new Preferences(this.eventBus, options);
+               preferences = new Preferences(eventBus);
        }
 
        //
@@ -1656,18 +1650,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
 
                /* store the options first. */
                try {
-                       configuration.getIntValue("Option/ConfigurationVersion").setValue(0);
-                       configuration.getIntValue("Option/InsertionDelay").setValue(options.getIntegerOption("InsertionDelay").getReal());
-                       configuration.getIntValue("Option/PostsPerPage").setValue(options.getIntegerOption("PostsPerPage").getReal());
-                       configuration.getIntValue("Option/ImagesPerPage").setValue(options.getIntegerOption("ImagesPerPage").getReal());
-                       configuration.getIntValue("Option/CharactersPerPost").setValue(options.getIntegerOption("CharactersPerPost").getReal());
-                       configuration.getIntValue("Option/PostCutOffLength").setValue(options.getIntegerOption("PostCutOffLength").getReal());
-                       configuration.getBooleanValue("Option/RequireFullAccess").setValue(options.getBooleanOption("RequireFullAccess").getReal());
-                       configuration.getIntValue("Option/PositiveTrust").setValue(options.getIntegerOption("PositiveTrust").getReal());
-                       configuration.getIntValue("Option/NegativeTrust").setValue(options.getIntegerOption("NegativeTrust").getReal());
-                       configuration.getStringValue("Option/TrustComment").setValue(options.getStringOption("TrustComment").getReal());
-                       configuration.getBooleanValue("Option/ActivateFcpInterface").setValue(options.getBooleanOption("ActivateFcpInterface").getReal());
-                       configuration.getIntValue("Option/FcpFullAccessRequired").setValue(options.getIntegerOption("FcpFullAccessRequired").getReal());
+                       preferences.saveTo(configuration);
 
                        /* save known Sones. */
                        int soneCounter = 0;
@@ -1719,30 +1702,7 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
         * Loads the configuration.
         */
        private void loadConfiguration() {
-               /* create options. */
-               options.addIntegerOption("InsertionDelay", new DefaultOption<Integer>(60, new IntegerRangePredicate(0, Integer.MAX_VALUE)));
-               options.addIntegerOption("PostsPerPage", new DefaultOption<Integer>(10, new IntegerRangePredicate(1, Integer.MAX_VALUE)));
-               options.addIntegerOption("ImagesPerPage", new DefaultOption<Integer>(9, new IntegerRangePredicate(1, Integer.MAX_VALUE)));
-               options.addIntegerOption("CharactersPerPost", new DefaultOption<Integer>(400, Predicates.<Integer> or(new IntegerRangePredicate(50, Integer.MAX_VALUE), Predicates.equalTo(-1))));
-               options.addIntegerOption("PostCutOffLength", new DefaultOption<Integer>(200, Predicates.<Integer> or(new IntegerRangePredicate(50, Integer.MAX_VALUE), Predicates.equalTo(-1))));
-               options.addBooleanOption("RequireFullAccess", new DefaultOption<Boolean>(false));
-               options.addIntegerOption("PositiveTrust", new DefaultOption<Integer>(75, new IntegerRangePredicate(0, 100)));
-               options.addIntegerOption("NegativeTrust", new DefaultOption<Integer>(-25, new IntegerRangePredicate(-100, 100)));
-               options.addStringOption("TrustComment", new DefaultOption<String>("Set from Sone Web Interface"));
-               options.addBooleanOption("ActivateFcpInterface", new DefaultOption<Boolean>(false));
-               options.addIntegerOption("FcpFullAccessRequired", new DefaultOption<Integer>(2));
-
-               loadConfigurationValue("InsertionDelay");
-               loadConfigurationValue("PostsPerPage");
-               loadConfigurationValue("ImagesPerPage");
-               loadConfigurationValue("CharactersPerPost");
-               loadConfigurationValue("PostCutOffLength");
-               options.getBooleanOption("RequireFullAccess").set(configuration.getBooleanValue("Option/RequireFullAccess").getValue(null));
-               loadConfigurationValue("PositiveTrust");
-               loadConfigurationValue("NegativeTrust");
-               options.getStringOption("TrustComment").set(configuration.getStringValue("Option/TrustComment").getValue(null));
-               options.getBooleanOption("ActivateFcpInterface").set(configuration.getBooleanValue("Option/ActivateFcpInterface").getValue(null));
-               options.getIntegerOption("FcpFullAccessRequired").set(configuration.getIntValue("Option/FcpFullAccessRequired").getValue(null));
+               new PreferencesLoader(preferences).loadFrom(configuration);
 
                /* load known Sones. */
                int soneCounter = 0;
@@ -1785,21 +1745,6 @@ public class Core extends AbstractService implements SoneProvider, PostProvider,
        }
 
        /**
-        * Loads an {@link Integer} configuration value for the option with the
-        * given name, logging validation failures.
-        *
-        * @param optionName
-        *            The name of the option to load
-        */
-       private void loadConfigurationValue(String optionName) {
-               try {
-                       options.getIntegerOption(optionName).set(configuration.getIntValue("Option/" + optionName).getValue(null));
-               } catch (IllegalArgumentException iae1) {
-                       logger.log(Level.WARNING, String.format("Invalid value for %s in configuration, using default.", optionName));
-               }
-       }
-
-       /**
         * Notifies the core that a new {@link OwnIdentity} was added.
         *
         * @param ownIdentityAddedEvent
index 7edff1a..f7ecdab 100644 (file)
 
 package net.pterodactylus.sone.core;
 
+import static com.google.common.base.Predicates.equalTo;
+import static java.lang.Integer.MAX_VALUE;
+import static net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.ALWAYS;
+import static net.pterodactylus.sone.utils.IntegerRangePredicate.range;
+
 import net.pterodactylus.sone.core.event.InsertionDelayChangedEvent;
 import net.pterodactylus.sone.fcp.FcpInterface;
 import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired;
 import net.pterodactylus.sone.fcp.event.FcpInterfaceActivatedEvent;
 import net.pterodactylus.sone.fcp.event.FcpInterfaceDeactivatedEvent;
 import net.pterodactylus.sone.fcp.event.FullAccessRequiredChanged;
+import net.pterodactylus.sone.utils.DefaultOption;
+import net.pterodactylus.sone.utils.Option;
+import net.pterodactylus.util.config.Configuration;
+import net.pterodactylus.util.config.ConfigurationException;
 
+import com.google.common.base.Predicates;
 import com.google.common.eventbus.EventBus;
 
 /**
@@ -35,11 +45,33 @@ import com.google.common.eventbus.EventBus;
 public class Preferences {
 
        private final EventBus eventBus;
-       private final Options options;
-
-       public Preferences(EventBus eventBus, Options options) {
+       private final Option<Integer> insertionDelay =
+                       new DefaultOption<Integer>(60, range(0, MAX_VALUE));
+       private final Option<Integer> postsPerPage =
+                       new DefaultOption<Integer>(10, range(1, MAX_VALUE));
+       private final Option<Integer> imagesPerPage =
+                       new DefaultOption<Integer>(9, range(1, MAX_VALUE));
+       private final Option<Integer> charactersPerPost =
+                       new DefaultOption<Integer>(400, Predicates.<Integer>or(
+                                       range(50, MAX_VALUE), equalTo(-1)));
+       private final Option<Integer> postCutOffLength =
+                       new DefaultOption<Integer>(200, Predicates.<Integer>or(
+                                       range(50, MAX_VALUE), equalTo(-1)));
+       private final Option<Boolean> requireFullAccess =
+                       new DefaultOption<Boolean>(false);
+       private final Option<Integer> positiveTrust =
+                       new DefaultOption<Integer>(75, range(0, 100));
+       private final Option<Integer> negativeTrust =
+                       new DefaultOption<Integer>(-25, range(-100, 100));
+       private final Option<String> trustComment =
+                       new DefaultOption<String>("Set from Sone Web Interface");
+       private final Option<Boolean> activateFcpInterface =
+                       new DefaultOption<Boolean>(false);
+       private final Option<FullAccessRequired> fcpFullAccessRequired =
+                       new DefaultOption<FullAccessRequired>(ALWAYS);
+
+       public Preferences(EventBus eventBus) {
                this.eventBus = eventBus;
-               this.options = options;
        }
 
        /**
@@ -48,7 +80,7 @@ public class Preferences {
         * @return The insertion delay
         */
        public int getInsertionDelay() {
-               return options.getIntegerOption("InsertionDelay").get();
+               return insertionDelay.get();
        }
 
        /**
@@ -60,7 +92,7 @@ public class Preferences {
         *         {@code false} otherwise
         */
        public boolean validateInsertionDelay(Integer insertionDelay) {
-               return options.getIntegerOption("InsertionDelay").validate(insertionDelay);
+               return this.insertionDelay.validate(insertionDelay);
        }
 
        /**
@@ -72,7 +104,7 @@ public class Preferences {
         * @return This preferences
         */
        public Preferences setInsertionDelay(Integer insertionDelay) {
-               options.getIntegerOption("InsertionDelay").set(insertionDelay);
+               this.insertionDelay.set(insertionDelay);
                eventBus.post(new InsertionDelayChangedEvent(getInsertionDelay()));
                return this;
        }
@@ -83,7 +115,7 @@ public class Preferences {
         * @return The number of posts to show per page
         */
        public int getPostsPerPage() {
-               return options.getIntegerOption("PostsPerPage").get();
+               return postsPerPage.get();
        }
 
        /**
@@ -95,7 +127,7 @@ public class Preferences {
         *         {@code false} otherwise
         */
        public boolean validatePostsPerPage(Integer postsPerPage) {
-               return options.getIntegerOption("PostsPerPage").validate(postsPerPage);
+               return this.postsPerPage.validate(postsPerPage);
        }
 
        /**
@@ -106,7 +138,7 @@ public class Preferences {
         * @return This preferences object
         */
        public Preferences setPostsPerPage(Integer postsPerPage) {
-               options.getIntegerOption("PostsPerPage").set(postsPerPage);
+               this.postsPerPage.set(postsPerPage);
                return this;
        }
 
@@ -116,7 +148,7 @@ public class Preferences {
         * @return The number of images to show per page
         */
        public int getImagesPerPage() {
-               return options.getIntegerOption("ImagesPerPage").get();
+               return imagesPerPage.get();
        }
 
        /**
@@ -128,7 +160,7 @@ public class Preferences {
         *         {@code false} otherwise
         */
        public boolean validateImagesPerPage(Integer imagesPerPage) {
-               return options.getIntegerOption("ImagesPerPage").validate(imagesPerPage);
+               return this.imagesPerPage.validate(imagesPerPage);
        }
 
        /**
@@ -139,7 +171,7 @@ public class Preferences {
         * @return This preferences object
         */
        public Preferences setImagesPerPage(Integer imagesPerPage) {
-               options.getIntegerOption("ImagesPerPage").set(imagesPerPage);
+               this.imagesPerPage.set(imagesPerPage);
                return this;
        }
 
@@ -150,7 +182,7 @@ public class Preferences {
         * @return The numbers of characters per post
         */
        public int getCharactersPerPost() {
-               return options.getIntegerOption("CharactersPerPost").get();
+               return charactersPerPost.get();
        }
 
        /**
@@ -162,7 +194,7 @@ public class Preferences {
         *         {@code false} otherwise
         */
        public boolean validateCharactersPerPost(Integer charactersPerPost) {
-               return options.getIntegerOption("CharactersPerPost").validate(charactersPerPost);
+               return this.charactersPerPost.validate(charactersPerPost);
        }
 
        /**
@@ -174,7 +206,7 @@ public class Preferences {
         * @return This preferences objects
         */
        public Preferences setCharactersPerPost(Integer charactersPerPost) {
-               options.getIntegerOption("CharactersPerPost").set(charactersPerPost);
+               this.charactersPerPost.set(charactersPerPost);
                return this;
        }
 
@@ -184,7 +216,7 @@ public class Preferences {
         * @return The number of characters of the snippet
         */
        public int getPostCutOffLength() {
-               return options.getIntegerOption("PostCutOffLength").get();
+               return postCutOffLength.get();
        }
 
        /**
@@ -196,7 +228,7 @@ public class Preferences {
         *         valid, {@code false} otherwise
         */
        public boolean validatePostCutOffLength(Integer postCutOffLength) {
-               return options.getIntegerOption("PostCutOffLength").validate(postCutOffLength);
+               return this.postCutOffLength.validate(postCutOffLength);
        }
 
        /**
@@ -207,7 +239,7 @@ public class Preferences {
         * @return This preferences
         */
        public Preferences setPostCutOffLength(Integer postCutOffLength) {
-               options.getIntegerOption("PostCutOffLength").set(postCutOffLength);
+               this.postCutOffLength.set(postCutOffLength);
                return this;
        }
 
@@ -218,7 +250,7 @@ public class Preferences {
         *         otherwise
         */
        public boolean isRequireFullAccess() {
-               return options.getBooleanOption("RequireFullAccess").get();
+               return requireFullAccess.get();
        }
 
        /**
@@ -229,7 +261,7 @@ public class Preferences {
         *            otherwise
         */
        public void setRequireFullAccess(Boolean requireFullAccess) {
-               options.getBooleanOption("RequireFullAccess").set(requireFullAccess);
+               this.requireFullAccess.set(requireFullAccess);
        }
 
        /**
@@ -238,7 +270,7 @@ public class Preferences {
         * @return The positive trust
         */
        public int getPositiveTrust() {
-               return options.getIntegerOption("PositiveTrust").get();
+               return positiveTrust.get();
        }
 
        /**
@@ -250,7 +282,7 @@ public class Preferences {
         *         otherwise
         */
        public boolean validatePositiveTrust(Integer positiveTrust) {
-               return options.getIntegerOption("PositiveTrust").validate(positiveTrust);
+               return this.positiveTrust.validate(positiveTrust);
        }
 
        /**
@@ -262,7 +294,7 @@ public class Preferences {
         * @return This preferences
         */
        public Preferences setPositiveTrust(Integer positiveTrust) {
-               options.getIntegerOption("PositiveTrust").set(positiveTrust);
+               this.positiveTrust.set(positiveTrust);
                return this;
        }
 
@@ -272,7 +304,7 @@ public class Preferences {
         * @return The negative trust
         */
        public int getNegativeTrust() {
-               return options.getIntegerOption("NegativeTrust").get();
+               return negativeTrust.get();
        }
 
        /**
@@ -284,7 +316,7 @@ public class Preferences {
         *         otherwise
         */
        public boolean validateNegativeTrust(Integer negativeTrust) {
-               return options.getIntegerOption("NegativeTrust").validate(negativeTrust);
+               return this.negativeTrust.validate(negativeTrust);
        }
 
        /**
@@ -296,7 +328,7 @@ public class Preferences {
         * @return The preferences
         */
        public Preferences setNegativeTrust(Integer negativeTrust) {
-               options.getIntegerOption("NegativeTrust").set(negativeTrust);
+               this.negativeTrust.set(negativeTrust);
                return this;
        }
 
@@ -307,7 +339,7 @@ public class Preferences {
         * @return The trust comment
         */
        public String getTrustComment() {
-               return options.getStringOption("TrustComment").get();
+               return trustComment.get();
        }
 
        /**
@@ -319,7 +351,7 @@ public class Preferences {
         * @return This preferences
         */
        public Preferences setTrustComment(String trustComment) {
-               options.getStringOption("TrustComment").set(trustComment);
+               this.trustComment.set(trustComment);
                return this;
        }
 
@@ -332,7 +364,7 @@ public class Preferences {
         *         {@code false} otherwise
         */
        public boolean isFcpInterfaceActive() {
-               return options.getBooleanOption("ActivateFcpInterface").get();
+               return activateFcpInterface.get();
        }
 
        /**
@@ -345,9 +377,9 @@ public class Preferences {
         *            to deactivate the FCP interface
         * @return This preferences object
         */
-       public Preferences setFcpInterfaceActive(boolean fcpInterfaceActive) {
-               options.getBooleanOption("ActivateFcpInterface").set(fcpInterfaceActive);
-               if (fcpInterfaceActive) {
+       public Preferences setFcpInterfaceActive(Boolean fcpInterfaceActive) {
+               this.activateFcpInterface.set(fcpInterfaceActive);
+               if (isFcpInterfaceActive()) {
                        eventBus.post(new FcpInterfaceActivatedEvent());
                } else {
                        eventBus.post(new FcpInterfaceDeactivatedEvent());
@@ -363,7 +395,7 @@ public class Preferences {
         *         is required
         */
        public FullAccessRequired getFcpFullAccessRequired() {
-               return FullAccessRequired.values()[options.getIntegerOption("FcpFullAccessRequired").get()];
+               return fcpFullAccessRequired.get();
        }
 
        /**
@@ -374,10 +406,30 @@ public class Preferences {
         *            The action level
         * @return This preferences
         */
-       public Preferences setFcpFullAccessRequired(FullAccessRequired fcpFullAccessRequired) {
-               options.getIntegerOption("FcpFullAccessRequired").set((fcpFullAccessRequired != null) ? fcpFullAccessRequired.ordinal() : null);
-               eventBus.post(new FullAccessRequiredChanged(fcpFullAccessRequired));
+       public Preferences setFcpFullAccessRequired(
+                       FullAccessRequired fcpFullAccessRequired) {
+               this.fcpFullAccessRequired.set(fcpFullAccessRequired);
+               eventBus.post(new FullAccessRequiredChanged(getFcpFullAccessRequired()));
                return this;
        }
 
+       public void saveTo(Configuration configuration) throws ConfigurationException {
+               configuration.getIntValue("Option/ConfigurationVersion").setValue(0);
+               configuration.getIntValue("Option/InsertionDelay").setValue(insertionDelay.getReal());
+               configuration.getIntValue("Option/PostsPerPage").setValue(postsPerPage.getReal());
+               configuration.getIntValue("Option/ImagesPerPage").setValue(imagesPerPage.getReal());
+               configuration.getIntValue("Option/CharactersPerPost").setValue(charactersPerPost.getReal());
+               configuration.getIntValue("Option/PostCutOffLength").setValue(postCutOffLength.getReal());
+               configuration.getBooleanValue("Option/RequireFullAccess").setValue(requireFullAccess.getReal());
+               configuration.getIntValue("Option/PositiveTrust").setValue(positiveTrust.getReal());
+               configuration.getIntValue("Option/NegativeTrust").setValue(negativeTrust.getReal());
+               configuration.getStringValue("Option/TrustComment").setValue(trustComment.getReal());
+               configuration.getBooleanValue("Option/ActivateFcpInterface").setValue(activateFcpInterface.getReal());
+               configuration.getIntValue("Option/FcpFullAccessRequired").setValue(toInt(fcpFullAccessRequired.getReal()));
+       }
+
+       private Integer toInt(FullAccessRequired fullAccessRequired) {
+               return (fullAccessRequired == null) ? null : fullAccessRequired.ordinal();
+       }
+
 }
diff --git a/src/main/java/net/pterodactylus/sone/core/PreferencesLoader.java b/src/main/java/net/pterodactylus/sone/core/PreferencesLoader.java
new file mode 100644 (file)
index 0000000..6cc2e5e
--- /dev/null
@@ -0,0 +1,101 @@
+package net.pterodactylus.sone.core;
+
+import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired;
+import net.pterodactylus.util.config.Configuration;
+import net.pterodactylus.util.config.ConfigurationException;
+
+/**
+ * Loads preferences stored in a {@link Configuration} into a {@link
+ * Preferences} object.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class PreferencesLoader {
+
+       private final Preferences preferences;
+
+       public PreferencesLoader(Preferences preferences) {
+               this.preferences = preferences;
+       }
+
+       public void loadFrom(Configuration configuration) {
+               loadInsertionDelay(configuration);
+               loadPostsPerPage(configuration);
+               loadImagesPerPage(configuration);
+               loadCharactersPerPost(configuration);
+               loadPostCutOffLength(configuration);
+               loadRequireFullAccess(configuration);
+               loadPositiveTrust(configuration);
+               loadNegativeTrust(configuration);
+               loadTrustComment(configuration);
+               loadFcpInterfaceActive(configuration);
+               loadFcpFullAccessRequired(configuration);
+       }
+
+       private void loadInsertionDelay(Configuration configuration) {
+               preferences.setInsertionDelay(configuration.getIntValue(
+                               "Option/InsertionDelay").getValue(null));
+       }
+
+       private void loadPostsPerPage(Configuration configuration) {
+               preferences.setPostsPerPage(
+                               configuration.getIntValue("Option/PostsPerPage")
+                                               .getValue(null));
+       }
+
+       private void loadImagesPerPage(Configuration configuration) {
+               preferences.setImagesPerPage(
+                               configuration.getIntValue("Option/ImagesPerPage")
+                                               .getValue(null));
+       }
+
+       private void loadCharactersPerPost(Configuration configuration) {
+               preferences.setCharactersPerPost(
+                               configuration.getIntValue("Option/CharactersPerPost")
+                                               .getValue(null));
+       }
+
+       private void loadPostCutOffLength(Configuration configuration) {
+               preferences.setPostCutOffLength(
+                               configuration.getIntValue("Option/PostCutOffLength")
+                                               .getValue(null));
+       }
+
+       private void loadRequireFullAccess(Configuration configuration) {
+               preferences.setRequireFullAccess(
+                               configuration.getBooleanValue("Option/RequireFullAccess")
+                                               .getValue(null));
+       }
+
+       private void loadPositiveTrust(Configuration configuration) {
+               preferences.setPositiveTrust(
+                               configuration.getIntValue("Option/PositiveTrust")
+                                               .getValue(null));
+       }
+
+       private void loadNegativeTrust(Configuration configuration) {
+               preferences.setNegativeTrust(
+                               configuration.getIntValue("Option/NegativeTrust")
+                                               .getValue(null));
+       }
+
+       private void loadTrustComment(Configuration configuration) {
+               preferences.setTrustComment(
+                               configuration.getStringValue("Option/TrustComment")
+                                               .getValue(null));
+       }
+
+       private void loadFcpInterfaceActive(Configuration configuration) {
+               preferences.setFcpInterfaceActive(configuration.getBooleanValue(
+                               "Option/ActivateFcpInterface").getValue(null));
+       }
+
+       private void loadFcpFullAccessRequired(Configuration configuration) {
+               Integer fullAccessRequiredInteger = configuration
+                               .getIntValue("Option/FcpFullAccessRequired").getValue(null);
+               preferences.setFcpFullAccessRequired(
+                               (fullAccessRequiredInteger == null) ? null :
+                                               FullAccessRequired.values()[fullAccessRequiredInteger]);
+       }
+
+}
diff --git a/src/test/java/net/pterodactylus/sone/core/PreferencesLoaderTest.java b/src/test/java/net/pterodactylus/sone/core/PreferencesLoaderTest.java
new file mode 100644 (file)
index 0000000..91120fb
--- /dev/null
@@ -0,0 +1,73 @@
+package net.pterodactylus.sone.core;
+
+import static net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.WRITING;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import net.pterodactylus.sone.TestValue;
+import net.pterodactylus.util.config.Configuration;
+
+import com.google.common.eventbus.EventBus;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit test for {@link PreferencesLoader}.
+ *
+ * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
+ */
+public class PreferencesLoaderTest {
+
+       private final EventBus eventBus = mock(EventBus.class);
+       private final Preferences preferences = new Preferences(eventBus);
+       private final Configuration configuration = mock(Configuration.class);
+       private final PreferencesLoader preferencesLoader =
+                       new PreferencesLoader(preferences);
+
+       @Before
+       public void setupConfiguration() {
+               setupIntValue("InsertionDelay", 15);
+               setupIntValue("PostsPerPage", 25);
+               setupIntValue("ImagesPerPage", 12);
+               setupIntValue("CharactersPerPost", 150);
+               setupIntValue("PostCutOffLength", 300);
+               setupBooleanValue("RequireFullAccess", true);
+               setupIntValue("PositiveTrust", 50);
+               setupIntValue("NegativeTrust", -50);
+               when(configuration.getStringValue("Option/TrustComment")).thenReturn(
+                               new TestValue<String>("Trusted"));
+               setupBooleanValue("ActivateFcpInterface", true);
+               setupIntValue("FcpFullAccessRequired", 1);
+       }
+
+       private void setupIntValue(String optionName, int value) {
+               when(configuration.getIntValue("Option/" + optionName)).thenReturn(
+                               new TestValue<Integer>(value));
+       }
+
+       private void setupBooleanValue(String optionName, boolean value) {
+               when(configuration.getBooleanValue(
+                               "Option/" + optionName)).thenReturn(
+                               new TestValue<Boolean>(value));
+       }
+
+       @Test
+       public void configurationIsLoadedCorrectly() {
+               setupConfiguration();
+               preferencesLoader.loadFrom(configuration);
+               assertThat(preferences.getInsertionDelay(), is(15));
+               assertThat(preferences.getPostsPerPage(), is(25));
+               assertThat(preferences.getImagesPerPage(), is(12));
+               assertThat(preferences.getCharactersPerPost(), is(150));
+               assertThat(preferences.getPostCutOffLength(), is(300));
+               assertThat(preferences.isRequireFullAccess(), is(true));
+               assertThat(preferences.getPositiveTrust(), is(50));
+               assertThat(preferences.getNegativeTrust(), is(-50));
+               assertThat(preferences.getTrustComment(), is("Trusted"));
+               assertThat(preferences.isFcpInterfaceActive(), is(true));
+               assertThat(preferences.getFcpFullAccessRequired(), is(WRITING));
+       }
+
+}
index ad6bbea..cfa3495 100644 (file)
@@ -1,25 +1,23 @@
 package net.pterodactylus.sone.core;
 
 import static net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.ALWAYS;
+import static net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.NO;
+import static net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.WRITING;
 import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.instanceOf;
 import static org.hamcrest.Matchers.is;
-import static org.mockito.ArgumentCaptor.forClass;
 import static org.mockito.Matchers.any;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
 
 import net.pterodactylus.sone.core.event.InsertionDelayChangedEvent;
 import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired;
 import net.pterodactylus.sone.fcp.event.FcpInterfaceActivatedEvent;
 import net.pterodactylus.sone.fcp.event.FcpInterfaceDeactivatedEvent;
 import net.pterodactylus.sone.fcp.event.FullAccessRequiredChanged;
-import net.pterodactylus.sone.utils.Option;
 
 import com.google.common.eventbus.EventBus;
-import org.junit.Before;
+import org.junit.After;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
@@ -30,238 +28,279 @@ import org.mockito.ArgumentCaptor;
  */
 public class PreferencesTest {
 
-       private static final int INTEGER_VALUE = 1;
-       private static final String STRING_VALUE = "string-value";
-       private final Options options = mock(Options.class);
        private final EventBus eventBus = mock(EventBus.class);
-       private final Preferences preferences = new Preferences(eventBus, options);
-       private final Option<Integer> integerOption = when(mock(Option.class).get()).thenReturn(INTEGER_VALUE).getMock();
-       private final Option<Boolean> booleanOption = when(mock(Option.class).get()).thenReturn(true).getMock();
-       private final Option<String> stringOption = when(mock(Option.class).get()).thenReturn(STRING_VALUE).getMock();
+       private final Preferences preferences = new Preferences(eventBus);
 
-       @Before
-       public void setupOptions() {
-               when(integerOption.validate(INTEGER_VALUE)).thenReturn(true);
-               when(options.getIntegerOption("InsertionDelay")).thenReturn(integerOption);
-               when(options.getIntegerOption("PostsPerPage")).thenReturn(integerOption);
-               when(options.getIntegerOption("ImagesPerPage")).thenReturn(integerOption);
-               when(options.getIntegerOption("CharactersPerPost")).thenReturn(integerOption);
-               when(options.getIntegerOption("PostCutOffLength")).thenReturn(integerOption);
-               when(options.getBooleanOption("RequireFullAccess")).thenReturn(booleanOption);
-               when(options.getIntegerOption("PositiveTrust")).thenReturn(integerOption);
-               when(options.getIntegerOption("NegativeTrust")).thenReturn(integerOption);
-               when(options.getStringOption("TrustComment")).thenReturn(stringOption);
-               when(options.getBooleanOption("ActivateFcpInterface")).thenReturn(booleanOption);
-               when(options.getIntegerOption("FcpFullAccessRequired")).thenReturn(integerOption);
+       @After
+       public void tearDown() {
+               verifyNoMoreInteractions(eventBus);
        }
 
        @Test
-       public void testGettingInsertionDelay() {
-               assertThat(preferences.getInsertionDelay(), is(INTEGER_VALUE));
-               verify(integerOption).get();
+       public void preferencesRetainInsertionDelay() {
+               preferences.setInsertionDelay(15);
+               assertThat(preferences.getInsertionDelay(), is(15));
+               verify(eventBus).post(any(InsertionDelayChangedEvent.class));
        }
 
-       @Test
-       public void validationOfInsertionDelayIsForwardedToOptions() {
-               preferences.validateInsertionDelay(INTEGER_VALUE);
-               verify(integerOption).validate(INTEGER_VALUE);
+       @Test(expected = IllegalArgumentException.class)
+       public void invalidInsertionDelayIsRejected() {
+               preferences.setInsertionDelay(-15);
        }
 
        @Test
-       public void settingInsertionDelayIsForwardedToOptions() {
-               assertThat(preferences.setInsertionDelay(INTEGER_VALUE), instanceOf(Preferences.class));
-               verify(integerOption).set(INTEGER_VALUE);
+       public void preferencesReturnDefaultValueWhenInsertionDelayIsSetToNull() {
+               preferences.setInsertionDelay(null);
+               assertThat(preferences.getInsertionDelay(), is(60));
+               verify(eventBus).post(any(InsertionDelayChangedEvent.class));
        }
 
        @Test
-       public void settingInsertionDelayIsForwardedToEventBus() {
-               assertThat(preferences.setInsertionDelay(INTEGER_VALUE), instanceOf(Preferences.class));
-               verify(eventBus).post(any(InsertionDelayChangedEvent.class));
+       public void preferencesStartWithInsertionDelayDefaultValue() {
+               assertThat(preferences.getInsertionDelay(), is(60));
        }
 
        @Test
-       public void testGettingPostsPerPage() {
-               assertThat(preferences.getPostsPerPage(), is(INTEGER_VALUE));
-               verify(integerOption).get();
+       public void preferencesRetainPostsPerPage() {
+               preferences.setPostsPerPage(15);
+               assertThat(preferences.getPostsPerPage(), is(15));
+       }
+
+       @Test(expected = IllegalArgumentException.class)
+       public void invalidPostsPerPageIsRejected() {
+               preferences.setPostsPerPage(-15);
        }
 
        @Test
-       public void validationOfPostsPerPageIsForwardedToOptions() {
-               preferences.validatePostsPerPage(INTEGER_VALUE);
-               verify(integerOption).validate(INTEGER_VALUE);
+       public void preferencesReturnDefaultValueWhenPostsPerPageIsSetToNull() {
+               preferences.setPostsPerPage(null);
+               assertThat(preferences.getPostsPerPage(), is(10));
        }
 
        @Test
-       public void settingPostsPerPageIsForwardedToOptions() {
-               assertThat(preferences.setPostsPerPage(INTEGER_VALUE), instanceOf(Preferences.class));
-               verify(integerOption).set(INTEGER_VALUE);
+       public void preferencesStartWithPostsPerPageDefaultValue() {
+               assertThat(preferences.getPostsPerPage(), is(10));
        }
 
        @Test
-       public void testGettingImagesPerPage() {
-               assertThat(preferences.getImagesPerPage(), is(INTEGER_VALUE));
-               verify(integerOption).get();
+       public void preferencesRetainImagesPerPage() {
+               preferences.setImagesPerPage(15);
+               assertThat(preferences.getImagesPerPage(), is(15));
+       }
+
+       @Test(expected = IllegalArgumentException.class)
+       public void invalidImagesPerPageIsRejected() {
+               preferences.setImagesPerPage(-15);
        }
 
        @Test
-       public void validationOfImagesPerPageIsForwardedToOptions() {
-               preferences.validateImagesPerPage(INTEGER_VALUE);
-               verify(integerOption).validate(INTEGER_VALUE);
+       public void preferencesReturnDefaultValueWhenImagesPerPageIsSetToNull() {
+               preferences.setImagesPerPage(null);
+               assertThat(preferences.getImagesPerPage(), is(9));
        }
 
        @Test
-       public void settingImagesPerPageIsForwardedToOptions() {
-               assertThat(preferences.setImagesPerPage(INTEGER_VALUE), instanceOf(Preferences.class));
-               verify(integerOption).set(INTEGER_VALUE);
+       public void preferencesStartWithImagesPerPageDefaultValue() {
+               assertThat(preferences.getImagesPerPage(), is(9));
        }
 
        @Test
-       public void testGettingCharactersPerPost() {
-               assertThat(preferences.getCharactersPerPost(), is(INTEGER_VALUE));
-               verify(integerOption).get();
+       public void preferencesRetainCharactersPerPost() {
+               preferences.setCharactersPerPost(150);
+               assertThat(preferences.getCharactersPerPost(), is(150));
+       }
+
+       @Test(expected = IllegalArgumentException.class)
+       public void invalidCharactersPerPostIsRejected() {
+               preferences.setCharactersPerPost(-15);
        }
 
        @Test
-       public void validationOfCharactersPerPostIsForwardedToOptions() {
-               preferences.validateCharactersPerPost(INTEGER_VALUE);
-               verify(integerOption).validate(INTEGER_VALUE);
+       public void preferencesReturnDefaultValueWhenCharactersPerPostIsSetToNull() {
+               preferences.setCharactersPerPost(null);
+               assertThat(preferences.getCharactersPerPost(), is(400));
        }
 
        @Test
-       public void settingCharactersPerPostIsForwardedToOptions() {
-               assertThat(preferences.setCharactersPerPost(INTEGER_VALUE), instanceOf(Preferences.class));
-               verify(integerOption).set(INTEGER_VALUE);
+       public void preferencesStartWithCharactersPerPostDefaultValue() {
+               assertThat(preferences.getCharactersPerPost(), is(400));
        }
 
        @Test
-       public void testGettingPostCutOffLength() {
-               assertThat(preferences.getPostCutOffLength(), is(INTEGER_VALUE));
-               verify(integerOption).get();
+       public void preferencesRetainPostCutOffLength() {
+               preferences.setPostCutOffLength(150);
+               assertThat(preferences.getPostCutOffLength(), is(150));
+       }
+
+       @Test(expected = IllegalArgumentException.class)
+       public void invalidPostCutOffLengthIsRejected() {
+               preferences.setPostCutOffLength(-15);
        }
 
        @Test
-       public void validationOfPostCutOffLengthIsForwardedToOptions() {
-               preferences.validatePostCutOffLength(INTEGER_VALUE);
-               verify(integerOption).validate(INTEGER_VALUE);
+       public void preferencesReturnDefaultValueWhenPostCutOffLengthIsSetToNull() {
+               preferences.setPostCutOffLength(null);
+               assertThat(preferences.getPostCutOffLength(), is(200));
        }
 
        @Test
-       public void settingPostCutOffLengthIsForwardedToOptions() {
-               assertThat(preferences.setPostCutOffLength(INTEGER_VALUE), instanceOf(Preferences.class));
-               verify(integerOption).set(INTEGER_VALUE);
+       public void preferencesStartWithPostCutOffLengthDefaultValue() {
+               assertThat(preferences.getPostCutOffLength(), is(200));
        }
 
        @Test
-       public void testGettingRequireFullAccess() {
+       public void preferencesRetainRequireFullAccessOfTrue() {
+               preferences.setRequireFullAccess(true);
                assertThat(preferences.isRequireFullAccess(), is(true));
-               verify(booleanOption).get();
        }
 
        @Test
-       public void settingRequireFullAccessIsForwardedToOption() {
-               preferences.setRequireFullAccess(true);
-               verify(booleanOption).set(true);
+       public void preferencesRetainRequireFullAccessOfFalse() {
+               preferences.setRequireFullAccess(false);
+               assertThat(preferences.isRequireFullAccess(), is(false));
        }
 
        @Test
-       public void testGettingPositiveTrust() {
-               assertThat(preferences.getPositiveTrust(), is(INTEGER_VALUE));
-               verify(integerOption).get();
+       public void preferencesReturnDefaultValueWhenRequireFullAccessIsSetToNull() {
+               preferences.setRequireFullAccess(null);
+               assertThat(preferences.isRequireFullAccess(), is(false));
        }
 
        @Test
-       public void validationOfPositiveTrustIsForwardedToOptions() {
-               preferences.validatePositiveTrust(INTEGER_VALUE);
-               verify(integerOption).validate(INTEGER_VALUE);
+       public void preferencesStartWithRequireFullAccessDefaultValue() {
+               assertThat(preferences.isRequireFullAccess(), is(false));
        }
 
        @Test
-       public void settingPositiveTrustIsForwardedToOptions() {
-               assertThat(preferences.setPositiveTrust(INTEGER_VALUE), instanceOf(Preferences.class));
-               verify(integerOption).set(INTEGER_VALUE);
+       public void preferencesRetainPositiveTrust() {
+               preferences.setPositiveTrust(15);
+               assertThat(preferences.getPositiveTrust(), is(15));
+       }
+
+       @Test(expected = IllegalArgumentException.class)
+       public void invalidPositiveTrustIsRejected() {
+               preferences.setPositiveTrust(-15);
        }
 
        @Test
-       public void testGettingNegativeTrust() {
-               assertThat(preferences.getNegativeTrust(), is(INTEGER_VALUE));
-               verify(integerOption).get();
+       public void preferencesReturnDefaultValueWhenPositiveTrustIsSetToNull() {
+               preferences.setPositiveTrust(null);
+               assertThat(preferences.getPositiveTrust(), is(75));
        }
 
        @Test
-       public void validationOfNegativeTrustIsForwardedToOptions() {
-               preferences.validateNegativeTrust(INTEGER_VALUE);
-               verify(integerOption).validate(INTEGER_VALUE);
+       public void preferencesStartWithPositiveTrustDefaultValue() {
+               assertThat(preferences.getPositiveTrust(), is(75));
        }
 
        @Test
-       public void settingNegativeTrustIsForwardedToOptions() {
-               assertThat(preferences.setNegativeTrust(INTEGER_VALUE), instanceOf(Preferences.class));
-               verify(integerOption).set(INTEGER_VALUE);
+       public void preferencesRetainNegativeTrust() {
+               preferences.setNegativeTrust(-15);
+               assertThat(preferences.getNegativeTrust(), is(-15));
+       }
+
+       @Test(expected = IllegalArgumentException.class)
+       public void invalidNegativeTrustIsRejected() {
+               preferences.setNegativeTrust(150);
        }
 
        @Test
-       public void gettingTrustCommentIsForwardedToOption() {
-               assertThat(preferences.getTrustComment(), is(STRING_VALUE));
-               verify(stringOption).get();
+       public void preferencesReturnDefaultValueWhenNegativeTrustIsSetToNull() {
+               preferences.setNegativeTrust(null);
+               assertThat(preferences.getNegativeTrust(), is(-25));
        }
 
        @Test
-       public void settingTrustCommentIsForwardedToOption() {
-               preferences.setTrustComment(STRING_VALUE);
-               verify(stringOption).set(STRING_VALUE);
+       public void preferencesStartWithNegativeTrustDefaultValue() {
+               assertThat(preferences.getNegativeTrust(), is(-25));
        }
 
        @Test
-       public void gettingFcpInterfaceActiveIsForwardedToOption() {
-               assertThat(preferences.isFcpInterfaceActive(), is(true));
-               verify(booleanOption).get();
+       public void preferencesRetainTrustComment() {
+               preferences.setTrustComment("Trust");
+               assertThat(preferences.getTrustComment(), is("Trust"));
        }
 
        @Test
-       public void settingFcpInterfaceActiveIsForwardedToEventBus() {
-           preferences.setFcpInterfaceActive(true);
+       public void preferencesReturnDefaultValueWhenTrustCommentIsSetToNull() {
+               preferences.setTrustComment(null);
+               assertThat(preferences.getTrustComment(),
+                               is("Set from Sone Web Interface"));
+       }
+
+       @Test
+       public void preferencesStartWithTrustCommentDefaultValue() {
+               assertThat(preferences.getTrustComment(),
+                               is("Set from Sone Web Interface"));
+       }
+
+       @Test
+       public void preferencesRetainFcpInterfaceActiveOfTrue() {
+               preferences.setFcpInterfaceActive(true);
+               assertThat(preferences.isFcpInterfaceActive(), is(true));
                verify(eventBus).post(any(FcpInterfaceActivatedEvent.class));
-               verifyNoMoreInteractions(eventBus);
        }
 
        @Test
-       public void settingFcpInterfaceInactiveIsForwardedToEventBus() {
-           preferences.setFcpInterfaceActive(false);
+       public void preferencesRetainFcpInterfaceActiveOfFalse() {
+               preferences.setFcpInterfaceActive(false);
+               assertThat(preferences.isFcpInterfaceActive(), is(false));
                verify(eventBus).post(any(FcpInterfaceDeactivatedEvent.class));
-               verifyNoMoreInteractions(eventBus);
        }
 
        @Test
-       public void settingFcpInterfaceActiveIsForwardedToOption() {
-               preferences.setFcpInterfaceActive(true);
-               verify(booleanOption).set(true);
+       public void preferencesReturnDefaultValueWhenFcpInterfaceActiveIsSetToNull() {
+               preferences.setFcpInterfaceActive(null);
+               assertThat(preferences.isFcpInterfaceActive(), is(false));
+               verify(eventBus).post(any(FcpInterfaceDeactivatedEvent.class));
+       }
+
+       @Test
+       public void preferencesStartWithFcpInterfaceActiveDefaultValue() {
+               assertThat(preferences.isFcpInterfaceActive(), is(false));
+       }
+
+       @Test
+       public void preferencesRetainFcpFullAccessRequiredOfNo() {
+               preferences.setFcpFullAccessRequired(NO);
+               assertThat(preferences.getFcpFullAccessRequired(), is(NO));
+               verifyFullAccessRequiredChangedEvent(NO);
+       }
+
+       private void verifyFullAccessRequiredChangedEvent(
+                       FullAccessRequired fullAccessRequired) {
+               ArgumentCaptor<FullAccessRequiredChanged> fullAccessRequiredCaptor =
+                               ArgumentCaptor.forClass(FullAccessRequiredChanged.class);
+               verify(eventBus).post(fullAccessRequiredCaptor.capture());
+               assertThat(
+                               fullAccessRequiredCaptor.getValue().getFullAccessRequired(),
+                               is(fullAccessRequired));
        }
 
        @Test
-       public void gettingFcpFullAccessRequired() {
-               assertThat(preferences.getFcpFullAccessRequired(), is(FullAccessRequired.values()[INTEGER_VALUE]));
-               verify(integerOption).get();
+       public void preferencesRetainFcpFullAccessRequiredOfWriting() {
+               preferences.setFcpFullAccessRequired(WRITING);
+               assertThat(preferences.getFcpFullAccessRequired(), is(WRITING));
+               verifyFullAccessRequiredChangedEvent(WRITING);
        }
 
        @Test
-       public void settingFcpFullAccessRequiredIsForwardedToOption() {
+       public void preferencesRetainFcpFullAccessRequiredOfAlways() {
                preferences.setFcpFullAccessRequired(ALWAYS);
-               verify(integerOption).set(ALWAYS.ordinal());
+               assertThat(preferences.getFcpFullAccessRequired(), is(ALWAYS));
+               verifyFullAccessRequiredChangedEvent(ALWAYS);
        }
 
        @Test
-       public void settingFcpFullAccessRequiredToNullIsForwardedToOption() {
+       public void preferencesReturnDefaultValueWhenFcpFullAccessRequiredIsSetToNull() {
                preferences.setFcpFullAccessRequired(null);
-               verify(integerOption).set(null);
+               assertThat(preferences.getFcpFullAccessRequired(), is(ALWAYS));
+               verifyFullAccessRequiredChangedEvent(ALWAYS);
        }
 
        @Test
-       public void settingFcpFullAccessRequiredIsForwardedToEventBus() {
-               preferences.setFcpFullAccessRequired(ALWAYS);
-               verify(integerOption).set(2);
-               ArgumentCaptor<FullAccessRequiredChanged> fullAccessRequiredChangedCaptor = forClass(FullAccessRequiredChanged.class);
-               verify(eventBus).post(fullAccessRequiredChangedCaptor.capture());
-               assertThat(fullAccessRequiredChangedCaptor.getValue().getFullAccessRequired(), is(ALWAYS));
+       public void preferencesStartWithFcpFullAccessRequiredDefaultValue() {
+               assertThat(preferences.getFcpFullAccessRequired(), is(ALWAYS));
        }
 
 }