private void checkAllBooksInstalled() {
    BookInstaller bookInstaller = new BookInstaller();
    List<Book> books = (List<Book>) bookInstaller.getRepositoryBooks(REPOSITORY, BOOK_FILTER);

    for (Book book : books) {
      try {
        Book installedBook = bookInstaller.getInstalledBook(book.getInitials());
        if (installedBook == null) {
          System.out.println("Not installed:" + book.getInitials() + " Name:" + book.getName());
        } else {
          Version versionObj = (Version) book.getProperty("Version");
          String version = versionObj == null ? "No version" : versionObj.toString();

          Version installedVersionObj =
              (Version) installedBook.getBookMetaData().getProperty("Version");
          String installedVersion =
              installedVersionObj == null ? "No version" : installedVersionObj.toString();
          if (!version.equals(installedVersion)) {
            System.out.println(
                "Incorrect version of "
                    + book.getInitials()
                    + " installed:"
                    + installedVersion
                    + " Repo:"
                    + version);
          } else {
            System.out.println("Okay:" + book.getInitials() + " " + version);
          }
        }
      } catch (Exception e) {
        System.out.println("Error installing:" + book.getInitials());
        e.printStackTrace();
      }
    }
  }
 private CurrentPage getBookPage(Book book) {
   if (book.equals(currentMyNotePage.getCurrentDocument())) {
     return currentMyNotePage;
   } else {
     return getBookPage(book.getBookCategory());
   }
 }
  private void showInstalledBooks() {
    List<Book> books = (List<Book>) BookInstaller.getInstalledBooks();

    for (Book book : books) {
      System.out.println(book.getName());
    }
  }
  private void addPropertiesFile() {
    Properties indexProperties = new Properties();
    indexProperties.put("version", "1");
    indexProperties.put(
        "java.specification.version", System.getProperty("java.specification.version"));
    indexProperties.put("java.vendor", System.getProperty("java.vendor"));
    indexProperties.put(
        "lucene.specification.version", LucenePackage.get().getSpecificationVersion());

    List<Book> books = (List<Book>) BookInstaller.getInstalledBooks();
    for (Book book : books) {
      System.out.println(
          "Adding properties file:" + book.getInitials() + " name:" + book.getName());
      String initials = book.getInitials();
      File indexPropertiesFile = new File(LUCENE_INDEX_DIR_FILE, initials + "/index.properties");

      FileOutputStream fos = null;
      try {
        fos = new FileOutputStream(indexPropertiesFile);
        indexProperties.store(fos, null);
      } catch (IOException ioe) {
        System.out.println(ioe.getMessage());
        ioe.printStackTrace();
      } finally {
        if (fos != null) {
          try {
            fos.close();
          } catch (IOException e2) {
            e2.printStackTrace();
          }
        }
      }
    }
  }
  /**
   * check index exists and go to search screen if index exists if no more jobs in progress and no
   * index then error
   */
  @Override
  protected void jobFinished(Progress jobJustFinished) {
    // give the document up to 12 secs to reload - the Progress declares itself finished before the
    // index status has been changed
    int attempts = 0;
    while (!IndexStatus.DONE.equals(documentBeingIndexed.getIndexStatus()) && attempts++ < 6) {
      CommonUtils.pause(2);
    }

    // if index is fine then goto search
    if (IndexStatus.DONE.equals(documentBeingIndexed.getIndexStatus())) {
      Log.i(TAG, "Index created");
      Intent intent = null;
      if (StringUtils.isNotEmpty(getIntent().getStringExtra(SearchControl.SEARCH_TEXT))) {
        // the search string was passed in so execute it directly
        intent = new Intent(this, SearchResults.class);
        intent.putExtras(getIntent().getExtras());
      } else {
        // just go to the normal Search screen
        intent = new Intent(this, Search.class);
      }
      startActivity(intent);
      finish();
    } else {
      // if jobs still running then just wait else error

      if (isAllJobsFinished()) {
        Log.e(TAG, "Index finished but document's index is invalid");
        showErrorMsg(R.string.error_occurred);
      }
    }
  }
  private void showRepoBooks() {
    BookInstaller bookInstaller = new BookInstaller();
    List<Book> books = (List<Book>) bookInstaller.getRepositoryBooks(REPOSITORY, BOOK_FILTER);

    for (Book book : books) {
      String lang = book.getLanguage() == null ? " " : book.getLanguage().getCode();
      System.out.println(lang + " " + book.getName());
    }
  }
