[jsword-svn] r1960 - trunk/jsword/src/main/java/org/crosswire/jsword/book/sword

dmsmith at crosswire.org dmsmith at crosswire.org
Tue Oct 27 16:17:16 MST 2009


Author: dmsmith
Date: 2009-10-27 16:17:16 -0700 (Tue, 27 Oct 2009)
New Revision: 1960

Modified:
   trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ConfigEntry.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
Log:
Updated SWORD configuration handling to do:
a) simplified looking for RTF using a Java pattern
b) Added new config element as defined in wiki.
c) Changed ConfigEntryTable to store all fields, even unknown ones. This will keep the writing of the conf from losing info.

Modified: trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ConfigEntry.java
===================================================================
--- trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ConfigEntry.java	2009-10-27 23:13:20 UTC (rev 1959)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ConfigEntry.java	2009-10-27 23:17:16 UTC (rev 1960)
@@ -24,6 +24,7 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
+import java.util.regex.Pattern;
 
 import org.crosswire.common.util.Histogram;
 import org.crosswire.common.util.Language;
@@ -205,6 +206,7 @@
         Object def = type.getDefault();
         return def != null && def.equals(search);
     }
+
     /**
      * Add a value to the list of values for this ConfigEntry
      */
@@ -218,8 +220,11 @@
             aValue = type.filter(aValue);
         }
 
-        // call handleRTF for error reporting, but don't use the result
-        handleRTF(aValue);
+        // Report on fields that shouldn't have RTF but do
+        if (!allowsRTF() && RTF_PATTERN.matcher(aValue).find())
+        {
+            log.info(report("Ignoring unexpected RTF for", getName(), aValue)); //$NON-NLS-1$
+        }
 
         if (mayRepeat())
         {
@@ -388,25 +393,14 @@
         {
             buf.append(getName());
             buf.append('=');
+            String text = getConfValue(value);
             if (allowsContinuation())
             {
-                String text = getConfValue(value);
-                String [] lines = StringUtil.splitAll(text, '\n');
-                for (int i = 0; i < lines.length; i++)
-                {
-                    if (i > 0)
-                    {
-                        buf.append("\\\n"); //$NON-NLS-1$
-                    }
-                    buf.append(lines[i]);
-                }
-                buf.append('\n');
+                // With continuation each line is ended with a '\', except the last.
+                text = text.replaceAll("\n", "\\\\\n"); //$NON-NLS-1$ //$NON-NLS-2$
             }
-            else
-            {
-                buf.append(getConfValue(value));
-                buf.append('\n');
-            }
+            buf.append(text);
+            buf.append('\n');
         }
         // CipherKey is empty to indicate that it is encrypted and locked.
         else if (type.equals(ConfigEntryType.CIPHER_KEY))
@@ -466,43 +460,6 @@
         return null;
     }
 
-    private String handleRTF(String aValue)
-    {
-        String copy = aValue;
-        // This method is a hack! It could be made much nicer.
-
-        // strip \pard
-        copy = copy.replaceAll("\\\\pard ?", ""); //$NON-NLS-1$ //$NON-NLS-2$
-
-        // replace rtf newlines
-        copy = copy.replaceAll("\\\\pa[er] ?", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
-
-        // strip whatever \qc is.
-        copy = copy.replaceAll("\\\\qc ?", ""); //$NON-NLS-1$ //$NON-NLS-2$
-
-        // strip bold and italic
-        copy = copy.replaceAll("\\\\[bi]0? ?", ""); //$NON-NLS-1$ //$NON-NLS-2$
-
-        // strip unicode characters
-        copy = copy.replaceAll("\\\\u-?[0-9]{4,6}+\\?", ""); //$NON-NLS-1$ //$NON-NLS-2$
-
-        // strip { and } which are found in {\i text }
-        copy = copy.replaceAll("[{}]", ""); //$NON-NLS-1$ //$NON-NLS-2$
-
-        // This check is here rather than at the top, so we can find the problems
-        // and fix the source.
-        if (!allowsRTF())
-        {
-            if (!copy.equals(aValue))
-            {
-                log.info(report("Ignoring unexpected RTF for", getName(), aValue)); //$NON-NLS-1$
-            }
-            return aValue;
-        }
-
-        return copy;
-    }
-
     private List processLines(OSISUtil.OSISFactory factory, String aValue)
     {
         List list = new ArrayList();
@@ -533,15 +490,22 @@
     /**
      * The log stream
      */
-    private static final Logger log = Logger.getLogger(ConfigEntry.class);
+    private static final Logger  log         = Logger.getLogger(ConfigEntry.class);
+
     /**
+     * A pattern of allowable RTF in a SWORD conf.
+     * These are: \pard, \pae, \par, \qc \b, \i and embedded Unicode
+     */
+    private static final Pattern RTF_PATTERN = Pattern.compile("\\\\pard|\\\\pa[er]|\\\\qc|\\\\[bi]|\\\\u-?[0-9]{4,6}+"); //$NON-NLS-1$
+
+    /**
      * A histogram for debugging.
      */
-    private static Histogram histogram = new Histogram();
+    private static Histogram     histogram   = new Histogram();
 
-    private ConfigEntryType type;
-    private String internal;
-    private String name;
-    private List values;
-    private Object value;
+    private ConfigEntryType      type;
+    private String               internal;
+    private String               name;
+    private List                 values;
+    private Object               value;
 }

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	2009-10-27 23:13:20 UTC (rev 1959)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ConfigEntryTable.java	2009-10-27 23:17:16 UTC (rev 1960)
@@ -31,8 +31,10 @@
 import java.io.OutputStreamWriter;
 import java.io.Writer;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeMap;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -72,6 +74,7 @@
     public ConfigEntryTable(String bookName)
     {
         table = new HashMap();
+        extra = new TreeMap();
         internal = bookName;
         supported = true;
     }
@@ -100,6 +103,7 @@
                 questionable = false;
                 readahead = null;
                 table.clear();
+                extra.clear();
                 in = new BufferedReader(new InputStreamReader(new FileInputStream(file), ENCODING_LATIN1));
                 loadInitials(in);
                 loadContents(in);
@@ -144,6 +148,7 @@
                 questionable = false;
                 readahead = null;
                 table.clear();
+                extra.clear();
                 in = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(buffer), ENCODING_LATIN1));
                 loadInitials(in);
                 loadContents(in);
