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