| AbstractBackend.java |
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: AbstractBackend.java 2099 2011-03-07 17:13:00Z dmsmith $
21 */
22 package org.crosswire.jsword.book.sword;
23
24 import java.io.File;
25 import java.io.IOException;
26 import java.net.URI;
27
28 import org.crosswire.common.activate.Activatable;
29 import org.crosswire.common.crypt.Sapphire;
30 import org.crosswire.common.util.NetUtil;
31 import org.crosswire.jsword.JSOtherMsg;
32 import org.crosswire.jsword.book.BookException;
33 import org.crosswire.jsword.passage.Key;
34
35 /**
36 * A generic way to read data from disk for later formatting.
37 *
38 * @see gnu.lgpl.License for license details.<br>
39 * The copyright to this program is held by it's authors.
40 * @author Joe Walker [joe at eireneh dot com]
41 * @author DM Smith [dmsmith555 at yahoo dot com]
42 */
43 public abstract class AbstractBackend implements Activatable {
44 /**
45 * Default constructor for the sake of serialization.
46 */
47 /* protected */public AbstractBackend() {
48 }
49
50 /**
51 * Construct a minimal backend
52 *
53 * @param sbmd
54 */
55 public AbstractBackend(SwordBookMetaData sbmd) {
56 bmd = sbmd;
57 }
58
59 /**
60 * @return Returns the Sword BookMetaData.
61 */
62 public SwordBookMetaData getBookMetaData() {
63 return bmd;
64 }
65
66 /**
67 * Decipher the data in place, if it is enciphered and there is a key to
68 * unlock it.
69 *
70 * @param data
71 * the data to unlock
72 */
73 public void decipher(byte[] data) {
74 String cipherKeyString = (String) getBookMetaData().getProperty(ConfigEntryType.CIPHER_KEY);
75 if (cipherKeyString != null) {
76 Sapphire cipherEngine = new Sapphire(cipherKeyString.getBytes());
77 for (int i = 0; i < data.length; i++) {
78 data[i] = cipherEngine.cipher(data[i]);
79 }
80 // destroy any evidence!
81 cipherEngine.burn();
82 }
83 }
84
85 /**
86 * Encipher the data in place, if there is a key to unlock it.
87 *
88 * @param data
89 */
90 public void encipher(byte[] data) {
91 // Enciphering and deciphering are the same!
92 decipher(data);
93 }
94
95 public URI getExpandedDataPath() throws BookException {
96 URI loc = NetUtil.lengthenURI(bmd.getLibrary(), (String) bmd.getProperty(ConfigEntryType.DATA_PATH));
97
98 if (loc == null) {
99 // FIXME(DMS): missing parameter
100 throw new BookException(JSOtherMsg.lookupText("Missing data files for old and new testaments in {0}."));
101 }
102
103 return loc;
104 }
105
106 /**
107 * Initialize a AbstractBackend before use. This method needs to call
108 * addKey() a number of times on GenBookBackend
109 */
110 public Key readIndex() {
111 // TODO(dms): Eliminate readIndex by deriving GenBookBackend from
112 // AbstractKeyBackend
113 return null;
114 }
115
116 /**
117 * Determine whether this Book contains the key in question
118 *
119 * @param key
120 * The key whose presence is desired.
121 * @return true if the Book contains the key
122 */
123 public abstract boolean contains(Key key);
124
125 /**
126 * Get the text allotted for the given entry
127 *
128 * @param key
129 * The key to fetch
130 * @return String The data for the verse in question
131 * @throws BookException
132 * If the data can not be read.
133 */
134 public abstract String getRawText(Key key) throws BookException;
135
136 /**
137 * Set the text allotted for the given verse
138 *
139 * @param key
140 * The key to set text to
141 * @param text
142 * The text to be set for key
143 * @throws BookException
144 * If the data can not be set.
145 * @throws IOException
146 * If the module data path could not be created.
147 */
148 public abstract void setRawText(Key key, String text) throws BookException, IOException;
149
150 /**
151 * Sets alias for a comment on a verse range
152 * I.e. setRawText() was for verse range Gen.1.1-3 then setAliasKey should be called for Gen.1.1.2 and Gen.1.1.3
153 * @param alias Alias Key
154 * @param source Source Key
155 * @throws IOException Exception when anything goes wrong on writing the alias
156 */
157 public abstract void setAliasKey(Key alias, Key source) throws IOException;
158
159 /**
160 * Create the directory to hold the Book if it does not exist.
161 *
162 * @throws IOException
163 * @throws BookException
164 */
165 public void create() throws IOException, BookException {
166 File dataPath = new File(getExpandedDataPath());
167 if (!dataPath.exists() && !dataPath.mkdirs()) {
168 throw new IOException("Unable to create module data path!");
169 }
170 }
171
172 /**
173 * Returns whether this AbstractBackend is implemented.
174 *
175 * @return true if this AbstractBackend is implemented.
176 */
177 public boolean isSupported() {
178 return true;
179 }
180
181 /**
182 * A Backend is writable if the file system allows the underlying files to
183 * be opened for writing and if the backend has implemented writing.
184 * Ultimately, all drivers should allow writing. At this time writing is not
185 * supported by backends, so abstract implementations should return false
186 * and let specific implementations return true otherwise.
187 *
188 * @return true if the book is writable
189 */
190 public boolean isWritable() {
191 return false;
192 }
193
194 private SwordBookMetaData bmd;
195 }
196