@@ -241,7 +246,7 @@
     }
 
     /**
-     * Returns an Enumeration of all the keys found in the config file.
+     * Returns an Enumeration of all the known keys found in the config file.
      */
     public Set getKeys()
     {
@@ -249,6 +254,14 @@
     }
 
     /**
+     * Returns an Enumeration of all the unknown keys found in the config file.
+     */
+    public Set getExtraKeys()
+    {
+        return extra.keySet();
+    }
+
+    /**
      * Returns an Enumeration of all the keys found in the config file.
      */
     public BookType getBookType()
@@ -286,6 +299,30 @@
     }
 
     /**
+     * Gets a particular unknown entries value by its key
+     * @param key of the unknown entry
+     * @return the requested value or null (if there is no value)
+     */
+    public String getExtraValue(String key)
+    {
+        return (String) extra.get(key);
+    }
+
+    /**
+     * Determine whether this ConfigEntryTable has the ConfigEntry
+     * and it matches the value.
+     *
+     * @param key The kind of unknown entry to look for
+     * @param search the value to match against
+     * @return true if there is a unknown entry matching the value
+     */
+    public boolean matchExtra(String key, String search)
+    {
+        String ce = (String) extra.get(key);
+        return ce != null && ce.equalsIgnoreCase(search);
+    }
+
+    /**
      * Sort the keys for a more meaningful presentation order.
      */
     public Element toOSIS()
@@ -297,6 +334,7 @@
         toOSIS(factory, ele, "LicenseInfo", COPYRIGHT_INFO); //$NON-NLS-1$
         toOSIS(factory, ele, "FeatureInfo", FEATURE_INFO); //$NON-NLS-1$
         toOSIS(factory, ele, "SysInfo", SYSTEM_INFO); //$NON-NLS-1$
+        toOSIS(factory, ele, "Extra", extra); //$NON-NLS-1$
         return ele;
     }
 
@@ -318,6 +356,7 @@
         toConf(buf, FEATURE_INFO);
         toConf(buf, LANG_INFO);
         toConf(buf, COPYRIGHT_INFO);
+        toConf(buf, extra);
         return buf.toString();
     }
 
@@ -400,7 +439,8 @@
             {
                 if (type == null)
                 {
-                    log.warn("Ignoring unexpected entry in " + internal  + " of " + configEntry.getName()); //$NON-NLS-1$ //$NON-NLS-2$
+                    log.warn("Extra entry in " + internal  + " of " + configEntry.getName()); //$NON-NLS-1$ //$NON-NLS-2$
+                    extra.put(key, configEntry);
                 }
                 else if (type.isSynthetic())
                 {
@@ -610,7 +650,7 @@
             {
                 log.warn("Missing data for " + internal + ". Assuming " + ConfigEntryType.GLOSSARY_FROM.getName() + '=' + Languages.DEFAULT_LANG_CODE);  //$NON-NLS-1$ //$NON-NLS-2$
                 langFrom = Language.DEFAULT_LANG;
-                add(ConfigEntryType.GLOSSARY_FROM, lang.toString());
+                add(ConfigEntryType.GLOSSARY_FROM, lang.getCode());
             }
             testLanguage(internal, langFrom);
 
@@ -618,7 +658,7 @@
             {
                 log.warn("Missing data for " + internal + ". Assuming " + ConfigEntryType.GLOSSARY_TO.getName() + '=' + Languages.DEFAULT_LANG_CODE);  //$NON-NLS-1$ //$NON-NLS-2$
                 langTo = Language.DEFAULT_LANG;
-                add(ConfigEntryType.GLOSSARY_TO, lang.toString());
+                add(ConfigEntryType.GLOSSARY_TO, lang.getCode());
             }
             testLanguage(internal, langTo);
 
@@ -640,7 +680,7 @@
                           " (" + langFrom.getCode() + ") does not match " + ConfigEntryType.LANG.getName() + " (" + lang.getCode() + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
              */
                 lang = langFrom;
-                add(ConfigEntryType.LANG, lang.toString());
+                add(ConfigEntryType.LANG, lang.getCode());
             }
         }
     }
@@ -767,6 +807,53 @@
         }
     }
 
