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