1
20 package org.crosswire.jsword.book.basic;
21
22 import java.util.List;
23 import java.util.Set;
24 import java.util.concurrent.CopyOnWriteArrayList;
25
26 import org.crosswire.common.activate.Lock;
27 import org.crosswire.common.util.Language;
28 import org.crosswire.jsword.JSOtherMsg;
29 import org.crosswire.jsword.book.Book;
30 import org.crosswire.jsword.book.BookCategory;
31 import org.crosswire.jsword.book.BookDriver;
32 import org.crosswire.jsword.book.BookException;
33 import org.crosswire.jsword.book.BookMetaData;
34 import org.crosswire.jsword.book.FeatureType;
35 import org.crosswire.jsword.book.sword.Backend;
36 import org.crosswire.jsword.book.sword.processing.NoOpRawTextProcessor;
37 import org.crosswire.jsword.book.sword.processing.RawTextToXmlProcessor;
38 import org.crosswire.jsword.index.IndexStatus;
39 import org.crosswire.jsword.index.IndexStatusEvent;
40 import org.crosswire.jsword.index.IndexStatusListener;
41 import org.crosswire.jsword.index.search.DefaultSearchRequest;
42 import org.crosswire.jsword.index.search.SearchRequest;
43 import org.crosswire.jsword.index.search.Searcher;
44 import org.crosswire.jsword.index.search.SearcherFactory;
45 import org.crosswire.jsword.passage.Key;
46 import org.jdom2.Content;
47 import org.jdom2.Document;
48
49
57 public abstract class AbstractBook implements Book {
58
64 public AbstractBook(BookMetaData bmd, Backend backend) {
65 this.bmd = bmd;
66 this.backend = backend;
67 this.listeners = new CopyOnWriteArrayList<IndexStatusListener>();
68 }
69
70
73 public Key getScope() {
74 return getGlobalKeyList();
75 }
76
77
80 public final BookMetaData getBookMetaData() {
81 return bmd;
82 }
83
84
87 public final void setBookMetaData(BookMetaData bmd) {
88 this.bmd = bmd;
89 }
90
91 public final Backend getBackend() {
92 return backend;
93 }
94
95
98 public void activate(Lock lock) {
99 }
100
101
104 public void deactivate(Lock lock) {
105 }
106
107
110 public Key find(String request) throws BookException {
111 return find(new DefaultSearchRequest(request));
112 }
113
114
117 public Key find(SearchRequest request) throws BookException {
118 if (searcher == null) {
119 try {
120 searcher = SearcherFactory.createSearcher(this);
121 } catch (InstantiationException ex) {
122 throw new BookException(JSOtherMsg.lookupText("Failed to initialize the search index"), ex);
123 }
124 }
125
126 return searcher.search(request);
127 }
128
129
134 public Book getBook() {
135 return this;
136 }
137
138
141 public BookDriver getDriver() {
142 return bmd == null ? null : bmd.getDriver();
143 }
144
145
148 public String getDriverName() {
149 return bmd == null ? null : bmd.getDriverName();
150 }
151
152
155 public boolean match(String name) {
156 if (name == null) {
157 return false;
158 }
159 if (name.equals(getInitials())) {
160 return true;
161 }
162 if (name.equals(getName())) {
163 return true;
164 }
165 if (name.equalsIgnoreCase(getInitials())) {
166 return true;
167 }
168 if (name.equalsIgnoreCase(getName())) {
169 return true;
170 }
171 if (name.startsWith(getInitials())) {
172 return true;
173 }
174 if (name.startsWith(getName())) {
175 return true;
176 }
177 return false;
178 }
179
180
183 public IndexStatus getIndexStatus() {
184 return bmd.getIndexStatus();
185 }
186
187
190 public void setIndexStatus(IndexStatus newStatus) {
191 IndexStatus oldStatus = bmd.getIndexStatus();
192 bmd.setIndexStatus(newStatus);
193 firePropertyChange(oldStatus, newStatus);
194 }
195
196
199 public String getAbbreviation() {
200 return bmd.getAbbreviation();
201 }
202
203
206 public String getInitials() {
207 return bmd.getInitials();
208 }
209
210
213 public Language getLanguage() {
214 return bmd.getLanguage();
215 }
216
217
220 public String getName() {
221 return bmd.getName();
222 }
223
224
227 public String getOsisID() {
228 return bmd.getOsisID();
229 }
230
231
234 public Set<String> getPropertyKeys() {
235 return bmd.getPropertyKeys();
236 }
237
238
241 public String getProperty(String key) {
242 return bmd.getProperty(key);
243 }
244
245
248 public void putProperty(String key, String value) {
249 bmd.putProperty(key, value, false);
250 }
251
252
255 public void putProperty(String key, String value, boolean forFrontend) {
256 bmd.putProperty(key, value, forFrontend);
257 }
258
259
262 public BookCategory getBookCategory() {
263 return bmd.getBookCategory();
264 }
265
266
269 public boolean isLeftToRight() {
270 return bmd.isLeftToRight();
271 }
272
273
276 public boolean isSupported() {
277 return bmd.isSupported();
278 }
279
280
283 public boolean isEnciphered() {
284 return bmd.isEnciphered();
285 }
286
287
290 public boolean isLocked() {
291 return bmd.isLocked();
292 }
293
294
297 public boolean unlock(String unlockKey) {
298 boolean state = bmd.unlock(unlockKey);
299 if (state) {
300 return isUnlockKeyValid();
302 }
303 return state;
304 }
305
306
312 private boolean isUnlockKeyValid() {
313 try {
314 Key key = getGlobalKeyList();
315 if (key == null) {
316 return true;
318 }
319
320 if (key.getCardinality() > 0) {
321 key = key.get(0);
322 }
323
324 getOsis(key, new NoOpRawTextProcessor());
325
326 return true;
327 } catch (BookException ex) {
328 return false;
329 }
330 }
331
332 protected abstract List<Content> getOsis(Key key, RawTextToXmlProcessor noOpRawTextProcessor) throws BookException;
333
334
337 public String getUnlockKey() {
338 return bmd.getUnlockKey();
339 }
340
341
344 public boolean isQuestionable() {
345 return bmd.isQuestionable();
346 }
347
348
351 public boolean hasFeature(FeatureType feature) {
352 return bmd.hasFeature(feature);
353 }
354
355
358 public void addIndexStatusListener(IndexStatusListener listener) {
359 if (listeners == null) {
360 listeners = new CopyOnWriteArrayList<IndexStatusListener>();
361 }
362 listeners.add(listener);
363 }
364
365
368 public void removeIndexStatusListener(IndexStatusListener listener) {
369 if (listeners == null) {
370 return;
371 }
372
373 listeners.remove(listener);
374 }
375
376
387 protected void firePropertyChange(IndexStatus oldStatus, IndexStatus newStatus) {
388 if (oldStatus != null && newStatus != null && oldStatus.equals(newStatus)) {
389 return;
390 }
391
392 IndexStatusEvent ev = new IndexStatusEvent(this, newStatus);
393 for (IndexStatusListener listener : listeners) {
394 listener.statusChanged(ev);
395 }
396 }
397
398
401 public Document toOSIS() {
402 return bmd.toOSIS();
403 }
404
405
408 @Override
409 public boolean equals(Object obj) {
410 if (obj == null) {
412 return false;
413 }
414
415
418 if (!obj.getClass().equals(this.getClass())) {
421 return false;
422 }
423
424 Book that = (Book) obj;
426
427 return bmd.equals(that.getBookMetaData());
428 }
429
430
433 @Override
434 public int hashCode() {
435 return bmd.hashCode();
436 }
437
438
441 public int compareTo(Book obj) {
442 return this.bmd.compareTo(obj.getBookMetaData());
443 }
444
445
448 @Override
449 public String toString() {
450 return bmd.toString();
451 }
452
453
456 private Searcher searcher;
457
458
461 private BookMetaData bmd;
462
463
466 private Backend backend;
467
468
469
472 private List<IndexStatusListener> listeners;
473 }
474