+    /**
+     * Build an ordered map so that it displays in a consistent order.
+     */
+    private void toOSIS(OSISUtil.OSISFactory factory, Element ele, String aTitle, Map map)
+    {
+        Element title = null;
+        Iterator iter = map.entrySet().iterator();
+        while (iter.hasNext())
+        {
+            Map.Entry mapEntry = (Map.Entry) iter.next();
+            ConfigEntry entry = (ConfigEntry) mapEntry.getValue();
+            Element configElement = null;
+
+            if (entry != null)
+            {
+                configElement = entry.toOSIS();
+            }
+
+            if (title == null && configElement != null)
+            {
+                // I18N(DMS): use aTitle to lookup translation.
+                title = factory.createHeader();
+                title.addContent(aTitle);
+                ele.addContent(title);
+            }
+
+            if (configElement != null)
+            {
+                ele.addContent(configElement);
+            }
+        }
+    }
+    private void toConf(StringBuffer buf, Map map)
+    {
+        Iterator iter = map.entrySet().iterator();
+        while (iter.hasNext())
+        {
+            Map.Entry mapEntry = (Map.Entry) iter.next();
+            ConfigEntry entry = (ConfigEntry) mapEntry.getValue();
+            String text = entry.toConf();
+            if (text != null && text.length() > 0)
+            {
+                buf.append(text);
+            }
+        }
+    }
+
     private String report(String issue, String confEntryName, String line)
     {
         StringBuffer buf = new StringBuffer(100);
@@ -888,6 +975,11 @@
     private Map table;
 
     /**
+     * A map of lists of unknown config entries.
+     */
+    private Map extra;
+
+    /**
      * The BookType for this ConfigEntry
      */
     private BookType bookType;

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	2009-10-27 23:13:20 UTC (rev 1959)
+++ trunk/jsword/src/main/java/org/crosswire/jsword/book/sword/ConfigEntryType.java	2009-10-27 23:17:16 UTC (rev 1960)
@@ -36,6 +36,10 @@
  * http://www.crosswire.org/ucgi-bin/twiki/view/Swordapi/ConfFileLayout
  * now located at
  * http://www.crosswire.org/wiki/index.php/DevTools:Modules
+ * now located at
+ * http://www.crosswire.org/wiki/DevTools:confFiles
+ * 
+ * Note: This file is organized the same as the latest wiki documentation.
  *
  * @see gnu.lgpl.License for license details.
  *      The copyright to this program is held by it's authors.
@@ -66,13 +70,6 @@
               "false", //$NON-NLS-1$
           };
 
-    private static final String[] KEY_TYPE_PICKS
-        = new String[]
-          {
-              "TreeKey", //$NON-NLS-1$
-              "VerseKey", //$NON-NLS-1$
-          };
-
     private static final String[] CATEGORY_PICKS
         = new String[]
           {
@@ -103,29 +100,24 @@
               DIRECTION_BIDI,
           };
 
-    private static final String[] LICENSE_PICKS
+    private static final String[] KEY_TYPE_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$
+              "TreeKey", //$NON-NLS-1$
+              "VerseKey", //$NON-NLS-1$
           };
 
-    private static final String[] ENCODING_PICKS
+    private static final String[] FEATURE_PICKS
         = new String[]
           {
-              "Latin-1", //$NON-NLS-1$
-              "UTF-8", //$NON-NLS-1$
+              "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$
           };
 
     private static final String[] GLOBAL_OPTION_FILTER_PICKS
@@ -147,29 +139,42 @@
               "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$
               "OSISLemma", //$NON-NLS-1$
-              "OSISMorph", //$NON-NLS-1$
-              "OSISRedLetterWords", //$NON-NLS-1$
               "OSISRuby", //$NON-NLS-1$
-              "OSISScripref", //$NON-NLS-1$
-              "OSISStrongs", //$NON-NLS-1$
           };
 
-    private static final String[] FEATURE_PICKS
+    private static final String[] LICENSE_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 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$
+              "Copyrighted; Permission granted to distribute non-commercially in Sword format", //$NON-NLS-1$
+              "GFDL", //$NON-NLS-1$
+              "GPL", //$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$
           };
 
+    private static final String[] ENCODING_PICKS
+        = new String[]
+          {
+              "Latin-1", //$NON-NLS-1$
+              "UTF-8", //$NON-NLS-1$
+          };
+
     private static final String[] MOD_DRV_PICKS
         = new String[]
           {
@@ -196,6 +201,17 @@
               "TEI", //$NON-NLS-1$
           };
 
+    private static final String[] VERSIFICATION_PICKS
+        = new String[]
+          {
+              "KJV", //$NON-NLS-1$
+              "KJVA", //$NON-NLS-1$
+              "NRSV", //$NON-NLS-1$
+              "NRSVA", //$NON-NLS-1$
+              "Leningrad", //$NON-NLS-1$
+              "MT", //$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. 
@@ -311,33 +327,52 @@
     }
 
     /**
-     * Contains rtf that describes the book.
+     * 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 ABOUT = new ConfigEntryType("About") //$NON-NLS-1$
+    public static final ConfigEntryType INITIALS = new ConfigEntrySyntheticType("Initials"); //$NON-NLS-1$
+
+    /**
+     * Relative path to the data files, some issues with this
+     */
+    public static final ConfigEntryType DATA_PATH = new ConfigEntryType("DataPath") //$NON-NLS-1$
     {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsContinuation()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
          */
-        public boolean allowsContinuation()
+        public boolean isAllowed(String value)
         {
             return true;
         }
 
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsRTF()
-         */
-        public boolean allowsRTF()
-        {
-            return true;
-        }
-
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3258416110121334073L;
+        private static final long serialVersionUID = 3546926870244309296L;
     };
 
     /**
+     * The full name of this book
+     */
+    public static final ConfigEntryType DESCRIPTION = new ConfigEntryType("Description"); //$NON-NLS-1$
+
+    /**
+     * This indicates how the book was stored.
+     */
+    public static final ConfigEntryType MOD_DRV = new ConfigEntryPickType("ModDrv", MOD_DRV_PICKS); //$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 ConfigEntryPickType("CompressType", COMPRESS_TYPE_PICKS, COMPRESS_TYPE_PICKS[0]); //$NON-NLS-1$
+
+    /**
+     * 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$
+
+    /**
      * single value integer, unknown use, some indications that we ought to be using it
      */
     public static final ConfigEntryType BLOCK_COUNT = new ConfigEntryType("BlockCount", new Integer(200)) //$NON-NLS-1$
@@ -380,84 +415,133 @@
     };
 
     /**
-     * The level at which compression is applied, BOOK, CHAPTER, or VERSE
+     * The kind of key that a Generic Book uses.
      */
