Coverage Report - org.crosswire.jsword.examples.APIExamples
 
Classes in this File Line Coverage Branch Coverage Complexity
APIExamples
0%
0/139
0%
0/40
2.733
APIExamples$MyBookFilter
0%
0/4
N/A
2.733
APIExamples$MyBooksListener
0%
0/3
N/A
2.733
 
 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  
  * Copyright: 2005
 18  
  *     The copyright to this program is held by its authors.
 19  
  *
 20  
  */
 21  
 package org.crosswire.jsword.examples;
 22  
 
 23  
 import java.net.URL;
 24  
 import java.util.Iterator;
 25  
 import java.util.List;
 26  
 import java.util.Map;
 27  
 
 28  
 import javax.xml.transform.TransformerException;
 29  
 
 30  
 import org.crosswire.common.util.NetUtil;
 31  
 import org.crosswire.common.util.ResourceUtil;
 32  
 import org.crosswire.common.xml.Converter;
 33  
 import org.crosswire.common.xml.SAXEventProvider;
 34  
 import org.crosswire.common.xml.TransformingSAXEventProvider;
 35  
 import org.crosswire.common.xml.XMLUtil;
 36  
 import org.crosswire.jsword.book.Book;
 37  
 import org.crosswire.jsword.book.BookCategory;
 38  
 import org.crosswire.jsword.book.BookData;
 39  
 import org.crosswire.jsword.book.BookException;
 40  
 import org.crosswire.jsword.book.BookFilter;
 41  
 import org.crosswire.jsword.book.BookFilters;
 42  
 import org.crosswire.jsword.book.BookMetaData;
 43  
 import org.crosswire.jsword.book.Books;
 44  
 import org.crosswire.jsword.book.BooksEvent;
 45  
 import org.crosswire.jsword.book.BooksListener;
 46  
 import org.crosswire.jsword.book.OSISUtil;
 47  
 import org.crosswire.jsword.book.install.InstallException;
 48  
 import org.crosswire.jsword.book.install.InstallManager;
 49  
 import org.crosswire.jsword.book.install.Installer;
 50  
 import org.crosswire.jsword.index.search.DefaultSearchModifier;
 51  
 import org.crosswire.jsword.index.search.DefaultSearchRequest;
 52  
 import org.crosswire.jsword.passage.Key;
 53  
 import org.crosswire.jsword.passage.NoSuchKeyException;
 54  
 import org.crosswire.jsword.passage.Passage;
 55  
 import org.crosswire.jsword.passage.PassageTally;
 56  
 import org.crosswire.jsword.passage.RestrictionType;
 57  
 import org.crosswire.jsword.passage.VerseRange;
 58  
 import org.crosswire.jsword.util.ConverterFactory;
 59  
 import org.xml.sax.SAXException;
 60  
 
 61  
 /**
 62  
  * All the methods in this class highlight some are of the API and how to use
 63  
  * it.
 64  
  * 
 65  
  * @see gnu.lgpl.License The GNU Lesser General Public License for details.
 66  
  * @author Joe Walker
 67  
  */
 68  0
 public class APIExamples {
 69  
     /**
 70  
      * The name of a Bible to find
 71  
      */
 72  
     private static final String BIBLE_NAME = "KJV";
 73  
 
 74  
     /**
 75  
      * Get a particular installed book by initials.
 76  
      * 
 77  
      * @param bookInitials
 78  
      *            The book name to search for
 79  
      * @return The found book. Null otherwise.
 80  
      */
 81  
     public Book getBook(String bookInitials) {
 82  0
         return Books.installed().getBook(bookInitials);
 83  
     }
 84  
 
 85  
     /**
 86  
      * Get just the canonical text of one or more book entries without any
 87  
      * markup.
 88  
      * 
 89  
      * @param bookInitials
 90  
      *            the book to use
 91  
      * @param reference
 92  
      *            a reference, appropriate for the book, of one or more entries
 93  
      * @return the plain text for the reference
 94  
      * @throws BookException 
 95  
      * @throws NoSuchKeyException 
 96  
      */
 97  
     public String getPlainText(String bookInitials, String reference) throws BookException, NoSuchKeyException {
 98  0
         Book book = getBook(bookInitials);
 99  0
         if (book == null) {
 100  0
             return "";
 101  
         }
 102  
 
 103  0
         Key key = book.getKey(reference);
 104  0
         BookData data = new BookData(book, key);
 105  0
         return OSISUtil.getCanonicalText(data.getOsisFragment());
 106  
     }
 107  
 
 108  
     /**
 109  
      * Obtain a SAX event provider for the OSIS document representation of one
 110  
      * or more book entries.
 111  
      * 
 112  
      * @param bookInitials
 113  
      *            the book to use
 114  
      * @param reference
 115  
      *            a reference, appropriate for the book, of one or more entries
 116  
      * @param maxKeyCount 
 117  
      * @return a SAX Event Provider to retrieve the reference
 118  
      * @throws BookException 
 119  
      * @throws NoSuchKeyException 
 120  
      */
 121  
     public SAXEventProvider getOSIS(String bookInitials, String reference, int maxKeyCount) throws BookException, NoSuchKeyException {
 122  0
         if (bookInitials == null || reference == null) {
 123  0
             return null;
 124  
         }
 125  
 
 126  0
         Book book = getBook(bookInitials);
 127  
 
 128  0
         Key key = null;
 129  0
         if (BookCategory.BIBLE.equals(book.getBookCategory())) {
 130  0
             key = book.getKey(reference);
 131  0
             ((Passage) key).trimVerses(maxKeyCount);
 132  
         } else {
 133  0
             key = book.createEmptyKeyList();
 134  
 
 135  0
             int count = 0;
 136  0
             for (Key aKey : book.getKey(reference)) {
 137  0
                 if (++count >= maxKeyCount) {
 138  0
                     break;
 139  
                 }
 140  0
                 key.addAll(aKey);
 141  
             }
 142  
         }
 143  
 
 144  0
         BookData data = new BookData(book, key);
 145  
 
 146  0
         return data.getSAXEventProvider();
 147  
     }
 148  
 
 149  
     /**
 150  
      * Obtain styled text (in this case HTML) for a book reference.
 151  
      * 
 152  
      * @param bookInitials
 153  
      *            the book to use
 154  
      * @param reference
 155  
      *            a reference, appropriate for the book, of one or more entries
 156  
      * @param maxKeyCount 
 157  
      * @return the styled text
 158  
      * @throws NoSuchKeyException 
 159  
      * @throws BookException 
 160  
      * @throws TransformerException 
 161  
      * @throws SAXException 
 162  
      * @see Book
 163  
      * @see SAXEventProvider
 164  
      */
 165  
     public String readStyledText(String bookInitials, String reference, int maxKeyCount) throws NoSuchKeyException, BookException, TransformerException,
 166  
             SAXException
 167  
     {
 168  0
         Book book = getBook(bookInitials);
 169  0
         SAXEventProvider osissep = getOSIS(bookInitials, reference, maxKeyCount);
 170  0
         if (osissep == null) {
 171  0
             return "";
 172  
         }
 173  
 
 174  0
         Converter styler = ConverterFactory.getConverter();
 175  
 
 176  0
         TransformingSAXEventProvider htmlsep = (TransformingSAXEventProvider) styler.convert(osissep);
 177  
 
 178  
         // You can also pass parameters to the XSLT. What you pass depends upon
 179  
         // what the XSLT can use.
 180  0
         BookMetaData bmd = book.getBookMetaData();
 181  0
         boolean direction = bmd.isLeftToRight();
 182  0
         htmlsep.setParameter("direction", direction ? "ltr" : "rtl");
 183  
 
 184  
         // Finally you can get the styled text.
 185  0
         return XMLUtil.writeToString(htmlsep);
 186  
     }
 187  
 
 188  
     /**
 189  
      * While Bible and Commentary are very similar, a Dictionary is read in a
 190  
      * slightly different way. It is also worth looking at the JavaDoc for Book
 191  
      * that has a way of treating Bible, Commentary and Dictionary the same.
 192  
      * 
 193  
      * @throws BookException 
 194  
      * @see Book
 195  
      */
 196  
     public void readDictionary() throws BookException {
 197  
         // This just gets a list of all the known dictionaries and picks the
 198  
         // first. In a real world app you will probably have a better way
 199  
         // of doing this.
 200  0
         List<Book> dicts = Books.installed().getBooks(BookFilters.getDictionaries());
 201  0
         Book dict = dicts.get(0);
 202  
 
 203  
         // If I want every key in the Dictionary then I do this (or something
 204  
         // like it - in the real world you want to call hasNext() on an iterator
 205  
         // before next() but the point is the same:
 206  0
         Key keys = dict.getGlobalKeyList();
 207  0
         Key first = keys.iterator().next();
 208  
 
 209  0
         System.out.println("The first Key in the default dictionary is " + first);
 210  
 
 211  0
         BookData data = new BookData(dict, first);
 212  0
         System.out.println("And the text against that key is " + OSISUtil.getPlainText(data.getOsisFragment()));
 213  0
     }
 214  
 
 215  
     /**
 216  
      * An example of how to search for various bits of data.
 217  
      * 
 218  
      * @throws BookException 
 219  
      */
 220  
     public void search() throws BookException {
 221  0
         Book bible = Books.installed().getBook(BIBLE_NAME);
 222  
 
 223  
         // This does a standard operator search. See the search documentation
 224  
         // for more examples of how to search
 225  0
         Key key = bible.find("+moses +aaron");
 226  
 
 227  0
         System.out.println("The following verses contain both moses and aaron: " + key.getName());
 228  
 
 229  
         // You can also trim the result to a more manageable quantity.
 230  
         // The test here is not necessary since we are working with a bible. It
 231  
         // is necessary if we don't know what it
 232  
         // is.
 233  0
         if (key instanceof Passage) {
 234  0
             Passage remaining = ((Passage) key).trimVerses(5);
 235  0
             System.out.println("The first 5 verses containing both moses and aaron: " + key.getName());
 236  0
             if (remaining != null) {
 237  0
                 System.out.println("The rest of the verses are: " + remaining.getName());
 238  
             } else {
 239  0
                 System.out.println("There are only 5 verses containing both moses and aaron");
 240  
             }
 241  
         }
 242  0
     }
 243  
 
 244  
     /**
 245  
      * An example of how to perform a ranked search.
 246  
      * 
 247  
      * @throws BookException
 248  
      */
 249  
     void rankedSearch() throws BookException {
 250  0
         Book bible = Books.installed().getBook(BIBLE_NAME);
 251  
 
 252  
         // For a more complex example:
 253  
         // Rank the verses and show the first 20
 254  0
         boolean rank = true;
 255  0
         int max = 20;
 256  
 
 257  0
         DefaultSearchModifier modifier = new DefaultSearchModifier();
 258  0
         modifier.setRanked(rank);
 259  0
         modifier.setMaxResults(max);
 260  
 
 261  0
         Key results = bible.find(new DefaultSearchRequest("for god so loved the world", modifier));
 262  0
         int total = results.getCardinality();
 263  0
         int partial = total;
 264  
 
 265  
         // we get PassageTallys for rank searches
 266  0
         if (results instanceof PassageTally || rank) {
 267  0
             PassageTally tally = (PassageTally) results;
 268  0
             tally.setOrdering(PassageTally.Order.TALLY);
 269  0
             int rankCount = max;
 270  0
             if (rankCount > 0 && rankCount < total) {
 271  
                 // Here we are trimming by ranges, where a range is a set of
 272  
                 // continuous verses.
 273  0
                 tally.trimRanges(rankCount, RestrictionType.NONE);
 274  0
                 partial = rankCount;
 275  
             }
 276  
         }
 277  0
         System.out.println("Showing the first " + partial + " of " + total + " verses.");
 278  0
         System.out.println(results);
 279  0
     }
 280  
 
 281  
     /**
 282  
      * An example of how to do a search and then get text for each range of
 283  
      * verses.
 284  
      * 
 285  
      * @throws BookException
 286  
      * @throws SAXException
 287  
      */
 288  
     void searchAndShow() throws BookException, SAXException {
 289  0
         Book bible = Books.installed().getBook(BIBLE_NAME);
 290  
 
 291  
         // Search for words like Melchezedik
 292  0
         Key key = bible.find("melchesidec~");
 293  
 
 294  
         // Here is an example of how to iterate over the ranges and get the text
 295  
         // for each.
 296  
         // The key's iterator would have iterated over verses.
 297  
 
 298  
         // The following shows how to use a stylesheet of your own choosing
 299  0
         String path = "xsl/cswing/simple.xsl";
 300  0
         URL xslurl = ResourceUtil.getResource(path);
 301  
         // Make ranges  break  on  chapter
 302  0
         Iterator<VerseRange> rangeIter = ((Passage) key).rangeIterator(RestrictionType.CHAPTER);
 303  
         // boundaries.
 304  0
         while (rangeIter.hasNext()) {
 305  0
             Key range = rangeIter.next();
 306  0
             BookData data = new BookData(bible, range);
 307  0
             SAXEventProvider osissep = data.getSAXEventProvider();
 308  0
             SAXEventProvider htmlsep = new TransformingSAXEventProvider(NetUtil.toURI(xslurl), osissep);
 309  0
             String text = XMLUtil.writeToString(htmlsep);
 310  0
             System.out.println("The html text of " + range.getName() + " is " + text);
 311  0
         }
 312  0
     }
 313  
 
 314  
     /**
 315  
      * This is an example of the different ways to select a Book from the
 316  
      * selection available.
 317  
      * 
 318  
      * @see org.crosswire.common.config.Config
 319  
      * @see Books
 320  
      */
 321  
     public void pickBible() {
 322  
         // The Default Bible - JSword does everything it can to make this work
 323  0
         Book book = Books.installed().getBook(BIBLE_NAME);
 324  
 
 325  
         // And you can find out more too:
 326  0
         System.out.println(book.getLanguage());
 327  
 
 328  
         // If you want a greater selection of Books:
 329  0
         List<Book> books = Books.installed().getBooks();
 330  0
         book = books.get(0);
 331  
 
 332  
         // Or you can narrow the range a bit
 333  0
         books = Books.installed().getBooks(BookFilters.getOnlyBibles());
 334  0
         book = books.get(0);
 335  
 
 336  
         // There are implementations of BookFilter for all sorts of things in
 337  
         // the BookFilters class
 338  
 
 339  
         // If you are wanting to get really fancy you can implement your own
 340  
         // BookFilter easily
 341  0
         List<Book> test = Books.installed().getBooks(new MyBookFilter("ESV"));
 342  0
         book = test.get(0);
 343  
 
 344  0
         if (book != null) {
 345  0
             System.out.println(book.getInitials());
 346  
         }
 347  
 
 348  
         // If you want to know about new books as they arrive:
 349  0
         Books.installed().addBooksListener(new MyBooksListener());
 350  0
     }
 351  
 
 352  
     public void installBook() {
 353  
         // An installer knows how to install books
 354  0
         Installer installer = null;
 355  
 
 356  0
         InstallManager imanager = new InstallManager();
 357  
 
 358  
         // Ask the Install Manager for a map of all known module sites
 359  0
         Map<String, Installer> installers = imanager.getInstallers();
 360  
 
 361  
         // Get all the installers one after the other
 362  0
         String name = null;
 363  0
         for (Map.Entry<String, Installer> mapEntry : installers.entrySet()) {
 364  0
             name = mapEntry.getKey();
 365  0
             installer = mapEntry.getValue();
 366  0
             System.out.println(name + ": " + installer.getInstallerDefinition());
 367  
         }
 368  
 
 369  0
         name = "CrossWire";
 370  
         // If we know the name of the installer we can get it directly
 371  0
         installer = imanager.getInstaller(name);
 372  
 
 373  
         // Now we can get the list of books
 374  
         try {
 375  0
             installer.reloadBookList();
 376  0
         } catch (InstallException e) {
 377  0
             e.printStackTrace();
 378  0
         }
 379  
 
 380  
         // Get a list of all the available books
 381  0
         List<Book> availableBooks = installer.getBooks();
 382  
 
 383  0
         Book book = availableBooks.get(0);
 384  0
         if (book != null) {
 385  0
             System.out.println("Book " + book.getInitials() + " is available");
 386  
         }
 387  
 
 388  
         // get some available books. In this case, just one book.
 389  0
         availableBooks = installer.getBooks(new MyBookFilter("ESV"));
 390  
 
 391  0
         book = availableBooks.get(0);
 392  
 
 393  0
         if (book != null) {
 394  0
             System.out.println("Book " + book.getInitials() + " is available");
 395  
 
 396  
             // Delete the book, if present
 397  
             // At the moment, JSword will not re-install. Later it will, if the
 398  
             // remote version is greater.
 399  
             try {
 400  0
                 if (Books.installed().getBook("ESV") != null) {
 401  
                     // Make the book unavailable.
 402  
                     // This is normally done via listeners.
 403  0
                     Books.installed().removeBook(book);
 404  
 
 405  
                     // Actually do the delete
 406  
                     // This should be a call on installer.
 407  0
                     book.getDriver().delete(book);
 408  
                 }
 409  0
             } catch (BookException e1) {
 410  0
                 e1.printStackTrace();
 411  0
             }
 412  
 
 413  
             try {
 414  
                 // Now install it. Note this is a background task.
 415  0
                 installer.install(book);
 416  0
             } catch (InstallException e) {
 417  0
                 e.printStackTrace();
 418  0
             }
 419  
         }
 420  0
     }
 421  
 
 422  
     /**
 423  
      * A simple BookFilter that looks for a Bible by name.
 424  
      */
 425  
     static class MyBookFilter implements BookFilter {
 426  0
         public MyBookFilter(String bookName) {
 427  0
             name = bookName;
 428  0
         }
 429  
 
 430  
         public boolean test(Book bk) {
 431  0
             return bk.getInitials().equals(name);
 432  
         }
 433  
 
 434  
         private String name;
 435  
     }
 436  
 
 437  
     /**
 438  
      * A simple BooksListener that actually does nothing.
 439  
      */
 440  0
     static class MyBooksListener implements BooksListener {
 441  
         /*
 442  
          * (non-Javadoc)
 443  
          * 
 444  
          * @see
 445  
          * org.crosswire.jsword.book.BooksListener#bookAdded(org.crosswire.jsword
 446  
          * .book.BooksEvent)
 447  
          */
 448  
         public void bookAdded(BooksEvent ev) {
 449  0
         }
 450  
 
 451  
         /*
 452  
          * (non-Javadoc)
 453  
          * 
 454  
          * @see
 455  
          * org.crosswire.jsword.book.BooksListener#bookRemoved(org.crosswire
 456  
          * .jsword.book.BooksEvent)
 457  
          */
 458  
         public void bookRemoved(BooksEvent ev) {
 459  0
         }
 460  
     }
 461  
 
 462  
     /**
 463  
      * Quick Demo
 464  
      * @param args 
 465  
      * 
 466  
      * @throws NoSuchKeyException
 467  
      * @throws BookException
 468  
      * @throws SAXException
 469  
      * @throws TransformerException
 470  
      */
 471  
     public static void main(String[] args) throws BookException, NoSuchKeyException, TransformerException, SAXException {
 472  0
         APIExamples examples = new APIExamples();
 473  
 
 474  0
         examples.installBook();
 475  0
         System.out.println("The plain text of Gen 1:1 is " + examples.getPlainText(BIBLE_NAME, "Gen 1:1"));
 476  0
         System.out.println("The html text of Gen 1:1 is " + examples.readStyledText(BIBLE_NAME, "Gen 1:1", 100));
 477  0
         examples.readDictionary();
 478  0
         examples.search();
 479  0
         examples.rankedSearch();
 480  0
         examples.searchAndShow();
 481  0
     }
 482  
 }