示例#7
0
 private Book getBook(String initials) {
   for (Book book : books) {
     if (book.getInitials().equals(initials)) {
       System.out.print("Found:" + book.getName());
       return book;
     }
   }
   return null;
 }
  /** @param book */
  private void createZipFile(Book book) {
    System.out.println("Zipping file:" + book.getInitials() + " name:" + book.getName());
    String initials = book.getInitials();
    String version = book.getBookMetaData().getProperty("Version").toString();
    String versionSuffix = version != null ? "-" + version : "";
    File zipFile = new File(LUCENE_ZIP_DIR_FILE, initials + versionSuffix + ".zip");

    File indexDir = new File(LUCENE_INDEX_DIR_FILE, initials);

    createZipFile(zipFile, indexDir);
  }
 /** ensure a book is indexed and the index contains typical Greek or Hebrew Strongs Numbers */
 private boolean checkStrongs(Book bible) {
   try {
     return bible.getIndexStatus().equals(IndexStatus.DONE)
         && (bible.find("+[Gen 1:1] strong:h7225").getCardinality() > 0
             || bible.find("+[John 1:1] strong:g746").getCardinality() > 0
             || bible.find("+[Gen 1:1] strong:g746").getCardinality() > 0);
   } catch (BookException be) {
     System.out.println("Error checking strongs numbers: " + be.getMessage());
     return false;
   }
 }
示例#10
0
  public void testGetStrongs() throws NoSuchKeyException, BookException {
    Book book = Books.installed().getBook("KJV");
    assertTrue(
        "Should have Strongs", book.getBookMetaData().hasFeature(FeatureType.STRONGS_NUMBERS));

    Key key = book.getKey("Gen 1:1");
    BookData data = new BookData(book, key);
    Element osis = data.getOsisFragment();

    String strongsNumbers = OSISUtil.getStrongsNumbers(osis);
    assertTrue("No Strongs in KJV", strongsNumbers.length() > 0);
  }
  private void deleteBook(Book book) {
    System.out.println("Deleting:" + book.getInitials() + " name:" + book.getName());
    try {
      IndexManager imanager = IndexManagerFactory.getIndexManager();
      if (imanager.isIndexed(book)) {
        imanager.deleteIndex(book);
      }

      book.getDriver().delete(book);
    } catch (Exception e) {
      System.out.println("Failed to delete " + book.getInitials() + ":" + e.getMessage());
      e.printStackTrace();
    }
  }
  /*
   * (non-Javadoc)
   *
   * @see org.crosswire.jsword.book.BookList#getBook(java.lang.String)
   */
  public synchronized Book getBook(String name) {
    // Check name first
    // First check for exact matches
    for (Book book : getBooks()) {
      if (name.equals(book.getName())) {
        return book;
      }
    }

    // Next check for case-insensitive matches
    for (Book book : getBooks()) {
      if (name.equalsIgnoreCase(book.getName())) {
        return book;
      }
    }

    // Then check initials
    // First check for exact matches
    for (Book book : getBooks()) {
      BookMetaData bmd = book.getBookMetaData();
      if (name.equals(bmd.getInitials())) {
        return book;
      }
    }

    // Next check for case-insensitive matches
    for (Book book : getBooks()) {
      if (name.equalsIgnoreCase(book.getInitials())) {
        return book;
      }
    }
    return null;
  }
  /** display a new Document and return the new Page */
  public CurrentPage setCurrentDocument(Book nextDocument) {
    CurrentPage nextPage = null;
    if (nextDocument != null) {
      PassageChangeMediator.getInstance().onBeforeCurrentPageChanged();

      nextPage = getBookPage(nextDocument);

      // is the next doc the same as the prev doc
      boolean sameDoc = nextDocument.equals(nextPage.getCurrentDocument());

      // must be in this order because History needs to grab the current doc before change
      nextPage.setCurrentDocument(nextDocument);
      currentDisplayedPage = nextPage;

      // page will change due to above
      // if there is a valid share key or the doc (hence the key) in the next page is the same then
      // show the page straight away
      if ((nextPage.isShareKeyBetweenDocs() || sameDoc) && nextPage.getKey() != null) {
        PassageChangeMediator.getInstance().onCurrentPageChanged();
      } else {
        Context context = CurrentActivityHolder.getInstance().getCurrentActivity();
        // pop up a key selection screen
        Intent intent = new Intent(context, nextPage.getKeyChooserActivity());
        context.startActivity(intent);
      }
    } else {
      // should never get here because a doc should always be passed in but I have seen errors lie
      // this once or twice
      nextPage = currentDisplayedPage;
    }

    return nextPage;
  }