-    public static final ConfigEntryType BLOCK_TYPE = new ConfigEntryPickType("BlockType", BLOCK_TYPE_PICKS, BLOCK_TYPE_PICKS[0]); //$NON-NLS-1$
+    public static final ConfigEntryType KEY_TYPE = new ConfigEntryPickType("KeyType", KEY_TYPE_PICKS, KEY_TYPE_PICKS[0]); //$NON-NLS-1$
 
     /**
-     * The kind of key that a Generic Book uses.
+     * If this exists in the conf, then the book is encrypted. The value is used to
+     * unlock the book. The encryption algorithm is Sapphire.
      */
-    public static final ConfigEntryType KEY_TYPE = new ConfigEntryPickType("KeyType", KEY_TYPE_PICKS, KEY_TYPE_PICKS[0]); //$NON-NLS-1$
+    public static final ConfigEntryType CIPHER_KEY = new ConfigEntryType("CipherKey"); //$NON-NLS-1$
 
     /**
-     * The Category of the book. Used on the web to classify books into a tree.
+     * This indicates the versification of the book, with KJV being the default.
      */
-    public static final ConfigEntryType CATEGORY = new ConfigEntryPickType("Category", CATEGORY_PICKS, BookCategory.OTHER) //$NON-NLS-1$
+    public static final ConfigEntryType VERSIFICATION = new ConfigEntryPickType("Versification", VERSIFICATION_PICKS); //$NON-NLS-1$
+
+    /**
+     * 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 ConfigEntryPickType("GlobalOptionFilter", GLOBAL_OPTION_FILTER_PICKS)//$NON-NLS-1$
     {
-        /*
-         * (non-Javadoc)
-         * 
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#convert(java.lang.String)
+        /* (non-Javadoc)
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#mayRepeat()
          */
-        public Object convert(String input)
+        public boolean mayRepeat()
         {
-            return BookCategory.fromString(input);
+            return true;
         }
 
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3258412850174571569L;
+        private static final long serialVersionUID = 3258417209599931960L;
     };
 
     /**
-     * If this exists in the conf, then the book is encrypted. The value is used to
-     * unlock the book. The encryption algorithm is Sapphire.
+     * 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 CIPHER_KEY = new ConfigEntryType("CipherKey"); //$NON-NLS-1$
+    public static final ConfigEntryType DIRECTION = new ConfigEntryPickType("Direction", DIRECTION_PICKS, DIRECTION_PICKS[0]); //$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.
+     * This indicates the kind of markup used for the book.
      */
-    public static final ConfigEntryType COMPRESS_TYPE = new ConfigEntryPickType("CompressType", COMPRESS_TYPE_PICKS, COMPRESS_TYPE_PICKS[0]); //$NON-NLS-1$
+    public static final ConfigEntryType SOURCE_TYPE = new ConfigEntryPickType("SourceType", SOURCE_TYPE_PICKS, SOURCE_TYPE_PICKS[0]); //$NON-NLS-1$
 
     /**
-     * Informational copyright notice.
+     * The character encoding. Only Latin-1 and UTF-8 are supported.
      */
-    public static final ConfigEntryType COPYRIGHT = new ConfigEntryType("Copyright") //$NON-NLS-1$
+    public static final ConfigEntryType ENCODING = new ConfigEntryPickType("Encoding", ENCODING_PICKS, ENCODING_PICKS[0]); //$NON-NLS-1$
+
+    /**
+     * 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$
     {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsContinuation()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
          */
-        public boolean allowsContinuation()
+        public boolean isAllowed(String value)
         {
-            return true;
+            try
+            {
+                Integer.parseInt(value);
+                return true;
+            }
+            catch (NumberFormatException e)
+            {
+                return false;
+            }
         }
 
+        /* (non-Javadoc)
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#convert(java.lang.String)
+         */
+        public Object convert(String input)
+        {
+            try
+            {
+                return new Integer(input);
+            }
+            catch (NumberFormatException e)
+            {
+                return null;
+            }
+        }
+
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3256441412957517110L;
+        private static final long serialVersionUID = 3979274654953451830L;
     };
 
     /**
-     * Copyright info. Informational only.
+     * A recommended font to use for the book.
      */
-    public static final ConfigEntryType COPYRIGHT_CONTACT_ADDRESS = new ConfigEntryType("CopyrightContactAddress") //$NON-NLS-1$
+    public static final ConfigEntryType FONT = new ConfigEntryType("Font"); //$NON-NLS-1$
+
+    /**
+     * When false do not show quotation marks for OSIS text that has <q> elements.
+     */
+    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#allowsContinuation()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#convert(java.lang.String)
          */
-        public boolean allowsContinuation()
+        public Object convert(String input)
         {
-            return true;
+            return Boolean.valueOf(input);
         }
 
+        /**
+         * Serialization ID
+         */
+        private static final long serialVersionUID = 3258412850174373936L;
+    };
+
+    /**
+     * A Feature describes a characteristic of the Book.
+     */
+    public static final ConfigEntryType FEATURE = new ConfigEntryPickType("Feature", FEATURE_PICKS) //$NON-NLS-1$
+    {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsRTF()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#mayRepeat()
          */
-        public boolean allowsRTF()
+        public boolean mayRepeat()
         {
             return true;
         }
@@ -465,45 +549,57 @@
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3256721784077365556L;
+        private static final long serialVersionUID = 3833181424051172401L;
     };
 
     /**
-     * Copyright info. Informational only.
+     * Books with a Feature of Glossary are used to map words FROM one language TO another.
      */
