source: trunk/gli/src/org/greenstone/gatherer/shell/GBuildProgressMonitor.java@ 10530

Last change on this file since 10530 was 10530, checked in by kjdon, 19 years ago

modified to use new searchtypemanager isSearchTypeEnabled instead of isMGPPEnabled

  • Property svn:keywords set to Author Date Id Revision
File size: 21.3 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * <BR><BR>
9 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37package org.greenstone.gatherer.shell;
38
39import java.awt.Component;
40import java.util.ArrayList;
41import javax.swing.JProgressBar;
42import org.greenstone.gatherer.Configuration;
43import org.greenstone.gatherer.DebugStream;
44import org.greenstone.gatherer.Dictionary;
45import org.greenstone.gatherer.Gatherer;
46import org.greenstone.gatherer.cdm.CollectionDesignManager;
47import org.greenstone.gatherer.util.StaticStrings;
48/** This implementation of <i>GShellProgressMonitor</i> is designed to parse and translate the progress of a buildcol.pl call.
49 * @author John Thompson, Greenstone Digital Library, University of Waikato
50 * @version 2.3
51 */
52public class GBuildProgressMonitor
53 implements GShellProgressMonitor {
54 /** The minimum value = 0 */
55 static final private int MIN = 0;
56 /** In order to get a smoothish progress bar, set the maximum to a large number = 1000000 */
57 static final private int MAX = 1000000;
58 /** The various states the build progress state machine can be in, starting at the base state. */
59 static final int BASE = -1;
60 static final int BUILD = 0;
61 static final int COMPRESSTEXT = 10;
62 static final int COMPRESSTEXT_COLLECTTEXTSTATS = 11;
63 static final int COMPRESSTEXT_CREATINGCOMPRESS = 12;
64 static final int COMPRESSTEXT_COMPRESSINGTEXT = 13;
65 static final int INDEX = 20;
66 static final int INDEX_CREATINGINDEXDIC = 21;
67 static final int INDEX_INVERTINGTEXT = 22;
68 static final int INDEX_CREATETHEWEIGHTS = 23;
69 static final int INDEX_CREATESTEMMEDDIC = 24;
70 static final int INDEX_CREATINGSTEMINDX = 25;
71 static final int CREATEINFODATA = 30;
72 static final int PHIND = 40;
73 static final int PHIND_EXTRACTINGVOCAB = 41;
74 static final int PHIND_EXTRACTINGPHRASE = 42;
75 static final int PHIND_SORTANDRENUMBER = 43;
76 static final int PHIND_PHRASEDATABASES = 44;
77 static final int PHIND_WORDLEVELINDEXES = 45;
78 static final int PHIND_DOCINFODATABASES = 46;
79 static final int CREATINGAUXILARY = 50;
80 /** Now the language independant sentinel strings. */
81 static final String BUILD_ELEMENT = "Build";
82 static final String COLLECTTEXTSTATS_VALUE = "CollectTextStats";
83 static final String COMPRESSINGTEXT_VALUE = "CompressingText";
84 static final String COMPRESSTEXT_VALUE = "CompressText";
85 static final String CREATINGAUXILARY_VALUE = "CreatingAuxilary";
86 static final String CREATINGCOMPRESS_VALUE = "CreatingCompress";
87 static final String CREATINGINDEXDIC_VALUE = "CreatingIndexDic";
88 static final String CREATINGSTEMINDX_VALUE = "CreatingStemIndx";
89 static final String CREATEINFODATA_VALUE = "CreateInfoData";
90 static final String CREATESTEMMEDDIC_VALUE = "CreateStemmedDic";
91 static final String CREATETHEWEIGHTS_VALUE = "CreateTheWeights";
92 static final String DOCINFODATABASES_VALUE = "DocInfoDatabases";
93 static final String EXTRACTINGPHRASE_VALUE = "ExtractingPhrase";
94 static final String EXTRACTINGVOCAB_VALUE = "ExtractingVocab";
95 static final String FATALERROR_ELEMENT = "FatalError";
96 static final String INDEX_VALUE = "Index";
97 static final String INVERTINGTEXT_VALUE = "InvertingText";
98 static final String NAME_ATTRIBUTE = "name";
99 static final String PHASE_ELEMENT = "Phase";
100 static final String PHIND_VALUE = "Phind";
101 static final String PHRASEDATABASES_VALUE = "PhraseDatabases";
102 static final String SKIPCREATINGCOMP_VALUE = "SkipCreatingComp";
103 static final String SORTANDRENUMBER_VALUE = "SortAndRenumber";
104 static final String SOURCE_ATTRIBUTE = "source";
105 static final String STAGE_ELEMENT = "Stage";
106 static final String WARNING_ELEMENT = "Warning";
107 static final String WORDLEVELINDEXES_VALUE = "WordLevelIndexes";
108 /** Indicates if the GUI has asked the process this object monitors to stop. */
109 private boolean stop = false;
110 /** The current number of stages we have completed. */
111 private int current_stages = 0;
112 /** The number of stages we are expecting to complete. */
113 private int expected_stages = 0;
114
115 private int threshold = Configuration.SYSTEMS_MODE;
116 /** The current state we are in. The state will change depending on the next flag recieved. */
117 private int state = BASE;
118 /** The progress bar this monitor updates. */
119 private JProgressBar progress_bar;
120 /** A progress bar that is shared between this this listener and the Import monitor. */
121 private JProgressBar shared_progress_bar;
122
123 /** Construct a new GBuildProgressMonitor. */
124 public GBuildProgressMonitor(JProgressBar shared_progress_bar) {
125 this.shared_progress_bar = shared_progress_bar;
126 progress_bar = new JProgressBar();
127 progress_bar.setMaximum(MAX);
128 progress_bar.setMinimum(MIN);
129 progress_bar.setString(null);
130 progress_bar.setStringPainted(true);
131 setValue(MIN);
132 }
133
134 /** Method to register a new progress bar with this monitor.
135 * @param progress_bar The new <strong>JProgressBar</strong>.
136 */
137 public void addProgressBar(JProgressBar progress_bar) {
138 this.progress_bar = progress_bar;
139 progress_bar.setMaximum(MAX);
140 progress_bar.setMinimum(MIN);
141 progress_bar.setStringPainted(false);
142 progress_bar.setString(null);
143 setValue(MIN);
144 }
145
146 /** Determine the script exit value according to the progress monitor. This gets around a problem where several script failures actually result with a successful exit value.
147 * @return A <i>int</i> with a value of zero if and only if the script was successful.
148 */
149 public int exitValue() {
150 if(state == BASE) {
151 return 0;
152 }
153 return 1;
154 }
155 /** Method to retrieve whatever control is being used as the progress indicator. Usually a <strong>JProgressBar</strong> but there may be others implemented later.
156 * @return A <strong>Component</strong> on which the progress of the process is being displayed.
157 */
158 public Component getProgress() {
159 return progress_bar;
160 }
161
162 public JProgressBar getSharedProgress() {
163 return shared_progress_bar;
164 }
165
166 public void messageOnProgressBar(String message)
167 {
168 if ((message!=null) & (message!="")) {
169 progress_bar.setString(message);
170 shared_progress_bar.setString(message);
171 }
172 else {
173 progress_bar.setString(null);
174 shared_progress_bar.setString(null);
175 }
176 }
177
178 /** Method to determine the state of the stop flag, which may be set by the visual component that created this monitor.
179 * @return A <strong>boolean</strong> indicating if the process has been asked to stop.
180 */
181 public synchronized boolean hasSignalledStop() {
182 return stop;
183 }
184 /** Inform the progress bar that it should programatically increment progress by one step. */
185 public void increment() {
186 // There is no reason this should be called for a build.
187 }
188
189 /** This method is used to 'feed in' a line of text captured from the process.
190 * @param queue a queue which at the moment should contain a single GShellEvent
191 */
192 public void process(ArrayList queue) {
193 GShellEvent event = (GShellEvent) queue.get(0);
194 // Remove 'build.pl> ' bit
195 String line = event.getMessage();
196 line = line.substring(line.indexOf(StaticStrings.GREATER_THAN_CHARACTER) + 1);
197 line = line.trim();
198 // We are only really interested in processing pseudo-XML tags
199 if(line.startsWith(StaticStrings.LESS_THAN_CHARACTER) && line.endsWith(StaticStrings.GREATER_THAN_CHARACTER)) {
200 // All events are vetoed
201 event.veto();
202
203 // Create a new element from it
204 GShellElement element = new GShellElement(line);
205 // Now change states within the state machine as appropriate. A state change may subsequently incur a progress update.
206 String name = null;
207 String value = null;
208 switch(state) {
209 case BASE:
210 // The only thing we would expect is a build message
211 name = element.getElementName();
212 if(name.equals(BUILD_ELEMENT)) {
213 progress_bar.setIndeterminate(false);
214 state = BUILD;
215 // Produce a lower detail message if required
216 if(Configuration.getMode() <= threshold && !stop) {
217 queue.add(new GShellEvent(event.getSource(), 0, event.getType(), Dictionary.get("GShell.Build.BuildBegun1"), event.getStatus()));
218 }
219 }
220 else {
221 // Unknown command, go indeterminate
222 DebugStream.println("Unknown name: " + name);
223 progress_bar.setIndeterminate(true);
224 }
225 name = null;
226 break;
227 case BUILD:
228 // The only thing we would expect is a stage element
229 name = element.getElementName();
230 if(name.equals(STAGE_ELEMENT)) {
231 progress_bar.setIndeterminate(false);
232 // Now we determine what stage we are moving to
233 value = element.getAttribute(NAME_ATTRIBUTE);
234 if(value.equals(COMPRESSTEXT_VALUE)) {
235 state = COMPRESSTEXT;
236 if(Configuration.getMode() <= threshold) {
237 queue.add(new GShellEvent(event.getSource(), 0, event.getType(), Dictionary.get("GShell.Build.CompressText"), event.getStatus()));
238 }
239 }
240 else if(value.equals(INDEX_VALUE)) {
241 state = INDEX;
242 if(Configuration.getMode() <= threshold) {
243 String args[] = new String[1];
244 args[0] = element.getAttribute(SOURCE_ATTRIBUTE);
245 queue.add(new GShellEvent(event.getSource(), 0, event.getType(), Dictionary.get("GShell.Build.Index", args), event.getStatus()));
246 args = null;
247 }
248 }
249 else if(value.equals(CREATEINFODATA_VALUE)) {
250 state = CREATEINFODATA;
251 if(Configuration.getMode() <= threshold) {
252 queue.add(new GShellEvent(event.getSource(), 0, event.getType(), Dictionary.get("GShell.Build.InfoDatabase"), event.getStatus()));
253 }
254 }
255 else if(value.equals(PHIND_VALUE)) {
256 state = PHIND;
257 if(Configuration.getMode() <= threshold) {
258 queue.add(new GShellEvent(event.getSource(), 0, event.getType(), Dictionary.get("GShell.Build.Phind"), event.getStatus()));
259 }
260 }
261 else if(value.equals(CREATINGAUXILARY_VALUE)) {
262 state = CREATINGAUXILARY;
263 if(Configuration.getMode() <= threshold) {
264 queue.add(new GShellEvent(event.getSource(), 0, event.getType(), Dictionary.get("GShell.Build.Auxilary"), event.getStatus()));
265 }
266 }
267 else {
268 // Unknown command, go indeterminate
269 DebugStream.println("Unknown value: " + value);
270 progress_bar.setIndeterminate(true);
271 }
272 value = null;
273 }
274 // The build end message indicates a successfulish build.
275 else if(name.equals(BUILD_ELEMENT) && element.isClosed()) {
276 progress_bar.setIndeterminate(false);
277 setValue(MAX);
278 state = BASE;
279 if(Configuration.getMode() <= threshold) {
280 queue.add(new GShellEvent(event.getSource(), 0, event.getType(), Dictionary.get("GShell.Build.BuildComplete1"), event.getStatus()));
281 }
282 }
283 else {
284 // Unknown command, go indeterminate
285 DebugStream.println("Unknown name: " + name);
286 progress_bar.setIndeterminate(true);
287 }
288 name = null;
289 break;
290 case COMPRESSTEXT:
291 // We are either dealing with a phase, aa fatal error or an end stage
292 name = element.getElementName();
293 if(name.equals(PHASE_ELEMENT)) {
294 // There are three phases within compressing text (or of four possible ones)
295 value = element.getAttribute(NAME_ATTRIBUTE);
296 if(value.equals(COLLECTTEXTSTATS_VALUE)) {
297 // Nothing to do
298 }
299 else if(value.equals(CREATINGCOMPRESS_VALUE) || value.equals(SKIPCREATINGCOMP_VALUE)) {
300 // One third complete
301 progress_bar.setIndeterminate(false);
302 setValue((int)(((double)current_stages + 0.3d) * MAX) / expected_stages);
303 }
304 else if(value.equals(COMPRESSINGTEXT_VALUE)) {
305 // Two thirds complete
306 progress_bar.setIndeterminate(false);
307 setValue((int)(((double)current_stages + 0.6d) * MAX) / expected_stages);
308 }
309 else {
310 // Unknown command, go indeterminate
311 DebugStream.println("Unknown value: " + value);
312 progress_bar.setIndeterminate(true);
313 }
314 value = null;
315 }
316 // Note that a fatal error is always followed by an end-stage, but not an end build. Thus the final state will be build (not base) and calls to exitValue() with indicate failure.
317 else if(name.equals(FATALERROR_ELEMENT)) {
318 // On simplier modes produce a meaningful message
319 queue.add(new GShellEvent(event.getSource(), 0, event.getType(), Dictionary.get("GShell.Build.FatalError"), event.getStatus()));
320 }
321 else if(name.equals(STAGE_ELEMENT) && element.isClosed()) {
322 // Increase progress so that stage is complete.
323 current_stages++;
324 progress_bar.setIndeterminate(false);
325 setValue((current_stages * MAX) / expected_stages);
326 state = BUILD;
327 }
328 else {
329 // Unknown command, go indeterminate
330 DebugStream.println("Unknown name: " + name);
331 progress_bar.setIndeterminate(true);
332 }
333 name = null;
334 break;
335 case INDEX:
336 /** @todo - If on lower modes output a meaningful message. */
337 name = element.getElementName();
338 if(name.equals(PHASE_ELEMENT)) {
339 value = element.getAttribute(NAME_ATTRIBUTE);
340 if(value.equals(CREATINGINDEXDIC_VALUE)) {
341 // Nothing to do
342 }
343 else if(value.equals(INVERTINGTEXT_VALUE)) {
344 // One fifth complete
345 progress_bar.setIndeterminate(false);
346 setValue((int)(((double)current_stages + 0.2d) * MAX) / expected_stages);
347 }
348 else if(value.equals(CREATETHEWEIGHTS_VALUE)) {
349 // Two fifths complete
350 progress_bar.setIndeterminate(false);
351 setValue((int)(((double)current_stages + 0.4d) * MAX) / expected_stages);
352 }
353 else if(value.equals(CREATESTEMMEDDIC_VALUE)) {
354 // Three fifths complete
355 progress_bar.setIndeterminate(false);
356 setValue((int)(((double)current_stages + 0.6d) * MAX) / expected_stages);
357 }
358 else if(value.equals(CREATINGSTEMINDX_VALUE)) {
359 // Four fifths complete
360 progress_bar.setIndeterminate(false);
361 setValue((int)(((double)current_stages + 0.8d) * MAX) / expected_stages);
362 }
363 else {
364 // Unknown command, go indeterminate
365 DebugStream.println("Unknown value: " + value);
366 progress_bar.setIndeterminate(true);
367 }
368 value = null;
369 }
370 else if(name.equals(WARNING_ELEMENT)) {
371 /** @todo - If on lower modes output a meaningful message. */
372 }
373 // Note that a fatal error is always followed by an end-stage, but not an end build. Thus the final state will be build (not base) and calls to exitValue() with indicate failure.
374 else if(name.equals(FATALERROR_ELEMENT)) {
375 // On lower modes output a meaningful message.
376
377 }
378 else if(name.equals(STAGE_ELEMENT) && element.isClosed()) {
379 // Increase progress so that stage is complete.
380 current_stages++;
381 progress_bar.setIndeterminate(false);
382 setValue((current_stages * MAX) / expected_stages);
383 state = BUILD;
384 }
385 else {
386 // Unknown command, go indeterminate
387 DebugStream.println("Unknown name: " + name);
388 progress_bar.setIndeterminate(true);
389 }
390 name = null;
391 break;
392 case PHIND:
393 name = element.getElementName();
394 if(name.equals(PHASE_ELEMENT)) {
395 value = element.getAttribute(NAME_ATTRIBUTE);
396 if(value.equals(EXTRACTINGVOCAB_VALUE)) {
397 // Nothing to do
398 }
399 else if(value.equals(EXTRACTINGPHRASE_VALUE)) {
400 // One sixth complete
401 progress_bar.setIndeterminate(false);
402 setValue((int)(((double)current_stages + 0.16d) * MAX) / expected_stages);
403 }
404 else if(value.equals(SORTANDRENUMBER_VALUE)) {
405 // Two sixths complete
406 progress_bar.setIndeterminate(false);
407 setValue((int)(((double)current_stages + 0.33d) * MAX) / expected_stages);
408 }
409 else if(value.equals(PHRASEDATABASES_VALUE)) {
410 // Three sixths complete
411 progress_bar.setIndeterminate(false);
412 setValue((int)(((double)current_stages + 0.5d) * MAX) / expected_stages);
413 }
414 else if(value.equals(WORDLEVELINDEXES_VALUE)) {
415 // Four sixths complete
416 progress_bar.setIndeterminate(false);
417 setValue((int)(((double)current_stages + 0.66d) * MAX) / expected_stages);
418 }
419 else if(value.equals(DOCINFODATABASES_VALUE)) {
420 // Five sixths complete
421 progress_bar.setIndeterminate(false);
422 setValue((int)(((double)current_stages + 0.83d) * MAX) / expected_stages);
423 }
424 else {
425 // Unknown command, go indeterminate
426 DebugStream.println("Unknown value: " + value);
427 progress_bar.setIndeterminate(true);
428 }
429 value = null;
430 }
431 else if(name.equals(STAGE_ELEMENT) && element.isClosed()) {
432 // Increase progress so that stage is complete.
433 current_stages++;
434 progress_bar.setIndeterminate(false);
435 setValue((current_stages * MAX) / expected_stages);
436 state = BUILD;
437 }
438 else {
439 // Unknown command, go indeterminate
440 DebugStream.println("Unknown name: " + name);
441 progress_bar.setIndeterminate(true);
442 }
443 name = null;
444 break;
445 case CREATEINFODATA:
446 case CREATINGAUXILARY:
447 name = element.getElementName();
448 if(name.equals(STAGE_ELEMENT) && element.isClosed()) {
449 // Another stage complete
450 current_stages++;
451 progress_bar.setIndeterminate(false);
452 setValue((current_stages * MAX) / expected_stages);
453 state = BUILD;
454 }
455 else {
456 // Unknown command, go indeterminate
457 DebugStream.println("Unknown name: " + name);
458 progress_bar.setIndeterminate(true);
459 }
460 name = null;
461 break;
462 default:
463 // Unknown command, go indeterminate
464 DebugStream.println("Unknown name: " + name);
465 progress_bar.setIndeterminate(true);
466 }
467 }
468 // If we are dealing with lower detail modes then veto any other messages. We do this here as the progress monitors are garuenteed to recieve this message before anything else
469 else if(Configuration.getMode() <= threshold) {
470 event.veto();
471 }
472 }
473
474 public void reset() {
475 current_stages = 0;
476 expected_stages = 0;
477 progress_bar.setIndeterminate(false);
478 progress_bar.setString(null);
479 setValue(MIN);
480 state = BASE;
481 progress_bar.updateUI();
482 }
483
484 public void saving() {
485 }
486
487 public void setSharedProgressBar(JProgressBar shared_progress_bar) {
488 this.shared_progress_bar = shared_progress_bar;
489 }
490
491 /** Since the creator of this process monitor is actually in the GUI, this class provides the simpliest way to send a cancel process message between the two.
492 * @param state The desired state of the stop flag as a <strong>boolean</strong>.
493 */
494 public synchronized void setStop(boolean state) {
495 this.stop = state;
496 progress_bar.setIndeterminate(false);
497 }
498 /** This method resets this monitor to the start, reseting the process parsing and progress bar.
499 * TODO Everthing.
500 */
501 public void start() {
502 stop = false;
503 setValue(MIN);
504 expected_stages = 3; // Always compress text, create info database and auxiliary creation
505 // Retrieve cdm.
506 CollectionDesignManager cdm = Gatherer.c_man.getCollection().cdm;
507 // If we are using MGPP the number of indexes is always 1
508 if(cdm.searchtype_manager.isMGPP()) {
509 expected_stages = expected_stages + 1;
510 } else if (cdm.searchtype_manager.isLucene()) {
511 // lucene no of indexes == number of levels
512 int num_levels = cdm.index_manager.getNumLevels();
513 if (num_levels == 0) num_levels = 1;
514 expected_stages = expected_stages + num_levels;
515 }
516 else {
517 int num_indexes = cdm.index_manager.getSize();
518 int num_partitions = cdm.subcollectionindex_manager.getSize();
519 if(num_partitions > 0) {
520 num_indexes = num_indexes * num_partitions;
521 }
522 int num_languages = cdm.language_manager.getSize();
523 if(num_languages > 0) {
524 num_indexes = num_indexes * num_languages;
525 }
526 expected_stages = expected_stages + num_indexes;
527 }
528 // And if we have a phind classifier, we have one further index
529 if(cdm.classifier_manager.isPhindClassifierAssigned()) {
530 expected_stages = expected_stages + 1;
531 }
532 cdm = null;
533 }
534 /** This method indicates the process is complete.
535 * TODO Everthing.
536 */
537 public void stop() {
538 progress_bar.setIndeterminate(false);
539 setValue(MAX);
540 }
541
542 private void setValue(int value) {
543 progress_bar.setValue(value);
544 // Incrementing the shared progress bar is a little more problematic as we may very well be trying to set it to MIN but instead set it to halfway if we're not careful.
545 if(value > MIN) {
546 shared_progress_bar.setValue(MAX + value);
547 }
548 }
549}
550
Note: See TracBrowser for help on using the repository browser.