source: trunk/gli/src/org/greenstone/gatherer/shell/GShell.java@ 9348

Last change on this file since 9348 was 9348, checked in by mdewsnip, 19 years ago

Moved some strings out of the resource bundle into here.

  • Property svn:keywords set to Author Date Id Revision
File size: 26.4 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.io.*;
40import java.net.*;
41import java.util.ArrayList;
42import java.util.Enumeration;
43import javax.swing.*;
44import javax.swing.event.*;
45import javax.swing.tree.*;
46import org.greenstone.gatherer.Configuration;
47import org.greenstone.gatherer.DebugStream;
48import org.greenstone.gatherer.Dictionary;
49import org.greenstone.gatherer.Gatherer;
50import org.greenstone.gatherer.GathererApplet;
51import org.greenstone.gatherer.cdm.CollectionConfiguration;
52import org.greenstone.gatherer.cdm.CollectionDesignManager;
53import org.greenstone.gatherer.cdm.CollectionMetaManager;
54import org.greenstone.gatherer.cdm.CollectionMeta;
55import org.greenstone.gatherer.metadata.DocXMLFileManager;
56import org.greenstone.gatherer.util.StaticStrings;
57import org.greenstone.gatherer.util.Utility;
58
59/** The <strong>GShell</strong> is reponsible for running a separately threaded process in the command shell. This is necessary for executing the Perl Scripts and also for other system related funcitonality.
60 */
61public class GShell
62 extends Thread {
63 /** A flag used to determine if this process has been asked to cancel. */
64 private boolean cancel = false;
65 /** The list of listeners associated with this class. */
66 private EventListenerList listeners = null;
67 /** The current status of this shell process. */
68 private int status = -1;
69 /** The type of message being sent. */
70 private int msg_type = -1;
71 /** The type of shell process. */
72 private int type = -1;
73 /** The caller of this process, and thus the class most interested in messages. */
74 private GShellListener caller = null;
75 /** The progress monitor associated with this process. */
76 private GShellProgressMonitor progress = null;
77 /** Arguments to be given to the process (including the executable you are calling. */
78 private String args[] = null;
79 /** Element in process type enumeration. */
80 static final public int BUILD = 0;
81 /** Element in process type enumeration. */
82 static final public int IMPORT = 1;
83 /** Element in process type enumeration. */
84 static final public int NEW = 2;
85 /** Element in process type enumeration. */
86 static final public int EXPORTAS = 3;
87 /** Element in process type enumeration. */
88 static final public int CDIMAGE = 4;
89 /** Element in process type enumeration. */
90 static final public int CONVERT = 5;
91 /** Element in process type enumeration. */
92 static final public int OTHER = 6;
93 /** Element in status type enumeration. */
94 static final public int ERROR = 0;
95 /** Element in status type enumeration. */
96 static final public int OK = 1;
97 static final public int CANCELLED = 2;
98 /** Element in process type name enumeration. */
99 static public String GSHELL_BUILD = "gshell_build";
100 /** Element in process type name enumeration. */
101 static public String GSHELL_IMPORT = "gshell_import";
102 /** Element in process type name enumeration. */
103 static public String GSHELL_NEW = "gshell_new";
104 /** Element in process type name enumeration */
105 static public String GSHELL_EXPORTAS = "gshell_exportas";
106 /** Element in process type name enumeration */
107 static public String GSHELL_CDIMAGE = "gshell_cdimage";
108 /** Element in process type name enumeration */
109 static public String GSHELL_CONVERT = "gshell_convert";
110 /** Element in process type name enumeration */
111 static public String GSHELL_OTHER = "gshell_other";
112
113 /** Determine if the given process is still executing. It does this by attempting to throw an exception - not the most efficient way, but the only one as far as I know
114 * @param process the Process to test
115 * @return true if it is still executing, false otherwise
116 */
117 static public boolean processRunning(Process process) {
118 boolean process_running = false;
119
120 try {
121 process.exitValue(); // This will throw an exception if the process hasn't ended yet.
122 }
123 catch(IllegalThreadStateException itse) {
124 process_running = true;
125 }
126 catch(Exception exception) {
127 DebugStream.printStackTrace(exception);
128 }
129 return process_running;
130 }
131
132 /** Constructor gatherer all the data required to create a new process, and emit meaningfull messages.
133 * @param args A <strong>String[]</strong> containing the arguments to the process thread, including the name of the executable.
134 * @param type An <strong>int</strong> that indicates what group of processes this process belongs to, as some are treated slightly differently (i.e an IMPORT type process is always followed by a BUILD one).
135 * @param msg_type As process threads may be background (like a makecol.pl call) or important processes in their own right (such as an IMPORT-BUILD) we must be able to set what level messages posted by this class will have by usings this <strong>int</strong>.
136 * @param caller The default <i>GShellListener</i> that is interested in the progress of this process.
137 * @param progress The <i>GShellProgressMonitor</i> associated with this process.
138 * @param name A <strong>String</strong> identifier given to the process, for convience and debug reasons.
139 */
140 public GShell(String args[], int type, int msg_type, GShellListener caller, GShellProgressMonitor progress, String name) {
141 super(name);
142 this.args = args;
143 this.msg_type = msg_type;
144 this.type = type;
145 this.caller = caller;
146 this.progress = progress;
147 this.status = 0;
148 // Lower this jobs priority
149 this.setPriority(Thread.MIN_PRIORITY);
150 listeners = new EventListenerList();
151 listeners.add(GShellListener.class, caller);
152 }
153 /** This method adds another shell listener to this process.
154 * @param listener The new <i>GShellListener</i>.
155 */
156 public void addGShellListener(GShellListener listener) {
157 listeners.add(GShellListener.class, listener);
158 }
159 /** This method removes a certain shell listener from this process.
160 * @param listener The <i>GShellListener</i> to be removed.
161 */
162 /* private void removeGShellListener(GShellListener listener) {
163 listeners.remove(GShellListener.class, listener);
164 } */
165
166
167
168 protected boolean got_stream_char(InputStreamReader isr, StringBuffer line_buffer,
169 BufferedOutputStream bos) throws IOException
170 {
171 // Hopefully this doesn't block if the process is trying to write to STDOUT/STDERR.
172
173 boolean input_status = false;
174
175 if(isr.ready()) {
176 input_status = true;
177 int c = isr.read();
178 if(c == '\n' || c == '\r') {
179 if(line_buffer.length() > 0) {
180 String line = line_buffer.toString();
181 DebugStream.println("* " + line + " *");
182 fireMessage(type, typeAsString(type) + "> " + line, status, bos);
183 line = null;
184 line_buffer = new StringBuffer();
185 }
186 }
187 else {
188 line_buffer.append((char)c);
189 }
190 }
191
192 return input_status;
193 }
194
195
196 protected StringBuffer get_stream_char(InputStreamReader isr, StringBuffer line_buffer,
197 BufferedOutputStream bos) throws IOException
198 {
199 int c = isr.read();
200 ///atherer.println("isr: '" + (char) c + "'");
201 if(c == '\n' || c == '\r') {
202 if(line_buffer.length() > 0) {
203 String line = line_buffer.toString();
204 // DebugStream.println("* " + line + " *");
205 fireMessage(type, typeAsString(type) + "> " + line, status, bos);
206 line_buffer = new StringBuffer();
207 }
208 }
209 else {
210 line_buffer.append((char)c);
211 }
212
213 return line_buffer;
214 }
215
216
217 protected int check_for_error(String line, StringBuffer error_list,
218 int error_count)
219 {
220 if (line.startsWith("ERROR:")) {
221 error_count++;
222 if (error_count<10) {
223 error_list.append(line);
224 }
225 else if (error_count==10) {
226 error_list.append("...\n");
227 }
228 }
229 return error_count;
230 }
231
232
233 protected void runRemote(String[] args, BufferedOutputStream bos)
234 {
235 if(hasSignalledStop()) { return; }
236 int error_count = 0;
237 StringBuffer error_list = new StringBuffer();
238 try {
239 if (type == IMPORT) {
240 String col_name = args[args.length-1];
241 if (progress!=null) {
242 progress.messageOnProgressBar("Uploading data to server");
243 }
244
245 String collect_directory_path = Gatherer.getCollectDirectoryPath();
246
247 //Only upload the parts of the import folder (files/metadata) that has been changed.
248 if(Gatherer.c_man.getCollection().getFilesChanged()) {
249 // zip up import folder, but exclude metadata
250 Utility.zipup(collect_directory_path, col_name, "import", this, "", ".*metadata\\.xml");
251
252 if(hasSignalledStop()) { return; }
253 // upload it to gsdl server
254 GathererApplet.upload_url_zip(col_name, "import", "files", this);
255
256 Gatherer.c_man.getCollection().setFilesChanged(false);
257 System.err.println("Finished uploading files");
258 }
259 if(Gatherer.c_man.getCollection().getMetadataChanged()) {
260 // zip up metadata from import folder
261 Utility.zipup(collect_directory_path, col_name, "import", this, ".*metadata\\.xml", "");
262
263 if(hasSignalledStop()) { return; }
264 // upload it to gsdl server
265 GathererApplet.upload_url_zip(col_name, "import", "metadata", this);
266 Gatherer.c_man.getCollection().setMetadataChanged(false);
267 System.err.println("Finished uploading metadata.");
268 }
269
270 if(hasSignalledStop()) { return; }
271 // upload etc folder to server (need collect.cfg and any hfiles)
272 Utility.zipup(collect_directory_path, col_name, "etc", this, "", "");
273
274 if(hasSignalledStop()) { return; }
275 GathererApplet.upload_url_zip(col_name, "etc", "", this);
276
277 String collection_directory_path = Gatherer.c_man.getCollectionDirectoryPath(col_name);
278 File img_dir = new File(Gatherer.c_man.getCollectionImagesDirectoryPath());
279 if (img_dir.exists() && img_dir.list().length > 0) {
280 // upload images/ directory to server
281 if(hasSignalledStop()) { return; }
282 Utility.zipup(collect_directory_path, col_name, "images", this, "", "");
283
284 if(hasSignalledStop()) { return; }
285 GathererApplet.upload_url_zip(col_name, "images", "", this);
286
287 System.err.println("collect_directory_path: " + collect_directory_path);
288 System.err.println("col_name: " + col_name);
289 }
290
291 if(hasSignalledStop()) { return; }
292 // see if collection specific image needs uploading
293 CollectionMetaManager cmm
294 = CollectionDesignManager.collectionmeta_manager;
295
296 CollectionMeta icon_collection_collectionmeta
297 = cmm.getMetadatum(CollectionConfiguration.COLLECTIONMETADATA_ICONCOLLECTION_STR);
298 CollectionMeta icon_collection_small_collectionmeta
299 = cmm.getMetadatum(CollectionConfiguration.COLLECTIONMETADATA_ICONCOLLECTIONSMALL_STR);
300
301 String ics_text = icon_collection_collectionmeta.getValue(CollectionMeta.TEXT);
302 String icsc_text = icon_collection_small_collectionmeta.getValue(CollectionMeta.TEXT);
303 if ((ics_text != null) && (ics_text != "")) {
304 // Stub code for detecting when collectoin image changed
305 // => need to upload images
306 // System.err.println("**** ics_text = " + ics_text);
307 }
308
309 if (progress!=null) {
310 progress.messageOnProgressBar("");
311 }
312 }
313
314 if(hasSignalledStop()) { return; }
315 String perl_cmd = args[0];
316 int perl_cmd_root = perl_cmd.lastIndexOf(File.separator);
317
318 if (perl_cmd_root > 0) {
319 String perl_cmd_cut = perl_cmd.substring(perl_cmd_root+1);
320 perl_cmd = perl_cmd_cut;
321 }
322
323 String launch = Gatherer.cgiBase + "launch";
324 launch = launch + "?cmd=" + perl_cmd;
325
326 for(int i = 1; i<args.length; i++) {
327
328 String arg = args[i];
329
330 if (arg.equals("-collectdir") || arg.equals("-importdir")
331 || arg.equals("-builddir")) {
332 // skip it
333 i++;
334 continue;
335 }
336
337 launch += "&";
338
339 if(arg.startsWith(StaticStrings.MINUS_CHARACTER)) {
340 String name = arg.substring(1);
341 launch = launch + name + "=";
342 if (i+1<args.length-1) {
343 if (!args[i+1].startsWith(StaticStrings.MINUS_CHARACTER)) {
344 i++;
345 String val = URLEncoder.encode(args[i],"UTF-8");
346 launch = launch + val;
347 }
348 }
349 }
350 else {
351 launch = launch + "c=" + arg;
352 }
353 }
354
355 System.err.println("**** launch url = " + launch);
356 // fireMessage(type, Dictionary.get("GShell.Command") + ": " + launch, status, null); // ****
357
358 URL launch_url = new URL(launch);
359 URLConnection launch_connection = launch_url.openConnection();
360 InputStream stdis = launch_connection.getInputStream();
361 InputStreamReader stdisr = new InputStreamReader(stdis, "UTF-8");
362
363 BufferedReader stdbr = new BufferedReader(stdisr);
364
365 if (type == GShell.NEW) {
366 while(true) {
367 String line = stdbr.readLine();
368 if (line == null) { break; }
369 error_count = check_for_error(line,error_list,error_count);
370 }
371 }
372 else {
373 while(!hasSignalledStop()) {
374 String line = stdbr.readLine();
375 if (line == null) { break; }
376 error_count = check_for_error(line,error_list,error_count);
377 fireMessage(type, typeAsString(type) + "> " + line, status, bos);
378 }
379 //System.err.println("Wants to stop (1)."); //debug --Matthew
380 }
381 stdbr.close();
382
383 if (error_count>0) {
384 status = ERROR;
385 System.err.println(error_list);
386 if (type != GShell.NEW) {
387 fireMessage(type, typeAsString(type) + "> " + error_list, status, null);
388 }
389 }
390 else if(hasSignalledStop()) {
391 //User pressed the cancel button.
392 //Status already set in hasSignalledStop method.
393 }
394 else {
395 status = OK;
396 fireMessage(type, typeAsString(type) + "> " + Dictionary.get("GShell.Success"), status, null);
397 }
398
399
400 }
401 // Exception
402 catch (Exception exception) {
403 System.err.println("Exception in GShell.runRemote() - unexpected");
404 DebugStream.printStackTrace(exception);
405 status = ERROR;
406 }
407 }
408
409
410 protected void runLocal(String[] args, BufferedOutputStream bos)
411 {
412 try {
413 String command = "";
414 for(int i = 0; i < args.length; i++) {
415 command = command + args[i] + " ";
416 }
417
418 DebugStream.println("Command: "+command);
419 ///ystem.err.println("Command: " + command);
420 fireMessage(type, Dictionary.get("GShell.Command") + ": " + command, status, null);
421
422 Runtime rt = Runtime.getRuntime();
423 Process prcs = rt.exec(args);
424
425 InputStreamReader eisr = new InputStreamReader( prcs.getErrorStream(), "UTF-8" );
426 InputStreamReader stdisr = new InputStreamReader( prcs.getInputStream(), "UTF-8" );
427
428 StringBuffer eline_buffer = new StringBuffer();
429 StringBuffer stdline_buffer = new StringBuffer();
430
431 while(type != GShell.NEW && processRunning(prcs) && !hasSignalledStop()) {
432 // Hopefully this doesn't block if the process is trying to write to STDOUT.
433 if((eisr!=null) && eisr.ready()) {
434 eline_buffer = get_stream_char(eisr,eline_buffer,bos);
435 }
436 // Hopefully this won't block if the process is trying to write to STDERR
437 else if(stdisr.ready()) {
438 stdline_buffer = get_stream_char(stdisr,stdline_buffer,bos);
439 }
440 else {
441 try {
442 sleep(100);
443 }
444 catch(Exception exception) {
445 }
446 }
447 }
448
449 if(!hasSignalledStop()) {
450 // Of course, just because the process is finished doesn't
451 // mean the incoming streams are empty. Unfortunately I've
452 // got no chance of preserving order, so I'll process the
453 // error stream first, then the out stream
454 while(eisr.ready()) {
455 eline_buffer = get_stream_char(eisr,eline_buffer,bos);
456 }
457
458 while(stdisr.ready()) {
459 stdline_buffer = get_stream_char(stdisr,stdline_buffer,bos);
460 }
461
462 // Ensure that any messages still remaining in the string buffers are fired off.
463 if(eline_buffer.length() > 0) {
464 String eline = eline_buffer.toString();
465 //DebugStream.println("Last bit of eline: " + eline);
466 fireMessage(type, typeAsString(type) + "> " + eline, status, bos);
467 eline = null;
468 }
469
470 if(stdline_buffer.length() > 0) {
471 String stdline = stdline_buffer.toString();
472 //DebugStream.println("Last bit of stdline: " + stdline);
473 fireMessage(type, typeAsString(type) + "> " + stdline, status, null);
474 stdline = null;
475 }
476 }
477 else {
478 System.err.println("We've been asked to stop.");
479 }
480
481
482 if(!hasSignalledStop()) {
483 // Now display final message based on exit value
484
485 prcs.waitFor();
486
487 if(prcs.exitValue() == 0) {
488 status = OK;
489 fireMessage(type, typeAsString(type) + "> " + Dictionary.get("GShell.Success"), status, null);
490 }
491 else {
492 status = ERROR;
493 fireMessage(type, typeAsString(type) + "> " + Dictionary.get("GShell.Failure"), status, null);
494 }
495
496 eisr.close();
497 stdisr.close();
498 }
499 else {
500 // I need to somehow kill the child process. Unfortunately
501 // Thread.stop() and Process.destroy() both fail to do
502 // this. But now, thankx to the magic of Michaels 'close the
503 // stream suggestion', it works fine (no it doesn't!)
504 prcs.getInputStream().close();
505 prcs.getErrorStream().close();
506 prcs.getOutputStream().close();
507 prcs.destroy();
508 status = CANCELLED;
509 }
510 }
511 // Exception
512 catch (Exception exception) {
513 DebugStream.println("Exception in GShell.runLocal() - unexpected");
514 DebugStream.printStackTrace(exception);
515 status = ERROR;
516 }
517 }
518
519
520
521 /** Any threaded class must include this method to allow the thread body to be run. */
522 public void run() {
523
524 String col_name = args[args.length-1];
525
526 // Determine if the user has asked for an outfile.
527 String out_name = null;
528 BufferedOutputStream bos = null;
529 if(type == IMPORT || type == BUILD) {
530 if(type == IMPORT) {
531 out_name = (String) Gatherer.c_man.getCollection().import_options.getValue("out");
532 }
533 else {
534 out_name = (String) Gatherer.c_man.getCollection().build_options.getValue("out");
535 }
536 if(out_name != null && out_name.length() > 0) {
537 try {
538 bos = new BufferedOutputStream(new FileOutputStream(new File(out_name), true));
539 }
540 catch (Exception error) {
541 DebugStream.printStackTrace(error);
542 }
543 }
544 }
545
546 // Issue a processBegun event
547 fireProcessBegun(type, status);
548 if (Gatherer.isGsdlRemote) {
549 runRemote(args,bos);
550 }
551 else {
552 runLocal(args,bos);
553 }
554
555 if(status == OK) {
556 if (type == NEW) {
557 if (Gatherer.isGsdlRemote) {
558 GathererApplet.download_url_zip(col_name, ".", this, "", "");
559 if (!hasSignalledStop()) {
560 Utility.unzip(Gatherer.getCollectDirectoryPath(), col_name);
561 }
562 }
563 }
564 else if(type == IMPORT) {
565
566 // download the archives directory (if gsdl server is remote)
567 if (Gatherer.isGsdlRemote) {
568
569 if (progress!=null) {
570 progress.messageOnProgressBar("Downloading archive data from server");
571 }
572
573 Utility.delete(Gatherer.c_man.getCollectionArchivesDirectoryPath()); // remove current archives
574 //new File(Gatherer.c_man.getCollectionArchivesDirectoryPath()).mkdir(); //Make a clean dir
575 GathererApplet.download_url_zip(col_name, "archives", this, ".*doc\\.xml", "");
576 if (hasSignalledStop()) {
577 // Clean up, then exit
578 fireProcessComplete(type, status);
579 // Close bos
580 if(bos != null) {
581 try {
582 bos.close();
583 bos = null;
584 }
585 catch(Exception error) {
586 DebugStream.printStackTrace(error);
587 }
588 }
589 return;
590 }
591 Utility.unzip(Gatherer.getCollectDirectoryPath(), col_name);
592
593 if (progress!=null) {
594 progress.messageOnProgressBar("");
595 }
596 }
597
598 // Refresh the DocXMLFileManager
599 fireMessage(type, typeAsString(type) + "> " + Dictionary.get("GShell.Parsing_Metadata_Start"), status, null);
600 DocXMLFileManager.clearDocXMLFiles();
601 DocXMLFileManager.loadDocXMLFiles(new File(Gatherer.c_man.getCollectionArchivesDirectoryPath()));
602 fireMessage(type, typeAsString(type) + "> " + Dictionary.get("GShell.Parsing_Metadata_Complete"), status, null);
603 }
604
605 else if(type == BUILD) {
606 // download the building directory (if gsdl server is remote)
607 if (Gatherer.isGsdlRemote) {
608 if (progress!=null) {
609 progress.messageOnProgressBar("Downloading index data from server");
610 }
611
612 File buildDir = new File(Gatherer.c_man.getCollectionBuildingDirectoryPath());
613 Utility.delete(buildDir); // remove current build dir
614 //buildDir.mkdir(); //Make a clean dir
615 GathererApplet.download_url_zip(col_name, "building/build.cfg", this, "", ""); //Only need build.cfg
616 //Maybe change to GathererApplet.download_url_zip(col_name, "building", this, "build.cfg")
617 if (!hasSignalledStop()) {
618 Utility.unzip(Gatherer.getCollectDirectoryPath(), col_name);
619 }
620
621 if (progress!=null) {
622 progress.messageOnProgressBar("");
623 }
624 }
625 }
626 }
627
628 // We're done.
629 fireProcessComplete(type, status);
630 // Close bos
631 if(bos != null) {
632 try {
633 bos.close();
634 bos = null;
635 }
636 catch(Exception error) {
637 DebugStream.printStackTrace(error);
638 }
639 }
640 }
641 /** Method for firing a message to all interested listeners.
642 * @param type An <strong>int</strong> indicating the process type.
643 * @param message The message as a <strong>String</strong>.
644 * @param status An <strong>int</strong> specifying the current status of the process.
645 */
646 public void fireMessage(int type, String message, int status, BufferedOutputStream bos) {
647 GShellEvent event = new GShellEvent(this, 0, type, message, status);
648 // If there is a progress monitor attached, pass the event to it first. Note that we pass a queue of messages as the processing may cause one message to be split into several.
649 ArrayList message_queue = new ArrayList();
650 message_queue.add(event);
651 if(progress != null) {
652 progress.process(message_queue);
653 }
654 for(int j = 0; j < message_queue.size(); j++) {
655 GShellEvent current_event = (GShellEvent) message_queue.get(j);
656 // If the event hasn't been vetoed, pass it on to other listeners
657 if(!current_event.isVetoed()) {
658 Object[] concerned = listeners.getListenerList();
659 for(int i = 0; i < concerned.length ; i++) {
660 if(concerned[i] == GShellListener.class) {
661 ((GShellListener)concerned[i+1]).message(current_event);
662 }
663 }
664 concerned = null;
665 }
666 }
667 // And if we have a buffered output stream from error messages, send the message there
668 if(bos != null) {
669 try {
670 bos.write(message.getBytes(), 0, message.length());
671 }
672 catch(Exception exception) {
673 DebugStream.println("Exception in GShell.fireMessage() - unexpected");
674 DebugStream.printStackTrace(exception);
675 }
676 }
677 message_queue = null;
678 event = null;
679 }
680
681 /** Method for firing a process begun event which is called, strangly enough, when the process begins.
682 * @param type An <strong>int</strong> indicating the process type.
683 * @param status An <strong>int</strong> specifying the current status of the process.
684 */
685 protected void fireProcessBegun(int type, int status) {
686 // Start the progres monitor if available
687 if(progress != null) {
688 progress.start();
689 }
690 // Fire an event
691 GShellEvent event = new GShellEvent(this, 0, type, "", status);
692 Object[] concerned = listeners.getListenerList();
693 for(int i = 0; i < concerned.length ; i++) {
694 if(concerned[i] == GShellListener.class) {
695 ((GShellListener)concerned[i+1]).processBegun(event);
696 }
697 }
698 }
699 /** Method for firing a process complete event which is called, no surprise here, when the process ends.
700 * @param type An <strong>int</strong> indicating the process type.
701 * @param status An <strong>int</strong> specifying the current status of the process.
702 */
703 protected void fireProcessComplete(int type, int status) {
704 // Tidy up by stopping the progress bar. If it was cancelled then the cancel command has arrived via the progress bars and they don't need to be told again (it actually causes problems).
705 if(progress != null && status != CANCELLED) {
706 progress.stop();
707 }
708
709 // If we were cancelled, and we are lower details modes, fire off one last message.
710 if(status == CANCELLED && Configuration.getMode() <= Configuration.SYSTEMS_MODE) {
711 GShellEvent current_event = new GShellEvent(this, 0, type, Dictionary.get("GShell.Build.BuildCancelled"), status);
712 Object[] concerned = listeners.getListenerList();
713 for(int i = 0; i < concerned.length ; i++) {
714 if(concerned[i] == GShellListener.class) {
715 ((GShellListener)concerned[i+1]).message(current_event);
716 }
717 }
718 concerned = null;
719 }
720 // And firing off an event
721 GShellEvent event = new GShellEvent(this, 0, type, "", status);
722 Object[] concerned = listeners.getListenerList();
723 for(int i = 0; i < concerned.length ; i++) {
724 if(concerned[i] == GShellListener.class) {
725 ((GShellListener)concerned[i+1]).processComplete(event);
726 }
727 }
728 }
729
730 /** Method to determine if the user, via the progress monitor, has signalled stop.
731 * @return A <strong>boolean</strong> indicating if the user wanted to stop.
732 */
733 public boolean hasSignalledStop() {
734 boolean has_signalled_stop = false;
735 if(progress != null) {
736 has_signalled_stop = progress.hasSignalledStop();
737 }
738 if(has_signalled_stop) {
739 status = CANCELLED;
740 }
741 return has_signalled_stop;
742 }
743
744 /** Converts a type into a text representation.
745 * @param type An <strong>int</strong> which maps to a shell process type.
746 * @return A <strong>String</strong> which is the thread process's text name.
747 */
748 public String typeAsString(int type) {
749 String name = null;
750 switch(type) {
751 case BUILD:
752 name = "buildcol.pl";
753 break;
754 case IMPORT:
755 name = "import.pl";
756 break;
757 case NEW:
758 name = "mkcol.pl";
759 break;
760 case EXPORTAS:
761 name = "export.pl";
762 break;
763 case CDIMAGE:
764 name = "exportcol.pl";
765 break;
766 case CONVERT:
767 name = "convert_coll_from_gs2.pl";
768 break;
769 default:
770 name = "";
771 }
772 return name;
773 }
774}
Note: See TracBrowser for help on using the repository browser.