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 - 2012
18   *     The copyright to this program is held by it's authors.
19   *
20   * ID: $Id: BibleBook.java 2223 2012-01-26 21:28:02Z dmsmith $
21   */
22  package org.crosswire.jsword.versification;
23  
24  import java.util.HashMap;
25  import java.util.Locale;
26  import java.util.Map;
27  
28  /**
29   * A BibleBook is a book of the Bible. It may or may not be canonical.
30   * Note that the ordering of these books varies from one Versification to another.
31   *
32   * @see gnu.lgpl.License for license details.<br>
33   *      The copyright to this program is held by it's authors.
34   * @author DM Smith [dmsmith555 at yahoo dot com]
35   */
36  public enum BibleBook {
37      // JSword introduction to the Bible
38      INTRO_BIBLE("Intro.Bible"),
39      // JSword introduction to the Old Testament
40      INTRO_OT("Intro.OT"),
41      // Old Testament
42      GEN("Gen"),
43      EXOD("Exod"),
44      LEV("Lev"),
45      NUM("Num"),
46      DEUT("Deut"),
47      JOSH("Josh"),
48      JUDG("Judg"),
49      RUTH("Ruth"),
50      SAM1("1Sam"),
51      SAM2("2Sam"),
52      KGS1("1Kgs"),
53      KGS2("2Kgs"),
54      CHR1("1Chr"),
55      CHR2("2Chr"),
56      EZRA("Ezra"),
57      NEH("Neh"),
58      ESTH("Esth"),
59      JOB("Job"),
60      PS("Ps"),
61      PROV("Prov"),
62      ECCL("Eccl"),
63      SONG("Song"),
64      ISA("Isa"),
65      JER("Jer"),
66      LAM("Lam"),
67      EZEK("Ezek"),
68      DAN("Dan"),
69      HOS("Hos"),
70      JOEL("Joel"),
71      AMOS("Amos"),
72      OBAD("Obad"),
73      JONAH("Jonah"),
74      MIC("Mic"),
75      NAH("Nah"),
76      HAB("Hab"),
77      ZEPH("Zeph"),
78      HAG("Hag"),
79      ZECH("Zech"),
80      MAL("Mal"),
81      // JSword introduction to the New Testament
82      INTRO_NT("Intro.NT"),
83      // New Testament
84      MATT("Matt"),
85      MARK("Mark"),
86      LUKE("Luke"),
87      JOHN("John"),
88      ACTS("Acts"),
89      ROM("Rom"),
90      COR1("1Cor"),
91      COR2("2Cor"),
92      GAL("Gal"),
93      EPH("Eph"),
94      PHIL("Phil"),
95      COL("Col"),
96      THESS1("1Thess"),
97      THESS2("2Thess"),
98      TIM1("1Tim"),
99      TIM2("2Tim"),
100     TITUS("Titus"),
101     PHLM("Phlm"),
102     HEB("Heb"),
103     JAS("Jas"),
104     PET1("1Pet"),
105     PET2("2Pet"),
106     JOHN1("1John"),
107     JOHN2("2John"),
108     JOHN3("3John"),
109     JUDE("Jude"),
110     REV("Rev"),
111     // Apocrypha
112     TOB("Tob"),
113     JDT("Jdt"),
114     ADD_ESTH("AddEsth"),
115     WIS("Wis"),
116     SIR("Sir"),
117     BAR("Bar"),
118     EP_JER("EpJer"),
119     PR_AZAR("PrAzar"),
120     SUS("Sus"),
121     BEL("Bel"),
122     MACC1("1Macc"),
123     MACC2("2Macc"),
124     MACC3("3Macc"),
125     MACC4("4Macc"),
126     PR_MAN("PrMan"),
127     ESD1("1Esd"),
128     ESD2("2Esd"),
129     PSS151("Ps151"),
130     // Rahlfs' LXX
131     ODES("Odes"),
132     PSALM_SOL("PssSol"),
133     // Vulgate & other later Latin mss
134     EP_LAO("EpLao"),
135     ESD3("3Esd"),
136     ESD4("4Esd"),
137     ESD5("5Esd"),
138     // Ethiopian Orthodox Canon/Ge'ez Translation
139     EN1("1En"),
140     JUBS("Jub"),
141     BAR4("4Bar"),
142     ASCEN_ISA("AscenIsa"),
143     PS_JOS("PsJos"),
144     // Coptic Orthodox Canon
145     APOSTOLIC("AposCon"),
146     CLEM1("1Clem"),
147     CLEM2("2Clem"),
148     // Armenian Orthodox Canon
149     COR3("3Cor"),
150     EP_COR_PAUL("EpCorPaul"),
151     JOS_ASEN("JosAsen"),
152     T12PATR("T12Patr"),
153     T12PATR_TASH("T12Patr.TAsh"),
154     T12PATR_TBENJ("T12Patr.TBenj"),
155     T12PATR_TDAN("T12Patr.TDan"),
156     T12PATR_GAD("T12Patr.TGad"),
157     T12PATR_TISS("T12Patr.TIss"),
158     T12PATR_TJOS("T12Patr.TJos"),
159     T12PATR_TJUD("T12Patr.TJud"),
160     T12PATR_TLEVI("T12Patr.TLevi"),
161     T12PATR_TNAPH("T12Patr.TNaph"),
162     T12PATR_TREU("T12Patr.TReu"),
163     T12PATR_TSIM("T12Patr.TSim"),
164     T12PATR_TZeb("T12Patr.TZeb"),
165     // Peshitta
166     BAR2("2Bar"),
167     EP_BAR("EpBar"),
168     // Codex Sinaiticus
169     BARN("Barn"),
170     HERM("Herm"),
171     HERM_MAND("Herm.Mand"),
172     HERM_SIM("Herm.Sim"),
173     HERM_VIS("Herm.Vis"),
174     // Other books
175     ADD_DAN("AddDan"),
176     ADD_PS("AddPs"),
177     ESTH_GR("EsthGr");
178 
179     BibleBook(String osis) {
180         this.osis = osis;
181     }
182 
183     /**
184      * Get the OSIS representation of this BibleBook.
185      *
186      * @return the OSIS name
187      */
188     public String getOSIS() {
189         return osis;
190     }
191 
192     /**
193      * Get the OSIS representation of this BibleBook.
194      *
195      * @return the OSIS name
196      */
197     @Override
198     public String toString() {
199         return osis;
200     }
201 
202     /**
203      * Case insensitive search for BibleBook for an OSIS name.
204      *
205      * @param osis
206      * @return the matching BibleBook or null
207      */
208     public static BibleBook fromOSIS(String osis) {
209         String match = BookName.normalize(osis, Locale.ENGLISH);
210         return osisMap.get(match);
211     }
212 
213     /**
214      * Get the BookName.
215      *
216      * @param book
217      *            The book of the Bible
218      * @return The requested BookName
219      */
220     public BookName getBookName() {
221         return bibleNames.getBookName(this);
222     }
223 
224     /**
225      * Get the preferred name of a book. Altered by the case setting (see
226      * setBookCase() and isFullBookName())
227      *
228      * @param book
229      *            The book of the Bible
230      * @return The full name of the book
231      */
232     public String getPreferredName() {
233         return bibleNames.getPreferredName(this);
234     }
235 
236     /**
237      * Get the full name of a book (e.g. "Genesis"). Altered by the case setting
238      * (see setBookCase())
239      *
240      * @param book
241      *            The book of the Bible
242      * @return The full name of the book
243      */
244     public String getLongName() {
245         return bibleNames.getLongName(this);
246     }
247 
248     /**
249      * Get the short name of a book (e.g. "Gen"). Altered by the case setting
250      * (see setBookCase())
251      *
252      * @param book
253      *            The book of the Bible
254      * @return The short name of the book
255      */
256     public String getShortName() {
257         return bibleNames.getShortName(this);
258     }
259 
260     /**
261      * Get a book from its name.
262      *
263      * @param find
264      *            The string to identify
265      * @return The BibleBook, On error null
266      */
267     public static BibleBook getBook(String find) {
268         BibleBook book = null;
269         if (containsLetter(find)) {
270             book = fromOSIS(find);
271 
272             if (book == null) {
273                 book = bibleNames.getBook(find);
274             }
275 
276             if (book == null && englishBibleNames != null) {
277                 book = englishBibleNames.getBook(find);
278             }
279         }
280         return book;
281     }
282 
283     /**
284      * Is the given string a valid book name. If this method returns true then
285      * getBook() will return a BibleBook and not null.
286      *
287      * @param find
288      *            The string to identify
289      * @return true when the book name is recognized
290      */
291     public static boolean isBook(String find) {
292         return getBook(find) != null;
293     }
294 
295     /* package */ static BibleBook[] getBooks() {
296         return books;
297     }
298 
299     /**
300      * Load up the resources for Bible book and section names.
301      */
302     private static void initialize() {
303         Locale locale = Locale.getDefault();
304         bibleNames = new BibleNames(locale);
305 
306         // If the locale is not the program's default get it for alternates
307         if (!locale.getLanguage().equals(Locale.ENGLISH.getLanguage())) {
308             englishBibleNames = new BibleNames(Locale.ENGLISH);
309         }
310     }
311 
312     /**
313      * This is simply a convenience function to wrap Character.isLetter()
314      *
315      * @param text
316      *            The string to be parsed
317      * @return true if the string contains letters
318      */
319     private static boolean containsLetter(String text) {
320         for (int i = 0; i < text.length(); i++) {
321             if (Character.isLetter(text.charAt(i))) {
322                 return true;
323             }
324         }
325 
326         return false;
327     }
328 
329     private String osis;
330 
331     /** A quick lookup based on OSIS name for the book */
332     private static Map<String, BibleBook> osisMap = new HashMap<String, BibleBook>();
333 
334     /** The universe of ordered books, allowing for efficient previous next */
335     private static BibleBook[] books = BibleBook.values();
336 
337     /** Localized BibleNames */
338     private static BibleNames bibleNames;
339 
340     /** English BibleNames, or null when using the program's default locale */
341     private static BibleNames englishBibleNames;
342 
343     static {
344         for (BibleBook book : BibleBook.values()) {
345             osisMap.put(BookName.normalize(book.getOSIS(), Locale.ENGLISH), book);
346         }
347         initialize();
348     }
349 
350 }
351