Source code: com/eireneh/bible/book/Verifier.java
1
2 package com.eireneh.bible.book;
3
4 import java.io.*;
5 import java.util.*;
6
7 import com.eireneh.util.*;
8 import com.eireneh.bible.passage.*;
9
10 /**
11 * The Verifier check 2 versions for identical text.
12 *
13 * <table border='1' cellPadding='3' cellSpacing='0' width="100%">
14 * <tr><td bgColor='white'class='TableRowColor'><font size='-7'>
15 * Distribution Licence:<br />
16 * Project B is free software; you can redistribute it
17 * and/or modify it under the terms of the GNU General Public License,
18 * version 2 as published by the Free Software Foundation.<br />
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.<br />
23 * The License is available on the internet
24 * <a href='http://www.gnu.org/copyleft/gpl.html'>here</a>, by writing to
25 * <i>Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
26 * MA 02111-1307, USA</i>, Or locally at the Licence link below.<br />
27 * The copyright to this program is held by it's authors.
28 * </font></td></tr></table>
29 * @see <a href='http://www.eireneh.com/servlets/Web'>Project B Home</a>
30 * @see docs.Licence
31 * @author Joe Walker
32 * @version D0.I0.T0
33 */
34 public class Verifier
35 {
36 /**
37 * Basic constructor
38 */
39 public Verifier()
40 {
41 }
42
43 /**
44 * Constructor that sets up the Bibles as well.
45 */
46 public Verifier(Bible bible1, Bible bible2)
47 {
48 setBible1(bible1);
49 setBible2(bible2);
50 }
51
52 /**
53 * The first Bible that we are checking, this is supposed to be the
54 * more accurate of the 2 Bibles, so we use this as a source of the
55 * words to check.
56 * @param bible1 A Bible to check
57 */
58 public void setBible1(Bible bible1)
59 {
60 this.bible1 = bible1;
61 }
62
63 /**
64 * The first Bible that we are checking
65 * @return A Bible to check
66 */
67 public Bible getBible1()
68 {
69 return bible1;
70 }
71
72 /**
73 * The second Bible that we are checking, this is supposed to be the
74 * less accurate, or more recent of the 2 Bibles, so we use this in
75 * firing ProgressEvents.
76 * @param bible2 A Bible to check
77 */
78 public void setBible2(Bible bible2)
79 {
80 this.bible2 = bible2;
81 }
82
83 /**
84 * The second Bible that we are checking
85 * @return A Bible to check
86 */
87 public Bible getBible2()
88 {
89 return bible2;
90 }
91
92 /**
93 * Read from the given source version to generate ourselves
94 * @param version The source
95 */
96 public void checkText(PrintWriter out) throws IOException, NoSuchVerseException, BookException
97 {
98 checkText(WHOLE, out);
99 }
100
101 /**
102 * Read from the given source version to generate ourselves
103 * @param version The source
104 */
105 public void checkText(Passage ref, PrintWriter out) throws IOException, NoSuchVerseException, BookException
106 {
107 int progress = 0;
108 alive = true;
109
110 // For every verse in the Bible
111 Enumeration en = ref.verseElements();
112 while (en.hasMoreElements() && alive)
113 {
114 Verse verse = (Verse) en.nextElement();
115 VerseRange range = new VerseRange(verse);
116
117 // Fire a progress event?
118 int new_progress = 100 * verse.getOrdinal() / Books.versesInBible();
119 if (progress != new_progress)
120 {
121 progress = new_progress;
122 fireProgressMade("Checking Verses:", progress);
123 }
124
125 try
126 {
127 // Read the document from the first bible
128 String text1 = bible1.getText(range);
129 String text2 = bible2.getText(range);
130
131 // Check
132 if (!text1.equals(text2))
133 {
134 out.println("Verse: "+range);
135 out.println(bible1.getName()+": "+text1);
136 out.println(bible2.getName()+": "+text2);
137 out.println();
138 }
139 }
140 catch (Exception ex)
141 {
142 out.println("Verse: "+range);
143 ex.printStackTrace(out);
144 out.println();
145 }
146
147 // This could take a long time ...
148 Thread.currentThread().yield();
149 if (Thread.currentThread().isInterrupted())
150 break;
151 }
152 }
153
154 /**
155 * Read from the given source version to generate ourselves
156 * @param version The source
157 */
158 public void checkPassage(PrintWriter out) throws IOException, NoSuchVerseException, BookException
159 {
160 int count = 0;
161 alive = true;
162
163 // For every word in the word list
164 Enumeration en = bible1.listWords();
165 while (en.hasMoreElements() && alive)
166 {
167 String word = (String) en.nextElement();
168 checkSinglePassage(word, out);
169
170 // Fire a progress event?
171 fireProgressMade("Checking Words:", 100 * count++ / Version.GUESS_WORDS);
172
173 // This could take a long time ...
174 Thread.currentThread().yield();
175 if (Thread.currentThread().isInterrupted())
176 break;
177 }
178 }
179
180 /**
181 * Read from the given source version to generate ourselves
182 * @param version The source
183 */
184 public void checkPassage(String starts, PrintWriter out) throws IOException, NoSuchVerseException, BookException
185 {
186 if (starts == null || starts.equals(""))
187 {
188 checkPassage(out);
189 return;
190 }
191
192 int count = 0;
193 alive = true;
194
195 // For every word in the word list
196 String[] words = bible1.getStartsWith(starts);
197 for (int i=0; i<words.length && alive; i++)
198 {
199 checkSinglePassage(words[i], out);
200
201 // Fire a progress event?
202 fireProgressMade("Checking Words:", 100 * count++ / Version.GUESS_WORDS);
203
204 // This could take a long time ...
205 Thread.currentThread().yield();
206 if (Thread.currentThread().isInterrupted())
207 break;
208 }
209 }
210
211 /**
212 * Read from the given source version to generate ourselves
213 * @param version The source
214 */
215 private void checkSinglePassage(String word, PrintWriter out) throws IOException, NoSuchVerseException, BookException
216 {
217 Passage ref1 = bible1.findPassage(word);
218 Passage ref2 = bible2.findPassage(word);
219
220 // Check
221 if (!ref1.equals(ref2))
222 {
223 out.println("Word: "+word);
224 out.println(bible1.getName()+": "+ref1);
225 out.println(bible2.getName()+": "+ref2);
226 out.println();
227 }
228 }
229
230 /**
231 * Since many of these operations take a long time, we may want to
232 * kill them politely without killing any Threads
233 */
234 public void stopChecking()
235 {
236 alive = false;
237 }
238
239 /**
240 * Add a progress listener to the list of things wanting
241 * to know whenever we make some progress
242 */
243 public void addProgressListener(ProgressListener li)
244 {
245 listeners.add(ProgressListener.class, li);
246 }
247
248 /**
249 * Remove a progress listener from the list of things wanting
250 * to know whenever we make some progress
251 */
252 public void removeProgressListener(ProgressListener li)
253 {
254 listeners.remove(ProgressListener.class, li);
255 }
256
257 /**
258 * Called to fire a ProgressEvent to all the Listeners, but only if
259 * there is actual progress since last time.
260 * @param percent The percentage of the way through that we are now
261 */
262 protected void fireProgressMade(String name, int percent)
263 {
264 if (this.percent == percent)
265 return;
266
267 this.percent = percent;
268
269 // Guaranteed to return a non-null array
270 Object[] contents = listeners.getListenerList();
271
272 // Process the listeners last to first, notifying
273 // those that are interested in this event
274 ProgressEvent ev = null;
275 for (int i=contents.length-2; i>=0; i-=2)
276 {
277 if (contents[i] == ProgressListener.class)
278 {
279 if (ev == null)
280 ev = new ProgressEvent(bible2, name, percent);
281
282 ((ProgressListener) contents[i+1]).progressMade(ev);
283 }
284 }
285 }
286
287 /** The Whole Bible */
288 public static Passage WHOLE = PassageFactory.getWholeBiblePassage();
289
290 /** The list of listeners */
291 protected EventListenerList listeners = new EventListenerList();
292
293 /** The current progress */
294 protected int percent = -1;
295
296 /** The first Bible that we are checking */
297 private Bible bible1;
298
299 /** The second Bible that we are checking */
300 private Bible bible2;
301
302 /** Is it OK to carry on */
303 private boolean alive = true;
304 }