Coverage Report - org.crosswire.jsword.book.sword.ConfigEntryType
 
Classes in this File Line Coverage Branch Coverage Complexity
ConfigEntryType
0%
0/113
0%
0/38
1.762
ConfigEntryType$1
0%
0/2
N/A
1.762
ConfigEntryType$10
0%
0/3
N/A
1.762
ConfigEntryType$11
0%
0/9
N/A
1.762
ConfigEntryType$12
0%
0/2
N/A
1.762
ConfigEntryType$13
0%
0/2
N/A
1.762
ConfigEntryType$14
0%
0/6
0%
0/2
1.762
ConfigEntryType$15
0%
0/9
N/A
1.762
ConfigEntryType$16
0%
0/3
N/A
1.762
ConfigEntryType$17
0%
0/2
N/A
1.762
ConfigEntryType$18
0%
0/2
N/A
1.762
ConfigEntryType$19
0%
0/3
N/A
1.762
ConfigEntryType$2
0%
0/9
N/A
1.762
ConfigEntryType$20
0%
0/3
N/A
1.762
ConfigEntryType$21
0%
0/3
N/A
1.762
ConfigEntryType$22
0%
0/3
N/A
1.762
ConfigEntryType$23
0%
0/3
N/A
1.762
ConfigEntryType$24
0%
0/2
N/A
1.762
ConfigEntryType$25
0%
0/2
N/A
1.762
ConfigEntryType$26
0%
0/2
N/A
1.762
ConfigEntryType$27
0%
0/2
N/A
1.762
ConfigEntryType$3
0%
0/3
N/A
1.762
ConfigEntryType$4
0%
0/2
N/A
1.762
ConfigEntryType$5
0%
0/9
N/A
1.762
ConfigEntryType$6
0%
0/3
N/A
1.762
ConfigEntryType$7
0%
0/2
N/A
1.762
ConfigEntryType$8
0%
0/6
0%
0/2
1.762
ConfigEntryType$9
0%
0/6
0%
0/2
1.762
 
 1  
 /**
 2  
  * Distribution License:
 3  
  * JSword is free software; you can redistribute it and/or modify it under
 4  
  * the terms of the GNU Lesser General Public License, version 2.1 or later
 5  
  * as published by the Free Software Foundation. This program is distributed
 6  
  * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 7  
  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 8  
  * See the GNU Lesser General Public License for more details.
 9  
  *
 10  
  * The License is available on the internet at:
 11  
  *      http://www.gnu.org/copyleft/lgpl.html
 12  
  * or by writing to:
 13  
  *      Free Software Foundation, Inc.
 14  
  *      59 Temple Place - Suite 330
 15  
  *      Boston, MA 02111-1307, USA
 16  
  *
 17  
  * © CrossWire Bible Society, 2005 - 2016
 18  
  *
 19  
  */
 20  
 package org.crosswire.jsword.book.sword;
 21  
 
 22  
 import java.util.regex.Pattern;
 23  
 
 24  
 import org.crosswire.common.util.Language;
 25  
 import org.crosswire.common.util.Version;
 26  
 import org.crosswire.jsword.book.BookCategory;
 27  
 import org.crosswire.jsword.book.BookMetaData;
 28  
 
 29  
 /**
 30  
  * Enumeration of SWORD config file keys and their characteristics.
 31  
  * The purpose of this enumeration is to allow validation of a SWORD config file.
 32  
  * <pre>
 33  
  * Originally from:
 34  
  *     http://sword.sourceforge.net/cgi-bin/twiki/view/Swordapi/ConfFileLayout
 35  
  * Then located at:
 36  
  *     http://www.crosswire.org/ucgi-bin/twiki/view/Swordapi/ConfFileLayout
 37  
  * Then located at:
 38  
  *     http://www.crosswire.org/wiki/index.php/DevTools:Modules
 39  
  * Now located at:
 40  
  *     http://www.crosswire.org/wiki/DevTools:confFiles
 41  
  * </pre>
 42  
  * <p>
 43  
  * Note: This file is organized the same as the latest wiki documentation.
 44  
  * </p>
 45  
  * Key characteristics:
 46  
  * <ul>
 47  
  * <li><b>Data Type</b> -- Most values are text, but some are integer, date, boolean.</li>
 48  
  * <li><b>Data Format</b> -- Some text is constrained to patterns.</li>
 49  
  * <li><b>Multiple Values</b> -- Some keys allow more than one value. Others only allow only one</li>
 50  
  * <li><b>RTF</b> -- Some keys allow RTF formatting of values.</li>
 51  
  * <li><b>HTML</b> -- Some keys allow HTML.</li>
 52  
  * <li><b>Pick list</b> -- Some keys allow a value from a pick list</li>
 53  
  * <li><b>Default values</b> -- Some keys have default values.</li>
 54  
  * <li><b>Localization</b> -- Some keys can be internationalized and localized.</li>
 55  
  * </ul>
 56  
  * 
 57  
  * @see gnu.lgpl.License The GNU Lesser General Public License for details.
 58  
  * @author Joe Walker
 59  
  * @author DM Smith
 60  
  */
 61  0
 /* protected */ enum ConfigEntryType {
 62  
     /**
 63  
      * Relative path to the data files, some issues with this
 64  
      */
 65  0
     DATA_PATH(SwordBookMetaData.KEY_DATA_PATH) {
 66  
         @Override
 67  
         public boolean isAllowed(String value) {
 68  0
             return true;
 69  
         }
 70  
     },
 71  
 
 72  
     /**
 73  
      * The full name of this book
 74  
      */
 75  0
     DESCRIPTION(SwordBookMetaData.KEY_DESCRIPTION),
 76  
 
 77  
     /**
 78  
      * This indicates how the book was stored.
 79  
      */
 80  0
     MOD_DRV(SwordBookMetaData.KEY_MOD_DRV,
 81  
         "RawText",
 82  
         "zText",
 83  
         "RawCom",
 84  
         "RawCom4",
 85  
         "zCom",
 86  
         "HREFCom",
 87  
         "RawFiles",
 88  
         "RawLD",
 89  
         "RawLD4",
 90  
         "zLD",
 91  
         "RawGenBook"
 92  
     ),
 93  
 
 94  
     /**
 95  
      * The type of compression in use. While LZSS is the default, it is not used.
 96  
      * At least so far. GZIP, BZIP2 and XZ were just added by SWORD.
 97  
      */
 98  0
     COMPRESS_TYPE(SwordBookMetaData.KEY_COMPRESS_TYPE,
 99  
         "LZSS",
 100  
         "ZIP",
 101  
         "GZIP",
 102  
         "BZIP2",
 103  
         "XZ"
 104  
     ),
 105  
 
 106  
     /**
 107  
      * The level at which compression is applied, BOOK, CHAPTER, or VERSE
 108  
      */
 109  0
     BLOCK_TYPE(SwordBookMetaData.KEY_BLOCK_TYPE,
 110  
         "BOOK",
 111  
         "CHAPTER",
 112  
         "VERSE"
 113  
     ),
 114  
 
 115  
     /**
 116  
      * single value integer, unknown use, some indications that we ought to be
 117  
      * using it
 118  
      */
 119  0
     BLOCK_COUNT(SwordBookMetaData.KEY_BLOCK_COUNT) {
 120  
         @Override
 121  
         public boolean isText() {
 122  0
             return false;
 123  
         }
 124  
 
 125  
         @Override
 126  
         public boolean isAllowed(String aValue) {
 127  
             try {
 128  0
                 Integer.parseInt(aValue);
 129  0
                 return true;
 130  0
             } catch (NumberFormatException e) {
 131  0
                 return false;
 132  
             }
 133  
         }
 134  
 
 135  
         @Override
 136  
         public Object convert(String input) {
 137  
             try {
 138  0
                 return Integer.valueOf(input);
 139  0
             } catch (NumberFormatException e) {
 140  0
                 return getDefault();
 141  
             }
 142  
         }
 143  
     },
 144  
 
 145  
     /**
 146  
      * The kind of key that a Generic Book uses.
 147  
      */
 148  0
     KEY_TYPE(SwordBookMetaData.KEY_KEY_TYPE,
 149  
         "TreeKey",
 150  
         "VerseKey"
 151  
     ),
 152  
 
 153  
     /**
 154  
      * The kind of key that a Generic Book uses.
 155  
      */
 156  0
     CASE_SENSITIVE_KEYS(SwordBookMetaData.KEY_CASE_SENSITIVE_KEYS,
 157  
         "true",
 158  
         "false"
 159  
     )
 160  
     {
 161  
         @Override
 162  
         public boolean isText() {
 163  0
             return false;
 164  
         }
 165  
 
 166  
         @Override
 167  
         public Object convert(String input) {
 168  0
             return Boolean.valueOf(input);
 169  
         }
 170  
     },
 171  
 
 172  
     /**
 173  
      * If this exists in the conf, then the book is encrypted. The value is used
 174  
      * to unlock the book. The encryption algorithm is Sapphire.
 175  
      */
 176  0
     CIPHER_KEY(SwordBookMetaData.KEY_CIPHER_KEY),
 177  
 
 178  
     /**
 179  
      * This indicates the versification of the book, with KJV being the default.
 180  
      */
 181  0
     VERSIFICATION(BookMetaData.KEY_VERSIFICATION,
 182  
         "Catholic",
 183  
         "Catholic2",
 184  
         "German",
 185  
         "KJV",
 186  
         "KJVA",
 187  
         "LXX",
 188  
         "Leningrad",
 189  
         "Luther",
 190  
         "MT",
 191  
         "NRSV",
 192  
         "NRSVA",
 193  
         "Orthodox",
 194  
         "Synodal",
 195  
         "SynodalProt",
 196  
         "Vulg"
 197  
     ),
 198  
 
 199  
     /**
 200  
      * Global Option Filters are the names of routines in SWORD that can be used
 201  
      * to display the data. These are not used by JSword.
 202  
      */
 203  0
     GLOBAL_OPTION_FILTER(SwordBookMetaData.KEY_GLOBAL_OPTION_FILTER,
 204  
         "GBFStrongs",
 205  
         "GBFFootnotes",
 206  
         "GBFMorph",
 207  
         "GBFHeadings",
 208  
         "GBFRedLetterWords",
 209  
         "GBFScripref", // no longer in wiki
 210  
         "ThMLStrongs",
 211  
         "ThMLFootnotes",
 212  
         "ThMLScripref",
 213  
         "ThMLMorph",
 214  
         "ThMLHeadings",
 215  
         "ThMLVariants",
 216  
         "ThMLLemma",
 217  
         "UTF8Cantillation",
 218  
         "UTF8GreekAccents",
 219  
         "UTF8HebrewPoints",
 220  
         "UTF8ArabicPoints",
 221  
         "OSISLemma",
 222  
         "OSISMorphSegmentation",
 223  
         "OSISStrongs",
 224  
         "OSISFootnotes",
 225  
         "OSISScripref",
 226  
         "OSISMorph",
 227  
         "OSISHeadings",
 228  
         "OSISVariants",
 229  
         "OSISRedLetterWords",
 230  
         "OSISGlosses",
 231  
         "OSISRuby", // Deprecated, replaced by OSISGlosses
 232  
         "OSISXlit",
 233  
         "OSISEnum",
 234  
         "OSISReferenceLinks|*",
 235  
         "OSISDictionary" // Deprecated, no replacement
 236  
     )
 237  
     {
 238  
         @Override
 239  
         public boolean mayRepeat() {
 240  0
             return true;
 241  
         }
 242  
     },
 243  
 
 244  
     /**
 245  
      * SiglumN defines the n-th label for an OSISGlosses. Used for variant readings
 246  
      */
 247  0
     SIGLUM1(SwordBookMetaData.KEY_SIGLUM1),
 248  0
     SIGLUM2(SwordBookMetaData.KEY_SIGLUM2),
 249  0
     SIGLUM3(SwordBookMetaData.KEY_SIGLUM3),
 250  0
     SIGLUM4(SwordBookMetaData.KEY_SIGLUM4),
 251  0
     SIGLUM5(SwordBookMetaData.KEY_SIGLUM5),
 252  
     /**
 253  
      * The layout direction of the text in the book. Hebrew, Arabic and Farsi
 254  
      * RtoL. Most are 'LtoR'. Some are 'bidi', bidirectional. E.g.
 255  
      * Hebrew-English glossary.
 256  
      */
 257  0
     DIRECTION(SwordBookMetaData.KEY_DIRECTION,
 258  
         "LtoR",
 259  
         "RtoL",
 260  
         "bidi"
 261  
     ),
 262  
 
 263  
     /**
 264  
      * This indicates the kind of markup used for the book.
 265  
      * In SWORD, Plaintext uses the GBF filter.
 266  
      */
 267  0
     SOURCE_TYPE(SwordBookMetaData.KEY_SOURCE_TYPE,
 268  
         "Plaintext",
 269  
         "GBF",
 270  
         "ThML",
 271  
         "OSIS",
 272  
         "TEI"
 273  
     ),
 274  
 
 275  
     /**
 276  
      * The character encoding. Only Latin-1 and UTF-8 are supported.
 277  
      * Internally, SWORD supports SCSU and UTF-16.
 278  
      * Currently, there is no way to build these modules.
 279  
      * JSword does not support SCSU.
 280  
      */
 281  0
     ENCODING(SwordBookMetaData.KEY_ENCODING,
 282  
         "Latin-1",
 283  
         "UTF-8",
 284  
         "UTF-16",
 285  
         "SCSU"
 286  
     ),
 287  
 
 288  
     /**
 289  
      * Display level is used by GenBooks to do auto expansion in the tree. A
 290  
      * level of 2 indicates that the first two levels should be shown.
 291  
      */
 292  0
     DISPLAY_LEVEL(SwordBookMetaData.KEY_DISPLAY_LEVEL) {
 293  
         @Override
 294  
         public boolean isText() {
 295  0
             return false;
 296  
         }
 297  
 
 298  
         @Override
 299  
         public boolean isAllowed(String value) {
 300  
             try {
 301  0
                 Integer.parseInt(value);
 302  0
                 return true;
 303  0
             } catch (NumberFormatException e) {
 304  0
                 return false;
 305  
             }
 306  
         }
 307  
 
 308  
         @Override
 309  
         public Object convert(String input) {
 310  
             try {
 311  0
                 return Integer.valueOf(input);
 312  0
             } catch (NumberFormatException e) {
 313  0
                 return null;
 314  
             }
 315  
         }
 316  
     },
 317  
 
 318  
     /**
 319  
      * A recommended font to use for the book.
 320  
      */
 321  0
     FONT(BookMetaData.KEY_FONT),
 322  
 
 323  
     /**
 324  
      * When false do not show quotation marks for OSIS text that has &lt;q&gt;
 325  
      * elements.
 326  
      */
 327  0
     OSIS_Q_TO_TICK(SwordBookMetaData.KEY_OSIS_Q_TO_TICK,
 328  
         "true",
 329  
         "false"
 330  
     )
 331  
     {
 332  
         @Override
 333  
         public boolean isText() {
 334  0
             return false;
 335  
         }
 336  
 
 337  
         @Override
 338  
         public Object convert(String input) {
 339  0
             return Boolean.valueOf(input);
 340  
         }
 341  
     },
 342  
 
 343  
     /**
 344  
      * A Feature describes a characteristic of the Book.
 345  
      */
 346  0
     FEATURE(SwordBookMetaData.KEY_FEATURE,
 347  
         "StrongsNumbers",
 348  
         "GreekDef",
 349  
         "HebrewDef",
 350  
         "GreekParse",
 351  
         "HebrewParse",
 352  
         "DailyDevotion",
 353  
         "Glossary",
 354  
         "Images",
 355  
         "NoParagraphs"
 356  
     )
 357  
     {
 358  
         @Override
 359  
         public boolean mayRepeat() {
 360  0
             return true;
 361  
         }
 362  
     },
 363  
 
 364  
     /**
 365  
      * Books with a Feature of Glossary are used to map words FROM one language
 366  
      * TO another.
 367  
      */
 368  0
     GLOSSARY_FROM(SwordBookMetaData.KEY_GLOSSARY_FROM) {
 369  
         @Override
 370  
         public boolean isText() {
 371  0
             return false;
 372  
         }
 373  
 
 374  
         @Override
 375  
         public Object convert(String input) {
 376  0
             return new Language(input);
 377  
         }
 378  
 
 379  
         @Override
 380  
         public String unconvert(Object internal) {
 381  0
             if (internal instanceof Language) {
 382  0
                 return ((Language) internal).getGivenSpecification();
 383  
             }
 384  0
             return super.unconvert(internal);
 385  
         }
 386  
     },
 387  
 
 388  
     /**
 389  
      * Books with a Feature of Glossary are used to map words FROM one language
 390  
      * TO another.
 391  
      */
 392  0
     GLOSSARY_TO(SwordBookMetaData.KEY_GLOSSARY_TO) {
 393  
         @Override
 394  
         public boolean isText() {
 395  0
             return false;
 396  
         }
 397  
 
 398  
         @Override
 399  
         public Object convert(String input) {
 400  0
             return new Language(input);
 401  
         }
 402  
 
 403  
         @Override
 404  
         public String unconvert(Object internal) {
 405  0
             if (internal instanceof Language) {
 406  0
                 return ((Language) internal).getGivenSpecification();
 407  
             }
 408  0
             return super.unconvert(internal);
 409  
         }
 410  
     },
 411  
 
 412  
     /**
 413  
      * Names a file in the module's DataPath that should be referenced for the renderer as CSS display controls.
 414  
      * Generality is advised: Use controls that are not specific to any particular rendering engine, e.g. WebKit.
 415  
      */
 416  0
     PREFERRED_CSS_XHTML(SwordBookMetaData.KEY_PREFERRED_CSS_XHTML),
 417  
 
 418  
     /**
 419  
      * Names a file in the module's DataPath that should be referenced for the renderer as CSS display controls.
 420  
      * Generality is advised: Use controls that are not specific to any particular rendering engine, e.g. WebKit.
 421  
      */
 422  0
     STRONGS_PADDING(SwordBookMetaData.KEY_STRONGS_PADDING),
 423  
 
 424  
     /**
 425  
      * The short name of this book.
 426  
      */
 427  0
     ABBREVIATION(SwordBookMetaData.KEY_ABBREVIATION),
 428  
 
 429  
     /**
 430  
      * Contains RTF that describes the book.
 431  
      */
 432  0
     ABOUT(SwordBookMetaData.KEY_ABOUT) {
 433  
         @Override
 434  
         public boolean allowsContinuation() {
 435  0
             return true;
 436  
         }
 437  
 
 438  
         @Override
 439  
         public boolean allowsRTF() {
 440  0
             return true;
 441  
         }
 442  
     },
 443  
 
 444  
     /**
 445  
      * An informational string indicating the current version of the book.
 446  
      */
 447  0
     VERSION(SwordBookMetaData.KEY_VERSION) {
 448  
         @Override
 449  
         public boolean isText() {
 450  0
             return false;
 451  
         }
 452  
 
 453  
         @Override
 454  
         public boolean isAllowed(String aValue) {
 455  
             try {
 456  0
                 new Version(aValue);
 457  0
                 return true;
 458  0
             } catch (IllegalArgumentException e) {
 459  0
                 return false;
 460  
             }
 461  
         }
 462  
 
 463  
         @Override
 464  
         public Object convert(String input) {
 465  
             try {
 466  0
                 return new Version(input);
 467  0
             } catch (IllegalArgumentException e) {
 468  0
                 return null;
 469  
             }
 470  
         }
 471  
     },
 472  
 
 473  
     /**
 474  
      * multiple values starting with History, some sort of change-log. In the
 475  
      * conf these are of the form History_x.y. We strip off the x.y and prefix
 476  
      * the value with it. The x.y corresponds to a current or prior Version
 477  
      * value.
 478  
      */
 479  0
     HISTORY(SwordBookMetaData.KEY_HISTORY) {
 480  
         @Override
 481  
         public boolean mayRepeat() {
 482  0
             return true;
 483  
         }
 484  
     },
 485  
 
 486  
     /**
 487  
      * single value version number, lowest sword c++ version that can read this
 488  
      * book JSword does not use this value.
 489  
      */
 490  0
     MINIMUM_VERSION(SwordBookMetaData.KEY_MINIMUM_VERSION),
 491  
 
 492  
     /**
 493  
      * The Category of the book. Used on the web to classify books into a tree.
 494  
      */
 495  0
     CATEGORY(BookMetaData.KEY_CATEGORY,
 496  
         "Other",
 497  
         "Daily Devotional",
 498  
         "Glossaries",
 499  
         "Cults / Unorthodox / Questionable Material",
 500  
         "Essays",
 501  
         "Maps",
 502  
         "Images",
 503  
         "Biblical Texts",
 504  
         "Commentaries",
 505  
         "Lexicons / Dictionaries",
 506  
         "Generic Books"
 507  
     )
 508  
     {
 509  
         @Override
 510  
         public Object convert(String input) {
 511  0
             return BookCategory.fromString(input);
 512  
         }
 513  
     },
 514  
 
 515  
     /**
 516  
      * Library of Congress Subject Heading. Typically this is of the form
 517  
      * BookCategory Scope Language, where scope is typically O.T., N.T.
 518  
      */
 519  0
     LCSH(SwordBookMetaData.KEY_LCSH),
 520  
 
 521  
     /**
 522  
      * single value string, defaults to en, the language of the book
 523  
      */
 524  0
     LANG(BookMetaData.KEY_LANG) {
 525  
         @Override
 526  
         public boolean isText() {
 527  0
             return false;
 528  
         }
 529  
 
 530  
         @Override
 531  
         public Object convert(String input) {
 532  0
             return new Language(input);
 533  
         }
 534  
 
 535  
         @Override
 536  
         public String unconvert(Object internal) {
 537  0
             if (internal instanceof Language) {
 538  0
                 return ((Language) internal).getGivenSpecification();
 539  
             }
 540  0
             return super.unconvert(internal);
 541  
         }
 542  
     },
 543  
 
 544  
     /**
 545  
      * The installed size of the book in bytes. This is not the size of the zip
 546  
      * that is downloaded.
 547  
      */
 548  0
     INSTALL_SIZE(SwordBookMetaData.KEY_INSTALL_SIZE) {
 549  
         @Override
 550  
         public boolean isText() {
 551  0
             return false;
 552  
         }
 553  
 
 554  
         @Override
 555  
         public boolean isAllowed(String value) {
 556  
             try {
 557  0
                 Integer.parseInt(value);
 558  0
                 return true;
 559  0
             } catch (NumberFormatException e) {
 560  0
                 return false;
 561  
             }
 562  
         }
 563  
 
 564  
         @Override
 565  
         public Object convert(String input) {
 566  
             try {
 567  0
                 return Integer.valueOf(input);
 568  0
             } catch (NumberFormatException e) {
 569  0
                 return null;
 570  
             }
 571  
         }
 572  
     },
 573  
 
 574  
     /**
 575  
      * The date that this version of the book was last updated. Informational
 576  
      * only.
 577  
      */
 578  0
     SWORD_VERSION_DATE(SwordBookMetaData.KEY_SWORD_VERSION_DATE) {
 579  
         @Override
 580  
         public boolean isAllowed(String value) {
 581  0
             return validDatePattern.matcher(value).matches();
 582  
         }
 583  
 
 584  0
         private Pattern validDatePattern = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
 585  
     },
 586  
 
 587  
     /**
 588  
      * A list of prior "initials" for the current book.
 589  
      * TODO(dms): when a user installs a book with an obsoletes that matches
 590  
      * an installed book, offer the user the opportunity to delete the old book.
 591  
      */
 592  0
     OBSOLETES(SwordBookMetaData.KEY_OBSOLETES) {
 593  
         @Override
 594  
         public boolean mayRepeat() {
 595  0
             return true;
 596  
         }
 597  
     },
 598  
 
 599  
     /**
 600  
      * Single value version number, lowest sword c++ version that can read this
 601  
      * book JSword does not use this value.
 602  
      */
 603  0
     OSIS_VERSION(SwordBookMetaData.KEY_OSIS_VERSION),
 604  
 
 605  
     /**
 606  
      * Informational copyright notice.
 607  
      */
 608  0
     COPYRIGHT(SwordBookMetaData.KEY_COPYRIGHT) {
 609  
         @Override
 610  
         public boolean allowsContinuation() {
 611  0
             return true;
 612  
         }
 613  
     },
 614  
 
 615  
     /**
 616  
      * single value string, unknown use
 617  
      */
 618  0
     COPYRIGHT_HOLDER(SwordBookMetaData.KEY_COPYRIGHT_HOLDER),
 619  
 
 620  
     /**
 621  
      * Copyright info. Informational only.
 622  
      * This is a year, a year range or a comma separated list of these.
 623  
      */
 624  0
     COPYRIGHT_DATE(SwordBookMetaData.KEY_COPYRIGHT_DATE) {
 625  
         @Override
 626  
         public boolean isAllowed(String value) {
 627  0
             return validDatePattern.matcher(value).matches();
 628  
         }
 629  
 
 630  0
         private Pattern validDatePattern = Pattern.compile("\\d{4}(\\s*-\\s*\\d{4})?(\\s*,\\s*\\d{4}(\\s*-\\s*\\d{4})?)*");
 631  
     },
 632  
 
 633  
     /**
 634  
      * Copyright info. Informational only.
 635  
      */
 636  0
     COPYRIGHT_NOTES(SwordBookMetaData.KEY_COPYRIGHT_NOTES) {
 637  
         @Override
 638  
         public boolean allowsContinuation() {
 639  0
             return true;
 640  
         }
 641  
 
 642  
         @Override
 643  
         public boolean allowsRTF() {
 644  0
             return true;
 645  
         }
 646  
     },
 647  
 
 648  
     /**
 649  
      * Copyright info. Informational only.
 650  
      */
 651  0
     COPYRIGHT_CONTACT_NAME(SwordBookMetaData.KEY_COPYRIGHT_CONTACT_NAME) {
 652  
         @Override
 653  
         public boolean allowsContinuation() {
 654  0
             return true;
 655  
         }
 656  
 
 657  
         @Override
 658  
         public boolean allowsRTF() {
 659  0
             return true;
 660  
         }
 661  
     },
 662  
 
 663  
     /**
 664  
      * Copyright info. Informational only.
 665  
      */
 666  0
     COPYRIGHT_CONTACT_NOTES(SwordBookMetaData.KEY_COPYRIGHT_CONTACT_NOTES) {
 667  
         @Override
 668  
         public boolean allowsContinuation() {
 669  0
             return true;
 670  
         }
 671  
 
 672  
         @Override
 673  
         public boolean allowsRTF() {
 674  0
             return true;
 675  
         }
 676  
     },
 677  
 
 678  
     /**
 679  
      * Copyright info. Informational only.
 680  
      */
 681  0
     COPYRIGHT_CONTACT_ADDRESS(SwordBookMetaData.KEY_COPYRIGHT_CONTACT_ADDRESS) {
 682  
         @Override
 683  
         public boolean allowsContinuation() {
 684  0
             return true;
 685  
         }
 686  
 
 687  
         @Override
 688  
         public boolean allowsRTF() {
 689  0
             return true;
 690  
         }
 691  
     },
 692  
 
 693  
     /**
 694  
      * Copyright info. Informational only.
 695  
      */
 696  0
     COPYRIGHT_CONTACT_EMAIL(SwordBookMetaData.KEY_COPYRIGHT_CONTACT_EMAIL),
 697  
 
 698  
     /**
 699  
      * A one line promo statement, required by Lockman for NASB
 700  
      */
 701  0
     SHORT_PROMO(SwordBookMetaData.KEY_SHORT_PROMO) {
 702  
         @Override
 703  
         public boolean allowsHTML() {
 704  0
             return true;
 705  
         }
 706  
     },
 707  
 
 708  
     /**
 709  
      * A one line copyright statement, required by Lockman for NASB
 710  
      */
 711  0
     SHORT_COPYRIGHT(SwordBookMetaData.KEY_SHORT_COPYRIGHT),
 712  
 
 713  
     /**
 714  
      * Copyright info. Informational only.
 715  
      */
 716  0
     DISTRIBUTION_LICENSE(SwordBookMetaData.KEY_DISTRIBUTION_LICENSE,
 717  
         "Public Domain",
 718  
         "Copyrighted",
 719  
         "Copyrighted; Free non-commercial distribution",
 720  
         "Copyrighted; Permission to distribute granted to *",
 721  
         "Copyrighted; Freely distributable",
 722  
         "Copyrighted; Permission granted to distribute non-commercially in SWORD format",
 723  
         "GFDL",
 724  
         "GPL",
 725  
         "Creative Commons: by-nc-nd*",
 726  
         "Creative Commons: by-nc-sa*",
 727  
         "Creative Commons: by-nc*",
 728  
         "Creative Commons: by-nd*",
 729  
         "Creative Commons: by-sa*",
 730  
         "Creative Commons: by*",
 731  
         "Creative Commons: CC0*",
 732  
         "General public license for distribution for any purpose" // In kjv.conf
 733  
     ),
 734  
 
 735  
     /**
 736  
      * Copyright info. Informational only.
 737  
      */
 738  0
     DISTRIBUTION_NOTES(SwordBookMetaData.KEY_DISTRIBUTION_NOTES) {
 739  
         @Override
 740  
         public boolean allowsContinuation() {
 741  0
             return true;
 742  
         }
 743  
     },
 744  
 
 745  
     /**
 746  
      * Information on where the book's text was obtained.
 747  
      */
 748  0
     TEXT_SOURCE(SwordBookMetaData.KEY_TEXT_SOURCE) {
 749  
         @Override
 750  
         public boolean allowsContinuation() {
 751  0
             return true;
 752  
         }
 753  
     },
 754  
 
 755  
     /**
 756  
      * Contains the URL (a bare URL, not an HTML &lt;a&gt; link) of a web page for unlocking instructions/payment.
 757  
      */
 758  0
     UNLOCK_URL(SwordBookMetaData.KEY_UNLOCK_URL),
 759  
 
 760  
     /**
 761  
      * Deliberately not in wiki. Similar to DataPath. It gives where on the CrossWire server the book can
 762  
      * be found. Informational only.
 763  
      */
 764  0
     DISTRIBUTION_SOURCE(SwordBookMetaData.KEY_DISTRIBUTION_SOURCE) {
 765  
         @Override
 766  
         public boolean allowsContinuation() {
 767  0
             return true;
 768  
         }
 769  
     },
 770  
 
 771  
     /**
 772  
      * New. Not in wiki. Present in SWORD engine. Present in hesychius.conf w/ PapyriPlain
 773  
      */
 774  0
     LOCAL_STRIP_FILTER(SwordBookMetaData.KEY_LOCAL_STRIP_FILTER),
 775  
 
 776  
     /**
 777  
      * New. Not in wiki. Present in SWORD engine. Present in hesychius.conf w/ IncludeKeyInSearch
 778  
      */
 779  0
     SEARCH_OPTION(SwordBookMetaData.KEY_SEARCH_OPTION),
 780  
 
 781  
     /**
 782  
      * New. Not supported by Sword but supported by IBT. Scope is an OSIS Reference of all keys
 783  
      * contained in the book
 784  
      */
 785  0
     SCOPE(BookMetaData.KEY_SCOPE),
 786  
 
 787  
     /**
 788  
      * New. Not supported by Sword. Lists of books contained in the module. Usually derived and cached in the JSword
 789  
      * configuration files.
 790  
      */
 791  0
     BOOK_LIST(BookMetaData.KEY_BOOKLIST);
 792  
 
 793  
     /**
 794  
      * Simple ctor
 795  
      */
 796  0
     ConfigEntryType(String name) {
 797  0
         this.name = name;
 798  0
         this.picks = null;
 799  0
         String defValue = SwordBookMetaData.DEFAULTS.get(name);
 800  0
         this.defaultValue = defValue == null ? null : convert(defValue);
 801  0
     }
 802  
 
 803  
     /**
 804  
      * Simple ctor
 805  
      */
 806  0
     ConfigEntryType(String name, String... picks) {
 807  0
         this.name = name;
 808  0
         this.picks = picks;
 809  0
         String defValue = SwordBookMetaData.DEFAULTS.get(name);
 810  0
         this.defaultValue = defValue == null ? null : convert(defValue);
 811  0
     }
 812  
 
 813  
     /**
 814  
      * Some keys can be converted to something other than a string.
 815  
      * 
 816  
      * @return true if this ConfigEntryType is a string
 817  
      */
 818  
     public boolean isText() {
 819  0
         return true;
 820  
     }
 821  
 
 822  
     /**
 823  
      * Determines whether the string is allowed. For some config entries, the
 824  
      * value is expected to be one of a group, for others the format is defined.
 825  
      * 
 826  
      * @param value
 827  
      *            the string to be checked
 828  
      * @return true if the string is allowed
 829  
      */
 830  
     public boolean isAllowed(String value) {
 831  0
         if (value == null) {
 832  0
             return false;
 833  
         }
 834  0
         if (hasChoices()) {
 835  0
             for (String item : picks) {
 836  0
                 String val = value;
 837  0
                 String pick = item;
 838  
                 // If the pick ends with *
 839  
                 // then we want to do a "startsWithCaseInsensitive"
 840  
                 // with what is before the *
 841  0
                 if (pick.endsWith("*")) {
 842  0
                     int len = pick.length() - 1;
 843  0
                     pick = pick.substring(0, len);
 844  0
                     if (val.length() > len) {
 845  0
                         val = val.substring(0, len);
 846  
                     }
 847  
                 }
 848  0
                 if (pick.equalsIgnoreCase(val)) {
 849  0
                     return true;
 850  
                 }
 851  
             }
 852  
 
 853  0
             return false;
 854  
         }
 855  0
         return true;
 856  
     }
 857  
 
 858  
     /**
 859  
      * Modify the value if necessary.
 860  
      * 
 861  
      * @param value
 862  
      *            the input
 863  
      * @return either value or a modified version of it.
 864  
      */
 865  
     public String filter(String value) {
 866  
         // Look through the choice array, if present, for matches.
 867  0
         if (hasChoices()) {
 868  
             // Do we have an exact match?
 869  0
             for (String pick : picks) {
 870  0
                 if (pick.equals(value)) {
 871  0
                     return value;
 872  
                 }
 873  
             }
 874  
 
 875  
             // Do we have a case insensitive match?
 876  0
             for (String pick : picks) {
 877  0
                 if (pick.equalsIgnoreCase(value)) {
 878  0
                     return pick;
 879  
                 }
 880  
             }
 881  
         }
 882  
 
 883  0
         return value;
 884  
     }
 885  
 
 886  
     /**
 887  
      * RTF is allowed in a few config entries.
 888  
      * 
 889  
      * @return true if RTF is allowed
 890  
      */
 891  
     public boolean allowsRTF() {
 892  0
         return false;
 893  
     }
 894  
 
 895  
     /**
 896  
      * HTML is allowed in a few config entries.
 897  
      * 
 898  
      * @return true if HTML is allowed
 899  
      */
 900  
     public boolean allowsHTML() {
 901  0
         return false;
 902  
     }
 903  
 
 904  
     /**
 905  
      * While most fields are single line or single value, some allow
 906  
      * continuation. A continuation mark is a backslash at the end of a line. It
 907  
      * is not to be followed by whitespace.
 908  
      * 
 909  
      * @return true if continuation is allowed
 910  
      */
 911  
     public boolean allowsContinuation() {
 912  0
         return false;
 913  
     }
 914  
 
 915  
     /**
 916  
      * Some keys can repeat. When this happens each is a single value pick from
 917  
      * a list of choices.
 918  
      * 
 919  
      * @return true if this ConfigEntryType can occur more than once
 920  
      */
 921  
     public boolean mayRepeat() {
 922  0
         return false;
 923  
     }
 924  
 
 925  
     /**
 926  
      * Some keys can repeat. When this happens each is a single value pick from
 927  
      * a list of choices.
 928  
      * 
 929  
      * @return true if this ConfigEntryType can occur more than once
 930  
      */
 931  
     protected boolean hasChoices() {
 932  0
         return picks != null;
 933  
     }
 934  
 
 935  
     /**
 936  
      * Some ConfigEntryTypes have defaults.
 937  
      * 
 938  
      * @return the default, if there is one, null otherwise
 939  
      */
 940  
     public Object getDefault() {
 941  0
         return defaultValue;
 942  
     }
 943  
 
 944  
     /**
 945  
      * Convert the string value from the conf into the representation of this
 946  
      * ConfigEntryType.
 947  
      * 
 948  
      * @param input the text to convert
 949  
      * @return the converted object
 950  
      */
 951  
     public Object convert(String input) {
 952  0
         return input;
 953  
     }
 954  
 
 955  
     /**
 956  
      * Return the original representation of the object.
 957  
      * 
 958  
      * @param internal the object to convert
 959  
      * @return the original string
 960  
      */
 961  
     public String unconvert(Object internal) {
 962  0
         if (internal == null) {
 963  0
             return null;
 964  
         }
 965  0
         return internal.toString();
 966  
     }
 967  
 
 968  
     /**
 969  
      * Lookup method to convert from a String
 970  
      * 
 971  
      * @param name the key for the entry
 972  
      * @return the matching type
 973  
      */
 974  
     public static ConfigEntryType fromString(String name) {
 975  0
         if (name != null) {
 976  
             // special case
 977  0
             if (name.startsWith(ConfigEntryType.HISTORY.toString())) {
 978  0
                 return ConfigEntryType.HISTORY;
 979  
             }
 980  
 
 981  0
             for (ConfigEntryType o : ConfigEntryType.values()) {
 982  0
                 if (name.equals(o.name)) {
 983  0
                     return o;
 984  
                 }
 985  
             }
 986  
         }
 987  
 
 988  
         // should not get here.
 989  
         // But there are typos in the keys in the book conf files
 990  
         // And this allows for the addition of new fields in
 991  
         // advance of changing JSword
 992  0
         return null;
 993  
     }
 994  
 
 995  
     @Override
 996  
     public String toString() {
 997  0
         return name;
 998  
     }
 999  
 
 1000  
     /**
 1001  
      * The name of the ConfigEntryType
 1002  
      */
 1003  
     private final String name;
 1004  
 
 1005  
     /**
 1006  
      * The default for the ConfigEntryType
 1007  
      */
 1008  
     private final Object defaultValue;
 1009  
 
 1010  
     /**
 1011  
      * The array of choices.
 1012  
      */
 1013  
     private final String[] picks;
 1014  
 
 1015  
     /**
 1016  
      * Constants for direction
 1017  
      */
 1018  
     public static final String DIRECTION_LTOR = "LtoR";
 1019  
     public static final String DIRECTION_RTOL = "RtoL";
 1020  
     public static final String DIRECTION_BIDI = "bidi";
 1021  
 
 1022  
 }