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, 2012 - 2016
18   *
19   */
20  package org.crosswire.jsword.versification.system;
21  
22  import java.util.HashMap;
23  import java.util.HashSet;
24  import java.util.Iterator;
25  import java.util.Map;
26  import java.util.Set;
27  
28  import org.crosswire.jsword.versification.Versification;
29  
30  /**
31   * The Versifications class manages the creation of Versifications as needed.
32   * It delays the construction of the Versification until getVersification(String name) is called.
33   *
34   * @see gnu.lgpl.License The GNU Lesser General Public License for details.
35   * @author DM Smith
36   */
37  public final class Versifications {
38  
39      /**
40       * The default Versification for JSword is the KJV.
41       * This is subject to change at any time.
42       */
43      public static final String DEFAULT_V11N = SystemKJV.V11N_NAME;
44  
45      /**
46       * Get the singleton instance of Versifications.
47       *
48       * @return the singleton
49       */
50      public static Versifications instance() {
51          return instance;
52      }
53  
54      /**
55       * Get the default Versification.
56       *
57       * @return the default Versification.
58       * @deprecated Use {@link #getVersification(String)} instead.
59       */
60      @Deprecated
61      public synchronized Versification getDefaultVersification() {
62          return getVersification(DEFAULT_V11N);
63      }
64  
65      /**
66       * Get the Versification by its name. If name is null then return the default Versification.
67       *
68       * @param name the name of the Versification
69       * @return the Versification or null if it is not known.
70       */
71      public synchronized Versification getVersification(String name) {
72          String actual = name;
73          if (actual == null) {
74              actual = DEFAULT_V11N;
75          }
76  
77          // This class delays the building of a Versification to when it is
78          // actually needed.
79          Versification rs = fluffed.get(actual);
80          if (rs == null) {
81              rs = fluff(actual);
82              if (rs != null) {
83                  fluffed.put(actual, rs);
84              }
85          }
86  
87          return rs;
88      }
89  
90      /**
91       * Determine whether the named Versification is known.
92       *
93       * @param name the name of the Versification
94       * @return true when the Versification is available for use
95       */
96      public synchronized boolean isDefined(String name) {
97          return name == null || known.contains(name);
98      }
99  
100     private Versification fluff(String name) {
101         // Keep KJV at the top as it is the most common
102         if (name == null || SystemKJV.V11N_NAME.equals(name)) {
103             return new SystemKJV();
104         }
105 
106         //then in alphabetical order, to ease the developer checking we have them all
107         if (SystemCalvin.V11N_NAME.equals(name)) {
108             return new SystemCalvin();
109         }
110         if (SystemCatholic.V11N_NAME.equals(name)) {
111             return new SystemCatholic();
112         }
113         if (SystemCatholic2.V11N_NAME.equals(name)) {
114             return new SystemCatholic2();
115         }
116         if (SystemDarbyFR.V11N_NAME.equals(name)) {
117             return new SystemDarbyFR();
118         }
119         if (SystemGerman.V11N_NAME.equals(name)) {
120             return new SystemGerman();
121         }
122         if (SystemKJVA.V11N_NAME.equals(name)) {
123             return new SystemKJVA();
124         }
125         if (SystemLeningrad.V11N_NAME.equals(name)) {
126             return new SystemLeningrad();
127         }
128         if (SystemLuther.V11N_NAME.equals(name)) {
129             return new SystemLuther();
130         }
131         if (SystemLXX.V11N_NAME.equals(name)) {
132             return new SystemLXX();
133         }
134         if (SystemMT.V11N_NAME.equals(name)) {
135             return new SystemMT();
136         }
137         if (SystemNRSV.V11N_NAME.equals(name)) {
138             return new SystemNRSV();
139         }
140         if (SystemNRSVA.V11N_NAME.equals(name)) {
141             return new SystemNRSVA();
142         }
143         if (SystemOrthodox.V11N_NAME.equals(name)) {
144             return new SystemOrthodox();
145         }
146         if (SystemSegond.V11N_NAME.equals(name)) {
147             return new SystemSegond();
148         }
149         if (SystemSynodal.V11N_NAME.equals(name)) {
150             return new SystemSynodal();
151         }
152         if (SystemSynodalProt.V11N_NAME.equals(name)) {
153             return new SystemSynodalProt();
154         }
155         if (SystemVulg.V11N_NAME.equals(name)) {
156             return new SystemVulg();
157         }
158 
159         return null;
160     }
161 
162     /**
163      * Add a Versification that is not predefined by JSword.
164      *
165      * @param rs the Versification to register
166      */
167     public synchronized void register(Versification rs) {
168         fluffed.put(rs.getName(), rs);
169         known.add(rs.getName());
170     }
171 
172     /**
173      * Get an iterator over all known versifications.
174      * 
175      * @return an iterator of versification names.
176      */
177     public Iterator<String> iterator() {
178         return known.iterator();
179     }
180 
181     /**
182      * @return number of versifications
183      */
184     public int size() {
185         return known.size();
186     }
187 
188     /**
189      * This class is a singleton, enforced by a private constructor.
190      */
191     private Versifications() {
192         known = new HashSet<String>();
193         known.add(SystemCalvin.V11N_NAME);
194         known.add(SystemCatholic.V11N_NAME);
195         known.add(SystemCatholic2.V11N_NAME);
196         known.add(SystemDarbyFR.V11N_NAME);
197         known.add(SystemGerman.V11N_NAME);
198         known.add(SystemKJV.V11N_NAME);
199         known.add(SystemKJVA.V11N_NAME);
200         known.add(SystemLeningrad.V11N_NAME);
201         known.add(SystemLuther.V11N_NAME);
202         known.add(SystemLXX.V11N_NAME);
203         known.add(SystemMT.V11N_NAME);
204         known.add(SystemNRSV.V11N_NAME);
205         known.add(SystemNRSVA.V11N_NAME);
206         known.add(SystemOrthodox.V11N_NAME);
207         known.add(SystemSegond.V11N_NAME);
208         known.add(SystemSynodal.V11N_NAME);
209         known.add(SystemSynodalProt.V11N_NAME);
210         known.add(SystemVulg.V11N_NAME);
211         fluffed = new HashMap<String, Versification>();
212     }
213 
214     /**
215      * The set of v11n names.
216      */
217     private Set<String> known;
218 
219     /**
220      * The map of instantiated Versifications, given by their names.
221      */
222     private Map<String, Versification> fluffed;
223 
224     private static final Versifications instance = new Versifications();
225 }
226