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