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: DefaultBook.java 2054 2010-12-10 22:12:09Z dmsmith $
21   */
22  package org.crosswire.jsword.book;
23  
24  import java.util.Iterator;
25  import java.util.List;
26  
27  import org.crosswire.common.util.Logger;
28  
29  /**
30   * Defines a single default book.
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 class DefaultBook {
37      public DefaultBook(BookList bookList, BookFilter bookFilter) {
38          books = bookList;
39          filter = bookFilter;
40      }
41  
42      /**
43       * Set the default Book. It must satisfy the filter.
44       * 
45       * @param newBook
46       *            The version to use as default.
47       */
48      public void setDefault(Book newBook) {
49          if (filter.test(newBook)) {
50              book = newBook;
51          }
52      }
53  
54      /**
55       * Set the default Book conditionally. It has to satisfy the filter and the
56       * book must not currently be set.
57       * 
58       * @param newBook
59       *            The version to use as default.
60       */
61      public void setDefaultConditionally(Book newBook) {
62          if (book == null) {
63              setDefault(newBook);
64          }
65      }
66  
67      /**
68       * Unset the current default book and attempt to appoint another.
69       */
70      protected void unsetDefault() {
71          book = null;
72  
73          checkReplacement();
74      }
75  
76      /**
77       * Unset the current default book, if it matches the argument and attempt to
78       * appoint another.
79       */
80      protected void unsetDefaultConditionally(Book oldBook) {
81          if (book == oldBook) {
82              unsetDefault();
83          }
84      }
85  
86      /**
87       * Get the current default book or null if there is none.
88       * 
89       * @return the current default version
90       */
91      public Book getDefault() {
92          return book;
93      }
94  
95      /**
96       * This method is identical to <code>getDefault().getName()</code> and is
97       * only used by Config which works best with strings under reflection.
98       */
99      public String getDefaultName() {
100         if (book == null) {
101             return null;
102         }
103 
104         return book.getName();
105     }
106 
107     /**
108      * Trawl through all the known Books satisfying the filter looking for the
109      * one matching the given name.
110      * <p>
111      * This method is for use with config scripts and other things that
112      * <b>need</b> to work with Strings. The preferred method is to use Book
113      * objects.
114      * <p>
115      * This method is picky in that it only matches when the driver and the
116      * version are the same. The user (probably) only cares about the version
117      * though, and so might be disappointed when we fail to match AV (FooDriver)
118      * against AV (BarDriver).
119      * 
120      * @param name
121      *            The version to use as default.
122      */
123     public void setDefaultByName(String name) {
124         if (name == null || name.length() == 0) {
125             log.warn("Attempt to set empty book as default. Ignoring");
126             return;
127         }
128 
129         for (Book aBook : books.getBooks(filter)) {
130             if (aBook.match(name)) {
131                 setDefault(aBook);
132                 return;
133             }
134         }
135 
136         log.warn("Book not found. Ignoring: " + name);
137     }
138 
139     /**
140      * Go through all of the current books checking to see if we need to replace
141      * the current defaults with one of these.
142      */
143     protected void checkReplacement() {
144         List<Book> bookList = books.getBooks(filter);
145 
146         Iterator<Book> it = bookList.iterator();
147         if (it.hasNext()) {
148             book = it.next();
149         }
150     }
151 
152     /**
153      * The default book
154      */
155     private Book book;
156 
157     /**
158      * The list of candidate books.
159      */
160     private final BookList books;
161 
162     /**
163      * The filter against books that returns candidates.
164      */
165     private final BookFilter filter;
166 
167     /**
168      * The log stream
169      */
170     private static final Logger log = Logger.getLogger(DefaultBook.class);
171 }
172