示例#14
0
 public void testReference() {
   try {
     THMLFilter thmlFilter = new THMLFilter();
     Book dummyBook = Books.installed().getBook("KJV");
     List<Content> out =
         thmlFilter.toOSIS(
             dummyBook,
             dummyBook.getKey("Gen.1.1"),
             "<a href=\"sword://StrongsRealGreek/01909\">1909</a>");
     assertEquals(
         "THML reference not handled correctly",
         "<reference osisRef=\"sword://StrongsRealGreek/01909\">1909</reference>",
         new XMLOutputter().outputString((Element) out.get(0)));
   } catch (Exception e) {
     e.printStackTrace();
   }
 }
 public void validateIndex(Book book) {
   try {
     if (hasStrongs(book)) {
       if (!book.getIndexStatus().equals(IndexStatus.DONE)) {
         System.out.println("Unindexed:" + book);
       } else {
         if (!checkStrongs(book)) {
           System.out.println("No refs returned in" + book.getInitials());
         } else {
           System.out.println("Ok:" + book.getInitials());
         }
         //					assertTrue("No refs returned in"+book.getInitials(), resultsH.getCardinality()>0 ||
         // resultsG.getCardinality()>0);
       }
     }
   } catch (Exception e) {
     System.out.println("Error:" + book.getInitials() + ":" + e.getMessage());
   }
 }
  /* @Override */
  public boolean equals(Object obj) {
    // Since this can not be null
    if (obj == null) {
      return false;
    }

    // We might consider checking for equality against all Books?
    // However currently we dont.

    // Check that that is the same as this
    // Don't use instanceof since that breaks inheritance
    if (!obj.getClass().equals(this.getClass())) {
      return false;
    }

    // The real bit ...
    Book that = (Book) obj;

    return bmd.equals(that.getBookMetaData());
  }
  /** @param book */
  private void indexBook(Book book) {
    System.out.println("Indexing:" + book.getInitials() + " name:" + book.getName());
    try {
      BookIndexer bookIndexer = new BookIndexer(book);

      if (!bookIndexer.isIndexed()) {
        try {
          bookIndexer.createIndex();
          waitToFinish();
        } catch (Exception e) {
          System.out.println(e.getMessage());
          e.printStackTrace();
        }
      } else {
        System.out.println("Already indexed:" + book.getInitials());
      }
    } catch (Exception e) {
      System.out.println("Failed to delete " + book.getInitials() + ":" + e.getMessage());
      e.printStackTrace();
    }
  }
