| BibleBookList.java |
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: 2012
18 * The copyright to this program is held by it's authors.
19 *
20 * ID: $Id: BibleBookList.java 2238 2012-03-29 13:35:27Z dmsmith $
21 */
22 package org.crosswire.jsword.versification;
23
24 import java.io.Serializable;
25 import java.util.Iterator;
26 import java.util.NoSuchElementException;
27
28 /**
29 * A BibleBookList is an ordered list of one or more BibleBooks.
30 * Typically, a BibleBookList is a member of a Versification.
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 class BibleBookList implements Iterable<BibleBook>, Serializable {
37 /**
38 * Create an ordered BibleBookList from the input.
39 * @param books
40 */
41 public BibleBookList(BibleBook[] books) {
42 this.books = books.clone();
43 initialize();
44 }
45
46 /**
47 * Does this Versification contain the BibleBook.
48 *
49 * @param book
50 * @return true if it is present.
51 */
52 public boolean contains(BibleBook book) {
53 return bookMap[book.ordinal()] != -1;
54 }
55
56 /**
57 * Where does the BibleBook come in the order of books of the Bible.
58 * The first book is 0, the next is 1 and so forth.
59 * If the BibleBook is not in this Reference System,
60 * then the return value of this routine is -1.
61 *
62 * @param book
63 * return the ordinal value of the book or -1 if not present
64 */
65 public int getOrdinal(BibleBook book) {
66 return bookMap[book.ordinal()];
67 }
68
69 /**
70 * Get the number of books in this Versification.
71 * @return the number of books
72 */
73 public int getBookCount() {
74 return books.length;
75 }
76
77 /**
78 * Get the BibleBook by its position in this Versification.
79 * If the position is negative, return the first book.
80 * If the position is greater than the last, return the last book.
81 *
82 * @param ordinal
83 * @return the indicated book
84 */
85 public BibleBook getBook(int ordinal) {
86 int ord = ordinal;
87 if (ord < 0) {
88 ord = 0;
89 }
90 if (ord >= books.length) {
91 ord = books.length - 1;
92 }
93 return books[ord];
94 }
95
96 /**
97 * Get the BibleBooks in this Versification.
98 *
99 * @return an Iterator over the books
100 */
101 public Iterator<BibleBook> iterator() {
102 return new Iterator<BibleBook>() {
103
104 private BibleBook nextBook = books[0];
105
106 public boolean hasNext() {
107 return nextBook != null;
108 }
109
110 public BibleBook next() {
111
112 if (nextBook == null) {
113 throw new NoSuchElementException();
114 }
115
116 BibleBook current = nextBook;
117 nextBook = getNextBook(nextBook);
118 return current;
119 }
120
121 public void remove() {
122 throw new UnsupportedOperationException();
123 }
124
125 };
126 }
127
128 /**
129 * Return the first book in the list.
130 *
131 * @return the first book in the list
132 */
133 public BibleBook getFirstBook() {
134 return books[0];
135 }
136
137 /**
138 * Return the first book in the list.
139 *
140 * @return the first book in the list
141 */
142 public BibleBook getLastBook() {
143 return books[books.length - 1];
144 }
145
146 /**
147 * Given a BibleBook, get the previous BibleBook in this Versification. If it is the first book, return null.
148 * @param book A BibleBook in the Versification
149 * @return the previous BibleBook or null.
150 */
151 public BibleBook getPreviousBook(BibleBook book) {
152 int ordinal = book.ordinal();
153 int position = bookMap[ordinal];
154 if (position > 0) {
155 return books[position - 1];
156 }
157
158 return null;
159 }
160
161 /**
162 * Given a BibleBook, get the next BibleBook in this Versification. If it is the last book, return null.
163 * @param book A BibleBook in the Versification
164 * @return the previous BibleBook or null.
165 */
166 public BibleBook getNextBook(BibleBook book) {
167 int ordinal = book.ordinal();
168 int position = bookMap[ordinal];
169 if (position != -1 && position + 1 < books.length) {
170 return books[position + 1];
171 }
172 return null;
173 }
174
175 /**
176 * The bookMap contains one slot for every BibleBook, indexed by it's ordinal value.
177 * The value of that entry is the position of the book in the BookList.
178 * If the BibleBook is not present in books, it's value is -1.
179 */
180 private void initialize() {
181 bookMap = new int[BibleBook.values().length + 1];
182 // Initialize all slots to -1
183 for (BibleBook b : BibleBook.values()) {
184 bookMap[b.ordinal()] = -1;
185 }
186
187 // Fill in the position of the books into that list
188 for (int i = 0; i < books.length; i++) {
189 bookMap[books[i].ordinal()] = i;
190 }
191 }
192
193 private BibleBook[] books;
194
195 /** The bookMap maps from a BibleBook to the position that book has in <code>books</code>. */
196 private int[] bookMap;
197
198 /**
199 * Serialization ID
200 */
201 private static final long serialVersionUID = -2681289798451902815L;
202 }
203