[jsword-svn] r1877 - in trunk/jsword/src/main/java/org/crosswire/jsword: book book/install/sword book/sword bridge examples

dmsmith at www.crosswire.org dmsmith at www.crosswire.org
Wed Jun 18 13:22:46 MST 2008


Author: dmsmith
Date: 2008-06-18 13:22:45 -0700 (Wed, 18 Jun 2008)
New Revision: 1877

Modified:
   trunk/jsword/src/main/java/org/crosswire/jsword/book/BookCategory.java
   trunk/jsword/src/main/java/org/crosswire/jsword/book/OSISUtil.java
   trunk/jsword/src/main/java/org/crosswire/jsword/book/UserMsg.java
   trunk/jsword/src/main/java/org/crosswire/jsword/book/UserMsg.properties
   trunk/jsword/src/main/java/org/crosswire/jsword/book/install/sword/AbstractSwordInstaller.java
   trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ConfigEntryTable.java
   trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ConfigEntryType.java
   trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ZVerseBackend.java
   trunk/jsword/src/main/java/org/crosswire/jsword/bridge/BibleScope.java
   trunk/jsword/src/main/java/org/crosswire/jsword/examples/APIExamples.java
Log:
Fixed a download bug, where bad conf's would prevent the Book installer from coming up.
Made JSword accept SWORD config values with out regard to case.
Fixed a ZVerseBackend bug that incorrectly reported that a verse was present.
Added Maps, Images and Essays to the list of SWORD module categories.
Fixed bugs in APIExamples.
It is now possible to install over top of an existing module.


Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/BookCategory.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/BookCategory.java	2008-06-13 10:56:31 UTC (rev 1876)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/BookCategory.java	2008-06-18 20:22:45 UTC (rev 1877)
@@ -45,17 +45,17 @@
     /**
      * Books that are Bibles
      */
-    public static final BookCategory BIBLE = new BookCategory("Bible", UserMsg.BIBLE); //$NON-NLS-1$
+    public static final BookCategory BIBLE = new BookCategory("Biblical Texts", UserMsg.BIBLE); //$NON-NLS-1$
 
     /**
      * Books that are Dictionaries
      */
-    public static final BookCategory DICTIONARY = new BookCategory("Dictionary", UserMsg.DICTIONARY); //$NON-NLS-1$
+    public static final BookCategory DICTIONARY = new BookCategory("Lexicons / Dictionaries", UserMsg.DICTIONARY); //$NON-NLS-1$
 
     /**
      * Books that are Commentaries
      */
-    public static final BookCategory COMMENTARY = new BookCategory("Commentary", UserMsg.COMMENTARY); //$NON-NLS-1$
+    public static final BookCategory COMMENTARY = new BookCategory("Commentaries", UserMsg.COMMENTARY); //$NON-NLS-1$
 
     /**
      * Books that are indexed by day. AKA, Daily Devotions
@@ -73,11 +73,26 @@
     public static final BookCategory QUESTIONABLE = new BookCategory("Cults / Unorthodox / Questionable Material", UserMsg.UNORTHODOX); //$NON-NLS-1$
 
     /**
-     * Books that are not any of the above
+     * Books that are just essays.
      */
-    public static final BookCategory GENERAL_BOOK = new BookCategory("General Books", UserMsg.GENERAL); //$NON-NLS-1$
+    public static final BookCategory ESSAYS = new BookCategory("Essays", UserMsg.ESSAYS); //$NON-NLS-1$
 
     /**
+     * Books that are predominately images.
+     */
+    public static final BookCategory IMAGES = new BookCategory("Images", UserMsg.IMAGES); //$NON-NLS-1$
+
+    /**
+     * Books that are a collection of maps.
+     */
+    public static final BookCategory MAPS = new BookCategory("Maps", UserMsg.MAPS); //$NON-NLS-1$
+
+    /**
+     * Books that are just books.
+     */
+    public static final BookCategory GENERAL_BOOK = new BookCategory("Generic Books", UserMsg.GENERAL); //$NON-NLS-1$
+
+    /**
      * Books that are not any of the above
      */
     public static final BookCategory OTHER = new BookCategory("Other", UserMsg.OTHER); //$NON-NLS-1$
@@ -195,6 +210,9 @@
         DAILY_DEVOTIONS,
         GLOSSARY,
         QUESTIONABLE,
+        ESSAYS,
+        IMAGES,
+        MAPS,
         GENERAL_BOOK,
         OTHER,
     };

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/OSISUtil.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/OSISUtil.java	2008-06-13 10:56:31 UTC (rev 1876)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/OSISUtil.java	2008-06-18 20:22:45 UTC (rev 1877)
@@ -1120,6 +1120,12 @@
             }
 
         }
+
+        // If there is any text that has not been consumed
+        if (text.length() > 0)
+        {
+            div.addContent(text.toString());
+        }
 //        div.addContent(text.toString());
 //        // If the fragment is already in a document, then use that.
 //        Document doc = div.getDocument();

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/UserMsg.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/UserMsg.java	2008-06-13 10:56:31 UTC (rev 1876)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/UserMsg.java	2008-06-18 20:22:45 UTC (rev 1877)
@@ -41,6 +41,9 @@
     static final UserMsg GLOSSARIES = new UserMsg("BookCategory.Glossaries"); //$NON-NLS-1$
     static final UserMsg UNORTHODOX = new UserMsg("BookCategory.Unorthodox"); //$NON-NLS-1$
     static final UserMsg GENERAL = new UserMsg("BookCategory.General"); //$NON-NLS-1$