-    public static final ConfigEntryType COPYRIGHT_CONTACT_EMAIL = new ConfigEntryType("CopyrightContactEmail"); //$NON-NLS-1$
+    public static final ConfigEntryType GLOSSARY_FROM = new ConfigEntryType("GlossaryFrom") //$NON-NLS-1$
+    {
+        /**
+         * Serialization ID
+         */
+        private static final long serialVersionUID = 6619179970516935818L;
 
-    /**
-     * Copyright info. Informational only.
-     */
-    public static final ConfigEntryType COPYRIGHT_CONTACT_NAME = new ConfigEntryType("CopyrightContactName") //$NON-NLS-1$
-    {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsContinuation()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#convert(java.lang.String)
          */
-        public boolean allowsContinuation()
+        public Object convert(String input)
         {
-            return true;
+            return new Language(input);
         }
 
+    };
+
+    /**
+     * Books with a Feature of Glossary are used to map words FROM one language TO another.
+     */
+    public static final ConfigEntryType GLOSSARY_TO = new ConfigEntryType("GlossaryTo") //$NON-NLS-1$
+    {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsRTF()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#convert(java.lang.String)
          */
-        public boolean allowsRTF()
+        public Object convert(String input)
         {
-            return true;
+            return new Language(input);
         }
 
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3257001060181620787L;
+        private static final long serialVersionUID = 3273532519245386866L;
     };
 
     /**
-     * Copyright info. Informational only.
+     * The short name of this book.
      */
-    public static final ConfigEntryType COPYRIGHT_CONTACT_NOTES = new ConfigEntryType("CopyrightContactNotes") //$NON-NLS-1$
+    public static final ConfigEntryType ABBREVIATION = new ConfigEntryType("Abbreviation"); //$NON-NLS-1$
+
+    /**
+     * 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#allowsContinuation()
@@ -524,97 +620,119 @@
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3257001060181620787L;
+        private static final long serialVersionUID = 3258416110121334073L;
     };
 
     /**
-     * Copyright info. Informational only. This is a year, a year range or a comma separated list of these.
+     * An informational string indicating the current version of the book.
      */
-    public static final ConfigEntryType COPYRIGHT_DATE = new ConfigEntryType("CopyrightDate") //$NON-NLS-1$
+    public static final ConfigEntryType VERSION = new ConfigEntryType("Version", "1.0") //$NON-NLS-1$ //$NON-NLS-2$
     {
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
-         */
-        public boolean isAllowed(String value)
+        public boolean isAllowed(String aValue)
         {
-            return validDatePattern.matcher(value).matches();
+            try
+            {
+                Float.parseFloat(aValue);
+                return true;
+            }
+            catch (NumberFormatException e)
+            {
+                return false;
+            }
+
         }
 
-        private Pattern validDatePattern = Pattern.compile("\\d{4}(\\s*-\\s*\\d{4})?(\\s*,\\s*\\d{4}(\\s*-\\s*\\d{4})?)*"); //$NON-NLS-1$
-
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3258126977217935671L;
+        private static final long serialVersionUID = 3256443616242055221L;
     };
 
     /**
-     * single value string, unknown use
+     * multiple values starting with History, some sort of change-log.
+     * In the conf these are of the form History_x.y. We strip off the x.y and prefix the value with it.
+     * The x.y corresponds to a current or prior Version value.
      */
-    public static final ConfigEntryType COPYRIGHT_HOLDER = new ConfigEntryType("CopyrightHolder"); //$NON-NLS-1$
-
-    /**
-     * Copyright info. Informational only.
-     */
-    public static final ConfigEntryType COPYRIGHT_NOTES = new ConfigEntryType("CopyrightNotes") //$NON-NLS-1$
+    public static final ConfigEntryType HISTORY = new ConfigEntryType("History") //$NON-NLS-1$
     {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsContinuation()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#mayRepeat()
          */
-        public boolean allowsContinuation()
+        public boolean mayRepeat()
         {
             return true;
         }
 
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsRTF()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#reportDetails()
          */
-        public boolean allowsRTF()
+        public boolean reportDetails()
         {
-            return true;
+            return false;
         }
 
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3906926794258199608L;
+        private static final long serialVersionUID = 3979272443195830835L;
     };
 
     /**
-     * Relative path to the data files, some issues with this
+     * single value version number, lowest sword c++ version that can read this
+     * book JSword does not use this value.
      */
-    public static final ConfigEntryType DATA_PATH = new ConfigEntryType("DataPath") //$NON-NLS-1$
+    public static final ConfigEntryType MINIMUM_VERSION = new ConfigEntryType("MinimumVersion", "1.5.1a"); //$NON-NLS-1$ //$NON-NLS-2$
+
+    /**
+     * 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#isAllowed(java.lang.String)
+        /*
+         * (non-Javadoc)
+         * 
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#convert(java.lang.String)
          */
-        public boolean isAllowed(String value)
+        public Object convert(String input)
         {
-            return true;
+            return BookCategory.fromString(input);
         }
 
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3546926870244309296L;
+        private static final long serialVersionUID = 3258412850174571569L;
     };
 
     /**
-     * The full name of this book
+     * Library of Congress Subject Heading.
+     * Typically this is of the form BookCategory Scope Language, where scope is typically O.T., N.T.
      */
-    public static final ConfigEntryType DESCRIPTION = new ConfigEntryType("Description"); //$NON-NLS-1$
+    public static final ConfigEntryType LCSH = new ConfigEntryType("LCSH"); //$NON-NLS-1$
 
     /**
-     * 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.
+     * single value string, defaults to en, the language of the book
      */
-    public static final ConfigEntryType DIRECTION = new ConfigEntryPickType("Direction", DIRECTION_PICKS, DIRECTION_PICKS[0]); //$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#convert(java.lang.String)
+         */
+        public Object convert(String input)
+        {
+            return new Language(input);
+        }
 
+        /**
+         * Serialization ID
+         */
+        private static final long serialVersionUID = 3257008752317379897L;
+    };
+
     /**
-     * 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.
+     * The installed size of the book in bytes. This is not the size of the zip that is downloaded.
      */
