1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
|
20 | |
package org.crosswire.jsword.book.basic; |
21 | |
|
22 | |
import java.util.HashSet; |
23 | |
import java.util.Iterator; |
24 | |
import java.util.LinkedHashSet; |
25 | |
import java.util.List; |
26 | |
import java.util.Set; |
27 | |
|
28 | |
import org.crosswire.common.util.StringUtil; |
29 | |
import org.crosswire.jsword.book.BookData; |
30 | |
import org.crosswire.jsword.book.BookException; |
31 | |
import org.crosswire.jsword.book.BookMetaData; |
32 | |
import org.crosswire.jsword.book.OSISUtil; |
33 | |
import org.crosswire.jsword.book.filter.SourceFilter; |
34 | |
import org.crosswire.jsword.book.sword.Backend; |
35 | |
import org.crosswire.jsword.book.sword.processing.RawTextToXmlProcessor; |
36 | |
import org.crosswire.jsword.passage.Key; |
37 | |
import org.crosswire.jsword.passage.KeyUtil; |
38 | |
import org.crosswire.jsword.passage.NoSuchKeyException; |
39 | |
import org.crosswire.jsword.passage.Passage; |
40 | |
import org.crosswire.jsword.passage.PassageKeyFactory; |
41 | |
import org.crosswire.jsword.passage.RestrictionType; |
42 | |
import org.crosswire.jsword.passage.Verse; |
43 | |
import org.crosswire.jsword.passage.VerseKey; |
44 | |
import org.crosswire.jsword.passage.VerseRange; |
45 | |
import org.crosswire.jsword.versification.BibleBook; |
46 | |
import org.crosswire.jsword.versification.Versification; |
47 | |
import org.crosswire.jsword.versification.VersificationsMapper; |
48 | |
import org.crosswire.jsword.versification.system.Versifications; |
49 | |
import org.jdom2.Content; |
50 | |
import org.jdom2.Element; |
51 | |
import org.slf4j.Logger; |
52 | |
import org.slf4j.LoggerFactory; |
53 | |
|
54 | |
|
55 | |
|
56 | |
|
57 | |
|
58 | |
|
59 | |
|
60 | |
|
61 | |
|
62 | 0 | public abstract class AbstractPassageBook extends AbstractBook { |
63 | |
|
64 | |
|
65 | |
|
66 | |
|
67 | |
|
68 | |
|
69 | |
|
70 | |
public AbstractPassageBook(BookMetaData bmd, Backend backend) { |
71 | 0 | super(bmd, backend); |
72 | 0 | keyf = PassageKeyFactory.instance(); |
73 | 0 | this.versification = bmd.getProperty(BookMetaData.KEY_VERSIFICATION); |
74 | 0 | } |
75 | |
|
76 | |
|
77 | |
|
78 | |
|
79 | |
public Iterator<Content> getOsisIterator(final Key key, final boolean allowEmpty, final boolean allowGenTitles) throws BookException { |
80 | |
|
81 | |
|
82 | 0 | final SourceFilter filter = getFilter(); |
83 | |
|
84 | |
|
85 | |
|
86 | |
|
87 | |
|
88 | 0 | Passage ref = VersificationsMapper.instance().map(KeyUtil.getPassage(key), this.getVersification()); |
89 | |
|
90 | |
|
91 | |
|
92 | |
|
93 | 0 | final boolean showTitles = ref.hasRanges(RestrictionType.CHAPTER) || (!allowEmpty && allowGenTitles); |
94 | |
|
95 | 0 | RawTextToXmlProcessor processor = new RawTextToXmlProcessor() { |
96 | |
|
97 | 0 | private String previousVerseText = ""; |
98 | |
|
99 | |
public void preRange(VerseRange range, List<Content> partialDom) { |
100 | 0 | if (showTitles) { |
101 | 0 | Element title = OSISUtil.factory().createGeneratedTitle(); |
102 | 0 | title.addContent(range.getName()); |
103 | 0 | partialDom.add(title); |
104 | |
} |
105 | 0 | } |
106 | |
|
107 | |
public void postVerse(Key verse, List<Content> partialDom, String rawText) { |
108 | |
|
109 | 0 | if ((allowEmpty || rawText.length() > 0) && !previousVerseText.equals(rawText)) { |
110 | 0 | List<Content> osisContent = filter.toOSIS(AbstractPassageBook.this, verse, rawText); |
111 | 0 | addOSIS(verse, partialDom, osisContent); |
112 | |
} |
113 | 0 | previousVerseText = rawText; |
114 | 0 | } |
115 | |
|
116 | |
public void init(List<Content> partialDom) { |
117 | |
|
118 | 0 | } |
119 | |
}; |
120 | |
|
121 | 0 | return getOsis(ref, processor).iterator(); |
122 | |
} |
123 | |
|
124 | |
|
125 | |
|
126 | |
|
127 | |
|
128 | |
|
129 | |
|
130 | |
|
131 | |
|
132 | |
|
133 | |
public void addOSIS(Key key, Element div, List<Content> osisContent) { |
134 | 0 | assert key != null; |
135 | 0 | div.addContent(osisContent); |
136 | 0 | } |
137 | |
|
138 | |
|
139 | |
|
140 | |
|
141 | |
|
142 | |
|
143 | |
|
144 | |
|
145 | |
|
146 | |
public void addOSIS(Key key, List<Content> content, List<Content> osisContent) { |
147 | 0 | assert key != null; |
148 | 0 | content.addAll(osisContent); |
149 | 0 | } |
150 | |
|
151 | |
|
152 | |
|
153 | |
|
154 | |
|
155 | |
|
156 | |
|
157 | |
|
158 | |
protected abstract SourceFilter getFilter(); |
159 | |
|
160 | |
|
161 | |
|
162 | |
|
163 | |
|
164 | |
|
165 | |
|
166 | |
|
167 | |
public void setDocument(Key key, BookData bdata) throws BookException { |
168 | |
|
169 | 0 | for (Content nextElem : OSISUtil.getFragment(bdata.getOsisFragment())) { |
170 | 0 | if (nextElem instanceof Element) { |
171 | 0 | Element div = (Element) nextElem; |
172 | |
|
173 | |
|
174 | 0 | for (Content data : div.getContent()) { |
175 | 0 | if (data instanceof Element) { |
176 | 0 | Element overse = (Element) data; |
177 | 0 | String text = OSISUtil.getPlainText(overse); |
178 | |
|
179 | 0 | setRawText(key, text); |
180 | 0 | } else { |
181 | 0 | log.error("Ignoring non OSIS/Verse content of DIV."); |
182 | |
} |
183 | |
} |
184 | 0 | } else { |
185 | 0 | log.error("Ignoring non OSIS/Verse content of DIV."); |
186 | |
} |
187 | |
} |
188 | 0 | } |
189 | |
|
190 | |
|
191 | |
|
192 | |
|
193 | |
public boolean isWritable() { |
194 | 0 | return false; |
195 | |
} |
196 | |
|
197 | |
|
198 | |
|
199 | |
|
200 | |
public final Key createEmptyKeyList() { |
201 | 0 | return keyf.createEmptyKeyList(Versifications.instance().getVersification(versification)); |
202 | |
} |
203 | |
|
204 | |
|
205 | |
|
206 | |
|
207 | |
|
208 | |
public Key getValidKey(String name) { |
209 | |
try { |
210 | 0 | return getKey(name); |
211 | 0 | } catch (NoSuchKeyException e) { |
212 | 0 | return createEmptyKeyList(); |
213 | |
} |
214 | |
} |
215 | |
|
216 | |
|
217 | |
|
218 | |
|
219 | |
public final Key getKey(String text) throws NoSuchKeyException { |
220 | 0 | return PassageKeyFactory.instance().getKey(Versifications.instance().getVersification(versification), text); |
221 | |
} |
222 | |
|
223 | |
public Versification getVersification() { |
224 | 0 | if (this.versificationSystem == null) { |
225 | 0 | this.versificationSystem = Versifications.instance().getVersification(getBookMetaData().getProperty(BookMetaData.KEY_VERSIFICATION)); |
226 | |
} |
227 | 0 | return versificationSystem; |
228 | |
} |
229 | |
|
230 | |
|
231 | |
|
232 | |
|
233 | |
|
234 | |
|
235 | |
public Set<BibleBook> getBibleBooks() { |
236 | 0 | if (bibleBooks == null) { |
237 | 0 | synchronized (this) { |
238 | 0 | if (bibleBooks == null) { |
239 | 0 | bibleBooks = getBibleBooksInternal(); |
240 | |
} |
241 | 0 | } |
242 | |
} |
243 | |
|
244 | 0 | return bibleBooks; |
245 | |
} |
246 | |
|
247 | |
|
248 | |
|
249 | |
|
250 | |
|
251 | |
private Set<BibleBook> getBibleBooksInternal() { |
252 | 0 | String list = this.getBookMetaData().getProperty(BookMetaData.KEY_BOOKLIST); |
253 | |
Set<BibleBook> books; |
254 | 0 | if (list == null) { |
255 | |
|
256 | 0 | books = calculateBibleBookList(); |
257 | 0 | String listOfBooks = toString(books); |
258 | 0 | this.putProperty(BookMetaData.KEY_BOOKLIST, listOfBooks); |
259 | 0 | } else { |
260 | |
|
261 | 0 | books = fromString(list); |
262 | |
} |
263 | |
|
264 | 0 | return books; |
265 | |
} |
266 | |
|
267 | |
private Set<BibleBook> fromString(String list) { |
268 | 0 | Set<BibleBook> books = new LinkedHashSet<BibleBook>(list.length() / 2); |
269 | 0 | final String[] bookOsis = StringUtil.split(list, ' '); |
270 | 0 | for (String s : bookOsis) { |
271 | 0 | books.add(BibleBook.fromExactOSIS(s)); |
272 | |
} |
273 | 0 | return books; |
274 | |
} |
275 | |
|
276 | |
private String toString(Set<BibleBook> books) { |
277 | 0 | StringBuilder sb = new StringBuilder(books.size() * 8); |
278 | 0 | for (Iterator<BibleBook> iterator = books.iterator(); iterator.hasNext(); ) { |
279 | 0 | BibleBook b = iterator.next(); |
280 | 0 | sb.append(b.getOSIS()); |
281 | 0 | if (iterator.hasNext()) { |
282 | 0 | sb.append(' '); |
283 | |
} |
284 | |
|
285 | 0 | } |
286 | 0 | return sb.toString(); |
287 | |
} |
288 | |
|
289 | |
|
290 | |
|
291 | |
|
292 | |
private Set<BibleBook> calculateBibleBookList() { |
293 | 0 | final BookMetaData bookMetaData = this.getBookMetaData(); |
294 | 0 | final VerseKey scope = (VerseKey) getScope(); |
295 | 0 | if (scope == null) { |
296 | 0 | return new HashSet<BibleBook>(); |
297 | |
} |
298 | |
|
299 | 0 | final Set<BibleBook> bookList = new LinkedHashSet<BibleBook>(); |
300 | |
|
301 | |
|
302 | 0 | final Versification v11n = Versifications.instance().getVersification(bookMetaData.getProperty(BookMetaData.KEY_VERSIFICATION)); |
303 | 0 | final Iterator<BibleBook> v11nBookIterator = v11n.getBookIterator(); |
304 | |
|
305 | 0 | while (v11nBookIterator.hasNext()) { |
306 | 0 | BibleBook bibleBook = v11nBookIterator.next(); |
307 | |
|
308 | 0 | if (scope.contains(new Verse(v11n, bibleBook, 1, 1)) |
309 | |
|| scope.contains(new Verse(v11n, bibleBook, 1, 2))) |
310 | |
{ |
311 | 0 | bookList.add(bibleBook); |
312 | |
} |
313 | 0 | } |
314 | |
|
315 | 0 | return bookList; |
316 | |
} |
317 | |
|
318 | |
|
319 | |
|
320 | |
|
321 | |
private String versification; |
322 | |
|
323 | |
|
324 | |
|
325 | |
|
326 | |
private Versification versificationSystem; |
327 | |
|
328 | |
|
329 | |
|
330 | |
|
331 | |
private PassageKeyFactory keyf; |
332 | |
|
333 | |
|
334 | |
|
335 | |
|
336 | |
private volatile Set<BibleBook> bibleBooks; |
337 | |
|
338 | |
|
339 | |
|
340 | |
|
341 | 0 | private static final Logger log = LoggerFactory.getLogger(AbstractPassageBook.class); |
342 | |
|
343 | |
} |