+    static final UserMsg ESSAYS = new UserMsg("BookCategory.Essays"); //$NON-NLS-1$
+    static final UserMsg IMAGES = new UserMsg("BookCategory.Images"); //$NON-NLS-1$
+    static final UserMsg MAPS = new UserMsg("BookCategory.Maps"); //$NON-NLS-1$
     static final UserMsg OTHER = new UserMsg("BookCategory.Other"); //$NON-NLS-1$
 
     /**

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/UserMsg.properties
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/UserMsg.properties	2008-06-13 10:56:31 UTC (rev 1876)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/UserMsg.properties	2008-06-18 20:22:45 UTC (rev 1877)
@@ -2,11 +2,14 @@
 Defaults.DictionaryNotFound=Dictionary called "{0}" could not be found.
 Defaults.CommentaryNotFound=Commentary called "{0}" could not be found.
 
-BookCategory.Bible=Bible
-BookCategory.Dictionary=Dictionary
-BookCategory.Commentary=Commentary
-BookCategory.Readings=Daily Devotional
+BookCategory.Bible=Biblical Texts
+BookCategory.Dictionary=Dictionaries
+BookCategory.Commentary=Commentaries
+BookCategory.Readings=Daily Devotionals
 BookCategory.Glossaries=Glossaries
-BookCategory.Unorthodox=Cults / Unorthodox / Questionable Material
+BookCategory.Unorthodox=Cults / Unorthodox / Questionable Materials
 BookCategory.General=General Books
+BookCategory.Essays=Essays
+BookCategory.Images=Images
+BookCategory.Maps=Maps
 BookCategory.Other=Other

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/install/sword/AbstractSwordInstaller.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/install/sword/AbstractSwordInstaller.java	2008-06-13 10:56:31 UTC (rev 1876)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/install/sword/AbstractSwordInstaller.java	2008-06-18 20:22:45 UTC (rev 1877)
@@ -47,7 +47,6 @@
 import org.crosswire.jsword.book.BookFilterIterator;
 import org.crosswire.jsword.book.BookMetaData;
 import org.crosswire.jsword.book.BookSet;
-import org.crosswire.jsword.book.Books;
 import org.crosswire.jsword.book.basic.AbstractBookList;
 import org.crosswire.jsword.book.install.InstallException;
 import org.crosswire.jsword.book.install.Installer;
@@ -219,12 +218,12 @@
      */
     public void install(Book book)
     {
-        // Is the book already installed? Then nothing to do.
-        if (Books.installed().getBook(book.getName()) != null)
-        {
-            return;
-        }
-
+//        // 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
@@ -397,6 +396,11 @@
                         {
                             internal = internal.substring(0, internal.length() - 5);
                         }
+                        else
+                        {
+                            log.error("Not a SWORD config file: " + internal); //$NON-NLS-1$
+                            continue;
+                        }
 
                         if (internal.startsWith(SwordConstants.DIR_CONF + '/'))
                         {

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ConfigEntryTable.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ConfigEntryTable.java	2008-06-13 10:56:31 UTC (rev 1876)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ConfigEntryTable.java	2008-06-18 20:22:45 UTC (rev 1877)
@@ -88,19 +88,19 @@
         BufferedReader in = null;
         try
         {
-            in = new BufferedReader(new InputStreamReader(new FileInputStream(file), ENCODING_LATIN1));
+            in = new BufferedReader(new InputStreamReader(new FileInputStream(file), ENCODING_UTF8));
             loadInitials(in);
             loadContents(in);
             in.close();
             in = null;
-            if (getValue(ConfigEntryType.ENCODING).equals(ENCODING_UTF8))
+            if (getValue(ConfigEntryType.ENCODING).equals(ENCODING_LATIN1))
             {
                 supported = true;
                 bookType = null;
                 questionable = false;
                 readahead = null;
                 table.clear();
-                in = new BufferedReader(new InputStreamReader(new FileInputStream(file), ENCODING_UTF8));
+                in = new BufferedReader(new InputStreamReader(new FileInputStream(file), ENCODING_LATIN1));
                 loadInitials(in);
                 loadContents(in);
                 in.close();
@@ -132,19 +132,19 @@
         BufferedReader in = null;
         try
         {
-            in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(buffer), ENCODING_LATIN1));
+            in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(buffer), ENCODING_UTF8));
             loadInitials(in);
             loadContents(in);
             in.close();
             in = null;
-            if (getValue(ConfigEntryType.ENCODING).equals(ENCODING_UTF8))
+            if (getValue(ConfigEntryType.ENCODING).equals(ENCODING_LATIN1))
             {
                 supported = true;
                 bookType = null;
                 questionable = false;
                 readahead = null;
                 table.clear();
-                in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(buffer), ENCODING_UTF8));
+                in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(buffer), ENCODING_LATIN1));
                 loadInitials(in);
                 loadContents(in);
                 in.close();
@@ -386,11 +386,12 @@
             // Create a configEntry so that the name is normalized.
             ConfigEntry configEntry = new ConfigEntry(internal, key);
 
-            ConfigEntry e = (ConfigEntry) table.get(configEntry.getType());
+            ConfigEntryType type = configEntry.getType();
 
+            ConfigEntry e = (ConfigEntry) table.get(type);
+
             if (e == null)
             {
-                ConfigEntryType type = configEntry.getType();
                 if (type == null)
                 {
                     log.warn("Ignoring unexpected entry in " + internal  + " of " + configEntry.getName()); //$NON-NLS-1$ //$NON-NLS-2$
@@ -401,7 +402,7 @@
                 }
                 else
                 {
-                    table.put(configEntry.getType(), configEntry);
+                    table.put(type, configEntry);
                 }
             }
             else
@@ -416,7 +417,7 @@
             // The config entry is History without the x.x.
             // We want to put x.x at the beginning of the string
             value = buf.toString();
-            if (ConfigEntryType.HISTORY.equals(configEntry.getType()))
+            if (ConfigEntryType.HISTORY.equals(type))
             {
                 int pos = key.indexOf('_');
                 value = key.substring(pos + 1) + ' ' + value;
@@ -440,7 +441,7 @@
             if (line.charAt(0) == '[' && line.charAt(line.length() - 1) == ']')
             {
                 // The conf file contains a leading line of the form [KJV]
-                // This is the acronymn by which Sword refers to it.
+                // This is the acronym by which Sword refers to it.
                 initials = line.substring(1, line.length() - 1);
                 break;
             }
@@ -858,6 +859,7 @@
         ConfigEntryType.VERSION,
         ConfigEntryType.HISTORY,
         ConfigEntryType.OBSOLETES,
+        ConfigEntryType.INSTALL_SIZE,
     };
 
     private static final ConfigEntryType[] LANG_INFO =
@@ -899,13 +901,17 @@
         ConfigEntryType.MOD_DRV,
         ConfigEntryType.SOURCE_TYPE,
         ConfigEntryType.BLOCK_TYPE,
+        ConfigEntryType.BLOCK_COUNT,
         ConfigEntryType.COMPRESS_TYPE,
         ConfigEntryType.ENCODING,
         ConfigEntryType.MINIMUM_VERSION,
         ConfigEntryType.OSIS_VERSION,
+        ConfigEntryType.OSIS_Q_TO_TICK,
         ConfigEntryType.DIRECTION,
+        ConfigEntryType.KEY_TYPE,
+        ConfigEntryType.DISPLAY_LEVEL,
     };