-    public static final ConfigEntryType DISPLAY_LEVEL = new ConfigEntryType("DisplayLevel") //$NON-NLS-1$
+    public static final ConfigEntryType INSTALL_SIZE = new ConfigEntryType("InstallSize") //$NON-NLS-1$
     {
         /* (non-Javadoc)
          * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
@@ -650,38 +768,63 @@
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3979274654953451830L;
+        private static final long serialVersionUID = 3256720680388408370L;
     };
 
     /**
-     * Copyright info. Informational only.
+     * The date that this version of the book was last updated. Informational only.
      */
-    public static final ConfigEntryType DISTRIBUTION_LICENSE = new ConfigEntryPickType("DistributionLicense", LICENSE_PICKS, LICENSE_PICKS[0]); //$NON-NLS-1$
+    public static final ConfigEntryType SWORD_VERSION_DATE = new ConfigEntryType("SwordVersionDate") //$NON-NLS-1$
+    {
+        /* (non-Javadoc)
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
+         */
+        public boolean isAllowed(String value)
+        {
+            return validDatePattern.matcher(value).matches();
+        }
 
+        private Pattern validDatePattern = Pattern.compile("\\d{4}-\\d{2}-\\d{2}"); //$NON-NLS-1$
+
+        /**
+         * Serialization ID
+         */
+        private static final long serialVersionUID = 3618697504682948150L;
+    };
+
     /**
-     * Copyright info. 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 DISTRIBUTION_NOTES = new ConfigEntryType("DistributionNotes") //$NON-NLS-1$
+    public static final ConfigEntryType OBSOLETES = new ConfigEntryType("Obsoletes") //$NON-NLS-1$
     {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsContinuation()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#mayRepeat()
          */
-        public boolean allowsContinuation()
+        public boolean mayRepeat()
         {
             return true;
         }
 
+        /* (non-Javadoc)
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#reportDetails()
+         */
+        public boolean reportDetails()
+        {
+            return false;
+        }
+
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3257005453916518196L;
+        private static final long serialVersionUID = 3258412850157400372L;
     };
 
     /**
-     * Similar to DataPath. It gives where on the CrossWire server the book can be found.
-     * Informational only.
+     * Informational copyright notice.
      */
-    public static final ConfigEntryType DISTRIBUTION_SOURCE = new ConfigEntryType("DistributionSource") //$NON-NLS-1$
+    public static final ConfigEntryType COPYRIGHT = new ConfigEntryType("Copyright") //$NON-NLS-1$
     {
         /* (non-Javadoc)
          * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsContinuation()
@@ -694,257 +837,180 @@
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3763093051127904307L;
+        private static final long serialVersionUID = 3256441412957517110L;
     };
 
     /**
-     * The character encoding. Only Latin-1 and UTF-8 are supported.
+     * single value string, unknown use
      */
-    public static final ConfigEntryType ENCODING = new ConfigEntryPickType("Encoding", ENCODING_PICKS, ENCODING_PICKS[0]); //$NON-NLS-1$
+    public static final ConfigEntryType COPYRIGHT_HOLDER = new ConfigEntryType("CopyrightHolder"); //$NON-NLS-1$
 
     /**
-     * Global Option Filters are the names of routines in Sword that can be used to display the data.
-     * These are not used by JSword.
+     * Copyright info. Informational only. This is a year, a year range or a comma separated list of these.
      */
-    public static final ConfigEntryType GLOBAL_OPTION_FILTER = new ConfigEntryPickType("GlobalOptionFilter", GLOBAL_OPTION_FILTER_PICKS)//$NON-NLS-1$
+    public static final ConfigEntryType COPYRIGHT_DATE = new ConfigEntryType("CopyrightDate") //$NON-NLS-1$
     {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#mayRepeat()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
          */
-        public boolean mayRepeat()
+        public boolean isAllowed(String value)
         {
-            return true;
+            return validDatePattern.matcher(value).matches();
         }
 
+        private Pattern validDatePattern = Pattern.compile("\\d{4}(\\s*-\\s*\\d{4})?(\\s*,\\s*\\d{4}(\\s*-\\s*\\d{4})?)*"); //$NON-NLS-1$
+
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3258417209599931960L;
+        private static final long serialVersionUID = 3258126977217935671L;
     };
 
     /**
-     * Books with a Feature of Glossary are used to map words FROM one language TO another.
+     * Copyright info. Informational only.
      */
-    public static final ConfigEntryType GLOSSARY_FROM = new ConfigEntryType("GlossaryFrom") //$NON-NLS-1$
+    public static final ConfigEntryType COPYRIGHT_NOTES = new ConfigEntryType("CopyrightNotes") //$NON-NLS-1$
     {
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = 6619179970516935818L;
-
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#convert(java.lang.String)
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsContinuation()
          */
-        public Object convert(String input)
+        public boolean allowsContinuation()
         {
-            return new Language(input);
+            return true;
         }
 
-    };
-
-    /**
-     * Books with a Feature of Glossary are used to map words FROM one language TO another.
-     */
-    public static final ConfigEntryType GLOSSARY_TO = new ConfigEntryType("GlossaryTo") //$NON-NLS-1$
-    {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#convert(java.lang.String)
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsRTF()
          */
-        public Object convert(String input)
+        public boolean allowsRTF()
         {
-            return new Language(input);
+            return true;
         }
 
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3273532519245386866L;
+        private static final long serialVersionUID = 3906926794258199608L;
     };
 
     /**
-     * multiple values starting with History, some sort of change-log.
-     * In the conf these are of the form History_x.y. We strip off the x.y and prefix the value with it.
-     * The x.y corresponds to a current or prior Version value.
+     * Copyright info. Informational only.
      */
-    public static final ConfigEntryType HISTORY = new ConfigEntryType("History") //$NON-NLS-1$
+    public static final ConfigEntryType COPYRIGHT_CONTACT_NAME = new ConfigEntryType("CopyrightContactName") //$NON-NLS-1$
     {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#mayRepeat()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsContinuation()
          */
-        public boolean mayRepeat()
+        public boolean allowsContinuation()
         {
             return true;
         }
 
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#reportDetails()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsRTF()
          */
-        public boolean reportDetails()
+        public boolean allowsRTF()
         {
-            return false;
+            return true;
         }
 
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3979272443195830835L;
+        private static final long serialVersionUID = 3257001060181620787L;
     };
 
     /**
-     * The installed size of the book in bytes. This is not the size of the zip that is downloaded.
+     * Copyright info. Informational only.
      */
-    public static final ConfigEntryType INSTALL_SIZE = new ConfigEntryType("InstallSize") //$NON-NLS-1$
+    public static final ConfigEntryType COPYRIGHT_CONTACT_NOTES = new ConfigEntryType("CopyrightContactNotes") //$NON-NLS-1$
     {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsContinuation()
          */
-        public boolean isAllowed(String value)
+        public boolean allowsContinuation()
         {
-            try
-            {
-                Integer.parseInt(value);
-                return true;
-            }
-            catch (NumberFormatException e)
-            {
-                return false;
-            }
+            return true;
         }
 
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#convert(java.lang.String)
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsRTF()
          */
-        public Object convert(String input)
+        public boolean allowsRTF()
         {
-            try
-            {
-                return new Integer(input);
-            }
-            catch (NumberFormatException e)
-            {
-                return null;
-            }
+            return true;
         }
 
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3256720680388408370L;
+        private static final long serialVersionUID = 3257001060181620787L;
     };
 
     /**
-     * A Feature describes a characteristic of the Book.
+     * Copyright info. Informational only.
      */
-    public static final ConfigEntryType FEATURE = new ConfigEntryPickType("Feature", FEATURE_PICKS) //$NON-NLS-1$
+    public static final ConfigEntryType COPYRIGHT_CONTACT_ADDRESS = new ConfigEntryType("CopyrightContactAddress") //$NON-NLS-1$
     {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#mayRepeat()
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsContinuation()
          */
-        public boolean mayRepeat()
+        public boolean allowsContinuation()
         {
             return true;
         }
 
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = 3833181424051172401L;
-    };
-
-    /**
-     * A recommended font to use for the 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", new Language(null)) //$NON-NLS-1$
-    {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#convert(java.lang.String)
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsRTF()
          */
-        public Object convert(String input)
+        public boolean allowsRTF()
         {
-            return new Language(input);
+            return true;
         }
 
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3257008752317379897L;
+        private static final long serialVersionUID = 3256721784077365556L;
     };
 
     /**
-     * Library of Congress Subject Heading.
-     * Typically this is of the form BookCategory Scope Language, where scope is typically O.T., N.T.
+     * Copyright info. Informational only.
      */
