Coverage Report - org.crosswire.jsword.book.BookFilters
 
Classes in this File Line Coverage Branch Coverage Complexity
BookFilters
0%
0/27
0%
0/4
1.6
BookFilters$1
0%
0/2
0%
0/4
1.6
BookFilters$2
0%
0/2
0%
0/4
1.6
BookFilters$3
0%
0/2
0%
0/2
1.6
BookFilters$AllBookFilter
0%
0/2
N/A
1.6
BookFilters$BookCategoryFilter
0%
0/4
0%
0/4
1.6
BookFilters$BookFeatureFilter
0%
0/4
0%
0/4
1.6
BookFilters$CustomBookFilter
0%
0/16
0%
0/12
1.6
BookFilters$CustomBookFilter$Test
0%
0/11
0%
0/6
1.6
BookFilters$NotBookCategoryFilter
0%
0/4
0%
0/4
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  
 }