示例#18
0
  private URI getIndexStorageArea(Book book) throws IOException {
    BookMetaData bmd = book.getBookMetaData();
    String driverName = bmd.getDriverName();
    String bookName = bmd.getInitials();

    assert driverName != null;
    assert bookName != null;

    URI base = CWProject.instance().getWriteableProjectSubdir(DIR_LUCENE, false);
    URI driver = NetUtil.lengthenURI(base, driverName);

    return NetUtil.lengthenURI(driver, bookName);
  }
  /*
   * (non-Javadoc)
   *
   * @see
   * org.crosswire.jsword.book.install.Installer#downloadSearchIndex(org.crosswire
   * .jsword.book.BookMetaData, java.net.URI)
   */
  public void downloadSearchIndex(Book book, URI localDest) throws InstallException {
    // TRANSLATOR: Progress label for downloading one or more files.
    String jobName = JSMsg.gettext("Downloading files");
    Progress job = JobManager.createJob(jobName, Thread.currentThread());
    job.beginJob(jobName);

    // MJD START
    // use and-bible index location
    String indexLocation = "/and-bible/indices/v1";
    try {
      Version versionObj = (Version) book.getBookMetaData().getProperty("Version");
      String version = versionObj == null ? null : versionObj.toString();
      String versionSuffix = version != null ? "-" + version : "";
      download(job, indexLocation, book.getInitials() + versionSuffix + ZIP_SUFFIX, localDest);
      // MJD END
      //          download(job, packageDirectory + '/' + SEARCH_DIR, book.getInitials() +
      // ZIP_SUFFIX, localDest);
    } catch (InstallException ex) {
      job.cancel();
      throw ex;
    } finally {
      job.done();
    }
  }
  /*
   * (non-Javadoc)
   *
   * @see
   * org.crosswire.jsword.book.install.Installer#isNewer(org.crosswire.jsword
   * .book.BookMetaData)
   */
  public boolean isNewer(Book book) {
    File dldir = SwordBookPath.getSwordDownloadDir();

    SwordBookMetaData sbmd = (SwordBookMetaData) book.getBookMetaData();
    File conf = new File(dldir, sbmd.getConfPath());

    // The conf may not exist in our download dir.
    // In this case we say that it should not be downloaded again.
    if (!conf.exists()) {
      return false;
    }

    URI configURI = NetUtil.getURI(conf);

    URI remote = toRemoteURI(book);
    return NetUtil.isNewer(remote, configURI, proxyHost, proxyPort);
  }
  private void installRepoBooks() {
    BookInstaller bookInstaller = new BookInstaller();
    List<Book> books = (List<Book>) bookInstaller.getRepositoryBooks(REPOSITORY, BOOK_FILTER);

    for (Book book : books) {
      try {
        if (Books.installed().getBook(book.getInitials()) != null) {
          System.out.println("Already installed:" + book.getInitials() + ":" + book.getName());
        } else {
          System.out.println(
              "Downloading and installing:" + book.getInitials() + ":" + book.getName());
          bookInstaller.installBook(REPOSITORY, book);
          waitToFinish();
        }
      } catch (Exception e) {
        System.out.println("Error installing:" + book.getInitials());
        e.printStackTrace();
      }
    }
  }
  /** Load the cached index file into memory */
  private void loadCachedIndex() throws InstallException {
    // We need a sword book driver so the installer can use the driver
    // name to use in deciding where to put the index.
    BookDriver fake = SwordBookDriver.instance();

    entries.clear();

    URI cache = getCachedIndexFile();
    if (!NetUtil.isFile(cache)) {
      reloadBookList();
    }

    InputStream in = null;
    GZIPInputStream gin = null;
    TarInputStream tin = null;
    try {
      ConfigEntry.resetStatistics();

      in = NetUtil.getInputStream(cache);
      gin = new GZIPInputStream(in);
      tin = new TarInputStream(gin);
      while (true) {
        TarEntry entry = tin.getNextEntry();
        if (entry == null) {
          break;
        }

        String internal = entry.getName();
        if (!entry.isDirectory()) {
          try {
            int size = (int) entry.getSize();

            // Every now and then an empty entry sneaks in
            if (size == 0) {
              log.error("Empty entry: " + internal);
              continue;
            }

            byte[] buffer = new byte[size];
            if (tin.read(buffer) != size) {
              // This should not happen, but if it does then skip
              // it.
              log.error("Did not read all that was expected " + internal);
              continue;
            }

            if (internal.endsWith(SwordConstants.EXTENSION_CONF)) {
              internal = internal.substring(0, internal.length() - 5);
            } else {
              log.error("Not a SWORD config file: " + internal);
              continue;
            }

            if (internal.startsWith(SwordConstants.DIR_CONF + '/')) {
              internal = internal.substring(7);
            }

            SwordBookMetaData sbmd = new SwordBookMetaData(buffer, internal);
            sbmd.setDriver(fake);
            Book book = new SwordBook(sbmd, null);
            entries.put(book.getName(), book);
          } catch (IOException ex) {
            log.error("Failed to load config for entry: " + internal, ex);
          }
        }
      }

      loaded = true;

      ConfigEntry.dumpStatistics();
    } catch (IOException ex) {
      throw new InstallException(JSOtherMsg.lookupText("Error loading from cache"), ex);
    } finally {
      IOUtil.close(tin);
      IOUtil.close(gin);
      IOUtil.close(in);
    }
  }
  /*
   * (non-Javadoc)
   *
   * @see
   * org.crosswire.jsword.book.install.Installer#install(org.crosswire.jsword
   * .book.Book)
   */
  public void install(Book book) {
    // // Is the book already installed? Then nothing to do.
    // if (Books.installed().getBook(book.getName()) != null)
    // {
    // return;
    // }
    //
    final SwordBookMetaData sbmd = (SwordBookMetaData) book.getBookMetaData();

    // So now we know what we want to install - all we need to do
    // is installer.install(name) however we are doing it in the
    // background so we create a job for it.
    final Thread worker =
        new Thread("DisplayPreLoader") {
          /*
           * (non-Javadoc)
           *
           * @see java.lang.Runnable#run()
           */
          @Override
          public void run() {
            // TRANSLATOR: Progress label indicating the installation of a book. {0} is a
            // placeholder for the name of the book.
            String jobName = JSMsg.gettext("Installing book: {0}", sbmd.getName());
            Progress job = JobManager.createJob(jobName, this);

            // Don't bother setting a size, we'll do it later.
            job.beginJob(jobName);

            yield();

            URI temp = null;
            try {
              // TRANSLATOR: Progress label indicating the Initialization of installing of a book.
              job.setSectionName(JSMsg.gettext("Initializing"));

              temp = NetUtil.getTemporaryURI("swd", ZIP_SUFFIX);

              download(job, packageDirectory, sbmd.getInitials() + ZIP_SUFFIX, temp);

              // Once the unzipping is started, we need to continue
              job.setCancelable(false);
              if (!job.isFinished()) {
                File dldir = SwordBookPath.getSwordDownloadDir();
                IOUtil.unpackZip(NetUtil.getAsFile(temp), dldir);
                // TRANSLATOR: Progress label for installing the conf file for a book.
                job.setSectionName(JSMsg.gettext("Copying config file"));
                sbmd.setLibrary(NetUtil.getURI(dldir));
                SwordBookDriver.registerNewBook(sbmd);
              }

            } catch (IOException e) {
              Reporter.informUser(this, e);
              job.cancel();
            } catch (InstallException e) {
              Reporter.informUser(this, e);
              job.cancel();
            } catch (BookException e) {
              Reporter.informUser(this, e);
              job.cancel();
            } finally {
              job.done();
              // tidy up after ourselves
              // This is a best effort. If for some reason it does not delete now
              // it will automatically be deleted when the JVM exits normally.
              if (temp != null) {
                try {
                  NetUtil.delete(temp);
                } catch (IOException e) {
                  log.warn("Error deleting temp download file:" + e.getMessage());
                }
              }
            }
          }
        };

    // this actually starts the thread off
    worker.setPriority(Thread.MIN_PRIORITY);
    worker.start();
  }