-    public static final ConfigEntryType LCSH = new ConfigEntryType("LCSH"); //$NON-NLS-1$
+    public static final ConfigEntryType COPYRIGHT_CONTACT_EMAIL = new ConfigEntryType("CopyrightContactEmail"); //$NON-NLS-1$
 
     /**
-     * This indicates how the book was stored.
+     * A one line promo statement, required by Lockman for NASB
      */
-    public static final ConfigEntryType MOD_DRV = new ConfigEntryPickType("ModDrv", MOD_DRV_PICKS); //$NON-NLS-1$
+    public static final ConfigEntryType SHORT_PROMO = new ConfigEntryType("ShortPromo"); //$NON-NLS-1$
 
     /**
-     * single value version number, lowest sword c++ version that can read this
-     * book JSword does not use this value.
+     * A one line copyright statement, required by Lockman for NASB
      */
-    public static final ConfigEntryType MINIMUM_VERSION = new ConfigEntryType("MinimumVersion", "1.5.1a"); //$NON-NLS-1$ //$NON-NLS-2$
+    public static final ConfigEntryType SHORT_COPYRIGHT = new ConfigEntryType("ShortCopyright"); //$NON-NLS-1$
 
     /**
-     * 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.
+     * Copyright info. Informational only.
      */
-    public static final ConfigEntryType OBSOLETES = new ConfigEntryType("Obsoletes") //$NON-NLS-1$
-    {
-        /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#mayRepeat()
-         */
-        public boolean mayRepeat()
-        {
-            return true;
-        }
+    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#reportDetails()
-         */
-        public boolean reportDetails()
-        {
-            return false;
-        }
-
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = 3258412850157400372L;
-    };
-
     /**
-     * This indicates the kind of markup used for the book.
+     * Copyright info. Informational only.
      */
-    public static final ConfigEntryType SOURCE_TYPE = new ConfigEntryPickType("SourceType", SOURCE_TYPE_PICKS, SOURCE_TYPE_PICKS[0]); //$NON-NLS-1$
-
-    /**
-     * The date that this version of the book was last updated. Informational only.
-     */
-    public static final ConfigEntryType SWORD_VERSION_DATE = new ConfigEntryType("SwordVersionDate") //$NON-NLS-1$
+    public static final ConfigEntryType DISTRIBUTION_NOTES = new ConfigEntryType("DistributionNotes") //$NON-NLS-1$
     {
         /* (non-Javadoc)
-         * @see org.crosswire.jsword.book.sword.ConfigEntryType#isAllowed(java.lang.String)
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsContinuation()
          */
-        public boolean isAllowed(String value)
+        public boolean allowsContinuation()
         {
-            return validDatePattern.matcher(value).matches();
+            return true;
         }
 
-        private Pattern validDatePattern = Pattern.compile("\\d{4}-\\d{2}-\\d{2}"); //$NON-NLS-1$
-
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3618697504682948150L;
+        private static final long serialVersionUID = 3257005453916518196L;
     };
 
     /**
@@ -967,47 +1033,23 @@
     };
 
     /**
-     * An informational string indicating the current version of the book.
+     * Similar to DataPath. It gives where on the CrossWire server the book can be found.
+     * Informational only.
      */
