Java tutorial
package net.bible.service.download; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import net.bible.service.common.Logger; import net.bible.service.sword.AcceptableBookTypeFilter; import org.apache.commons.lang.StringUtils; import org.crosswire.jsword.book.Book; import org.crosswire.jsword.book.BookException; import org.crosswire.jsword.book.BookFilter; import org.crosswire.jsword.book.BookMetaData; import org.crosswire.jsword.book.Books; import org.crosswire.jsword.book.BooksEvent; import org.crosswire.jsword.book.BooksListener; import org.crosswire.jsword.book.install.InstallException; import org.crosswire.jsword.book.sword.ConfigEntryType; import org.crosswire.jsword.book.sword.SwordBookMetaData; /** some books need renaming after download due to problems with Xiphos module case * * @author Martin Denham [mjdenham at gmail dot com] * @see gnu.lgpl.License for license details.<br> * The copyright to this program is held by it's author. */ public class XiphosRepo extends RepoBase implements BooksListener { // see here for info ftp://ftp.xiphos.org/mods.d/ private static final String XIPHOS_REPOSITORY = "Xiphos"; static final String lineSeparator = System.getProperty("line.separator"); private static final String REAL_INITIALS = "RealInitials"; private static final Logger log = new Logger(XiphosRepo.class.getName()); private static BookFilter SUPPORTED_DOCUMENTS = new XiphosBookFilter(); private static Map<String, String> nameToZipMap = new HashMap<String, String>(); static { // gave up with this approach because of problems with deletion... moved and renamed the following 3 archives to AndBible repo // 1. copy zip from xiphos 2. rename zip to same as Initials 3. open zip and rename module conf to same as initials but lowercase // nameToZipMap.put("eBibleTeacherMaps", "ebibleteacher"); // nameToZipMap.put("EpiphanyMaps", "epiphany-maps"); // nameToZipMap.put("SmithBibleAtlas", "smithatlas"); } private static class XiphosBookFilter extends AcceptableBookTypeFilter { private static Set<String> acceptableInitials = new HashSet<String>(); static { acceptableInitials.add("Gill"); acceptableInitials.add("Augustine"); acceptableInitials.add("FinneySysTheo"); acceptableInitials.add("HodgeSysTheo"); acceptableInitials.add("LifeTimes"); acceptableInitials.add("TrainTwelve"); acceptableInitials.add("PolBibTysia"); acceptableInitials.add("ChiPinyin"); acceptableInitials.add("LuthersWorks"); acceptableInitials.add("Shaw"); acceptableInitials.add("StrongsRealGreek"); acceptableInitials.add("StrongsRealHebrew"); // acceptableInitials.add("Augustin"); // acceptableInitials.add("Chrysostom"); acceptableInitials.add("LutherBondageOfTheWill"); acceptableInitials.add("LutherShortClassics"); // maps acceptableInitials.add("ABSMaps"); // acceptableInitials.add("eBibleTeacherMaps"); // moved to AB repo because of naming inconsistency // acceptableInitials.add("EpiphanyMaps"); // moved to AB repo because of naming inconsistency acceptableInitials.add("HistMidEast"); // acceptableInitials.add("SmithBibleAtlas"); // moved to AB repo because of naming inconsistency acceptableInitials.add("SonLightFreeMaps"); acceptableInitials.add("TextbookAtlas"); acceptableInitials.add("KretzmannMaps"); // acceptableInitials.add("Lineage"); booktype is Images and zip error opening } @Override public boolean test(Book book) { return super.test(book) && acceptableInitials.contains(book.getInitials()); } } // This shows the greek word in addition to the content of the default Strongs dictionary but some of the Greek characters don't display correctly. // xiphosRepoBookList.add(new XiphosRepoBook("strongsrealgreek", "StrongsRealGreek", "DataPath=./modules/lexdict/rawld4/strongsrealgreek/strongsrealgreek\nModDrv=RawLD4\nLang=en\nFeature=GreekDef\nVersion=1.4-100511\nEncoding=UTF-8\nSourceType=ThML\nDescription=Strongs Real Greek Bible Dictionary\nAbout=Text pulled from Ulrik Petersen's content at http://morphgnt.org/projects/strongs-dictionary. In 1996, Michael Grier produced an e-text of Strong's dictionary. He entered every single letter, and did some proof-reading, but transliterated the Greek. In 2006, Ulrik Petersen took Michael Grier's e-text in the version published by the SWORD project and added Greek in UTF-8 where applicable, while transforming the text to XML.")); // must only register book listener once or books get given null names private static int booksToListenForCount = 0; private static boolean isBookListenerAdded = false; /** get a list of books that are available in Xiphos repo and seem to work in And Bible */ public List<Book> getRepoBooks(boolean refresh) throws InstallException { List<Book> booksInRepo = getBookList(SUPPORTED_DOCUMENTS, refresh); storeRepoNameInMetaData(booksInRepo); return booksInRepo; } @Override public void downloadDocument(Book book) throws InstallException, BookException { try { // all the zip files incorrectly have lower case names and other alterations e.g. 'added '-' so change initials until after download String alteredConf = getConfString(book, getZipFileName(book.getInitials())); Book alteredBook = FakeSwordBookFactory.createFakeRepoBook(book.getInitials(), alteredConf, XIPHOS_REPOSITORY); alteredBook.getBookMetaData().putProperty(REAL_INITIALS, book.getInitials()); super.downloadDocument(alteredBook); } catch (IOException ioe) { throw new InstallException(ioe.getMessage()); } } private String getZipFileName(String initials) { String zipName = nameToZipMap.get(initials); if (zipName == null) { zipName = initials.toLowerCase(Locale.ENGLISH); } return zipName; } public static String getRealInitials(Book book) { String realInitials = (String) book.getProperty(REAL_INITIALS); if (realInitials == null) { realInitials = book.getInitials(); } return realInitials; } /** reverse engineer the .conf file properties from a Book */ private String getConfString(Book book, String initials) { StringBuffer buff = new StringBuffer(); SwordBookMetaData metaData = (SwordBookMetaData) book.getBookMetaData(); Map<String, Object> props = metaData.getProperties(); buff.append("[").append(initials).append("]\n"); buff.append(getConfEntry(props, ConfigEntryType.DATA_PATH)); buff.append(getConfEntry(props, ConfigEntryType.MOD_DRV)); buff.append(getConfEntry(ConfigEntryType.LANG.toString(), book.getLanguage().getCode())); buff.append(getConfEntry(props, ConfigEntryType.ENCODING)); buff.append(getConfEntry(props, ConfigEntryType.SOURCE_TYPE)); buff.append(getConfEntry(props, ConfigEntryType.DESCRIPTION)); buff.append(getConfEntry(props, ConfigEntryType.ABOUT)); buff.append(getConfEntry(props, ConfigEntryType.GLOBAL_OPTION_FILTER)); buff.append(getConfEntry(props, ConfigEntryType.VERSION)); buff.append(getConfEntry(props, ConfigEntryType.CATEGORY)); buff.append(getConfEntry(props, ConfigEntryType.COMPRESS_TYPE)); buff.append(getConfEntry(props, ConfigEntryType.COPYRIGHT)); buff.append(getConfEntry(props, ConfigEntryType.VERSIFICATION)); return buff.toString(); } /** reverse engineer one .conf file property */ private String getConfEntry(Map<String, Object> props, Enum<ConfigEntryType> entryType) { return getConfEntry(entryType.toString(), props.get(entryType.toString())); } private String getConfEntry(String property, Object value) { StringBuilder buff = new StringBuilder(); if (value != null && StringUtils.isNotBlank(value.toString())) { String propertyValue = value.toString().replace("\n", "\\" + lineSeparator); buff.append(property).append("=").append(propertyValue).append(lineSeparator); } return buff.toString(); } /** true if book is in Xiphos repo */ public boolean needsPostDownloadAction(Book book) { return XIPHOS_REPOSITORY.equals(book.getProperty(DownloadManager.REPOSITORY_KEY)); } /** add a listener to handle module rename after download */ public void addHandler(Book book) { // If you want to know about new books as they arrive: if (needsPostDownloadAction(book)) { if (!isBookListenerAdded) { isBookListenerAdded = true; Books.installed().addBooksListener(this); } booksToListenForCount++; } } /** called after download of book from Xiphos repo completes to rename Module name to be camel case */ @Override public void bookAdded(BooksEvent ev) { Book book = ev.getBook(); log.debug("Book added " + book); String realInitials = getRealInitials(book); try { String conf = getConfString(book, realInitials); BookMetaData bmd = FakeSwordBookFactory.createRepoSBMD(realInitials, conf); // library is set during download, ensure it is maintained in recreated sbmd bmd.setLibrary(book.getBookMetaData().getLibrary()); book.setBookMetaData(bmd); } catch (Exception e) { log.error(e.getMessage()); } booksToListenForCount--; if (booksToListenForCount == 0) { isBookListenerAdded = false; Books.installed().removeBooksListener(this); } } @Override public void bookRemoved(BooksEvent ev) { //ignore } @Override public String getRepoName() { return XIPHOS_REPOSITORY; } }