-
+    
     private static final ConfigEntryType[] HIDDEN =
     {
         ConfigEntryType.CIPHER_KEY,

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ConfigEntryType.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ConfigEntryType.java	2008-06-13 10:56:31 UTC (rev 1876)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ConfigEntryType.java	2008-06-18 20:22:45 UTC (rev 1877)
@@ -22,10 +22,6 @@
 package org.crosswire.jsword.book.sword;
 
 import java.io.Serializable;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Locale;
-import java.util.Set;
 import java.util.regex.Pattern;
 
 import org.crosswire.common.util.Language;
@@ -33,218 +29,374 @@
 
 
 /**
- * Constants for the keys in a SwordConfig file.
+ * Constants for the keys in a Sword Config file.
  * Taken from
  * http://sword.sourceforge.net/cgi-bin/twiki/view/Swordapi/ConfFileLayout
  * now located at
  * http://www.crosswire.org/ucgi-bin/twiki/view/Swordapi/ConfFileLayout
+ * now located at
+ * http://www.crosswire.org/wiki/index.php/DevTools:Modules
  *
- * <p>Keys that might be available that we are ignoring for now:
- * <li>DistributionLicense: single value coded string, a ';' separated string of license attributes
- *     There are mis-spellings, etc. so there is a need for a distributionLicenseAdditionalInfo field. (Ugh!)
- *     See also SwordConstants.DISTIBUTION_LICENSE_STRINGS.
- *     <pre>
- *     // Returns the distributionLicense - this is a 'flag type' field - the value
- *     // will be the result of several constants ORed. See the
- *     // DISTRIBUTION_LICENSE* constants in SwordConstants. It appears some
- *     // versions do not stick to this convention, because of this, there is an
- *     // additional member distributionLicenseAdditionInfo, to store additional
- *     // information.
- *     private int distributionLicense;
- *     private String distributionLicenseAdditionalInfo = "";
- *     String licensesString = reader.getFirstValue("DistributionLicense");
- *     if (licensesString != null)
- *     {
- *         StringTokenizer tok = new StringTokenizer(licensesString, ";");
- *         while (tok.hasMoreTokens())
- *         {
- *             String distributionLicenseString = tok.nextToken().trim();
- *             int index = matchingIndex(SwordConstants.DISTIBUTION_LICENSE_STRINGS, distributionLicenseString, -1);
- *             if (index != -1)
- *             {
- *                 distributionLicense |= 1 << index;
- *             }
- *             else
- *             {
- *                 if (!distributionLicenseAdditionalInfo.equals(""))
- *                 {
- *                     distributionLicenseAdditionalInfo += "; ";
- *                 }
- *                 distributionLicenseAdditionalInfo += distributionLicenseString;
- *             }
- *         }
- *     }
- *     </pre>
- *
  * @see gnu.lgpl.License for license details.
  *      The copyright to this program is held by it's authors.
  * @author Joe Walker [joe at eireneh dot com]
- * @author DM Smith [dmsmith555 at yahoo dot com\
+ * @author DM Smith [dmsmith555 at yahoo dot com]
  */
 public class ConfigEntryType implements Serializable
 {
     /**
-     * Contains rtf that describes the book.
+     * Constants for direction
      */
-    public static final ConfigEntryType ABOUT = new ConfigEntryType("About") //$NON-NLS-1$
+    public static final String DIRECTION_LTOR = "LtoR"; //$NON-NLS-1$
+    public static final String DIRECTION_RTOL = "RtoL"; //$NON-NLS-1$
+    public static final String DIRECTION_BIDI = "bidi"; //$NON-NLS-1$
+
+    public static final String[] BLOCK_TYPE_PICKS
+        = new String[]
+          {
+              "BOOK", //$NON-NLS-1$
+              "CHAPTER", //$NON-NLS-1$
+              "VERSE", //$NON-NLS-1$
+          };
+
+    public static final String[] BOOLEAN_PICKS
+        = new String[]
+          {
+              "true", //$NON-NLS-1$
+              "false", //$NON-NLS-1$
+          };
+
+    public static final String[] KEY_TYPE_PICKS
+        = new String[]
+          {
+              "TreeKey", //$NON-NLS-1$
+              "VerseKey", //$NON-NLS-1$
+          };
+
+    public static final String[] CATEGORY_PICKS
+        = new String[]
+          {
+              "Daily Devotional", //$NON-NLS-1$
+              "Glossaries", //$NON-NLS-1$
+              "Cults / Unorthodox / Questionable Material", //$NON-NLS-1$
+              "Essays", //$NON-NLS-1$
+              "Maps", //$NON-NLS-1$
+              "Images", //$NON-NLS-1$
+              "Biblical Texts", //$NON-NLS-1$
+              "Commentaries", //$NON-NLS-1$
+              "Lexicons / Dictionaries", //$NON-NLS-1$
+              "Generic Books", //$NON-NLS-1$
+          };
+
+    public static final String[] COMPRESS_TYPE_PICKS
+        = new String[]
+          {
+              "LZSS", //$NON-NLS-1$
+              "ZIP", //$NON-NLS-1$
+          };
+
+    public static final String[] DIRECTION_PICKS
+        = new String[]
+          {
+              DIRECTION_LTOR,
+              DIRECTION_RTOL,
+              DIRECTION_BIDI,
+          };
+
+    public static final String[] LICENSE_PICKS
+        = new String[]
+          {
+              "Public Domain", //$NON-NLS-1$
+              "Copyrighted", //$NON-NLS-1$
+              "Copyrighted; Free non-commercial distribution", //$NON-NLS-1$
+              "Copyrighted; Permission to distribute granted to CrossWire", //$NON-NLS-1$
+              "Copyrighted; Freely distributable", //$NON-NLS-1$
+              "Creative Commons: by-nc-nd", //$NON-NLS-1$
+              "Creative Commons: by-nc-sa", //$NON-NLS-1$
+              "Creative Commons: by-nc", //$NON-NLS-1$
+              "Creative Commons: by-nd", //$NON-NLS-1$
+              "Creative Commons: by-sa", //$NON-NLS-1$
+              "Creative Commons: by", //$NON-NLS-1$
+              "GFDL", //$NON-NLS-1$
+              "GPL", //$NON-NLS-1$
+          };
+
+    public static final String[] ENCODING_PICKS
+        = new String[]
+          {
+              "Latin-1", //$NON-NLS-1$
+              "UTF-8", //$NON-NLS-1$
+          };
+
+    public static final String[] GLOBAL_OPTION_FILTER_PICKS
+        = new String[]
+          {
+              "GBFStrongs", //$NON-NLS-1$
+              "GBFFootnotes", //$NON-NLS-1$
+              "GBFScripref", //$NON-NLS-1$
+              "GBFMorph", //$NON-NLS-1$
+              "GBFHeadings", //$NON-NLS-1$
+              "GBFRedLetterWords", //$NON-NLS-1$
+              "ThMLStrongs", //$NON-NLS-1$
+              "ThMLFootnotes", //$NON-NLS-1$
+              "ThMLScripref", //$NON-NLS-1$
+              "ThMLMorph", //$NON-NLS-1$
+              "ThMLHeadings", //$NON-NLS-1$
+              "ThMLVariants", //$NON-NLS-1$
+              "ThMLLemma", //$NON-NLS-1$
+              "UTF8Cantillation", //$NON-NLS-1$
+              "UTF8GreekAccents", //$NON-NLS-1$
+              "UTF8HebrewPoints", //$NON-NLS-1$
+              "OSISFootnotes", //$NON-NLS-1$
+              "OSISHeadings", //$NON-NLS-1$
+              "OSISLemma", //$NON-NLS-1$
+              "OSISMorph", //$NON-NLS-1$
+              "OSISRedLetterWords", //$NON-NLS-1$
+              "OSISRuby", //$NON-NLS-1$
+              "OSISScripref", //$NON-NLS-1$
+              "OSISStrongs", //$NON-NLS-1$
+          };
+
+    public static final String[] FEATURE_PICKS
+        = new String[]
+          {
+              "StrongsNumbers", //$NON-NLS-1$
+              "GreekDef", //$NON-NLS-1$
+              "HebrewDef", //$NON-NLS-1$
+              "GreekParse", //$NON-NLS-1$
+              "HebrewParse", //$NON-NLS-1$
+              "DailyDevotion", //$NON-NLS-1$
+              "Glossary", //$NON-NLS-1$
+              "Images", //$NON-NLS-1$
+          };
+
+    public static final String[] MOD_DRV_PICKS
+        = new String[]
+          {
+              "RawText", //$NON-NLS-1$
+              "zText", //$NON-NLS-1$
+              "RawCom", //$NON-NLS-1$
+              "RawCom4", //$NON-NLS-1$
+              "zCom", //$NON-NLS-1$
+              "HREFCom", //$NON-NLS-1$
+              "RawFiles", //$NON-NLS-1$
+              "RawLD", //$NON-NLS-1$
+              "RawLD4", //$NON-NLS-1$
+              "zLD", //$NON-NLS-1$
+              "RawGenBook", //$NON-NLS-1$
+          };
+
+    public static final String[] SOURCE_TYPE_PICKS
+        = new String[]
+          {
+              "Plaintext", //$NON-NLS-1$
+              "GBF", //$NON-NLS-1$
+              "ThML", //$NON-NLS-1$
+              "OSIS", //$NON-NLS-1$
+              "TEI", //$NON-NLS-1$
+          };
+
+    /**
+     * A ConfigEntryPickType is a ConfigEntryType that allows values from a pick list.
+     * Matching is expected to be case-sensitive, but data problems dictate a more flexible approach. 
+     * 
+     */
+    public static class ConfigEntryPickType extends ConfigEntryType
     {
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsContinuation()
+        /**
+         * Simple ctor
          */
-        public boolean allowsContinuation()
+        public ConfigEntryPickType(String name, String[] picks)
         {
-            return true;
+            this(name, picks, null);
         }
 
+        /**
+         * Simple ctor
+         */
+        public ConfigEntryPickType(String name, String[] picks, Object defaultPick)
+        {
+            super(name, defaultPick);
+            choiceArray = picks;
+        }
+
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsRTF()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#hasChoices()
          */
-        public boolean allowsRTF()
+        protected boolean hasChoices()
         {
             return true;
         }
 
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = 3258416110121334073L;
-    };
-
-    /**
-     * single value integer, unknown use, some indications that we ought to be using it
-     */
-    public static final ConfigEntryType BLOCK_COUNT = new ConfigEntryType("BlockCount") //$NON-NLS-1$
-    {
         /* (non-Javadoc)
          * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
          */
-        public boolean isAllowed(String aValue)
+        public boolean isAllowed(String value)
         {
-            try
+            for (int i = 0; i < choiceArray.length; i++)
             {
-                Integer.parseInt(aValue);
-                return true;
+                if (choiceArray[i].equalsIgnoreCase(value))
+                {
+                    return true;
+                }
             }
-            catch (NumberFormatException e)
-            {
-                return false;
-            }
+
+            return false;
         }
 
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#convert(java.lang.String)
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#filter(java.lang.String)
          */
-        public Object convert(String input)
+        public String filter(String value)
         {
-            try
+            // Do we have an exact match?
+            for (int i = 0; i < choiceArray.length; i++)
             {
-                return new Integer(input);
+                if (choiceArray[i].equals(value))
+                {
+                    return value;
+                }
             }
-            catch (NumberFormatException e)
+
+            // Do we have a case insensitive match?
+            for (int i = 0; i < choiceArray.length; i++)
             {
-                return defaultValue;
+                if (choiceArray[i].equalsIgnoreCase(value))
+                {
+                    return choiceArray[i];
+                }
             }
+
+            // No match at all!
+            return value;
         }
 
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#getDefault()
+        /**
+         * The array of choices.
          */
-        public Object getDefault()
-        {
-            return defaultValue;
-        }
+        private final String[] choiceArray;
 
-        private Integer defaultValue = new Integer(200);
-
         /**
-         * Comment for <code>serialVersionUID</code>
+         * Serialization ID
          */
-        private static final long serialVersionUID = 3978711675019212341L;
-    };
+        private static final long serialVersionUID = 5642668733730291463L;
+    }
 
     /**
-     * The level at which compression is applied, BOOK, CHAPTER, or VERSE
+     * Represents a ConfigEntryType that is not actually represented by the Sword Config file.
+     *
      */
-    public static final ConfigEntryType BLOCK_TYPE = new ConfigEntryType("BlockType") //$NON-NLS-1$
+    public static class ConfigEntrySyntheticType extends ConfigEntryType
     {
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
+        /**
+         * Simple ctor
          */
-        public boolean isAllowed(String value)
+        public ConfigEntrySyntheticType(String name)
         {
-            return choices.contains(filter(value));
+            super(name);
         }
 
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#filter(java.lang.String)
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isSynthetic()
          */
-        public String filter(String value)
+        public boolean isSynthetic()
         {
-            return value.toUpperCase(Locale.ENGLISH);
+            return true;
         }
 
+        /**
+         * Serialization ID
+         */
+        private static final long serialVersionUID = -2468890875139856087L;
+    }
+
+    /**
+     * Contains rtf that describes the book.
+     */
+    public static final ConfigEntryType ABOUT = new ConfigEntryType("About") //$NON-NLS-1$
+    {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#hasChoices()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsContinuation()
          */
-        protected boolean hasChoices()
+        public boolean allowsContinuation()
         {
             return true;
         }
 
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#getDefault()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsRTF()
          */
-        public Object getDefault()
+        public boolean allowsRTF()
         {
-            return "CHAPTER"; //$NON-NLS-1$
+            return true;
         }
 
         /**
-         * The set of choices.
-         */
-        private final Set choices = new HashSet(Arrays.asList(new String[]
-        {
-            "BOOK", //$NON-NLS-1$
-            "CHAPTER", //$NON-NLS-1$
-            "VERSE", //$NON-NLS-1$
-        }));
-
-        /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3763101864299935031L;
+        private static final long serialVersionUID = 3258416110121334073L;
     };
 
     /**
-     * The Category of the book. Used on the web to classify books into a tree.
+     * single value integer, unknown use, some indications that we ought to be using it
      */
-    public static final ConfigEntryType CATEGORY = new ConfigEntryType("Category") //$NON-NLS-1$
+    public static final ConfigEntryType BLOCK_COUNT = new ConfigEntryType("BlockCount", new Integer(200)) //$NON-NLS-1$
     {
         /* (non-Javadoc)
          * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
          */
-        public boolean isAllowed(String value)
+        public boolean isAllowed(String aValue)
         {
-            return choices.contains(value);
+            try
+            {
+                Integer.parseInt(aValue);
+                return true;
+            }
+            catch (NumberFormatException e)
+            {
+                return false;
+            }
         }
 
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#hasChoices()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#convert(java.lang.String)
          */
-        protected boolean hasChoices()
+        public Object convert(String input)
         {
-            return true;
+            try
+            {
+                return new Integer(input);
+            }
+            catch (NumberFormatException e)
+            {
+                return getDefault();
+            }
         }
 
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#getDefault()
+        /**
+         * Comment for <code>serialVersionUID</code>
          */
-        public Object getDefault()
-        {
-            return BookCategory.OTHER;
-        }
+        private static final long serialVersionUID = 3978711675019212341L;
+    };
 
-        /* (non-Javadoc)
+    /**
+     * The level at which compression is applied, BOOK, CHAPTER, or VERSE
+     */
+    public static final ConfigEntryType BLOCK_TYPE = new ConfigEntryPickType("BlockType", BLOCK_TYPE_PICKS, BLOCK_TYPE_PICKS[0]);//$NON-NLS-1$
+
+    /**
+     * The kind of key that a Generic Book uses.
+     */
+    public static final ConfigEntryType KEY_TYPE = new ConfigEntryPickType("KeyType", KEY_TYPE_PICKS, KEY_TYPE_PICKS[0]); //$NON-NLS-1$
+
+    /**
+     * The Category of the book. Used on the web to classify books into a tree.
+     */
+    public static final ConfigEntryType CATEGORY = new ConfigEntryPickType("Category", CATEGORY_PICKS, BookCategory.OTHER) //$NON-NLS-1$
+    {
+        /*
+         * (non-Javadoc)
+         * 
          * @see org.crosswire.jsword.book.sword.ConfigEntryType#convert(java.lang.String)
          */
         public Object convert(String input)
@@ -253,23 +405,6 @@
         }
 
         /**
-         * The set of choices.
-         */
-        private final Set choices = new HashSet(Arrays.asList(new String[]
-        {
-            "Daily Devotional", //$NON-NLS-1$
-            "Glossaries", //$NON-NLS-1$
-            "Cults / Unorthodox / Questionable Material", //$NON-NLS-1$
-            "Essays", //$NON-NLS-1$
-            // The following are not actually in the conf,
-            // but are deduced from other fields
-            "Bible", //$NON-NLS-1$
-            "Dictionary", //$NON-NLS-1$
-            "Commentary", //$NON-NLS-1$
-            "General Books", //$NON-NLS-1$
-        }));
-
-        /**
          * Serialization ID
          */
         private static final long serialVersionUID = 3258412850174571569L;
@@ -281,59 +416,13 @@
      */
     public static final ConfigEntryType CIPHER_KEY = new ConfigEntryType("CipherKey"); //$NON-NLS-1$
 
+    
     /**
      * The type of compression in use. JSword does not support LZSS. While it is the default,
      * it is not used. At least so far.
      */
-    public static final ConfigEntryType COMPRESS_TYPE = new ConfigEntryType("CompressType") //$NON-NLS-1$
-    {
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
-         */
-        public boolean isAllowed(String value)
-        {
-            return choices.contains(filter(value));
-        }
+    public static final ConfigEntryType COMPRESS_TYPE = new ConfigEntryPickType("CompressType", COMPRESS_TYPE_PICKS, COMPRESS_TYPE_PICKS[0]); //$NON-NLS-1$
 
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#filter(java.lang.String)
-         */
-        public String filter(String value)
-        {
-            return value.toUpperCase(Locale.ENGLISH);
-        }
-
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#hasChoices()
-         */
-        protected boolean hasChoices()
-        {
-            return true;
-        }
-
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#getDefault()
-         */
-        public Object getDefault()
-        {
-            return "LZSS"; //$NON-NLS-1$
-        }
-
-        /**
-         * The set of choices.
-         */
-        private final Set choices = new HashSet(Arrays.asList(new String[]
-        {
-            "LZSS", //$NON-NLS-1$
-            "ZIP", //$NON-NLS-1$
-        }));
-
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = 3256726182190920496L;
-    };
-
     /**
      * Informational copyright notice.
      */
@@ -520,50 +609,11 @@
      * The layout direction of the text in the book. Hebrew, Arabic and Farsi RtoL. Most are 'LtoR'.
      * Some are 'bidi', bi-directional. E.g. hebrew-english glossary.
      */
-    public static final ConfigEntryType DIRECTION = new ConfigEntryType("Direction") //$NON-NLS-1$
-    {
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
-         */
-        public boolean isAllowed(String value)
-        {
-            return choices.contains(value);
-        }
+    public static final ConfigEntryType DIRECTION = new ConfigEntryPickType("Direction", DIRECTION_PICKS, DIRECTION_PICKS[0]); //$NON-NLS-1$
 
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#hasChoices()
-         */
-        protected boolean hasChoices()
-        {
-            return true;
-        }
-
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#getDefault()
-         */
-        public Object getDefault()
-        {
-            return DIRECTION_LTOR;
-        }
-
-        /**
-         * The set of choices.
-         */
-        private final Set choices = new HashSet(Arrays.asList(new String[]
-        {
-            DIRECTION_LTOR,
-            DIRECTION_RTOL,
-            DIRECTION_BIDI,
-        }));
-
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = 3257283651765940536L;
-    };
-
     /**
-     * single value integer, unknown use, some indications that we ought to be using it
+     * Display level is used by GenBooks to do auto expansion in the tree.
+     * A level of 2 indicates that the first two levels should be shown.
      */
     public static final ConfigEntryType DISPLAY_LEVEL = new ConfigEntryType("DisplayLevel") //$NON-NLS-1$
     {
@@ -607,49 +657,8 @@
     /**
      * Copyright info. Informational only.
      */
-    public static final ConfigEntryType DISTRIBUTION_LICENSE = new ConfigEntryType("DistributionLicense") //$NON-NLS-1$
-    {
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
-         */
-        public boolean isAllowed(String value)
-        {
-            return choices.contains(value);
-        }
+    public static final ConfigEntryType DISTRIBUTION_LICENSE = new ConfigEntryPickType("DistributionLicense", LICENSE_PICKS, LICENSE_PICKS[0]); //$NON-NLS-1$
 
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#hasChoices()
-         */
-        protected boolean hasChoices()
-        {
-            return true;
-        }
-
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#getDefault()
-         */
-        public Object getDefault()
-        {
-            return "Public Domain"; //$NON-NLS-1$
-        }
-
-        /**
-         * The set of choices.
-         */
-        private final Set choices = new HashSet(Arrays.asList(new String[]
-        {
-            "Public Domain", //$NON-NLS-1$
-            "Copyrighted; Free non-commercial distribution", //$NON-NLS-1$
-            "Copyrighted; Permission to distribute granted to CrossWire", //$NON-NLS-1$
-            "Copyrighted", //$NON-NLS-1$
-        }));
-
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = 3257289110669505585L;
-    };
-
     /**
      * Copyright info. Informational only.
      */
@@ -692,70 +701,15 @@
     /**
      * The character encoding. Only Latin-1 and UTF-8 are supported.
      */
-    public static final ConfigEntryType ENCODING = new ConfigEntryType("Encoding") //$NON-NLS-1$
-    {
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
-         */
-        public boolean isAllowed(String value)
-        {
-            return choices.contains(value);
-        }
+    public static final ConfigEntryType ENCODING = new ConfigEntryPickType("Encoding", ENCODING_PICKS, ENCODING_PICKS[0]); //$NON-NLS-1$
 
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#hasChoices()
-         */
-        protected boolean hasChoices()
-        {
-            return true;
-        }
-
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#getDefault()
-         */
-        public Object getDefault()
-        {
-            return "Latin-1"; //$NON-NLS-1$
-        }
-
-        /**
-         * The set of choices.
-         */
-        private final Set choices = new HashSet(Arrays.asList(new String[]
-        {
-            "Latin-1", //$NON-NLS-1$
-            "UTF-8", //$NON-NLS-1$
-        }));
-
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = 3761121643874891315L;
-    };
-
     /**
      * Global Option Filters are the names of routines in Sword that can be used to display the data.
      * These are not used by JSword.
      */
-    public static final ConfigEntryType GLOBAL_OPTION_FILTER = new ConfigEntryType("GlobalOptionFilter") //$NON-NLS-1$
+    public static final ConfigEntryType GLOBAL_OPTION_FILTER = new ConfigEntryPickType("GlobalOptionFilter", GLOBAL_OPTION_FILTER_PICKS)//$NON-NLS-1$
     {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
-         */
-        public boolean isAllowed(String value)
-        {
-            return choices.contains(value);
-        }
-
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#hasChoices()
-         */
-        protected boolean hasChoices()
-        {
-            return true;
-        }
-
-        /* (non-Javadoc)
          * @see org.crosswire.jsword.book.sword.ConfigEntryType#mayRepeat()
          */
         public boolean mayRepeat()
@@ -764,35 +718,6 @@
         }
 
         /**
-         * The set of choices.
-         */
-        private final Set choices = new HashSet(Arrays.asList(new String[]
-        {
-            "GBFStrongs", //$NON-NLS-1$
-            "GBFFootnotes", //$NON-NLS-1$
-            "GBFScripref", //$NON-NLS-1$
-            "GBFMorph", //$NON-NLS-1$
-            "GBFHeadings", //$NON-NLS-1$
-            "GBFRedLetterWords", //$NON-NLS-1$
-            "ThMLStrongs", //$NON-NLS-1$
-            "ThMLFootnotes", //$NON-NLS-1$
-            "ThMLScripref", //$NON-NLS-1$
-            "ThMLMorph", //$NON-NLS-1$
-            "ThMLHeadings", //$NON-NLS-1$
-            "ThMLVariants", //$NON-NLS-1$
-            "ThMLLemma", //$NON-NLS-1$
-            "UTF8Cantillation", //$NON-NLS-1$
-            "UTF8GreekAccents", //$NON-NLS-1$
-            "UTF8HebrewPoints", //$NON-NLS-1$
-            "OSISStrongs", //$NON-NLS-1$
-            "OSISFootnotes", //$NON-NLS-1$
-            "OSISScripref", //$NON-NLS-1$
-            "OSISMorph", //$NON-NLS-1$
-            "OSISHeadings", //$NON-NLS-1$
-            "OSISRedLetterWords", //$NON-NLS-1$
-        }));
-
-        /**
          * Serialization ID
          */
         private static final long serialVersionUID = 3258417209599931960L;
@@ -910,28 +835,10 @@
 
     /**
      * A Feature describes a characteristic of the Book.
-     * TODO(DMS): use this to present the user with a pick list of books for Strong's,
-     * and Heb/Greek Def/Parse. We should also use DailyDevotional to map the days to a date.
      */
-    public static final ConfigEntryType FEATURE = new ConfigEntryType("Feature") //$NON-NLS-1$
+    public static final ConfigEntryType FEATURE = new ConfigEntryPickType("Feature", FEATURE_PICKS) //$NON-NLS-1$
     {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
-         */
-        public boolean isAllowed(String value)
-        {
-            return choices.contains(value);
-        }
-
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#hasChoices()
-         */
-        protected boolean hasChoices()
-        {
-            return true;
-        }
-
-        /* (non-Javadoc)
          * @see org.crosswire.jsword.book.sword.ConfigEntryType#mayRepeat()
          */
         public boolean mayRepeat()
@@ -940,20 +847,6 @@
         }
 
         /**
-         * The set of choices.
-         */
-        private final Set choices = new HashSet(Arrays.asList(new String[]
-        {
-            "StrongsNumbers", //$NON-NLS-1$
-            "GreekDef", //$NON-NLS-1$
-            "HebrewDef", //$NON-NLS-1$
-            "GreekParse", //$NON-NLS-1$
-            "HebrewParse", //$NON-NLS-1$
-            "DailyDevotion", //$NON-NLS-1$
-            "Glossary", //$NON-NLS-1$
-        }));
-
-        /**
          * Serialization ID
          */
         private static final long serialVersionUID = 3833181424051172401L;
@@ -961,25 +854,15 @@
 
     /**
      * A recommended font to use for the book.
-     * TODO(DMS): Use this font.
-     * TODO(DMS): Allow a user to associate a font with a book.
      */
     public static final ConfigEntryType FONT = new ConfigEntryType("Font"); //$NON-NLS-1$
 
     /**
      * single value string, defaults to en, the language of the book
      */
-    public static final ConfigEntryType LANG = new ConfigEntryType("Lang") //$NON-NLS-1$
+    public static final ConfigEntryType LANG = new ConfigEntryType("Lang", new Language(null)) //$NON-NLS-1$
     {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#getDefault()
-         */
-        public Object getDefault()
-        {
-            return defaultLanguage;
-        }
-
-        /* (non-Javadoc)
          * @see org.crosswire.jsword.book.sword.ConfigEntryType#convert(java.lang.String)
          */
         public Object convert(String input)
@@ -987,8 +870,6 @@
             return new Language(input);
         }
 
-        private Language defaultLanguage = new Language(null);
-
         /**
          * Serialization ID
          */
@@ -1004,72 +885,18 @@
     /**
      * This indicates how the book was stored.
      */
-    public static final ConfigEntryType MOD_DRV = new ConfigEntryType("ModDrv") //$NON-NLS-1$
-    {
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
-         */
-        public boolean isAllowed(String value)
-        {
-            return choices.contains(value);
-        }
+    public static final ConfigEntryType MOD_DRV = new ConfigEntryPickType("ModDrv", MOD_DRV_PICKS); //$NON-NLS-1$
 
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#hasChoices()
-         */
-        protected boolean hasChoices()
-        {
-            return true;
-        }
-
-        /**
-         * The set of choices.
-         */
-        private final Set choices = new HashSet(Arrays.asList(new String[]
-        {
-            "RawText",  //$NON-NLS-1$
-            "zText",  //$NON-NLS-1$
-            "RawCom", //$NON-NLS-1$
-            "RawCom4", //$NON-NLS-1$
-            "zCom", //$NON-NLS-1$
-            "HREFCom", //$NON-NLS-1$
-            "RawFiles", //$NON-NLS-1$
-            "RawLD", //$NON-NLS-1$
-            "RawLD4", //$NON-NLS-1$
-            "zLD", //$NON-NLS-1$
-            "RawGenBook", //$NON-NLS-1$
-        }));
-
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = 3617569405685412913L;
-    };
-
     /**
-     * single value version number, lowest sword c++ version that can read this book
-     * JSword does not use this value.
+     * single value version number, lowest sword c++ version that can read this
+     * book JSword does not use this value.
      */
-    public static final ConfigEntryType MINIMUM_VERSION = new ConfigEntryType("MinimumVersion") //$NON-NLS-1$
-    {
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#getDefault()
-         */
-        public Object getDefault()
-        {
-            // This value is unimportant to JSword, but is to Sword
-            return "1.5.1a"; //$NON-NLS-1$
-        }
+    public static final ConfigEntryType MINIMUM_VERSION = new ConfigEntryType("MinimumVersion", "1.5.1a"); //$NON-NLS-1$ //$NON-NLS-2$
 
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = 4051044181290266680L;
-    };
-
-
     /**
-     * A list of prior "initials" for the current book. Informational only.
+     * A list of prior "initials" for the current book.
+     * TODO(dms): when a user installs a book with an obsoletes that matches an installed book,
+     *            offer the user the opportunity to delete the old book.
      */
     public static final ConfigEntryType OBSOLETES = new ConfigEntryType("Obsoletes") //$NON-NLS-1$
     {
@@ -1098,70 +925,8 @@
     /**
      * This indicates the kind of markup used for the book.
      */
-    public static final ConfigEntryType SOURCE_TYPE = new ConfigEntryType("SourceType") //$NON-NLS-1$
-    {
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
-         */
-        public boolean isAllowed(String value)
-        {
-            return choices.contains(filter(value));
-        }
+    public static final ConfigEntryType SOURCE_TYPE = new ConfigEntryPickType("SourceType", SOURCE_TYPE_PICKS, SOURCE_TYPE_PICKS[0]); //$NON-NLS-1$
 
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#filter(java.lang.String)
-         */
-        public String filter(String value)
-        {
-
-            for (int i = 0; i < choiceArray.length; i++)
-            {
-                if (choiceArray[i].equalsIgnoreCase(value))
-                {
-                    return choiceArray[i];
-                }
-            }
-            return value;
-        }
-
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#hasChoices()
-         */
-        protected boolean hasChoices()
-        {
-            return true;
-        }
-
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#getDefault()
-         */
-        public Object getDefault()
-        {
-            return "Plaintext"; //$NON-NLS-1$
-        }
-
-        /**
-         * The array of choices.
-         */
-        private final String[] choiceArray = new String[]
-        {
-            "Plaintext", //$NON-NLS-1$
-            "GBF", //$NON-NLS-1$
-            "ThML", //$NON-NLS-1$
-            "OSIS", //$NON-NLS-1$
-            "TEI", //$NON-NLS-1$
-        };
-        /**
-         * The set of choices.
-         */
-        private final Set choices = new HashSet(Arrays.asList(choiceArray));
-
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = 3834025853343774774L;
-    };
-
     /**
      * The date that this version of the book was last updated. Informational only.
      */
@@ -1205,7 +970,7 @@
     /**
      * An informational string indicating the current version of the book.
      */
-    public static final ConfigEntryType VERSION = new ConfigEntryType("Version") //$NON-NLS-1$
+    public static final ConfigEntryType VERSION = new ConfigEntryType("Version", "1.0") //$NON-NLS-1$ //$NON-NLS-2$
     {
         public boolean isAllowed(String aValue)
         {
@@ -1221,14 +986,6 @@
 
         }
 
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#getDefault()
-         */
-        public Object getDefault()
-        {
-            return "1.0"; //$NON-NLS-1$
-        }
-
         /**
          * Serialization ID
          */
@@ -1238,19 +995,9 @@
     /**
      * When false do not show quotation marks for OSIS text that has <q> elements.
      */
-    public static final ConfigEntryType OSIS_Q_TO_TICK = new ConfigEntryType("OSISqToTick") //$NON-NLS-1$
+    public static final ConfigEntryType OSIS_Q_TO_TICK = new ConfigEntryPickType("OSISqToTick", BOOLEAN_PICKS, Boolean.TRUE) //$NON-NLS-1$
     {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
-         */
-        public boolean isAllowed(String aValue)
-        {
-            return aValue != null
-                && (aValue.equalsIgnoreCase("true") //$NON-NLS-1$
-                || aValue.equalsIgnoreCase("false")); //$NON-NLS-1$
-        }
-
-        /* (non-Javadoc)
          * @see org.crosswire.jsword.book.sword.ConfigEntryType#convert(java.lang.String)
          */
         public Object convert(String input)
@@ -1258,14 +1005,6 @@
             return Boolean.valueOf(input);
         }
 
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#getDefault()
-         */
-        public Object getDefault()
-        {
-            return Boolean.TRUE;
-        }
-
         /**
          * Serialization ID
          */
@@ -1276,44 +1015,14 @@
      * single value version number, lowest sword c++ version that can read this book
      * JSword does not use this value.
      */
-    public static final ConfigEntryType OSIS_VERSION = new ConfigEntryType("OSISVersion") //$NON-NLS-1$
-    {
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#getDefault()
-         */
-        public Object getDefault()
-        {
-            // This value is unimportant to JSword, but is to Sword
-            return "1.5.1a"; //$NON-NLS-1$
-        }
+    public static final ConfigEntryType OSIS_VERSION = new ConfigEntryType("OSISVersion", "2.0"); //$NON-NLS-1$ //$NON-NLS-2$
 
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = -6381507058727637134L;
-    };
-
-
     /**
      * The abbreviated name by which this book is known. This is in the [] on the first non-blank
      * line of the conf. JSword uses this for display and access purposes.
      */
-    public static final ConfigEntryType INITIALS = new ConfigEntryType("Initials") //$NON-NLS-1$
-    {
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isSynthetic()
-         */
-        public boolean isSynthetic()
-        {
-            return true;
-        }
+    public static final ConfigEntryType INITIALS = new ConfigEntrySyntheticType("Initials"); //$NON-NLS-1$
 
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = 3257009838994108467L;
-    };
-
     /**
      * A one line promo statement, required by Lockman for NASB
      */
@@ -1327,47 +1036,28 @@
     /**
      * The location of a collection of modules. JSword uses this to install and delete a module.
      */
-    public static final ConfigEntryType LIBRARY_URL = new ConfigEntryType("LibraryURL") //$NON-NLS-1$
-    {
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isSynthetic()
-         */
-        public boolean isSynthetic()
-        {
-            return true;
-        }
+    public static final ConfigEntryType LIBRARY_URL = new ConfigEntrySyntheticType("LibraryURL"); //$NON-NLS-1$
 
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = -2468890875139856087L;
-    };
-
     /**
      * The location of the module. JSword uses this to access a module.
      */
-    public static final ConfigEntryType LOCATION_URL = new ConfigEntryType("LocationURL") //$NON-NLS-1$
-    {
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isSynthetic()
-         */
-        public boolean isSynthetic()
-        {
-            return true;
-        }
+    public static final ConfigEntryType LOCATION_URL = new ConfigEntrySyntheticType("LocationURL"); //$NON-NLS-1$
 
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = -2468890875139856087L;
-    };
-
     /**
      * Simple ctor
      */
     protected ConfigEntryType(String name)
     {
+        this(name, null);
+    }
+
+    /**
+     * Simple ctor
+     */
+    protected ConfigEntryType(String name, Object defaultValue)
+    {
         this.name = name;
+        this.defaultValue = defaultValue;
     }
 
     /**
@@ -1465,7 +1155,7 @@
      */
     public Object getDefault()
     {
-        return null;
+        return defaultValue;
     }
 
     /**
@@ -1490,6 +1180,7 @@
             {
                 return ConfigEntryType.HISTORY;
             }
+
             for (int i = 0; i < VALUES.length; i++)
             {
                 ConfigEntryType o = VALUES[i];
@@ -1499,6 +1190,7 @@
                 }
             }
         }
+
         // should not get here.
         // But there are typos in the keys in the book conf files
         // And this allows for the addition of new fields in
@@ -1541,18 +1233,16 @@
     }
 
     /**
-     * Constants for direction
-     */
-    public static final String DIRECTION_LTOR = "LtoR"; //$NON-NLS-1$
-    public static final String DIRECTION_RTOL = "RtoL"; //$NON-NLS-1$
-    public static final String DIRECTION_BIDI = "bidi"; //$NON-NLS-1$
-
-    /**
      * The name of the ConfigEntryType
      */
     private String name;
 
     /**
+     * The default for the ConfigEntryType
+     */
+    private Object defaultValue;
+    
+    /**
      * Serialization ID
      */
     private static final long serialVersionUID = 3258125873411273014L;
@@ -1612,5 +1302,6 @@
         SHORT_PROMO,
         SHORT_COPYRIGHT,
         LOCATION_URL,
+        KEY_TYPE,
     };
 }

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ZVerseBackend.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ZVerseBackend.java	2008-06-13 10:56:31 UTC (rev 1876)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ZVerseBackend.java	2008-06-18 20:22:45 UTC (rev 1877)
@@ -257,7 +257,16 @@
             // If the Bible does not contain the desired verse, return nothing.
             // Some Bibles have different versification, so the requested verse
             // may not exist.
-            return (temp != null && temp.length > 0);
+            if (temp == null || temp.length == 0)
+            {
+                return false;
+            }
+
+            // The data is little endian - extract the blockNum, verseStart and verseSize
+            int verseSize = SwordUtil.decodeLittleEndian16(temp, 8);
+
+            return (verseSize > 0);
+
         }
         catch (IOException e)
         {

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/bridge/BibleScope.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/bridge/BibleScope.java	2008-06-13 10:56:31 UTC (rev 1876)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/bridge/BibleScope.java	2008-06-18 20:22:45 UTC (rev 1877)
@@ -92,6 +92,21 @@
         }
     }
 
