Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
BookFilters |
|
| 1.6;1.6 | ||||
BookFilters$1 |
|
| 1.6;1.6 | ||||
BookFilters$2 |
|
| 1.6;1.6 | ||||
BookFilters$3 |
|
| 1.6;1.6 | ||||
BookFilters$AllBookFilter |
|
| 1.6;1.6 | ||||
BookFilters$BookCategoryFilter |
|
| 1.6;1.6 | ||||
BookFilters$BookFeatureFilter |
|
| 1.6;1.6 | ||||
BookFilters$CustomBookFilter |
|
| 1.6;1.6 | ||||
BookFilters$CustomBookFilter$Test |
|
| 1.6;1.6 | ||||
BookFilters$NotBookCategoryFilter |
|
| 1.6;1.6 |
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; | |
21 | ||
22 | import java.util.ArrayList; | |
23 | import java.util.List; | |
24 | ||
25 | /** | |
26 | * Some common implementations of BookFilter. | |
27 | * | |
28 | * @see gnu.lgpl.License The GNU Lesser General Public License for details. | |
29 | * @author Joe Walker | |
30 | */ | |
31 | public final class BookFilters { | |
32 | /** | |
33 | * Ensure we can't be created | |
34 | */ | |
35 | 0 | private BookFilters() { |
36 | 0 | } |
37 | ||
38 | /** | |
39 | * A simple default filter that returns everything | |
40 | * | |
41 | * @return the desired filter | |
42 | */ | |
43 | public static BookFilter getAll() { | |
44 | 0 | return new AllBookFilter(); |
45 | } | |
46 | ||
47 | /** | |
48 | * A filter that accepts everything that implements Bible or Commentary, | |
49 | * when commentaries are listed with Bibles. | |
50 | * | |
51 | * @return the desired filter | |
52 | */ | |
53 | public static BookFilter getBibles() { | |
54 | 0 | if (commentariesWithBibles) { |
55 | 0 | return either(new BookCategoryFilter(BookCategory.BIBLE), new BookCategoryFilter(BookCategory.COMMENTARY)); |
56 | } | |
57 | 0 | return new BookCategoryFilter(BookCategory.BIBLE); |
58 | } | |
59 | ||
60 | /** | |
61 | * A filter that accepts everything that implements Bible. | |
62 | * | |
63 | * @return the desired filter | |
64 | */ | |
65 | public static BookFilter getOnlyBibles() { | |
66 | 0 | return new BookCategoryFilter(BookCategory.BIBLE); |
67 | } | |
68 | ||
69 | /** | |
70 | * A filter that accepts everything that's not a Bible or a Commentary, when | |
71 | * commentaries are listed with Bibles. | |
72 | * | |
73 | * @return the desired filter | |
74 | */ | |
75 | public static BookFilter getNonBibles() { | |
76 | 0 | if (commentariesWithBibles) { |
77 | 0 | return both(new NotBookCategoryFilter(BookCategory.BIBLE), new NotBookCategoryFilter(BookCategory.COMMENTARY)); |
78 | } | |
79 | 0 | return new NotBookCategoryFilter(BookCategory.BIBLE); |
80 | } | |
81 | ||
82 | /** | |
83 | * A filter that accepts everything that implements Dictionary | |
84 | * | |
85 | * @return the desired filter | |
86 | */ | |
87 | public static BookFilter getDictionaries() { | |
88 | 0 | return new BookCategoryFilter(BookCategory.DICTIONARY); |
89 | } | |
90 | ||
91 | /** | |
92 | * A filter that accepts everything that implements Dictionary | |
93 | * | |
94 | * @return the desired filter | |
95 | */ | |
96 | public static BookFilter getGlossaries() { | |
97 | 0 | return new BookCategoryFilter(BookCategory.GLOSSARY); |
98 | } | |
99 | ||
100 | /** | |
101 | * A filter that accepts everything that implements DailyDevotionals | |
102 | * | |
103 | * @return the desired filter | |
104 | */ | |
105 | public static BookFilter getDailyDevotionals() { | |
106 | 0 | return new BookCategoryFilter(BookCategory.DAILY_DEVOTIONS); |
107 | } | |
108 | ||
109 | /** | |
110 | * A filter that accepts everything that implements Commentary | |
111 | * | |
112 | * @return the desired filter | |
113 | */ | |
114 | public static BookFilter getCommentaries() { | |
115 | 0 | return new BookCategoryFilter(BookCategory.COMMENTARY); |
116 | } | |
117 | ||
118 | /** | |
119 | * A filter that accepts everything that implements GeneralBook | |
120 | * | |
121 | * @return the desired filter | |
122 | */ | |
123 | public static BookFilter getGeneralBooks() { | |
124 | 0 | return new BookCategoryFilter(BookCategory.GENERAL_BOOK); |
125 | } | |
126 | ||
127 | /** | |
128 | * A filter that accepts everything that implements Maps | |
129 | * | |
130 | * @return the desired filter | |
131 | */ | |
132 | public static BookFilter getMaps() { | |
133 | 0 | return new BookCategoryFilter(BookCategory.MAPS); |
134 | } | |
135 | ||
136 | /** | |
137 | * A filter that accepts everything that is a Greek Definition Dictionary | |
138 | * | |
139 | * @return the desired filter | |
140 | */ | |
141 | public static BookFilter getGreekDefinitions() { | |
142 | 0 | return new BookFeatureFilter(FeatureType.GREEK_DEFINITIONS); |
143 | } | |
144 | ||
145 | /** | |
146 | * A filter that accepts everything that is a Greek Parse/Morphology | |
147 | * Dictionary | |
148 | * | |
149 | * @return the desired filter | |
150 | */ | |
151 | public static BookFilter getGreekParse() { | |
152 | 0 | return new BookFeatureFilter(FeatureType.GREEK_PARSE); |
153 | } | |
154 | ||
155 | /** | |
156 | * A filter that accepts everything that is a Hebrew Definition Dictionary | |
157 | * | |
158 | * @return the desired filter | |
159 | */ | |
160 | public static BookFilter getHebrewDefinitions() { | |
161 | 0 | return new BookFeatureFilter(FeatureType.HEBREW_DEFINITIONS); |
162 | } | |
163 | ||
164 | /** | |
165 | * A filter that accepts everything that is a Hebrew Parse/Morphology | |
166 | * Dictionary | |
167 | * | |
168 | * @return the desired filter | |
169 | */ | |
170 | public static BookFilter getHebrewParse() { | |
171 | 0 | return new BookFeatureFilter(FeatureType.HEBREW_PARSE); |
172 | } | |
173 | ||
174 | /** | |
175 | * Determine whether the getBible should return the current Bible or the | |
176 | * user's chosen default. | |
177 | * | |
178 | * @return true if the bible tracks the user's selection | |
179 | */ | |
180 | public static boolean isCommentariesWithBibles() { | |
181 | 0 | return commentariesWithBibles; |
182 | } | |
183 | ||
184 | /** | |
185 | * Establish whether the getBible should return the current Bible or the | |
186 | * user's chosen default. | |
187 | * | |
188 | * @param current whether commentaries should be returned together with Bibles | |
189 | */ | |
190 | public static void setCommentariesWithBibles(boolean current) { | |
191 | 0 | commentariesWithBibles = current; |
192 | 0 | } |
193 | ||
194 | /** | |
195 | * Whether biblesBookFilter includes commentaries. Initially false. | |
196 | */ | |
197 | private static boolean commentariesWithBibles; | |
198 | ||
199 | /** | |
200 | * Filter for all books | |
201 | */ | |
202 | 0 | static class AllBookFilter implements BookFilter { |
203 | /* (non-Javadoc) | |
204 | * @see org.crosswire.jsword.book.BookFilter#test(org.crosswire.jsword.book.Book) | |
205 | */ | |
206 | public boolean test(Book book) { | |
207 | 0 | return true; |
208 | } | |
209 | } | |
210 | ||
211 | /** | |
212 | * Filter for books by category | |
213 | */ | |
214 | static class BookCategoryFilter implements BookFilter { | |
215 | 0 | BookCategoryFilter(BookCategory category) { |
216 | 0 | this.category = category; |
217 | 0 | } |
218 | ||
219 | /* (non-Javadoc) | |
220 | * @see org.crosswire.jsword.book.BookFilter#test(org.crosswire.jsword.book.Book) | |
221 | */ | |
222 | public boolean test(Book book) { | |
223 | 0 | return book.getBookCategory().equals(category) && !book.isLocked(); |
224 | } | |
225 | ||
226 | private BookCategory category; | |
227 | } | |
228 | ||
229 | /** | |
230 | * Filter for books by category | |
231 | */ | |
232 | static class NotBookCategoryFilter implements BookFilter { | |
233 | 0 | NotBookCategoryFilter(BookCategory category) { |
234 | 0 | this.category = category; |
235 | 0 | } |
236 | ||
237 | /* (non-Javadoc) | |
238 | * @see org.crosswire.jsword.book.BookFilter#test(org.crosswire.jsword.book.Book) | |
239 | */ | |
240 | public boolean test(Book book) { | |
241 | 0 | return !book.getBookCategory().equals(category) && !book.isLocked(); |
242 | } | |
243 | ||
244 | private BookCategory category; | |
245 | } | |
246 | ||
247 | /** | |
248 | * Filter for books by feature | |
249 | */ | |
250 | public static class BookFeatureFilter implements BookFilter { | |
251 | 0 | public BookFeatureFilter(FeatureType feature) { |
252 | 0 | this.feature = feature; |
253 | 0 | } |
254 | ||
255 | /* (non-Javadoc) | |
256 | * @see org.crosswire.jsword.book.BookFilter#test(org.crosswire.jsword.book.Book) | |
257 | */ | |
258 | public boolean test(Book book) { | |
259 | 0 | return book.hasFeature(feature) && !book.isLocked(); |
260 | } | |
261 | ||
262 | private FeatureType feature; | |
263 | } | |
264 | ||
265 | /** | |
266 | * A filter that accepts Books that match two criteria. | |
267 | * | |
268 | * @param b1 the first filter criteria | |
269 | * @param b2 the second filter criteria | |
270 | * @return the desired filter | |
271 | */ | |
272 | public static BookFilter both(final BookFilter b1, final BookFilter b2) { | |
273 | 0 | return new BookFilter() { |
274 | public boolean test(Book book) { | |
275 | 0 | return b1.test(book) && b2.test(book); |
276 | } | |
277 | }; | |
278 | } | |
279 | ||
280 | /** | |
281 | * A filter that accepts Books that match either of two criteria. | |
282 | * | |
283 | * @param b1 the first filter criteria | |
284 | * @param b2 the second filter criteria | |
285 | * @return the desired filter | |
286 | */ | |
287 | public static BookFilter either(final BookFilter b1, final BookFilter b2) { | |
288 | 0 | return new BookFilter() { |
289 | public boolean test(Book book) { | |
290 | 0 | return b1.test(book) || b2.test(book); |
291 | } | |
292 | }; | |
293 | } | |
294 | ||
295 | /** | |
296 | * A filter that accepts Books that match by book driver. | |
297 | * | |
298 | * @param driver the driver to match | |
299 | * @return the desired filter | |
300 | */ | |
301 | public static BookFilter getBooksByDriver(final BookDriver driver) { | |
302 | 0 | return new BookFilter() { |
303 | public boolean test(Book book) { | |
304 | 0 | return book.getDriver() == driver; |
305 | } | |
306 | }; | |
307 | } | |
308 | ||
309 | /** | |
310 | * A simple default filter that returns everything. The match parameter is a | |
311 | * set of name value pairs like this: <br> | |
312 | * <code>initials=ESV;type=Bible;driverName=Sword</code><br> | |
313 | * Before the = there must be the name of a property on Book and after the | |
314 | * value to match (.toString()) is called on the results of the getter. | |
315 | * | |
316 | * @param match | |
317 | * a ; separated list of properties (of Book) to match | |
318 | * @return the desired filter | |
319 | * @see Book | |
320 | */ | |
321 | public static BookFilter getCustom(String match) { | |
322 | 0 | return new CustomBookFilter(match); |
323 | } | |
324 | ||
325 | /** | |
326 | * Custom Filter | |
327 | */ | |
328 | static class CustomBookFilter implements BookFilter { | |
329 | /** | |
330 | * Ctor | |
331 | * | |
332 | * @param match | |
333 | * The match spec. | |
334 | * @see BookFilters#getCustom(String) | |
335 | */ | |
336 | 0 | CustomBookFilter(String match) { |
337 | 0 | List<Test> cache = new ArrayList<Test>(); |
338 | 0 | String[] filters = match.split(";"); |
339 | 0 | for (int i = 0; i < filters.length; i++) { |
340 | 0 | cache.add(new Test(filters[i])); |
341 | } | |
342 | ||
343 | 0 | tests = cache.toArray(new Test[cache.size()]); |
344 | 0 | } |
345 | ||
346 | /* (non-Javadoc) | |
347 | * @see org.crosswire.jsword.book.BookFilter#test(org.crosswire.jsword.book.Book) | |
348 | */ | |
349 | public boolean test(Book book) { | |
350 | 0 | for (int i = 0; i < tests.length; i++) { |
351 | 0 | Test test = tests[i]; |
352 | 0 | if ("initials".equalsIgnoreCase(test.property)) { |
353 | 0 | if (!test.result.equals(book.getInitials())) { |
354 | 0 | return false; |
355 | } | |
356 | continue; | |
357 | } | |
358 | 0 | String result = book.getProperty(test.property); |
359 | 0 | if (result == null || !test.result.equals(result)) { |
360 | 0 | return false; |
361 | } | |
362 | } | |
363 | ||
364 | 0 | return true; |
365 | } | |
366 | ||
367 | private Test[] tests; | |
368 | ||
369 | /** | |
370 | * A helper class | |
371 | */ | |
372 | static class Test { | |
373 | 0 | protected Test(String filter) { |
374 | 0 | String[] parts = filter.split("="); |
375 | 0 | if (parts.length != 2 || parts[0].length() == 0 || parts[1].length() == 0) { |
376 | 0 | throw new IllegalArgumentException("Filter format is 'property=value', given: " + filter); |
377 | } | |
378 | 0 | this.property = parts[0]; |
379 | 0 | this.result = parts[1]; |
380 | ||
381 | 0 | } |
382 | 0 | protected Test(String property, String result) { |
383 | 0 | this.property = property; |
384 | 0 | this.result = result; |
385 | 0 | } |
386 | protected String property; | |
387 | protected String result; | |
388 | } | |
389 | } | |
390 | } |