Send generic “preference changed” event when changing insertion delay
[Sone.git] / src / main / java / net / pterodactylus / sone / core / Preferences.java
1 /*
2  * Sone - Preferences.java - Copyright © 2013–2016 David Roden
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 package net.pterodactylus.sone.core;
19
20 import static com.google.common.base.Predicates.equalTo;
21 import static java.lang.Integer.MAX_VALUE;
22 import static net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired.ALWAYS;
23 import static net.pterodactylus.sone.utils.IntegerRangePredicate.range;
24
25 import net.pterodactylus.sone.core.event.InsertionDelayChangedEvent;
26 import net.pterodactylus.sone.fcp.FcpInterface;
27 import net.pterodactylus.sone.fcp.FcpInterface.FullAccessRequired;
28 import net.pterodactylus.sone.fcp.event.FcpInterfaceActivatedEvent;
29 import net.pterodactylus.sone.fcp.event.FcpInterfaceDeactivatedEvent;
30 import net.pterodactylus.sone.fcp.event.FullAccessRequiredChanged;
31 import net.pterodactylus.sone.utils.DefaultOption;
32 import net.pterodactylus.sone.utils.Option;
33 import net.pterodactylus.util.config.Configuration;
34 import net.pterodactylus.util.config.ConfigurationException;
35
36 import com.google.common.base.Predicates;
37 import com.google.common.eventbus.EventBus;
38
39 /**
40  * Convenience interface for external classes that want to access the core’s
41  * configuration.
42  */
43 public class Preferences {
44
45         private final EventBus eventBus;
46         private final Option<Integer> insertionDelay =
47                         new DefaultOption<Integer>(60, range(0, MAX_VALUE));
48         private final Option<Integer> postsPerPage =
49                         new DefaultOption<Integer>(10, range(1, MAX_VALUE));
50         private final Option<Integer> imagesPerPage =
51                         new DefaultOption<Integer>(9, range(1, MAX_VALUE));
52         private final Option<Integer> charactersPerPost =
53                         new DefaultOption<Integer>(400, Predicates.<Integer>or(
54                                         range(50, MAX_VALUE), equalTo(-1)));
55         private final Option<Integer> postCutOffLength =
56                         new DefaultOption<Integer>(200, range(50, MAX_VALUE));
57         private final Option<Boolean> requireFullAccess =
58                         new DefaultOption<Boolean>(false);
59         private final Option<Integer> positiveTrust =
60                         new DefaultOption<Integer>(75, range(0, 100));
61         private final Option<Integer> negativeTrust =
62                         new DefaultOption<Integer>(-25, range(-100, 100));
63         private final Option<String> trustComment =
64                         new DefaultOption<String>("Set from Sone Web Interface");
65         private final Option<Boolean> activateFcpInterface =
66                         new DefaultOption<Boolean>(false);
67         private final Option<FullAccessRequired> fcpFullAccessRequired =
68                         new DefaultOption<FullAccessRequired>(ALWAYS);
69
70         public Preferences(EventBus eventBus) {
71                 this.eventBus = eventBus;
72         }
73
74         /**
75          * Returns the insertion delay.
76          *
77          * @return The insertion delay
78          */
79         public int getInsertionDelay() {
80                 return insertionDelay.get();
81         }
82
83         /**
84          * Validates the given insertion delay.
85          *
86          * @param insertionDelay
87          *            The insertion delay to validate
88          * @return {@code true} if the given insertion delay was valid,
89          *         {@code false} otherwise
90          */
91         public boolean validateInsertionDelay(Integer insertionDelay) {
92                 return this.insertionDelay.validate(insertionDelay);
93         }
94
95         /**
96          * Sets the insertion delay
97          *
98          * @param insertionDelay
99          *            The new insertion delay, or {@code null} to restore it to
100          *            the default value
101          * @return This preferences
102          */
103         public Preferences setInsertionDelay(Integer insertionDelay) {
104                 this.insertionDelay.set(insertionDelay);
105                 eventBus.post(new InsertionDelayChangedEvent(getInsertionDelay()));
106                 eventBus.post(new PreferenceChangedEvent("InsertionDelay", getInsertionDelay()));
107                 return this;
108         }
109
110         /**
111          * Returns the number of posts to show per page.
112          *
113          * @return The number of posts to show per page
114          */
115         public int getPostsPerPage() {
116                 return postsPerPage.get();
117         }
118
119         /**
120          * Validates the number of posts per page.
121          *
122          * @param postsPerPage
123          *            The number of posts per page
124          * @return {@code true} if the number of posts per page was valid,
125          *         {@code false} otherwise
126          */
127         public boolean validatePostsPerPage(Integer postsPerPage) {
128                 return this.postsPerPage.validate(postsPerPage);
129         }
130
131         /**
132          * Sets the number of posts to show per page.
133          *
134          * @param postsPerPage
135          *            The number of posts to show per page
136          * @return This preferences object
137          */
138         public Preferences setPostsPerPage(Integer postsPerPage) {
139                 this.postsPerPage.set(postsPerPage);
140                 return this;
141         }
142
143         /**
144          * Returns the number of images to show per page.
145          *
146          * @return The number of images to show per page
147          */
148         public int getImagesPerPage() {
149                 return imagesPerPage.get();
150         }
151
152         /**
153          * Validates the number of images per page.
154          *
155          * @param imagesPerPage
156          *            The number of images per page
157          * @return {@code true} if the number of images per page was valid,
158          *         {@code false} otherwise
159          */
160         public boolean validateImagesPerPage(Integer imagesPerPage) {
161                 return this.imagesPerPage.validate(imagesPerPage);
162         }
163
164         /**
165          * Sets the number of images per page.
166          *
167          * @param imagesPerPage
168          *            The number of images per page
169          * @return This preferences object
170          */
171         public Preferences setImagesPerPage(Integer imagesPerPage) {
172                 this.imagesPerPage.set(imagesPerPage);
173                 return this;
174         }
175
176         /**
177          * Returns the number of characters per post, or <code>-1</code> if the
178          * posts should not be cut off.
179          *
180          * @return The numbers of characters per post
181          */
182         public int getCharactersPerPost() {
183                 return charactersPerPost.get();
184         }
185
186         /**
187          * Validates the number of characters per post.
188          *
189          * @param charactersPerPost
190          *            The number of characters per post
191          * @return {@code true} if the number of characters per post was valid,
192          *         {@code false} otherwise
193          */
194         public boolean validateCharactersPerPost(Integer charactersPerPost) {
195                 return this.charactersPerPost.validate(charactersPerPost);
196         }
197
198         /**
199          * Sets the number of characters per post.
200          *
201          * @param charactersPerPost
202          *            The number of characters per post, or <code>-1</code> to
203          *            not cut off the posts
204          * @return This preferences objects
205          */
206         public Preferences setCharactersPerPost(Integer charactersPerPost) {
207                 this.charactersPerPost.set(charactersPerPost);
208                 return this;
209         }
210
211         /**
212          * Returns the number of characters the shortened post should have.
213          *
214          * @return The number of characters of the snippet
215          */
216         public int getPostCutOffLength() {
217                 return postCutOffLength.get();
218         }
219
220         /**
221          * Validates the number of characters after which to cut off the post.
222          *
223          * @param postCutOffLength
224          *            The number of characters of the snippet
225          * @return {@code true} if the number of characters of the snippet is
226          *         valid, {@code false} otherwise
227          */
228         public boolean validatePostCutOffLength(Integer postCutOffLength) {
229                 return this.postCutOffLength.validate(postCutOffLength);
230         }
231
232         /**
233          * Sets the number of characters the shortened post should have.
234          *
235          * @param postCutOffLength
236          *            The number of characters of the snippet
237          * @return This preferences
238          */
239         public Preferences setPostCutOffLength(Integer postCutOffLength) {
240                 this.postCutOffLength.set(postCutOffLength);
241                 return this;
242         }
243
244         /**
245          * Returns whether Sone requires full access to be even visible.
246          *
247          * @return {@code true} if Sone requires full access, {@code false}
248          *         otherwise
249          */
250         public boolean isRequireFullAccess() {
251                 return requireFullAccess.get();
252         }
253
254         /**
255          * Sets whether Sone requires full access to be even visible.
256          *
257          * @param requireFullAccess
258          *            {@code true} if Sone requires full access, {@code false}
259          *            otherwise
260          */
261         public void setRequireFullAccess(Boolean requireFullAccess) {
262                 this.requireFullAccess.set(requireFullAccess);
263         }
264
265         /**
266          * Returns the positive trust.
267          *
268          * @return The positive trust
269          */
270         public int getPositiveTrust() {
271                 return positiveTrust.get();
272         }
273
274         /**
275          * Validates the positive trust.
276          *
277          * @param positiveTrust
278          *            The positive trust to validate
279          * @return {@code true} if the positive trust was valid, {@code false}
280          *         otherwise
281          */
282         public boolean validatePositiveTrust(Integer positiveTrust) {
283                 return this.positiveTrust.validate(positiveTrust);
284         }
285
286         /**
287          * Sets the positive trust.
288          *
289          * @param positiveTrust
290          *            The new positive trust, or {@code null} to restore it to
291          *            the default vlaue
292          * @return This preferences
293          */
294         public Preferences setPositiveTrust(Integer positiveTrust) {
295                 this.positiveTrust.set(positiveTrust);
296                 return this;
297         }
298
299         /**
300          * Returns the negative trust.
301          *
302          * @return The negative trust
303          */
304         public int getNegativeTrust() {
305                 return negativeTrust.get();
306         }
307
308         /**
309          * Validates the negative trust.
310          *
311          * @param negativeTrust
312          *            The negative trust to validate
313          * @return {@code true} if the negative trust was valid, {@code false}
314          *         otherwise
315          */
316         public boolean validateNegativeTrust(Integer negativeTrust) {
317                 return this.negativeTrust.validate(negativeTrust);
318         }
319
320         /**
321          * Sets the negative trust.
322          *
323          * @param negativeTrust
324          *            The negative trust, or {@code null} to restore it to the
325          *            default value
326          * @return The preferences
327          */
328         public Preferences setNegativeTrust(Integer negativeTrust) {
329                 this.negativeTrust.set(negativeTrust);
330                 return this;
331         }
332
333         /**
334          * Returns the trust comment. This is the comment that is set in the web
335          * of trust when a trust value is assigned to an identity.
336          *
337          * @return The trust comment
338          */
339         public String getTrustComment() {
340                 return trustComment.get();
341         }
342
343         /**
344          * Sets the trust comment.
345          *
346          * @param trustComment
347          *            The trust comment, or {@code null} to restore it to the
348          *            default value
349          * @return This preferences
350          */
351         public Preferences setTrustComment(String trustComment) {
352                 this.trustComment.set(trustComment);
353                 return this;
354         }
355
356         /**
357          * Returns whether the {@link FcpInterface FCP interface} is currently
358          * active.
359          *
360          * @see FcpInterface#setActive(boolean)
361          * @return {@code true} if the FCP interface is currently active,
362          *         {@code false} otherwise
363          */
364         public boolean isFcpInterfaceActive() {
365                 return activateFcpInterface.get();
366         }
367
368         /**
369          * Sets whether the {@link FcpInterface FCP interface} is currently
370          * active.
371          *
372          * @see FcpInterface#setActive(boolean)
373          * @param fcpInterfaceActive
374          *            {@code true} to activate the FCP interface, {@code false}
375          *            to deactivate the FCP interface
376          * @return This preferences object
377          */
378         public Preferences setFcpInterfaceActive(Boolean fcpInterfaceActive) {
379                 this.activateFcpInterface.set(fcpInterfaceActive);
380                 if (isFcpInterfaceActive()) {
381                         eventBus.post(new FcpInterfaceActivatedEvent());
382                 } else {
383                         eventBus.post(new FcpInterfaceDeactivatedEvent());
384                 }
385                 return this;
386         }
387
388         /**
389          * Returns the action level for which full access to the FCP interface
390          * is required.
391          *
392          * @return The action level for which full access to the FCP interface
393          *         is required
394          */
395         public FullAccessRequired getFcpFullAccessRequired() {
396                 return fcpFullAccessRequired.get();
397         }
398
399         /**
400          * Sets the action level for which full access to the FCP interface is
401          * required
402          *
403          * @param fcpFullAccessRequired
404          *            The action level
405          * @return This preferences
406          */
407         public Preferences setFcpFullAccessRequired(
408                         FullAccessRequired fcpFullAccessRequired) {
409                 this.fcpFullAccessRequired.set(fcpFullAccessRequired);
410                 eventBus.post(new FullAccessRequiredChanged(getFcpFullAccessRequired()));
411                 return this;
412         }
413
414         public void saveTo(Configuration configuration) throws ConfigurationException {
415                 configuration.getIntValue("Option/ConfigurationVersion").setValue(0);
416                 configuration.getIntValue("Option/InsertionDelay").setValue(insertionDelay.getReal());
417                 configuration.getIntValue("Option/PostsPerPage").setValue(postsPerPage.getReal());
418                 configuration.getIntValue("Option/ImagesPerPage").setValue(imagesPerPage.getReal());
419                 configuration.getIntValue("Option/CharactersPerPost").setValue(charactersPerPost.getReal());
420                 configuration.getIntValue("Option/PostCutOffLength").setValue(postCutOffLength.getReal());
421                 configuration.getBooleanValue("Option/RequireFullAccess").setValue(requireFullAccess.getReal());
422                 configuration.getIntValue("Option/PositiveTrust").setValue(positiveTrust.getReal());
423                 configuration.getIntValue("Option/NegativeTrust").setValue(negativeTrust.getReal());
424                 configuration.getStringValue("Option/TrustComment").setValue(trustComment.getReal());
425                 configuration.getBooleanValue("Option/ActivateFcpInterface").setValue(activateFcpInterface.getReal());
426                 configuration.getIntValue("Option/FcpFullAccessRequired").setValue(toInt(fcpFullAccessRequired.getReal()));
427         }
428
429         private Integer toInt(FullAccessRequired fullAccessRequired) {
430                 return (fullAccessRequired == null) ? null : fullAccessRequired.ordinal();
431         }
432
433 }