示例#24
0
  /**
   * return a list of all available docs that have not already been downloaded, have no lang, or
   * don't work
   *
   * @return
   */
  public List<Book> getDownloadableDocuments(boolean refresh) {
    List<Book> availableDocs = null;
    try {
      availableDocs = SwordDocumentFacade.getInstance().getDownloadableDocuments(refresh);

      // create a Map of installed doc names so we can remove them from the list of downloadable
      // books
      // need to compare using lower case because Xiphos repo books are lower case
      List<Book> installedDocs = SwordDocumentFacade.getInstance().getDocuments();
      Map<String, Object> installedDocInitials = new HashMap<String, Object>();
      for (Book book : installedDocs) {
        Log.d(TAG, "Install list " + book.getInitials() + "/" + book.getInitials().toLowerCase());
        installedDocInitials.put(book.getInitials().toLowerCase(), null);
      }

      // there are a number of books we need to filter out of the download list for various reasons
      for (Iterator<Book> iter = availableDocs.iterator(); iter.hasNext(); ) {
        Book doc = iter.next();
        if (doc.getLanguage() == null) {
          Log.d(TAG, "Ignoring " + doc.getInitials() + " because it has no language");
          iter.remove();
        } else if (installedDocInitials.containsKey(doc.getInitials().toLowerCase())) {
          Log.d(TAG, "Ignoring " + doc.getInitials() + " because already installed");
          iter.remove();
        } else if (doc.isQuestionable()) {
          Log.d(TAG, "Ignoring " + doc.getInitials() + " because it is questionable");
          iter.remove();
        } else if (doc.getInitials().equalsIgnoreCase("westminster")) {
          Log.d(
              TAG,
              "Ignoring "
                  + doc.getInitials()
                  + " because some sections are too large for a mobile phone e.g. Q91-150");
          iter.remove();
        } else if (doc.getInitials().equalsIgnoreCase("passion")) {
          Log.d(TAG, "Ignoring " + doc.getInitials());
          iter.remove();
        } else if (doc.getInitials().equals("WebstersDict")) {
          Log.d(
              TAG,
              "Ignoring "
                  + doc.getInitials()
                  + " because it is too big and crashes dictionary code");
          iter.remove();
        }
      }

      // get fonts.properties at the same time as repo list, or if not yet downloaded
      // the download happens in another thread
      fontControl.checkFontPropertiesFile(refresh);

    } catch (Exception e) {
      Log.e(TAG, "Error downloading document list", e);
      availableDocs = new ArrayList<Book>();
    }
    return availableDocs;
  }
