1
20 package org.crosswire.jsword.book.readings;
21
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.Date;
25 import java.util.Iterator;
26 import java.util.List;
27 import java.util.Locale;
28 import java.util.Map;
29 import java.util.MissingResourceException;
30 import java.util.ResourceBundle;
31 import java.util.TreeMap;
32
33 import org.crosswire.common.util.CWClassLoader;
34 import org.crosswire.common.util.Language;
35 import org.crosswire.jsword.JSMsg;
36 import org.crosswire.jsword.JSOtherMsg;
37 import org.crosswire.jsword.book.BookCategory;
38 import org.crosswire.jsword.book.BookException;
39 import org.crosswire.jsword.book.FeatureType;
40 import org.crosswire.jsword.book.OSISUtil;
41 import org.crosswire.jsword.book.basic.AbstractBook;
42 import org.crosswire.jsword.book.basic.DefaultBookMetaData;
43 import org.crosswire.jsword.book.sword.processing.RawTextToXmlProcessor;
44 import org.crosswire.jsword.internationalisation.LocaleProviderManager;
45 import org.crosswire.jsword.passage.DefaultKeyList;
46 import org.crosswire.jsword.passage.Key;
47 import org.crosswire.jsword.passage.NoSuchKeyException;
48 import org.crosswire.jsword.passage.Passage;
49 import org.crosswire.jsword.passage.PassageKeyFactory;
50 import org.crosswire.jsword.passage.PreferredKey;
51 import org.crosswire.jsword.passage.RestrictionType;
52 import org.crosswire.jsword.passage.SetKeyList;
53 import org.crosswire.jsword.passage.VerseRange;
54 import org.crosswire.jsword.versification.system.Versifications;
55 import org.jdom2.Content;
56 import org.jdom2.Element;
57 import org.slf4j.Logger;
58 import org.slf4j.LoggerFactory;
59
60
66 public class ReadingsBook extends AbstractBook implements PreferredKey {
67
73 public ReadingsBook(ReadingsBookDriver driver, String setname, BookCategory type) {
74 super(null, null);
76 hash = new TreeMap<Key, String>();
77
78 Locale defaultLocale = LocaleProviderManager.getLocale();
81 ResourceBundle prop = ResourceBundle.getBundle(setname, defaultLocale, CWClassLoader.instance(ReadingsBookDriver.class));
82
83 String name = JSMsg.gettext("Readings");
85 try {
86 name = prop.getString("title");
87 } catch (MissingResourceException e) {
88 log.warn("Missing resource: 'title' while parsing: {}", setname);
89 }
90
91 DefaultBookMetaData bmd = new DefaultBookMetaData(driver, name, type);
92 bmd.setInitials(setname);
93 bmd.setLanguage(new Language(defaultLocale.getLanguage()));
94 setBookMetaData(bmd);
95
96 java.util.Calendar greg = new java.util.GregorianCalendar();
98 greg.set(java.util.Calendar.DAY_OF_MONTH, 1);
99 greg.set(java.util.Calendar.MONDAY, java.util.Calendar.JANUARY);
100 int currentYear = greg.get(java.util.Calendar.YEAR);
101
102 while (greg.get(java.util.Calendar.YEAR) == currentYear) {
103 String internalKey = ReadingsKey.external2internal(greg);
104 String readings = "";
105
106 try {
107 readings = prop.getString(internalKey);
108 hash.put(new ReadingsKey(greg.getTime()), readings);
109 } catch (MissingResourceException e) {
110 log.warn("Missing resource: {} while parsing: {}", internalKey, setname);
111 }
112
113 greg.add(java.util.Calendar.DATE, 1);
114 }
115
116 global = new SetKeyList(hash.keySet(), getName());
117 }
118
119
122 public Key getPreferred() {
123 return new ReadingsKey(new Date());
124 }
125
126 public Iterator<Content> getOsisIterator(final Key key, final boolean allowEmpty, final boolean allowGenTitles) throws BookException {
127 if (!(key instanceof ReadingsKey)) {
128 throw new BookException(JSMsg.gettext("Key not found {0}", key.getName()));
130 }
131
132 List<Content> content = new ArrayList<Content>();
134
135 Element title = OSISUtil.factory().createTitle();
136 title.addContent(key.getName());
137 content.add(title);
138
139 String readings = hash.get(key);
140 if (readings == null) {
141 throw new BookException(JSMsg.gettext("Key not found {0}", key.getName()));
143 }
144
145 try {
146 PassageKeyFactory keyf = PassageKeyFactory.instance();
150 Passage ref = keyf.getKey(Versifications.instance().getVersification("KJV"), readings);
151
152 Element list = OSISUtil.factory().createList();
153 content.add(list);
154
155 Iterator<VerseRange> it = ref.rangeIterator(RestrictionType.NONE);
156 while (it.hasNext()) {
157 Key range = it.next();
158
159 Element reading = OSISUtil.factory().createReference();
160 reading.setAttribute(OSISUtil.OSIS_ATTR_REF, range.getOsisRef());
161 reading.addContent(range.getName());
162
163 Element item = OSISUtil.factory().createItem();
164 item.addContent(reading);
165 list.addContent(item);
166 }
167 } catch (NoSuchKeyException ex) {
168 content.add(OSISUtil.factory().createText(JSOtherMsg.lookupText("Failed to parse {0}", readings)));
169 }
170
171 return content.iterator();
172 }
173
174
177 public boolean contains(Key key) {
178 return false;
179 }
180
181
185 public String getRawText(Key key) throws BookException {
186 return "";
187 }
188
189
192 @Override
193 public List<Content> getOsis(Key key, RawTextToXmlProcessor processor) throws BookException {
194 return Collections.emptyList();
195 }
196
197
200 public boolean isWritable() {
201 return false;
202 }
203
204
207 public void setRawText(Key key, String rawData) throws BookException {
208 throw new BookException(JSOtherMsg.lookupText("This Book is read-only."));
209 }
210
211
214 public void setAliasKey(Key alias, Key source) throws BookException {
215 throw new BookException(JSOtherMsg.lookupText("This Book is read-only."));
216 }
217
218
221 public Key getValidKey(String name) {
222 try {
223 return getKey(name);
224 } catch (NoSuchKeyException e) {
225 return createEmptyKeyList();
226 }
227 }
228
229
232 public Key getKey(String name) throws NoSuchKeyException {
233 DefaultKeyList reply = new DefaultKeyList();
234 reply.addAll(new ReadingsKey(name, name, global));
235 return reply;
236 }
237
238
241 public Key getGlobalKeyList() {
242 return global;
243 }
244
245
248 public Key createEmptyKeyList() {
249 return new DefaultKeyList();
250 }
251
252 @Override
253 public boolean hasFeature(FeatureType feature) {
254 return feature == FeatureType.DAILY_DEVOTIONS;
255 }
256
257
260 private Key global;
261
262
265 private Map<Key, String> hash;
266
267
270 private static final Logger log = LoggerFactory.getLogger(ReadingsBook.class);
271 }
272