1 package net.pterodactylus.sone.core;
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collections;
6 import java.util.HashMap;
11 * Stores various options that influence Sone’s behaviour.
13 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
15 public class Options {
18 * Contains current and default value of an option.
21 * The type of the option
22 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
24 public static interface Option<T> {
27 * Returns the default value of the option.
29 * @return The default value of the option
31 public T getDefault();
34 * Returns the current value of the option. If the current value is not
35 * set (usually {@code null}), the default value is returned.
37 * @return The current value of the option
42 * Returns the real value of the option. This will also return an unset
43 * value (usually {@code null})!
45 * @return The real value of the option
50 * Sets the current value of the option.
53 * The new value of the option
55 public void set(T value);
60 * Interface for objects that want to be notified when an option changes its
64 * The type of the option
65 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
67 public static interface OptionWatcher<T> {
70 * Notifies an object that an option has been changed.
73 * The option that has changed
75 * The old value of the option
77 * The new value of the option
79 public void optionChanged(Option<T> option, T oldValue, T newValue);
84 * Basic implementation of an {@link Option} that notifies an
85 * {@link OptionWatcher} if the value changes.
88 * The type of the option
89 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
91 public static class DefaultOption<T> implements Option<T> {
93 /** The default value. */
94 private final T defaultValue;
96 /** The current value. */
97 private volatile T value;
99 /** The option watcher. */
100 private final List<OptionWatcher<T>> optionWatchers = new ArrayList<OptionWatcher<T>>();
103 * Creates a new default option.
105 * @param defaultValue
106 * The default value of the option
107 * @param optionWatchers
108 * The option watchers
110 public DefaultOption(T defaultValue, OptionWatcher<T>... optionWatchers) {
111 this.defaultValue = defaultValue;
112 this.optionWatchers.addAll(Arrays.asList(optionWatchers));
119 public T getDefault() {
128 return (value != null) ? value : defaultValue;
132 * Returns the real value of the option. This will also return an unset
133 * value (usually {@code null})!
135 * @return The real value of the option
146 public void set(T value) {
147 T oldValue = this.value;
149 if (!get().equals(oldValue)) {
150 for (OptionWatcher<T> optionWatcher : optionWatchers) {
151 optionWatcher.optionChanged(this, oldValue, get());
158 /** Holds all {@link Boolean} {@link Option}s. */
159 private final Map<String, Option<Boolean>> booleanOptions = Collections.synchronizedMap(new HashMap<String, Option<Boolean>>());
161 /** Holds all {@link Integer} {@link Option}s. */
162 private final Map<String, Option<Integer>> integerOptions = Collections.synchronizedMap(new HashMap<String, Option<Integer>>());
164 /** Holds all {@link String} {@link Option}s. */
165 private final Map<String, Option<String>> stringOptions = Collections.synchronizedMap(new HashMap<String, Option<String>>());
168 * Adds a boolean option.
171 * The name of the option
172 * @param booleanOption
174 * @return The given option
176 public Option<Boolean> addBooleanOption(String name, Option<Boolean> booleanOption) {
177 booleanOptions.put(name, booleanOption);
178 return booleanOption;
182 * Returns the boolean option with the given name.
185 * The name of the option
186 * @return The option, or {@code null} if there is no option with the given
189 public Option<Boolean> getBooleanOption(String name) {
190 return booleanOptions.get(name);
194 * Adds an {@link Integer} {@link Option}.
197 * The name of the option
198 * @param integerOption
200 * @return The given option
202 public Option<Integer> addIntegerOption(String name, Option<Integer> integerOption) {
203 integerOptions.put(name, integerOption);
204 return integerOption;
208 * Returns an {@link Integer} {@link Option}.
211 * The name of the integer option to get
212 * @return The integer option, or {@code null} if there is no option with
215 public Option<Integer> getIntegerOption(String name) {
216 return integerOptions.get(name);
220 * Adds a {@link String} {@link Option}.
223 * The name of the option
224 * @param stringOption
226 * @return The given option
228 public Option<String> addStringOption(String name, Option<String> stringOption) {
229 stringOptions.put(name, stringOption);
234 * Returns a {@link String} {@link Option}.
237 * The name of the string option to get
238 * @return The string option, or {@code null} if there is no option with the
241 public Option<String> getStringOption(String name) {
242 return stringOptions.get(name);