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: BookType.java 2099 2011-03-07 17:13:00Z dmsmith $
21   */
22  package org.crosswire.jsword.book.sword;
23  
24  import org.crosswire.jsword.JSOtherMsg;
25  import org.crosswire.jsword.book.Book;
26  import org.crosswire.jsword.book.BookCategory;
27  import org.crosswire.jsword.book.BookException;
28  import org.crosswire.jsword.book.KeyType;
29  
30  /**
31   * Data about book types.
32   * 
33   * @see gnu.lgpl.License for license details.<br>
34   *      The copyright to this program is held by it's authors.
35   * @author Joe Walker [joe at eireneh dot com]
36   * @author DM Smith [dmsmith555 at yahoo dot com]
37   */
38  public enum BookType {
39      /**
40       * Uncompressed Bibles
41       */
42      RAW_TEXT ("RawText", BookCategory.BIBLE, KeyType.VERSE) {
43  
44          @Override
45          protected Book getBook(SwordBookMetaData sbmd, AbstractBackend backend) {
46              return new SwordBook(sbmd, backend);
47          }
48  
49          @Override
50          protected AbstractBackend getBackend(SwordBookMetaData sbmd) throws BookException {
51              return new RawBackend(sbmd, 2);
52          }
53      },
54  
55      /**
56       * Compressed Bibles
57       */
58      Z_TEXT ("zText", BookCategory.BIBLE, KeyType.VERSE) {
59          @Override
60          protected Book getBook(SwordBookMetaData sbmd, AbstractBackend backend) {
61              return new SwordBook(sbmd, backend);
62          }
63  
64          @Override
65          protected AbstractBackend getBackend(SwordBookMetaData sbmd) throws BookException {
66              BlockType blockType = BlockType.fromString((String) sbmd.getProperty(ConfigEntryType.BLOCK_TYPE));
67              return new ZVerseBackend(sbmd, blockType);
68          }
69      },
70  
71      /**
72       * Uncompressed Commentaries
73       */
74      RAW_COM ("RawCom", BookCategory.COMMENTARY, KeyType.VERSE) {
75  
76          @Override
77          protected Book getBook(SwordBookMetaData sbmd, AbstractBackend backend) {
78              return new SwordBook(sbmd, backend);
79          }
80  
81          @Override
82          protected AbstractBackend getBackend(SwordBookMetaData sbmd) throws BookException {
83              return new RawBackend(sbmd, 2);
84          }
85      },
86  
87      RAW_COM4 ("RawCom4", BookCategory.COMMENTARY, KeyType.VERSE) {
88  
89          @Override
90          protected Book getBook(SwordBookMetaData sbmd, AbstractBackend backend) {
91              return new SwordBook(sbmd, backend);
92          }
93  
94          @Override
95          protected AbstractBackend getBackend(SwordBookMetaData sbmd) throws BookException {
96              return new RawBackend(sbmd, 4);
97          }
98      },
99  
100     /**
101      * Compressed Commentaries
102      */
103     Z_COM ("zCom", BookCategory.COMMENTARY, KeyType.VERSE) {
104 
105         @Override
106         protected Book getBook(SwordBookMetaData sbmd, AbstractBackend backend) {
107             return new SwordBook(sbmd, backend);
108         }
109 
110         @Override
111         protected AbstractBackend getBackend(SwordBookMetaData sbmd) throws BookException {
112             BlockType blockType = BlockType.fromString((String) sbmd.getProperty(ConfigEntryType.BLOCK_TYPE));
113             return new ZVerseBackend(sbmd, blockType);
114         }
115     },
116 
117     /**
118      * Uncompresses HREF Commentaries
119      */
120     HREF_COM ("HREFCom", BookCategory.COMMENTARY, KeyType.VERSE) {
121 
122         @Override
123         protected Book getBook(SwordBookMetaData sbmd, AbstractBackend backend) {
124             return new SwordBook(sbmd, backend);
125         }
126 
127         @Override
128         protected AbstractBackend getBackend(SwordBookMetaData sbmd) throws BookException {
129             return new RawBackend(sbmd, 2);
130         }
131     },
132 
133     /**
134      * Uncompressed Commentaries
135      */
136     RAW_FILES ("RawFiles", BookCategory.COMMENTARY, KeyType.VERSE) {
137 
138         @Override
139         protected Book getBook(SwordBookMetaData sbmd, AbstractBackend backend) {
140             return new SwordBook(sbmd, backend);
141         }
142 
143         @Override
144         protected AbstractBackend getBackend(SwordBookMetaData sbmd) throws BookException {
145             return new RawFileBackend(sbmd, 2);
146         }
147     },
148 
149     /**
150      * 2-Byte Index Uncompressed Dictionaries
151      */
152     RAW_LD ("RawLD", BookCategory.DICTIONARY, KeyType.LIST) {
153 
154         @Override
155         protected Book getBook(SwordBookMetaData sbmd, AbstractBackend backend) {
156             if (sbmd.getBookCategory().equals(BookCategory.DAILY_DEVOTIONS)) {
157                 return new SwordDailyDevotion(sbmd, backend);
158             }
159             return new SwordDictionary(sbmd, backend);
160         }
161 
162         @Override
163         protected AbstractBackend getBackend(SwordBookMetaData sbmd) throws BookException {
164             return new RawLDBackend(sbmd, 2);
165         }
166     },
167 
168     /**
169      * 4-Byte Index Uncompressed Dictionaries
170      */
171     RAW_LD4 ("RawLD4", BookCategory.DICTIONARY, KeyType.LIST) {
172 
173         @Override
174         protected Book getBook(SwordBookMetaData sbmd, AbstractBackend backend) {
175             if (sbmd.getBookCategory().equals(BookCategory.DAILY_DEVOTIONS)) {
176                 return new SwordDailyDevotion(sbmd, backend);
177             }
178             return new SwordDictionary(sbmd, backend);
179         }
180 
181         @Override
182         protected AbstractBackend getBackend(SwordBookMetaData sbmd) throws BookException {
183             return new RawLDBackend(sbmd, 4);
184         }
185     },
186 
187     /**
188      * Compressed Dictionaries
189      */
190     Z_LD ("zLD", BookCategory.DICTIONARY, KeyType.LIST) {
191 
192         @Override
193         protected Book getBook(SwordBookMetaData sbmd, AbstractBackend backend) {
194             if (sbmd.getBookCategory().equals(BookCategory.DAILY_DEVOTIONS)) {
195                 return new SwordDailyDevotion(sbmd, backend);
196             }
197             return new SwordDictionary(sbmd, backend);
198         }
199 
200         @Override
201         protected AbstractBackend getBackend(SwordBookMetaData sbmd) throws BookException {
202             return new ZLDBackend(sbmd);
203         }
204     },
205 
206     /**
207      * Generic Books
208      */
209     RAW_GEN_BOOK ("RawGenBook", BookCategory.GENERAL_BOOK, KeyType.TREE) {
210 
211         @Override
212         protected Book getBook(SwordBookMetaData sbmd, AbstractBackend backend) {
213             return new SwordGenBook(sbmd, backend);
214         }
215 
216         @Override
217         protected AbstractBackend getBackend(SwordBookMetaData sbmd) throws BookException {
218             return new GenBookBackend(sbmd);
219         }
220     };
221 
222     /**
223      * Simple ctor
224      */
225     private BookType(String name, BookCategory category, KeyType type) {
226         this.name = name;
227         this.category = category;
228         this.keyType = type;
229     }
230 
231     /**
232      * Find a BookType from a name.
233      * 
234      * @param name
235      *            The name of the BookType to look up
236      * @return The found BookType or null if the name is not found
237      */
238     public static BookType getBookType(String name) {
239         for (BookType v : values()) {
240             if (v.name().equalsIgnoreCase(name)) {
241                 return v;
242             }
243         }
244 
245         throw new IllegalArgumentException(JSOtherMsg.lookupText("BookType {0} is not defined!", name));
246     }
247 
248     /**
249      * The category of this book
250      */
251     public BookCategory getBookCategory() {
252         return category;
253     }
254 
255     /**
256      * Get the way this type of Book organizes it's keys.
257      * 
258      * @return the organization of keys for this book
259      */
260     public KeyType getKeyType() {
261         return keyType;
262     }
263 
264     /**
265      * Given a SwordBookMetaData determine whether this BookType will work for
266      * it.
267      * 
268      * @param sbmd
269      *            the BookMetaData that this BookType works upon
270      * @return true if this is a usable BookType
271      */
272     public boolean isSupported(SwordBookMetaData sbmd) {
273         return category != null && sbmd != null;
274     }
275 
276     /**
277      * Create a Book appropriate for the BookMetaData
278      * 
279      * @throws BookException
280      */
281     public Book createBook(SwordBookMetaData sbmd) throws BookException {
282         return getBook(sbmd, getBackend(sbmd));
283     }
284 
285     /**
286      * Create a Book with the given backend
287      */
288     protected abstract Book getBook(SwordBookMetaData sbmd, AbstractBackend backend);
289 
290     /**
291      * Create a the appropriate backend for this type of book
292      */
293     protected abstract AbstractBackend getBackend(SwordBookMetaData sbmd) throws BookException;
294 
295     /**
296      * The name of the BookType
297      */
298     private String name;
299 
300     /**
301      * What category is this book
302      */
303     private BookCategory category;
304 
305     /**
306      * What category is this book
307      */
308     private KeyType keyType;
309 
310     /**
311      * Lookup method to convert from a String
312      */
313     public static BookType fromString(String name) {
314         for (BookType v : values()) {
315             if (v.name.equalsIgnoreCase(name)) {
316                 return v;
317             }
318         }
319 
320         throw new ClassCastException(JSOtherMsg.lookupText("DataType {0} is not defined!", name));
321     }
322 
323     /* (non-Javadoc)
324      * @see java.lang.Enum#toString()
325      */
326     @Override
327     public String toString() {
328         return name;
329     }
330 }
331