示例#25
0
 private void doFindTest(Book book, String test, int expected) throws BookException {
   Key key = book.find(test);
   System.out.println(test + " found " + key.getCardinality() + " occurences: " + key.getName());
   assertEquals(test + " find count wrong", expected, key.getCardinality());
 }
示例#26
0
  public void dump(String name, String range)
      throws NoSuchKeyException, IOException, BookException {
    Books books = Books.installed();
    Book bible = books.getBook(name);
    BookMetaData bmd = bible.getBookMetaData();
    String lastBookName = "";
    int lastChapter = -1;
    StringBuffer buf = new StringBuffer();
    boolean inPreVerse = false;

    Key keys = bible.getKey(range);

    openOutputFile(bmd.getInitials(), !BY_BOOK);
    buildDocumentOpen(buf, bmd, range, !BY_BOOK);
    if (!BY_BOOK) {
      writeDocument(buf);
    }

    // Get a verse iterator
    for (Key key : keys) {
      Verse verse = (Verse) key;
      String raw = bible.getRawText(verse);
      String osisID = verse.getOsisID();
      String currentBookName = verse.getBook().getOSIS();
      int currentChapter = verse.getChapter();

      boolean newBookFound = !lastBookName.equals(currentBookName);

      if (newBookFound) {
        if (lastBookName.length() > 0) {
          if (currentChapter == 1) {
            if (inPreVerse) {
              buildPreVerseClose(buf);
              inPreVerse = false;
            }
            buildChapterClose(buf);
          }
          buildBookClose(buf);
          buildDocumentClose(buf, BY_BOOK);
          openOutputFile(lastBookName, BY_BOOK);
          writeDocument(buf);
          closeOutputFile(BY_BOOK);
        }

        buf = new StringBuffer();
        buildDocumentOpen(buf, bmd, currentBookName, BY_BOOK);
        buildBookOpen(buf, currentBookName);
      }

      if (newBookFound || lastChapter != currentChapter) {
        if (currentChapter != 1) {
          if (inPreVerse) {
            buildPreVerseClose(buf);
            inPreVerse = false;
          }
          buildChapterClose(buf);
        }
        buildChapterOpen(buf, currentBookName, currentChapter);
      }

      /* Output the verse */

      boolean foundPreVerse = false;
      String preVerseText = "";
      if (raw.indexOf(preVerseStart) != -1) {
        Matcher matcher = preVersePattern.matcher(raw);
        StringBuffer rawbuf = new StringBuffer();
        if (matcher.find()) {
          foundPreVerse = true;
          preVerseText = matcher.group(1);
          matcher.appendReplacement(rawbuf, "");
        }
        matcher.appendTail(rawbuf);
        raw = rawbuf.toString();
      }

      boolean foundPsalmTitle = false;
      String psalmTitleText = "";
      if (raw.indexOf(psalmTitleStart) != -1) {
        Matcher matcher = psalmTitlePattern.matcher(raw);
        StringBuffer rawbuf = new StringBuffer();
        if (matcher.find()) {
          foundPsalmTitle = true;
          psalmTitleText = matcher.group(1);
          matcher.appendReplacement(rawbuf, "");
        }
        matcher.appendTail(rawbuf);
        raw = rawbuf.toString();
      }

      if (foundPsalmTitle) {
        buildPsalmTitle(buf, psalmTitleText);
      }

      if (foundPreVerse && !preVerseText.equals(psalmTitleText)) {
        if (inPreVerse) {
          buildPreVerseClose(buf);
        }
        buildPreVerseOpen(buf, preVerseText);
        inPreVerse = true;
      }

      buildVerseOpen(buf, osisID);
      buf.append(raw);
      buildVerseClose(buf, osisID);

      lastChapter = currentChapter;
      lastBookName = currentBookName;
    }

    // Close everything that is open
    if (inPreVerse) {
      buildPreVerseClose(buf);
      inPreVerse = false;
    }

    buildChapterClose(buf);
    buildBookClose(buf);
    buildDocumentClose(buf, true);
    openOutputFile(lastBookName, BY_BOOK);
    writeDocument(buf);
    closeOutputFile(true);
  }
 private boolean hasStrongs(Book book) {
   Object globalOptionFilter = book.getBookMetaData().getProperty("GlobalOptionFilter");
   return globalOptionFilter == null ? false : globalOptionFilter.toString().contains("Strongs");
 }
  private void installSingleBook(String initials) {
    BookInstaller bookInstaller = new BookInstaller();
    List<Book> books = (List<Book>) bookInstaller.getRepositoryBooks(REPOSITORY, BOOK_FILTER);

    for (Book book : books) {
      if (initials.equalsIgnoreCase(book.getInitials())) {
        String lang = book.getLanguage() == null ? " " : book.getLanguage().getCode();
        System.out.println("Found in repo:" + lang + " " + book.getName());

        try {
          if (Books.installed().getBook(book.getInitials()) != null) {
            System.out.println("Already installed:" + book.getInitials() + ":" + book.getName());
          } else {
            System.out.println(
                "Downloading and installing:" + book.getInitials() + ":" + book.getName());
            bookInstaller.installBook(REPOSITORY, book);
            waitToFinish();
          }

          Book installedBook = bookInstaller.getInstalledBook(book.getInitials());
          if (installedBook == null) {
            System.out.println("Not installed:" + book.getInitials() + " Name:" + book.getName());
          }

        } catch (Exception e) {
          System.out.println("Error installing:" + book.getInitials());
          e.printStackTrace();
        }
      }
    }
  }