| ZLDBackendState.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 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, 2013 - 2016
18 *
19 */
20 package org.crosswire.jsword.book.sword.state;
21
22 import java.io.File;
23 import java.io.IOException;
24 import java.io.RandomAccessFile;
25 import java.net.URI;
26
27 import org.crosswire.common.util.FileUtil;
28 import org.crosswire.common.util.IOUtil;
29 import org.crosswire.common.util.Reporter;
30 import org.crosswire.jsword.JSMsg;
31 import org.crosswire.jsword.book.BookException;
32 import org.crosswire.jsword.book.BookMetaData;
33 import org.crosswire.jsword.book.sword.SwordUtil;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 /**
38 * Stores the random access files required for processing the passage request.
39 *
40 * The caller is required to close to correctly free resources and avoid File
41 * pointer leaks.
42 *
43 * @see gnu.lgpl.License The GNU Lesser General Public License for details.
44 * @author DM Smith
45 */
46 public class ZLDBackendState extends RawLDBackendState {
47 /**
48 * This is default package access for forcing the use of the
49 * OpenFileStateManager to manage the creation. Not doing so may result in
50 * new instances of OpenFileState being created for no reason, and as a
51 * result, if they are released to the OpenFileStateManager by mistake this
52 * would result in leakage
53 *
54 * @param bookMetaData the appropriate metadata for the book
55 */
56 ZLDBackendState(BookMetaData bookMetaData) throws BookException {
57 super(bookMetaData);
58 zdxFile = null;
59 zdtFile = null;
60 zdxRaf = null;
61 zdtRaf = null;
62 lastBlockNum = -1;
63 lastUncompressed = EMPTY_BYTES;
64
65 URI path = null;
66 try {
67 path = SwordUtil.getExpandedDataPath(bookMetaData);
68 } catch (BookException e) {
69 Reporter.informUser(this, e);
70 return;
71 }
72
73 try {
74 zdxFile = new File(path.getPath() + EXTENSION_Z_INDEX);
75 zdtFile = new File(path.getPath() + EXTENSION_Z_DATA);
76
77 if (!zdxFile.canRead()) {
78 // TRANSLATOR: Common error condition: The file could not be read. There can be many reasons.
79 // {0} is a placeholder for the file.
80 Reporter.informUser(this, new BookException(JSMsg.gettext("Error reading {0}", zdtFile.getAbsolutePath())));
81 return;
82 }
83
84 if (!zdtFile.canRead()) {
85 // TRANSLATOR: Common error condition: The file could not be read. There can be many reasons.
86 // {0} is a placeholder for the file.
87 Reporter.informUser(this, new BookException(JSMsg.gettext("Error reading {0}", zdtFile.getAbsolutePath())));
88 return;
89 }
90
91 // Open the files
92 zdxRaf = new RandomAccessFile(zdxFile, FileUtil.MODE_READ);
93 zdtRaf = new RandomAccessFile(zdtFile, FileUtil.MODE_READ);
94 } catch (IOException ex) {
95 //failed to open the files, so close them now
96 IOUtil.close(zdxRaf);
97 IOUtil.close(zdtRaf);
98
99 LOGGER.error("failed to open files", ex);
100 zdxRaf = null;
101 zdtRaf = null;
102 return;
103 }
104 }
105
106 @Override
107 public void releaseResources() {
108 super.releaseResources();
109 lastBlockNum = -1;
110 lastUncompressed = EMPTY_BYTES;
111
112 IOUtil.close(zdxRaf);
113 IOUtil.close(zdtRaf);
114 zdxRaf = null;
115 zdtRaf = null;
116 }
117
118 /**
119 * @return the zdxRaf
120 */
121 public RandomAccessFile getZdxRaf() {
122 return zdxRaf;
123 }
124
125 /**
126 * @return the zdtRaf
127 */
128 public RandomAccessFile getZdtRaf() {
129 return zdtRaf;
130 }
131
132 /**
133 * @return the lastBlockNum
134 */
135 public long getLastBlockNum() {
136 return lastBlockNum;
137 }
138
139 /**
140 * @return the lastUncompressed
141 */
142 public byte[] getLastUncompressed() {
143 return lastUncompressed;
144 }
145
146 /**
147 * @param lastBlockNum the lastBlockNum to set
148 */
149 public void setLastBlockNum(long lastBlockNum) {
150 this.lastBlockNum = lastBlockNum;
151 }
152
153 /**
154 * @param lastUncompressed the lastUncompressed to set
155 */
156 public void setLastUncompressed(byte[] lastUncompressed) {
157 this.lastUncompressed = lastUncompressed;
158 }
159
160 private static final byte[] EMPTY_BYTES = new byte[0];
161 private static final String EXTENSION_Z_INDEX = ".zdx";
162 private static final String EXTENSION_Z_DATA = ".zdt";
163
164 /**
165 * The compressed index.
166 */
167 private File zdxFile;
168
169 /**
170 * The compressed index random access file.
171 */
172 private RandomAccessFile zdxRaf;
173
174 /**
175 * The compressed text.
176 */
177 private File zdtFile;
178
179 /**
180 * The compressed text random access file.
181 */
182 private RandomAccessFile zdtRaf;
183
184 /**
185 * The index of the block that is cached.
186 */
187 private long lastBlockNum;
188
189 /**
190 * The cache for a read of a compressed block.
191 */
192 private byte[] lastUncompressed;
193
194 /**
195 * The log stream
196 */
197 private static final Logger LOGGER = LoggerFactory.getLogger(ZLDBackendState.class);
198 }
199