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

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

GLI applet: collection building is now much happier about being cancelled. By Matthew Whyte.

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