-    public static final ConfigEntryType VERSION = new ConfigEntryType("Version", "1.0") //$NON-NLS-1$ //$NON-NLS-2$
+    public static final ConfigEntryType DISTRIBUTION_SOURCE = new ConfigEntryType("DistributionSource") //$NON-NLS-1$
     {
-        public boolean isAllowed(String aValue)
-        {
-            try
-            {
-                Float.parseFloat(aValue);
-                return true;
-            }
-            catch (NumberFormatException e)
-            {
-                return false;
-            }
-
-        }
-
-        /**
-         * Serialization ID
-         */
-        private static final long serialVersionUID = 3256443616242055221L;
-    };
-
-    /**
-     * When false do not show quotation marks for OSIS text that has <q> elements.
-     */
-    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#convert(java.lang.String)
+         * @see org.crosswire.jsword.book.sword.ConfigEntryType#allowsContinuation()
          */
-        public Object convert(String input)
+        public boolean allowsContinuation()
         {
-            return Boolean.valueOf(input);
+            return true;
         }
 
         /**
          * Serialization ID
          */
-        private static final long serialVersionUID = 3258412850174373936L;
+        private static final long serialVersionUID = 3763093051127904307L;
     };
 
     /**
@@ -1017,22 +1059,6 @@
     public static final ConfigEntryType OSIS_VERSION = new ConfigEntryType("OSISVersion", "2.0"); //$NON-NLS-1$ //$NON-NLS-2$
 
     /**
-     * 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 ConfigEntrySyntheticType("Initials"); //$NON-NLS-1$
-
-    /**
-     * A one line promo statement, required by Lockman for NASB
-     */
-    public static final ConfigEntryType SHORT_PROMO = new ConfigEntryType("ShortPromo"); //$NON-NLS-1$
-
-    /**
-     * A one line copyright statement, required by Lockman for NASB
-     */
-    public static final ConfigEntryType SHORT_COPYRIGHT = new ConfigEntryType("ShortCopyright"); //$NON-NLS-1$
-
-    /**
      * The location of a collection of modules. JSword uses this to install and delete a module.
      */
     public static final ConfigEntryType LIBRARY_URL = new ConfigEntrySyntheticType("LibraryURL"); //$NON-NLS-1$
@@ -1257,50 +1283,59 @@
 
     private static final ConfigEntryType[] VALUES =
     {
-        ABOUT,
+        INITIALS,
+        DATA_PATH,
+        DESCRIPTION,
+        MOD_DRV,
+
+        COMPRESS_TYPE,
+        BLOCK_TYPE,
         BLOCK_COUNT,
-        BLOCK_TYPE,
-        CATEGORY,
+        KEY_TYPE,
         CIPHER_KEY,
-        COMPRESS_TYPE,
-        COPYRIGHT,
-        COPYRIGHT_CONTACT_ADDRESS,
-        COPYRIGHT_CONTACT_EMAIL,
-        COPYRIGHT_CONTACT_NAME,
-        COPYRIGHT_CONTACT_NOTES,
-        COPYRIGHT_DATE,
-        COPYRIGHT_HOLDER,
-        COPYRIGHT_NOTES,
-        DATA_PATH,
-        DESCRIPTION,
+        VERSIFICATION,
+
+        GLOBAL_OPTION_FILTER,
         DIRECTION,
+        SOURCE_TYPE,
+        ENCODING,
         DISPLAY_LEVEL,
-        DISTRIBUTION_LICENSE,
-        DISTRIBUTION_NOTES,
-        DISTRIBUTION_SOURCE,
-        ENCODING,
-        GLOBAL_OPTION_FILTER,
+        FONT,
+        OSIS_Q_TO_TICK,
+        FEATURE,
         GLOSSARY_FROM,
         GLOSSARY_TO,
+
+        ABBREVIATION,
+        ABOUT,
+        VERSION,
         HISTORY,
+        MINIMUM_VERSION,
+        CATEGORY,
+        LCSH,
+        LANG,
         INSTALL_SIZE,
-        FEATURE,
-        FONT,
-        LANG,
-        LCSH,
-        MOD_DRV,
-        MINIMUM_VERSION,
+        SWORD_VERSION_DATE,
         OBSOLETES,
-        SOURCE_TYPE,
-        SWORD_VERSION_DATE,
+
+        COPYRIGHT,
+        COPYRIGHT_HOLDER,
+        COPYRIGHT_DATE,
+        COPYRIGHT_NOTES,
+        COPYRIGHT_CONTACT_NAME,
+        COPYRIGHT_CONTACT_NOTES,
+        COPYRIGHT_CONTACT_ADDRESS,
+        COPYRIGHT_CONTACT_EMAIL,
+        SHORT_PROMO,
+        SHORT_COPYRIGHT,
+        DISTRIBUTION_LICENSE,
+        DISTRIBUTION_NOTES,
         TEXT_SOURCE,
-        VERSION,
-        OSIS_Q_TO_TICK,
+
+        DISTRIBUTION_SOURCE,
         OSIS_VERSION,
-        INITIALS,
-        SHORT_PROMO,
-        SHORT_COPYRIGHT,
+
+        LIBRARY_URL,
         LOCATION_URL,
-        KEY_TYPE,
     };
 }




More information about the jsword-svn mailing list