1   /**
2    * Distribution License:
3    * JSword is free software; you can redistribute it and/or modify it under
4    * the terms of the GNU Lesser General Public License, version 2.1 or later
5    * as published by the Free Software Foundation. This program is distributed
6    * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
7    * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8    * See the GNU Lesser General Public License for more details.
9    *
10   * The License is available on the internet at:
11   *      http://www.gnu.org/copyleft/lgpl.html
12   * or by writing to:
13   *      Free Software Foundation, Inc.
14   *      59 Temple Place - Suite 330
15   *      Boston, MA 02111-1307, USA
16   *
17   * © CrossWire Bible Society, 2005 - 2016
18   *
19   */
20  package org.crosswire.jsword.book;
21  
22  import java.util.Map;
23  import java.util.TreeMap;
24  
25  import org.crosswire.common.config.ChoiceFactory;
26  
27  /**
28   * Handles the current default Books.
29   * 
30   * @see gnu.lgpl.License The GNU Lesser General Public License for details.
31   * @author Joe Walker
32   */
33  public final class Defaults {
34      /**
35       * Prevent construction.
36       */
37      private Defaults() {
38      }
39  
40      /**
41       * Determine whether the getBible should return the current Bible or the
42       * user's chosen default.
43       * 
44       * @return true if the bible tracks the user's selection
45       */
46      public static boolean isCurrentBible() {
47          return trackBible;
48      }
49  
50      /**
51       * Establish whether the getBible should return the current Bible or the
52       * user's chosen default.
53       * 
54       * @param current whether getBible tracks the current Bible
55       */
56      public static void setCurrentBible(boolean current) {
57          trackBible = current;
58      }
59  
60      /**
61       * If the user has chosen to remember the book (by type) then set the
62       * current book for that type.
63       * 
64       * @param book the current Book
65       */
66      public static void setCurrentBook(Book book) {
67          BookCategory type = book.getBookCategory();
68          if (type.equals(BookCategory.BIBLE) && isCurrentBible()) {
69              currentBible = book;
70          }
71      }
72  
73      /**
74       * Get the current Bible, if set, else the default Bible.
75       * 
76       * @return the current Bible
77       */
78      public static Book getCurrentBible() {
79          if (currentBible == null) {
80              return bibleDeft.getDefault();
81          }
82          return currentBible;
83      }
84  
85      /**
86       * Set the default Bible.
87       * 
88       * @param book the default Bible
89       */
90      public static void setBible(Book book) {
91          bibleDeft.setDefault(book);
92      }
93  
94      /**
95       * Unset the default Bible.
96       */
97      protected static void unsetBible() {
98          bibleDeft.unsetDefault();
99      }
100 
101     /**
102      * @return the default Bible
103      */
104     public static Book getBible() {
105         return bibleDeft.getDefault();
106     }
107 
108     /**
109      * @return the name of the default Bible
110      */
111     public static String getBibleByName() {
112         return bibleDeft.getDefaultName();
113     }
114 
115     /**
116      * Set the default Bible by name.
117      * 
118      * @param name the name of the default Bible
119      */
120     public static void setBibleByName(String name) {
121         bibleDeft.setDefaultByName(name);
122     }
123 
124     /**
125      * Set the default commentary.
126      * 
127      * @param book the default commentary
128      */
129     public static void setCommentary(Book book) {
130         commentaryDeft.setDefault(book);
131     }
132 
133     /**
134      * Unset the default commentary.
135      */
136     protected static void unsetCommentary() {
137         commentaryDeft.unsetDefault();
138     }
139 
140     /**
141      * @return the default commentary
142      */
143     public static Book getCommentary() {
144         return commentaryDeft.getDefault();
145     }
146 
147     /**
148      * @return the name of the default commentary
149      */
150     public static String getCommentaryByName() {
151         return commentaryDeft.getDefaultName();
152     }
153 
154     /**
155      * Set the default commentary by name.
156      * 
157      * @param name the default commentary's name
158      */
159     public static void setCommentaryByName(String name) {
160         commentaryDeft.setDefaultByName(name);
161     }
162 
163     /**
164      * Set the default dictionary.
165      * 
166      * @param book the default dictionary
167      */
168     public static void setDictionary(Book book) {
169         dictionaryDeft.setDefault(book);
170     }
171 
172     /**
173      * Unset the default dictionary.
174      */
175     protected static void unsetDictionary() {
176         dictionaryDeft.unsetDefault();
177     }
178 
179     /**
180      * @return the default dictionary
181      */
182     public static Book getDictionary() {
183         return dictionaryDeft.getDefault();
184     }
185 
186     /**
187      * @return the name of the default dictionary
188      */
189     public static String getDictionaryByName() {
190         return dictionaryDeft.getDefaultName();
191     }
192 
193     /**
194      * Set the default dictionary by name.
195      * 
196      * @param name the name of the default dictionary
197      */
198     public static void setDictionaryByName(String name) {
199         dictionaryDeft.setDefaultByName(name);
200     }
201 
202     /**
203      * Set the default daily devotional.
204      * 
205      * @param book the default daily devotional
206      */
207     public static void setDailyDevotional(Book book) {
208         dictionaryDeft.setDefault(book);
209     }
210 
211     /**
212      * Unset the default daily devotional.
213      */
214     protected static void unsetDailyDevotional() {
215         dailyDevotionalDeft.unsetDefault();
216     }
217 
218     /**
219      * @return the default daily devotional
220      */
221     public static Book getDailyDevotional() {
222         return dailyDevotionalDeft.getDefault();
223     }
224 
225     /**
226      * @return the name of the default daily devotional
227      */
228     public static String getDailyDevotionalByName() {
229         return dailyDevotionalDeft.getDefaultName();
230     }
231 
232     /**
233      * Set the default daily devotional by name.
234      * 
235      * @param name the name of the default daily devotional
236      */
237     public static void setDailyDevotionalByName(String name) {
238         dailyDevotionalDeft.setDefaultByName(name);
239     }
240 
241     /**
242      * Set the default Greek Strong's Numbers dictionary.
243      * 
244      * @param book the default Greek Strong's Numbers dictionary.
245      */
246     public static void setGreekDefinitions(Book book) {
247         greekDefinitionsDeft.setDefault(book);
248     }
249 
250     /**
251      * Unset the default Greek Strong's Numbers dictionary.
252      */
253     protected static void unsetGreekDefinitions() {
254         greekDefinitionsDeft.unsetDefault();
255     }
256 
257     /**
258      * @return the default Greek Strong's Numbers dictionary
259      */
260     public static Book getGreekDefinitions() {
261         return greekDefinitionsDeft.getDefault();
262     }
263 
264     /**
265      * @return the name of the default Greek Strong's Numbers dictionary
266      */
267     public static String getGreekDefinitionsByName() {
268         return greekDefinitionsDeft.getDefaultName();
269     }
270 
271     /**
272      * Set the default Greek Strong's Numbers dictionary by name.
273      * 
274      * @param name the name of the default Greek Strong's Numbers dictionary
275      */
276     public static void setGreekDefinitionsByName(String name) {
277         greekDefinitionsDeft.setDefaultByName(name);
278     }
279 
280     /**
281      * Set the default Hebrew Strong's Numbers dictionary.
282      * 
283      * @param book the default Hebrew Strong's Numbers dictionary.
284      */
285     public static void setHebrewDefinitions(Book book) {
286         hebrewDefinitionsDeft.setDefault(book);
287     }
288 
289     /**
290      * Unset the default Hebrew Strong's Numbers dictionary.
291      */
292     protected static void unsetHebrewDefinitions() {
293         hebrewDefinitionsDeft.unsetDefault();
294     }
295 
296     /**
297      * @return the default Hebrew Strong's Numbers dictionary
298      */
299     public static Book getHebrewDefinitions() {
300         return hebrewDefinitionsDeft.getDefault();
301     }
302 
303     /**
304      * @return the name of the default Hebrew Strong's Numbers dictionary
305      */
306     public static String getHebrewDefinitionsByName() {
307         return hebrewDefinitionsDeft.getDefaultName();
308     }
309 
310     /**
311      * Set the default Hebrew Strong's Numbers dictionary by name.
312      * 
313      * @param name the name of the default Hebrew Strong's Numbers dictionary
314      */
315     public static void setHebrewDefinitionsByName(String name) {
316         hebrewDefinitionsDeft.setDefaultByName(name);
317     }
318 
319     /**
320      * Set the default Greek morphology dictionary.
321      * 
322      * @param book the default Greek morphology dictionary.
323      */
324     public static void setGreekParse(Book book) {
325         greekParseDeft.setDefault(book);
326     }
327 
328     /**
329      * Unset the default Greek morphology dictionary.
330      */
331     protected static void unsetGreekParse() {
332         greekParseDeft.unsetDefault();
333     }
334 
335     /**
336      * @return the default Greek morphology dictionary
337      */
338     public static Book getGreekParse() {
339         return greekParseDeft.getDefault();
340     }
341 
342     /**
343      * Set the default Greek morphology dictionary by name.
344      * 
345      * @return the name of the default Greek morphology dictionary
346      */
347     public static String getGreekParseByName() {
348         return greekParseDeft.getDefaultName();
349     }
350 
351     /**
352      * @param name the name of the default Greek morphology dictionary
353      */
354     public static void setGreekParseByName(String name) {
355         greekParseDeft.setDefaultByName(name);
356     }
357 
358     /**
359      * Set the default Hebrew morphology dictionary by name.
360      * 
361      * @param book the default Hebrew morphology dictionary by name.
362      */
363     public static void setHebrewParse(Book book) {
364         hebrewParseDeft.setDefault(book);
365     }
366 
367     /**
368      * Unset the default Hebrew morphology dictionary.
369      */
370     protected static void unsetHebrewParse() {
371         hebrewParseDeft.unsetDefault();
372     }
373 
374     /**
375      * @return the default Hebrew morphology dictionary
376      */
377     public static Book getHebrewParse() {
378         return hebrewParseDeft.getDefault();
379     }
380 
381     /**
382      * @return the name of the default Hebrew morphology dictionary
383      */
384     public static String getHebrewParseByName() {
385         return hebrewParseDeft.getDefaultName();
386     }
387 
388     /**
389      * Set the default Hebrew morphology dictionary by name.
390      * 
391      * @param name the default Hebrew morphology dictionary by name.
392      */
393     public static void setHebrewParseByName(String name) {
394         hebrewParseDeft.setDefaultByName(name);
395     }
396 
397     /**
398      * @return the default Bible
399      */
400     protected static DefaultBook getDefaultBible() {
401         return bibleDeft;
402     }
403 
404     /**
405      * @return the default commentary
406      */
407     protected static DefaultBook getDefaultCommentary() {
408         return commentaryDeft;
409     }
410 
411     /**
412      * @return the default dictionary
413      */
414     protected static DefaultBook getDefaultDictionary() {
415         return dictionaryDeft;
416     }
417 
418     /**
419      * @return the default daily devotional
420      */
421     protected static DefaultBook getDefaultDailyDevotional() {
422         return dailyDevotionalDeft;
423     }
424 
425     /**
426      * @return the default Greek Strong's Numbers dictionary
427      */
428     protected static DefaultBook getDefaultGreekDefinitions() {
429         return greekDefinitionsDeft;
430     }
431 
432     /**
433      * @return the default Hebrew Strong's Numbers dictionary
434      */
435     protected static DefaultBook getDefaultHebrewDefinitions() {
436         return hebrewDefinitionsDeft;
437     }
438 
439     /**
440      * @return the default Greek morphology dictionary
441      */
442     protected static DefaultBook getDefaultGreekParse() {
443         return greekParseDeft;
444     }
445 
446     /**
447      * @return the default Hebrew morphology dictionary
448      */
449     protected static DefaultBook getDefaultHebrewParse() {
450         return hebrewParseDeft;
451     }
452 
453     /**
454      * Create book lists for every type of book.
455      */
456     public static void refreshBooks() {
457         // Create the array of Bibles
458         Map<Book, String> bnames = getBookMap(BookFilters.getOnlyBibles());
459         ChoiceFactory.getDataMap().put(BIBLE_KEY, bnames);
460 
461         // Create the array of Commentaries
462         Map<Book, String> cnames = getBookMap(BookFilters.getCommentaries());
463         ChoiceFactory.getDataMap().put(COMMENTARY_KEY, cnames);
464 
465         // Create the array of Dictionaries
466         Map<Book, String> dnames = getBookMap(BookFilters.getDictionaries());
467         ChoiceFactory.getDataMap().put(DICTIONARY_KEY, dnames);
468 
469         // Create the array of DailyDevotionals
470         Map<Book, String> rnames = getBookMap(BookFilters.getDailyDevotionals());
471         ChoiceFactory.getDataMap().put(DAILY_DEVOTIONALS_KEY, rnames);
472 
473         // Create the array of Dictionaries
474         Map<Book, String> greekDef = getBookMap(BookFilters.getGreekDefinitions());
475         ChoiceFactory.getDataMap().put(GREEKDEF_KEY, greekDef);
476 
477         // Create the array of Dictionaries
478         Map<Book, String> hebrewDef = getBookMap(BookFilters.getHebrewDefinitions());
479         ChoiceFactory.getDataMap().put(HEBREWDEF_KEY, hebrewDef);
480 
481         // Create the array of Dictionaries
482         Map<Book, String> greekParse = getBookMap(BookFilters.getGreekParse());
483         ChoiceFactory.getDataMap().put(GREEKPARSE_KEY, greekParse);
484 
485         // Create the array of Dictionaries
486         Map<Book, String> hebrewParse = getBookMap(BookFilters.getHebrewParse());
487         ChoiceFactory.getDataMap().put(HEBREWPARSE_KEY, hebrewParse);
488     }
489 
490     /**
491      * Go through all of the current books checking to see if we need to replace
492      * the current defaults with one of these.
493      */
494     protected static void checkAllPreferable() {
495         for (Book book : Books.installed().getBooks()) {
496             checkPreferable(book);
497         }
498     }
499 
500     /**
501      * Determine whether this Book become the default. It should, only if there
502      * is not one.
503      * 
504      * @param book the book to check
505      */
506     protected static void checkPreferable(Book book) {
507         assert book != null;
508 
509         bibleDeft.setDefaultConditionally(book);
510         commentaryDeft.setDefaultConditionally(book);
511         dictionaryDeft.setDefaultConditionally(book);
512         dailyDevotionalDeft.setDefaultConditionally(book);
513         greekDefinitionsDeft.setDefaultConditionally(book);
514         greekParseDeft.setDefaultConditionally(book);
515         hebrewDefinitionsDeft.setDefaultConditionally(book);
516         hebrewParseDeft.setDefaultConditionally(book);
517     }
518 
519     /**
520      * Convert a filter into an array of names of Books that pass the filter.
521      * 
522      * @param filter the filter to locate matching books
523      * @return matching books
524      */
525     private static Map<Book, String> getBookMap(BookFilter filter) {
526         Map<Book, String> books = new TreeMap<Book, String>(BookComparators.getDefault());
527 
528         for (Book book : Books.installed().getBooks(filter)) {
529             books.put(book, book.getName());
530         }
531 
532         return books;
533     }
534 
535     /**
536      * To keep us up to date with changes in the available Books
537      */
538     static class DefaultsBookListener implements BooksListener {
539         /* (non-Javadoc)
540          * @see org.crosswire.jsword.book.BooksListener#bookAdded(org.crosswire.jsword.book.BooksEvent)
541          */
542         public void bookAdded(BooksEvent ev) {
543             Book book = ev.getBook();
544             checkPreferable(book);
545             refreshBooks();
546         }
547 
548         /* (non-Javadoc)
549          * @see org.crosswire.jsword.book.BooksListener#bookRemoved(org.crosswire.jsword.book.BooksEvent)
550          */
551         public void bookRemoved(BooksEvent ev) {
552             Book book = ev.getBook();
553 
554             getDefaultBible().unsetDefaultConditionally(book);
555             getDefaultCommentary().unsetDefaultConditionally(book);
556             getDefaultDailyDevotional().unsetDefaultConditionally(book);
557             getDefaultDictionary().unsetDefaultConditionally(book);
558             getDefaultGreekDefinitions().unsetDefaultConditionally(book);
559             getDefaultGreekParse().unsetDefaultConditionally(book);
560             getDefaultHebrewDefinitions().unsetDefaultConditionally(book);
561             getDefaultHebrewParse().unsetDefaultConditionally(book);
562         }
563     }
564 
565     private static final String BIBLE_KEY = "bible-names";
566     private static final String COMMENTARY_KEY = "commentary-names";
567     private static final String DICTIONARY_KEY = "dictionary-names";
568     private static final String DAILY_DEVOTIONALS_KEY = "daily-devotional-names";
569     private static final String GREEKDEF_KEY = "greekdef-names";
570     private static final String HEBREWDEF_KEY = "hebrewdef-names";
571     private static final String GREEKPARSE_KEY = "greekparse-names";
572     private static final String HEBREWPARSE_KEY = "hebrewparse-names";
573 
574     /**
575      * Indicates whether the last book of each type is used next time.
576      */
577     private static boolean trackBible = true;
578 
579     /**
580      * The current bible being tracked.
581      */
582     private static Book currentBible;
583 
584     /**
585      * The default Bible
586      */
587     private static DefaultBook bibleDeft = new DefaultBook(Books.installed(), BookFilters.getOnlyBibles());
588 
589     /**
590      * The default Commentary
591      */
592     private static DefaultBook commentaryDeft = new DefaultBook(Books.installed(), BookFilters.getCommentaries());
593 
594     /**
595      * The default DailyDevotional
596      */
597     private static DefaultBook dailyDevotionalDeft = new DefaultBook(Books.installed(), BookFilters.getDailyDevotionals());
598 
599     /**
600      * The default Dictionary
601      */
602     private static DefaultBook dictionaryDeft = new DefaultBook(Books.installed(), BookFilters.getDictionaries());
603 
604     /**
605      * The default Greek Parse Dictionary.
606      */
607     private static DefaultBook greekParseDeft = new DefaultBook(Books.installed(), BookFilters.getGreekParse());
608 
609     /**
610      * The default Hebrew Parse Dictionary.
611      */
612     private static DefaultBook hebrewParseDeft = new DefaultBook(Books.installed(), BookFilters.getHebrewParse());
613 
614     /**
615      * The default Greek Definitions Dictionary.
616      */
617     private static DefaultBook greekDefinitionsDeft = new DefaultBook(Books.installed(), BookFilters.getGreekDefinitions());
618 
619     /**
620      * The default Hebrew Definitions Dictionary.
621      */
622     private static DefaultBook hebrewDefinitionsDeft = new DefaultBook(Books.installed(), BookFilters.getHebrewDefinitions());
623 
624     /**
625      * Register with Books so we know how to provide valid defaults
626      */
627     static {
628         Books.installed().addBooksListener(new DefaultsBookListener());
629         checkAllPreferable();
630     }
631 
632 }
633