/** *######################################################################### * * A component of the Gatherer application, part of the Greenstone digital * library suite from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * *

* * Author: John Thompson, Greenstone Digital Library, University of Waikato * *

* * Copyright (C) 1999 New Zealand Digital Library Project * *

* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * *

* * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * *

* * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *######################################################################## */ package org.greenstone.gatherer.shell; import java.awt.Component; import java.util.ArrayList; import org.greenstone.gatherer.Configuration; import org.greenstone.gatherer.DebugStream; import org.greenstone.gatherer.Dictionary; import org.greenstone.gatherer.Gatherer; import org.greenstone.gatherer.cdm.CollectionDesignManager; import org.greenstone.gatherer.gui.GProgressBar; import org.greenstone.gatherer.util.StaticStrings; /** This implementation of GShellProgressMonitor is designed to parse and translate the progress of a buildcol.pl call. * @author John Thompson, Greenstone Digital Library, University of Waikato * @version 2.3 */ /* Wendy's feeble attempt at writing a schedule progress monitor. While it's not really needed, I'm writing it so that the schedule.pl prompts will go away. ;) This also may need other "ELEMENTS" added to it. */ public class GScheduleProgressMonitor implements GShellProgressMonitor { /** The minimum value = 0 */ static final private int MIN = 0; /** In order to get a smoothish progress bar, set the maximum to a large number = 1000000 */ static final private int MAX = 1000000; /** The various states the Schedule progress state machine can be in, starting at the base state. There are only two stages - perl script generation and cron building - so i'm not sure we need too many steps. */ static final int BASE = -1; static final int SCHEDULE = 0; static final int DONE = 1; /** Now the language independant sentinel strings. */ static final String SCHEDULE_ELEMENT = "Schedule"; static final String SCHEDULE_DELETE = "Delete"; static final String SCHEDULE_DONE="Done"; static final private String ARGUMENT_ATTRIBUTE = "a"; static final private String CLASSIFIER_ATTRIBUTE = "c"; static final private String PLUGIN_ATTRIBUTE = "p"; /** Indicates if the GUI has asked the process this object monitors to stop. */ private boolean stop = false; /** The current number of stages we have completed. */ private int current_stages = 0; /** The number of stages we are expecting to complete. */ private int expected_stages = 0; private int threshold = Configuration.LIBRARIAN_MODE; /** The current state we are in. The state will change depending on the next flag recieved. */ private int state = BASE; /** The progress bar this monitor updates. */ //private GProgressBar progress_bar; /** A progress bar that is shared between this this listener and the Import and build monitor. not sure we need this. */ //private GProgressBar shared_progress_bar; /** Construct a new GScheduleProgressMonitor. */ public GScheduleProgressMonitor() { //this.shared_progress_bar = shared_progress_bar; //progress_bar = new GProgressBar(); //progress_bar.setMaximum(MAX); //progress_bar.setMinimum(MIN); //progress_bar.setString(null); //progress_bar.setStringPainted(true); //setValue(MIN); } /** Method to register a new progress bar with this monitor. * @param progress_bar The new GProgressBar. */ /*note - we don't really need this. Wendy */ public void addProgressBar(GProgressBar progress_bar) { //this.progress_bar = progress_bar; //progress_bar.setMaximum(MAX); //progress_bar.setMinimum(MIN); //progress_bar.setStringPainted(false); //progress_bar.setString(null); //setValue(MIN); } /** 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. * @return A int with a value of zero if and only if the script was successful. */ public int exitValue() { if(state == BASE) { return 0; } return 1; } /** Method to retrieve whatever control is being used as the progress indicator. Usually a GProgressBar but there may be others implemented later. * @return A Component on which the progress of the process is being displayed. */ public Component getProgress() { //return progress_bar; return null; } public GProgressBar getSharedProgress() { //return shared_progress_bar; //try returning null; return null; } public void messageOnProgressBar(String message) { //if (message!=null && !message.equals("")) { //progress_bar.setString(message); //shared_progress_bar.setString(message); //} //else { //progress_bar.setString(null); //shared_progress_bar.setString(null); //} } /** Method to determine the state of the stop flag, which may be set by the visual component that created this monitor. * @return A boolean indicating if the process has been asked to stop. */ public synchronized boolean hasSignalledStop() { return stop; } /** Inform the progress bar that it should programatically increment progress by one step. */ public void increment() { // I'm not sure we really need this for scheduling, so i'm going to ignore it for now. } /** This method is used to 'feed in' a line of text captured from the process. * @param queue a queue which at the moment should contain a single GShellEvent */ public void process(ArrayList queue) { GShellEvent event = (GShellEvent) queue.get(0); // Remove 'schedule.pl> ' bit String line = event.getMessage(); line = line.substring(line.indexOf(StaticStrings.GREATER_THAN_CHARACTER) + 1); line = line.trim(); // We are only really interested in processing pseudo-XML tags if(line.startsWith(StaticStrings.LESS_THAN_CHARACTER) && line.endsWith(StaticStrings.GREATER_THAN_CHARACTER)) { // All events are vetoed event.veto(); // Create a new element from it GShellElement element = new GShellElement(line); // Now change states within the state machine as appropriate. A state change may subsequently incur a progress update. String name = null; String value = null; name = element.getElementName(); if(name.equals(SCHEDULE_ELEMENT)) { //progress_bar.setIndeterminate(false); // Produce a lower detail message if required if(Configuration.getMode() <= threshold && !stop) { queue.add(new GShellEvent(event.getSource(), 0, event.getType(), Dictionary.get("GShell.Schedule.ScheduleBegun1"), event.getStatus())); } } else if(name.equals(SCHEDULE_DELETE)) { if(Configuration.getMode() <= threshold) { queue.add(new GShellEvent(event.getSource(), 0, event.getType(), Dictionary.get("GShell.Schedule.ScheduleDelete"), event.getStatus())); } } else if(name.equals(SCHEDULE_DONE)) { if(Configuration.getMode() <= threshold) { queue.add(new GShellEvent(event.getSource(), 0, event.getType(), Dictionary.get("GShell.Schedule.ScheduleComplete1"), event.getStatus())); } } else { // Unknown command, go indeterminate DebugStream.println("Unknown name: " + name); //progress_bar.setIndeterminate(true); } } // 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 else if(Configuration.getMode() <= threshold) { event.veto(); } } public void reset() { current_stages = 0; expected_stages = 0; //progress_bar.setIndeterminate(false); //progress_bar.setString(null); setValue(MIN); state = BASE; //progress_bar.updateUI(); } public void saving() { } public void setSharedProgressBar(GProgressBar shared_progress_bar) { //this.shared_progress_bar = shared_progress_bar; } /** 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. * @param state The desired state of the stop flag as a boolean. */ public synchronized void setStop(boolean state) { this.stop = state; //progress_bar.setIndeterminate(false); } /** This method resets this monitor to the start, reseting the process parsing and progress bar. * TODO Everthing. */ public void start() { stop = false; setValue(MIN); expected_stages = 1; // Always compress text, create info database and auxiliary creation } /** This method indicates the process is complete. * TODO Everthing. */ public void stop() { //progress_bar.setIndeterminate(false); setValue(MAX); } private void setValue(int value) { //progress_bar.setValue(value); // 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. //if(value > MIN) { // shared_progress_bar.setValue(MAX + value); //} } }