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 as published by
5    * the Free Software Foundation. This program is distributed in the hope
6    * that it will be useful, but WITHOUT ANY WARRANTY; without even the
7    * 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   * Copyright: 2005
18   *     The copyright to this program is held by it's authors.
19   *
20   * ID: $Id: CaseType.java 2050 2010-12-09 15:31:45Z dmsmith $
21   */
22  package org.crosswire.jsword.book;
23  
24  import java.util.Locale;
25  
26  /**
27   * Types of Sentence Case.
28   * 
29   * @see gnu.lgpl.License for license details.<br>
30   *      The copyright to this program is held by it's authors.
31   * @author Joe Walker [joe at eireneh dot com]
32   * @author DM Smith [dmsmith555 at yahoo dot com]
33   */
34  public enum CaseType {
35      LOWER  {
36          @Override
37          public String setCase(String word) {
38              return word.toLowerCase(Locale.getDefault());
39          }
40      },
41  
42      SENTENCE {
43          @Override
44          public String setCase(String word) {
45              int index = word.indexOf('-');
46              if (index == -1) {
47                  return toSentenceCase(word);
48              }
49  
50              // So there is a "-", however first some exceptions
51              if ("maher-shalal-hash-baz".equalsIgnoreCase(word)) {
52                  return "Maher-Shalal-Hash-Baz";
53              }
54  
55              if ("no-one".equalsIgnoreCase(word)) {
56                  return "No-one";
57              }
58  
59              if (word.substring(0, 4).equalsIgnoreCase("god-")) {
60                  return toSentenceCase(word);
61              }
62  
63              // So cut by the -
64              return toSentenceCase(word.substring(0, index)) + "-" + toSentenceCase(word.substring(index + 1));
65          }
66      },
67  
68      UPPER {
69          @Override
70          public String setCase(String word) {
71              return word.toUpperCase(Locale.getDefault());
72          }
73      };
74  
75      public abstract String setCase(String word);
76  
77      /**
78       * Change to sentence case - that is first character in caps, the rest in lower.
79       * 
80       * @param word
81       *            The word to be manipulated
82       * @return The altered word
83       */
84      public static String toSentenceCase(String word) {
85          assert word != null;
86  
87          if (word.length() == 0) {
88              return "";
89          }
90  
91          return Character.toUpperCase(word.charAt(0)) + word.substring(1).toLowerCase(Locale.getDefault());
92      }
93  
94      /**
95       * What case is the specified word?. A blank word is LOWER, a word with a
96       * single upper case letter is SENTENCE and not UPPER - Simply because this
97       * is more likely, however TO BE SURE I WOULD NEED TO THE CONTEXT. I could
98       * not tell otherwise.
99       * <p>
100      * The issue here is that getCase("FreD") is undefined. Telling if this is
101      * SENTENCE (Tubal-Cain) or MIXED (really the case) is complex and would
102      * slow things down for a case that I don't believe happens with Bible text.
103      * </p>
104      * 
105      * @param word
106      *            The word to be tested
107      * @return LOWER, SENTENCE, UPPER or MIXED
108      * @exception IllegalArgumentException
109      *                is the word is null
110      */
111     public static CaseType getCase(String word) {
112         assert word != null;
113 
114         // Blank word
115         if (word.length() == 0) {
116             return LOWER;
117         }
118 
119         // Lower case?
120         if (word.equals(word.toLowerCase(Locale.getDefault()))) {
121             return LOWER;
122         }
123 
124         // Upper case?
125         // A string length of 1 is no good ('I' or 'A' is sentence case)
126         if (word.equals(word.toUpperCase(Locale.getDefault())) && word.length() != 1) {
127             return UPPER;
128         }
129 
130         // So ...
131         return SENTENCE;
132     }
133 
134     /**
135      * Get an integer representation for this CaseType
136      */
137     public int toInteger() {
138         return ordinal();
139     }
140 
141     /**
142      * Lookup method to convert from a String
143      */
144     public static CaseType fromString(String name) {
145         for (CaseType v : values()) {
146             if (v.name().equalsIgnoreCase(name)) {
147                 return v;
148             }
149         }
150 
151         // cannot get here
152         assert false;
153         return null;
154     }
155 
156     /**
157      * Lookup method to convert from an integer
158      */
159     public static CaseType fromInteger(int i) {
160         for (CaseType v : values()) {
161             if (v.ordinal() == i) {
162                 return v;
163             }
164         }
165 
166         // cannot get here
167         assert false;
168         return null;
169     }
170 
171 }
172