Coverage Report - org.crosswire.jsword.versification.BookName
 
Classes in this File Line Coverage Branch Coverage Complexity
BookName
0%
0/60
0%
0/34
2.5
 
 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, 2007 - 2016
 18  
  *
 19  
  */
 20  
 package org.crosswire.jsword.versification;
 21  
 
 22  
 import java.util.Locale;
 23  
 import java.util.regex.Pattern;
 24  
 
 25  
 import org.crosswire.common.util.StringUtil;
 26  
 import org.crosswire.jsword.book.CaseType;
 27  
 
 28  
 /**
 29  
  * BookName represents the different ways a book of the bible is named.
 30  
  * 
 31  
  * @see gnu.lgpl.License The GNU Lesser General Public License for details.
 32  
  * @author DM Smith
 33  
  */
 34  
 public final class BookName {
 35  
     /**
 36  
      * Create a BookName for a Book of the Bible in a given language.
 37  
      * 
 38  
      * @param locale
 39  
      *            the language of this BookName
 40  
      * @param book
 41  
      *            the Book's canonical number
 42  
      * @param longName
 43  
      *            the Book's long name
 44  
      * @param shortName
 45  
      *            the Book's short name, if any
 46  
      * @param alternateNames
 47  
      *            optional comma separated list of alternates for the Book
 48  
      */
 49  0
     public BookName(Locale locale, BibleBook book, String longName, String shortName, String alternateNames) {
 50  0
         this.locale = locale;
 51  0
         this.book = book;
 52  0
         this.longName = longName;
 53  0
         this.normalizedLongName = normalize(longName, locale);
 54  0
         this.shortName = shortName;
 55  0
         this.normalizedShortName = normalize(shortName, locale);
 56  
 
 57  0
         if (alternateNames != null) {
 58  0
             this.alternateNames = StringUtil.split(normalize(alternateNames, locale), ',');
 59  
         }
 60  0
     }
 61  
 
 62  
     /**
 63  
      * Get the BibleBook to which this set of names is tied.
 64  
      * 
 65  
      * @return The book
 66  
      */
 67  
     public BibleBook getBook() {
 68  0
         return book;
 69  
     }
 70  
 
 71  
     /**
 72  
      * Get the preferred name of a book. Altered by the case setting (see
 73  
      * setBookCase() and isFullBookName())
 74  
      * 
 75  
      * @return The preferred name of the book
 76  
      */
 77  
     public String getPreferredName() {
 78  0
         if (BookName.isFullBookName()) {
 79  0
             return getLongName();
 80  
         }
 81  0
         return getShortName();
 82  
     }
 83  
 
 84  
     /**
 85  
      * Get the full name of a book (e.g. "Genesis"). Altered by the case setting
 86  
      * (see setBookCase())
 87  
      * 
 88  
      * @return The full name of the book
 89  
      */
 90  
     public String getLongName() {
 91  0
         CaseType caseType = BookName.getDefaultCase();
 92  
 
 93  0
         if (caseType == CaseType.LOWER) {
 94  0
             return longName.toLowerCase(locale);
 95  
         }
 96  
 
 97  0
         if (caseType == CaseType.UPPER) {
 98  0
             return longName.toUpperCase(locale);
 99  
         }
 100  
 
 101  0
         return longName;
 102  
     }
 103  
 
 104  
     /**
 105  
      * Get the short name of a book (e.g. "Gen"). Altered by the case setting
 106  
      * (see setBookCase())
 107  
      * 
 108  
      * @return The short name of the book
 109  
      */
 110  
     public String getShortName() {
 111  0
         CaseType caseType = BookName.getDefaultCase();
 112  
 
 113  0
         if (caseType == CaseType.LOWER) {
 114  0
             return shortName.toLowerCase(locale);
 115  
         }
 116  
 
 117  0
         if (caseType == CaseType.UPPER) {
 118  0
             return shortName.toUpperCase(locale);
 119  
         }
 120  
 
 121  0
         return shortName;
 122  
     }
 123  
 
 124  
     /**
 125  
      * @return the normalizedLongName
 126  
      */
 127  
     public String getNormalizedLongName() {
 128  0
         return normalizedLongName;
 129  
     }
 130  
 
 131  
     /**
 132  
      * @return the normalizedShortName
 133  
      */
 134  
     public String getNormalizedShortName() {
 135  0
         return normalizedShortName;
 136  
     }
 137  
 
 138  
     /**
 139  
      * Match the normalized name as closely as possible. It will match if:
 140  
      * <ol>
 141  
      * <li>it is a prefix of a normalized alternate name</li>
 142  
      * <li>a normalized alternate name is a prefix of it</li>
 143  
      * <li>it is a prefix of a normalized long name</li>
 144  
      * <li>it is a prefix of a normalized short name</li>
 145  
      * <li>a normalized short name is a prefix of it</li>
 146  
      * </ol>
 147  
      * 
 148  
      * @param normalizedName
 149  
      *            the already normalized name to match against.
 150  
      * @return true of false
 151  
      */
 152  
     public boolean match(String normalizedName) {
 153  
         // Does it match one of the alternative versions
 154  0
         for (int j = 0; j < alternateNames.length; j++) {
 155  0
             String targetBookName = alternateNames[j];
 156  0
             if (targetBookName.startsWith(normalizedName) || normalizedName.startsWith(targetBookName)) {
 157  0
                 return true;
 158  
             }
 159  
         }
 160  
 
 161  
         // Does it match a long version of the book
 162  0
         if (normalizedLongName.startsWith(normalizedName)) {
 163  0
             return true;
 164  
         }
 165  
 
 166  
         // or a short version
 167  0
         if (normalizedShortName.startsWith(normalizedName) || (normalizedShortName.length() > 0 && normalizedName.startsWith(normalizedShortName))) {
 168  0
             return true;
 169  
         }
 170  
 
 171  0
         return false;
 172  
     }
 173  
 
 174  
     /*
 175  
      * (non-Javadoc)
 176  
      * 
 177  
      * @see java.lang.Object#hashCode()
 178  
      */
 179  
     @Override
 180  
     public int hashCode() {
 181  0
         return book.hashCode();
 182  
     }
 183  
 
 184  
     /*
 185  
      * (non-Javadoc)
 186  
      * 
 187  
      * @see java.lang.Object#equals(java.lang.Object)
 188  
      */
 189  
     @Override
 190  
     public boolean equals(Object obj) {
 191  0
         if (this == obj) {
 192  0
             return true;
 193  
         }
 194  
 
 195  0
         if (obj == null) {
 196  0
             return false;
 197  
         }
 198  
 
 199  0
         if (getClass() != obj.getClass()) {
 200  0
             return false;
 201  
         }
 202  
 
 203  0
         final BookName other = (BookName) obj;
 204  0
         return book == other.book;
 205  
     }
 206  
 
 207  
     /*
 208  
      * (non-Javadoc)
 209  
      * 
 210  
      * @see java.lang.Object#toString()
 211  
      */
 212  
     @Override
 213  
     public String toString() {
 214  0
         return getPreferredName();
 215  
     }
 216  
 
 217  
     /**
 218  
      * Normalize by stripping punctuation and whitespace and lowercasing.
 219  
      * 
 220  
      * @param str
 221  
      *            the string to normalize
 222  
      * @param locale the locale that should be used for normalization
 223  
      * @return the normalized string
 224  
      */
 225  
     public static String normalize(String str, Locale locale) {
 226  0
         return normPattern.matcher(str).replaceAll("").toLowerCase(locale);
 227  
     }
 228  
 
 229  
     /**
 230  
      * This is only used by config.
 231  
      * 
 232  
      * @param bookCase
 233  
      *            The new case to use for reporting book names
 234  
      * @exception IllegalArgumentException
 235  
      *                If the case is not between 0 and 2
 236  
      * @see #getCase()
 237  
      */
 238  
     public static void setCase(int bookCase) {
 239  0
         BookName.bookCase = CaseType.fromInteger(bookCase);
 240  0
     }
 241  
 
 242  
     /**
 243  
      * How do we report the names of the books?. These are static. This is on
 244  
      * the assumption that we will not want to have different sections of the
 245  
      * app using a different format. I expect this to be a good assumption, and
 246  
      * it saves passing a Book class around everywhere. CaseType.MIXED is not
 247  
      * allowed
 248  
      * 
 249  
      * @param newBookCase
 250  
      *            The new case to use for reporting book names
 251  
      * @exception IllegalArgumentException
 252  
      *                If the case is not between 0 and 2
 253  
      * @see #getCase()
 254  
      */
 255  
     public static void setCase(CaseType newBookCase) {
 256  0
         BookName.bookCase = newBookCase;
 257  0
     }
 258  
 
 259  
     /**
 260  
      * This is only used by config
 261  
      * 
 262  
      * @return The current case setting
 263  
      * @see #setCase(CaseType)
 264  
      */
 265  
     public static int getCase() {
 266  0
         return BookName.bookCase.toInteger();
 267  
     }
 268  
 
 269  
     /**
 270  
      * This is only used by config
 271  
      * 
 272  
      * @return Whether the name is long or short. Default is Full (true).
 273  
      * @see #setFullBookName(boolean)
 274  
      */
 275  
     public static boolean isFullBookName() {
 276  0
         return BookName.fullBookName;
 277  
     }
 278  
 
 279  
     /**
 280  
      * Set whether the name should be full or abbreviated, long or short.
 281  
      * 
 282  
      * @param fullName
 283  
      *            The new case to use for reporting book names
 284  
      * @see #isFullBookName()
 285  
      */
 286  
     public static void setFullBookName(boolean fullName) {
 287  0
         BookName.fullBookName = fullName;
 288  0
     }
 289  
 
 290  
     /**
 291  
      * How do we report the names of the books?.
 292  
      * 
 293  
      * @return The current case setting
 294  
      * @see #setCase(int)
 295  
      */
 296  
     public static CaseType getDefaultCase() {
 297  0
         return BookName.bookCase;
 298  
     }
 299  
 
 300  
     /** remove spaces and some punctuation in Book Name (make sure , is allowed) */
 301  0
     private static Pattern normPattern = Pattern.compile("[. ]");
 302  
 
 303  
     private BibleBook book;
 304  
     private String longName;
 305  
     private String normalizedLongName;
 306  
     private String shortName;
 307  
     private String normalizedShortName;
 308  
     private String[] alternateNames;
 309  
 
 310  
     /** The locale for the Book Name */
 311  
     private Locale locale;
 312  
 
 313  
     /** How the book names are reported. */
 314  0
     private static CaseType bookCase = CaseType.SENTENCE;
 315  
 
 316  
     /** Whether long or short, full or abbreviated names are used. */
 317  0
     private static boolean fullBookName = true;
 318  
 
 319  
 }