| RocketPassage.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: RocketPassage.java 2226 2012-02-02 19:25:21Z dmsmith $
21 */
22 package org.crosswire.jsword.passage;
23
24 import java.io.IOException;
25 import java.io.ObjectInputStream;
26 import java.util.Iterator;
27
28 import org.crosswire.jsword.versification.Versification;
29
30 /**
31 * A RocketPassage is a bit and heavy implementation of Passage that goes fairly
32 * quickly once let of the leash. It manages its speed by creating contained
33 * instances of DistinctPassage and RangedPassage and selects the fastest
34 * implementation for each of its methods from the 3 available.
35 *
36 * @see gnu.lgpl.License for license details.<br>
37 * The copyright to this program is held by it's authors.
38 * @author Joe Walker [joe at eireneh dot com]
39 */
40 public class RocketPassage extends BitwisePassage {
41 /**
42 * Create a new RocketPassage
43 *
44 * @param v11n
45 * The Versification to which this Passage belongs.
46 */
47 public RocketPassage(Versification v11n) {
48 super(v11n);
49 }
50
51 /**
52 * Create a Verse from a human readable string. The opposite of getName(),
53 * Given any RangedPassage v1, and the following
54 * <code>RangedPassage v2 = new RangedPassage(v1.getName());</code> Then
55 * <code>v1.equals(v2);</code> Theoretically, since there are many ways of
56 * representing a RangedPassage as text string comparison along the lines
57 * of: <code>v1.getName().equals(v2.getName())</code> could be false.
58 * However since getName() is standardized this will be true. We don't need
59 * to worry about thread safety in a ctor since we don't exist yet.
60 *
61 *
62 * @param v11n
63 * The Versification to which this Passage belongs.
64 * @param refs
65 * A String containing the text of the RangedPassage
66 * @throws NoSuchVerseException
67 * if refs is invalid
68 */
69 protected RocketPassage(Versification v11n, String refs) throws NoSuchVerseException {
70 super(v11n, refs);
71 }
72
73 /*
74 * (non-Javadoc)
75 *
76 * @see org.crosswire.jsword.passage.AbstractPassage#optimizeReads()
77 */
78 @Override
79 public void optimizeReads() {
80 raiseEventSuppresion();
81
82 // We have to create the cached versions of these separately
83 // so that the calculations made by addAll(this) can
84 // safely call methods like countVerses() without any
85 // danger of them being optimized before the optimizations
86 // are ready for use.
87
88 DistinctPassage dtemp = new DistinctPassage(getVersification());
89 dtemp.raiseEventSuppresion();
90 dtemp.addAll(this);
91 dtemp.lowerEventSuppresionAndTest();
92
93 RangedPassage rtemp = new RangedPassage(getVersification());
94 rtemp.raiseEventSuppresion();
95 rtemp.addAll(this);
96 rtemp.lowerEventSuppresionAndTest();
97
98 distinct = dtemp;
99 ranged = rtemp;
100
101 // This is just an optimization so we dont need to fire any events
102 lowerEventSuppresionAndTest();
103 }
104
105 /*
106 * (non-Javadoc)
107 *
108 * @see org.crosswire.jsword.passage.AbstractPassage#optimizeWrites()
109 */
110 @Override
111 protected void optimizeWrites() {
112 distinct = null;
113 ranged = null;
114 }
115
116 /*
117 * (non-Javadoc)
118 *
119 * @see org.crosswire.jsword.passage.Passage#countRanges(int)
120 */
121 @Override
122 public int countRanges(RestrictionType restrict) {
123 if (ranged != null) {
124 return ranged.countRanges(restrict);
125 }
126
127 return super.countRanges(restrict);
128 }
129
130 /*
131 * (non-Javadoc)
132 *
133 * @see org.crosswire.jsword.passage.Passage#countVerses()
134 */
135 @Override
136 public int countVerses() {
137 if (distinct != null) {
138 return distinct.countVerses();
139 }
140
141 return super.countVerses();
142 }
143
144 /*
145 * (non-Javadoc)
146 *
147 * @see java.lang.Iterable#iterator()
148 */
149 @Override
150 public Iterator<Key> iterator() {
151 if (distinct != null) {
152 return distinct.iterator();
153 }
154
155 return super.iterator();
156 }
157
158 /*
159 * (non-Javadoc)
160 *
161 * @see org.crosswire.jsword.passage.Passage#rangeIterator(int)
162 */
163 @Override
164 public Iterator<Key> rangeIterator(RestrictionType restrict) {
165 if (ranged != null) {
166 return ranged.rangeIterator(restrict);
167 }
168
169 return super.rangeIterator(restrict);
170 }
171
172 /*
173 * (non-Javadoc)
174 *
175 * @see org.crosswire.jsword.passage.Passage#isEmpty()
176 */
177 @Override
178 public boolean isEmpty() {
179 if (distinct != null) {
180 return distinct.isEmpty();
181 }
182
183 return super.isEmpty();
184 }
185
186 /*
187 * (non-Javadoc)
188 *
189 * @see org.crosswire.jsword.passage.Passage#getVerseAt(int)
190 */
191 @Override
192 public Verse getVerseAt(int offset) throws ArrayIndexOutOfBoundsException {
193 if (distinct != null) {
194 return distinct.getVerseAt(offset);
195 }
196
197 return super.getVerseAt(offset);
198 }
199
200 /*
201 * (non-Javadoc)
202 *
203 * @see org.crosswire.jsword.passage.Passage#getVerseRangeAt(int, int)
204 */
205 @Override
206 public VerseRange getRangeAt(int offset, RestrictionType restrict) throws ArrayIndexOutOfBoundsException {
207 if (ranged != null) {
208 return ranged.getRangeAt(offset, restrict);
209 }
210
211 return super.getRangeAt(offset, restrict);
212 }
213
214 /*
215 * (non-Javadoc)
216 *
217 * @see org.crosswire.jsword.passage.Passage#booksInPassage()
218 */
219 @Override
220 public int booksInPassage() {
221 if (distinct != null) {
222 return distinct.booksInPassage();
223 }
224
225 return super.booksInPassage();
226 }
227
228 /*
229 * (non-Javadoc)
230 *
231 * @see
232 * org.crosswire.jsword.passage.Passage#containsAll(org.crosswire.jsword
233 * .passage.Passage)
234 */
235 @Override
236 public boolean containsAll(Passage that) {
237 if (ranged != null) {
238 return ranged.containsAll(that);
239 }
240
241 return super.containsAll(that);
242 }
243
244 /**
245 * Serialization support
246 *
247 * @param is
248 * The stream to read our state from
249 * @throws IOException
250 * if the read fails
251 * @throws ClassNotFoundException
252 * If the read data is incorrect
253 */
254 private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException {
255 optimizeWrites();
256 is.defaultReadObject();
257 }
258
259 /**
260 * The contained DistinctPassage
261 */
262 private transient DistinctPassage distinct;
263
264 /**
265 * The contained RangedPassage
266 */
267 private transient RangedPassage ranged;
268
269 /**
270 * Serialization ID
271 */
272 private static final long serialVersionUID = 3258125864771401268L;
273 }
274