+    public static void report(Book b)
+    {
+        if (!b.getBookCategory().equals(BookCategory.BIBLE) && !b.getBookCategory().equals(BookCategory.COMMENTARY))
+        {
+            System.err.println(b.getInitials() + " is not a Bible or Commentary"); //$NON-NLS-1$
+            //System.exit(1);
+        }
+
+        BibleScope scope = new BibleScope(b);
+        BibleInfo.setFullBookName(false); // use short names
+        System.out.println('[' + b.getInitials() + ']');
+        System.out.println("InScope=" + scope.getInScope().getOsisRef()); //$NON-NLS-1$
+        System.out.println("OutScope=" + scope.getOutOfScope().getOsisRef()); //$NON-NLS-1$        
+    }
+
     private Book book;
 
     /**
@@ -122,17 +137,19 @@
             System.exit(1);
         }
 
-        if (!b.getBookCategory().equals(BookCategory.BIBLE))
-        {
-            System.err.println(b.getInitials() + " is not a Bible"); //$NON-NLS-1$
-            System.exit(1);
-        }
+        report(b);
 
-        BibleScope scope = new BibleScope(b);
-        BibleInfo.setFullBookName(false); // use short names
-        System.out.println("Scope of KJV versification for " + b.getInitials()); //$NON-NLS-1$
-        System.out.println("In scope     = " + scope.getInScope().getName()); //$NON-NLS-1$
-        System.out.println("Out of scope = " + scope.getOutOfScope().getName()); //$NON-NLS-1$
+//        List books = Books.installed().getBooks(BookFilters.getCommentaries());
+//        Iterator iter = books.iterator();
+//        while (iter.hasNext())
+//        {
+//            try {
+//                report((Book) iter.next());
+//            } catch (Exception e) {
+//                System.out.println("exception " + e.toString());
+//            }
+//            System.out.println();
+//        }
     }
 
     public static void usage()

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/examples/APIExamples.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/examples/APIExamples.java	2008-06-13 10:56:31 UTC (rev 1876)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/examples/APIExamples.java	2008-06-18 20:22:45 UTC (rev 1877)
@@ -121,7 +121,7 @@
         if (BookCategory.BIBLE.equals(book.getBookCategory()))
         {
             key = book.getKey(reference);
-            key = ((Passage) key).trimVerses(maxKeyCount);
+            ((Passage) key).trimVerses(maxKeyCount);
         }
         else
         {
@@ -197,7 +197,7 @@
 
         System.out.println("The first Key in the default dictionary is " + first); //$NON-NLS-1$
 
-        BookData data = new BookData(dict, keys);
+        BookData data = new BookData(dict, first);
         System.out.println("And the text against that key is " + OSISUtil.getPlainText(data.getOsisFragment())); //$NON-NLS-1$
     }
 




More information about the jsword-svn mailing list