/**
*#########################################################################
*
* 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);
//}
}
}