Add boolean options.
[Sone.git] / src / main / java / net / pterodactylus / sone / core / Options.java
1 package net.pterodactylus.sone.core;
2
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.HashMap;
6 import java.util.List;
7 import java.util.Map;
8
9 /**
10  * Stores various options that influence Sone’s behaviour.
11  *
12  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
13  */
14 public class Options {
15
16         /**
17          * Contains current and default value of an option.
18          *
19          * @param <T>
20          *            The type of the option
21          * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
22          */
23         public static interface Option<T> {
24
25                 /**
26                  * Returns the default value of the option.
27                  *
28                  * @return The default value of the option
29                  */
30                 public T getDefault();
31
32                 /**
33                  * Returns the current value of the option. If the current value is not
34                  * set (usually {@code null}), the default value is returned.
35                  *
36                  * @return The current value of the option
37                  */
38                 public T get();
39
40                 /**
41                  * Returns the real value of the option. This will also return an unset
42                  * value (usually {@code null})!
43                  *
44                  * @return The real value of the option
45                  */
46                 public T getReal();
47
48                 /**
49                  * Sets the current value of the option.
50                  *
51                  * @param value
52                  *            The new value of the option
53                  */
54                 public void set(T value);
55
56         }
57
58         /**
59          * Interface for objects that want to be notified when an option changes its
60          * value.
61          *
62          * @param <T>
63          *            The type of the option
64          * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
65          */
66         public static interface OptionWatcher<T> {
67
68                 /**
69                  * Notifies an object that an option has been changed.
70                  *
71                  * @param option
72                  *            The option that has changed
73                  * @param oldValue
74                  *            The old value of the option
75                  * @param newValue
76                  *            The new value of the option
77                  */
78                 public void optionChanged(Option<T> option, T oldValue, T newValue);
79
80         }
81
82         /**
83          * Basic implementation of an {@link Option} that notifies an
84          * {@link OptionWatcher} if the value changes.
85          *
86          * @param <T>
87          *            The type of the option
88          * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
89          */
90         public static class DefaultOption<T> implements Option<T> {
91
92                 /** The default value. */
93                 private final T defaultValue;
94
95                 /** The current value. */
96                 private T value;
97
98                 /** The option watcher. */
99                 private final List<OptionWatcher<T>> optionWatchers = new ArrayList<OptionWatcher<T>>();
100
101                 /**
102                  * Creates a new default option.
103                  *
104                  * @param defaultValue
105                  *            The default value of the option
106                  * @param optionWatchers
107                  *            The option watchers
108                  */
109                 public DefaultOption(T defaultValue, OptionWatcher<T>... optionWatchers) {
110                         this.defaultValue = defaultValue;
111                         this.optionWatchers.addAll(Arrays.asList(optionWatchers));
112                 }
113
114                 /**
115                  * {@inheritDoc}
116                  */
117                 @Override
118                 public T getDefault() {
119                         return defaultValue;
120                 }
121
122                 /**
123                  * {@inheritDoc}
124                  */
125                 @Override
126                 public T get() {
127                         return (value != null) ? value : defaultValue;
128                 }
129
130                 /**
131                  * Returns the real value of the option. This will also return an unset
132                  * value (usually {@code null})!
133                  *
134                  * @return The real value of the option
135                  */
136                 @Override
137                 public T getReal() {
138                         return value;
139                 }
140
141                 /**
142                  * {@inheritDoc}
143                  */
144                 @Override
145                 public void set(T value) {
146                         T oldValue = this.value;
147                         this.value = value;
148                         if (!get().equals(oldValue)) {
149                                 for (OptionWatcher<T> optionWatcher : optionWatchers) {
150                                         optionWatcher.optionChanged(this, oldValue, get());
151                                 }
152                         }
153                 }
154
155         }
156
157         /** Holds all {@link Boolean} {@link Option}s. */
158         private final Map<String, Option<Boolean>> booleanOptions = new HashMap<String, Option<Boolean>>();
159
160         /** Holds all {@link Integer} {@link Option}s. */
161         private final Map<String, Option<Integer>> integerOptions = new HashMap<String, Option<Integer>>();
162
163         /**
164          * Adds a boolean option.
165          *
166          * @param name
167          *            The name of the option
168          * @param booleanOption
169          *            The option
170          * @return The given option
171          */
172         public Option<Boolean> addBooleanOption(String name, Option<Boolean> booleanOption) {
173                 booleanOptions.put(name, booleanOption);
174                 return booleanOption;
175         }
176
177         /**
178          * Returns the boolean option with the given name.
179          *
180          * @param name
181          *            The name of the option
182          * @return The option, or {@code null} if there is no option with the given
183          *         name
184          */
185         public Option<Boolean> getBooleanOption(String name) {
186                 return booleanOptions.get(name);
187         }
188
189         /**
190          * Adds an {@link Integer} {@link Option}.
191          *
192          * @param name
193          *            The name of the option
194          * @param integerOption
195          *            The option
196          * @return The given option
197          */
198         public Option<Integer> addIntegerOption(String name, Option<Integer> integerOption) {
199                 integerOptions.put(name, integerOption);
200                 return integerOption;
201         }
202
203         /**
204          * Returns an {@link Integer} {@link Option}.
205          *
206          * @param name
207          *            The name of the integer option to get
208          * @return The integer option, or {@code null} if there is no option with
209          *         the given name
210          */
211         public Option<Integer> getIntegerOption(String name) {
212                 return integerOptions.get(name);
213         }
214
215 }