source: trunk/gli/src/org/greenstone/gatherer/Gatherer.java@ 10248

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

A few fixes to previous changes for building collections remotely using a local GLI.

  • Property svn:keywords set to Author Date Id Revision
File size: 32.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 * Author: John Thompson, Greenstone Digital Library, University of Waikato
9 *
10 * Copyright (C) 1999 New Zealand Digital Library Project
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *########################################################################
26 */
27package org.greenstone.gatherer;
28
29import java.awt.*;
30import java.awt.event.*;
31import java.io.*;
32import java.lang.*;
33import java.net.*;
34import java.util.*;
35import javax.swing.*;
36import javax.swing.plaf.*;
37import javax.swing.text.*;
38import org.greenstone.gatherer.Configuration;
39import org.greenstone.gatherer.GAuthenticator;
40import org.greenstone.gatherer.cdm.ClassifierManager;
41import org.greenstone.gatherer.cdm.PluginManager;
42import org.greenstone.gatherer.collection.CollectionManager;
43import org.greenstone.gatherer.feedback.ActionRecorderDialog;
44import org.greenstone.gatherer.file.FileManager;
45import org.greenstone.gatherer.file.FileAssociationManager;
46import org.greenstone.gatherer.gui.GUIManager;
47import org.greenstone.gatherer.gui.URLField;
48import org.greenstone.gatherer.gui.WarningDialog;
49import org.greenstone.gatherer.util.JarTools;
50import org.greenstone.gatherer.util.StaticStrings;
51import org.greenstone.gatherer.util.Utility;
52
53
54/** Containing the top-level "core" for the Gatherer, this class is the
55 * common core for the GLI application and applet. It first parses the
56 * command line arguments, preparing to update the configuration as
57 * required. Next it loads several important support classes such as the
58 * Configuration and Dictionary. Finally it creates the other important
59 * managers and sends them on their way.
60 * @author John Thompson, Greenstone Digital Library, University of Waikato
61 * @version 2.3
62 */
63public class Gatherer
64{
65 static private Dimension size = new Dimension(800, 540);
66
67 /** Has the exit flag been set? */
68 public boolean exit = false;
69
70 /** All of the external applications that must exit before we close the Gatherer. */
71 public Vector apps = new Vector();
72 static private String non_standard_collect_directory_path = null;
73 static public String open_collection_file_path = null;
74 /** A public reference to the FileAssociationManager. */
75 static public FileAssociationManager assoc_man;
76 /** A public reference to the CollectionManager. */
77 static public CollectionManager c_man;
78 /** a reference to the Servlet Configuration is GS3 */
79 static public ServletConfiguration servlet_config;
80 /** A public reference to the FileManager. */
81 static public FileManager f_man;
82 /** A public reference to the GUIManager. */
83 static public GUIManager g_man = null;
84 static private boolean g_man_built = false;
85
86 /** A static reference to ourselves. */
87 static public Gatherer self;
88 /** We are using the GLI for GS3 */
89 static public boolean GS3 = false;
90
91 static public boolean isApplet = false;
92 static public boolean isGsdlRemote = false;
93 static public String cgiBase = "";
94
95 // feedback stuff
96 /** is the feedback feature enabled? */
97 static public boolean feedback_enabled = true;
98 /** the action recorder dialog */
99 static public ActionRecorderDialog feedback_dialog = null;
100
101 // Refresh reasons
102 static public final int COLLECTION_OPENED = 0;
103 static public final int COLLECTION_CLOSED = 1;
104 static public final int COLLECTION_REBUILT = 2;
105 static public final int PREFERENCES_CHANGED = 3;
106
107
108 /** Magic to allow Enter to fire the default button. */
109 static {
110 KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
111 Keymap map = JTextComponent.getKeymap(JTextComponent.DEFAULT_KEYMAP);
112 map.removeKeyStrokeBinding(enter);
113 }
114
115
116 public Gatherer(String[] args)
117 {
118 this.self = this;
119 JarTools.initialise(this);
120
121 GetOpt go = new GetOpt(args);
122
123 // If feedback is enabled, set up the recorder dialog
124 if (go.feedback_enabled) {
125 // Use the default locale for now - this will be changed by the Gatherer run method
126 feedback_enabled = true;
127 feedback_dialog = new ActionRecorderDialog(Locale.getDefault());
128 }
129
130 // Set the Greenstone path and collect directory specially when running with a remote Greenstone
131 if (isGsdlRemote) {
132 go.gsdl_path = Utility.getGLIUserFolder() + File.separator;
133 Gatherer.setCollectDirectoryPath(go.gsdl_path + "collect" + File.separator);
134 }
135
136 // Users may specify a non-standard collect directory (eg. when running one GLI in a network environment)
137 if (go.collect_directory_path != null) {
138 Gatherer.setCollectDirectoryPath(go.collect_directory_path);
139 }
140
141 // Special code for running with a remote Greenstone
142 if (isGsdlRemote) {
143 File gli_user_directory = Utility.getGLIUserFolder();
144
145 Utility.BASE_DIR = go.gsdl_path;
146 Utility.METADATA_DIR = Utility.BASE_DIR + "metadata" + File.separator;
147 Utility.TMP_DIR = Utility.BASE_DIR + "tmp" + File.separator;
148
149 Configuration.TEMPLATE_CONFIG_XML = "xml/configRemote.xml";
150 Configuration.CONFIG_XML = "configRemote.xml";
151 Configuration.GS3_CONFIG_XML = "config3Remote.xml";
152
153 File col_dir = new File(Gatherer.getCollectDirectoryPath());
154 if (!col_dir.exists()) {
155 if (JarTools.isInJar(Utility.COLLECT_ZIP)) {
156 // Dig out collect.zip from JAR file and unzip it (thereby
157 // creating collect directory and descendants.
158 // This is done to seed gsdl home folder with config files
159 // for documented example collections so "base this on
160 // existing collection" works
161 Utility.unzipFromJar(Utility.COLLECT_ZIP, gli_user_directory.toString());
162 }
163 else {
164 // Prepare an empty collect dir for general use
165 if (!col_dir.mkdir()) {
166 System.err.println("Warning: Unable to make directory: " + col_dir.toString());
167 }
168 }
169 }
170
171 File tmp_dir = new File(Utility.TMP_DIR);
172 if (!tmp_dir.exists()) {
173 if (!tmp_dir.mkdir()) {
174 System.err.println("Warning: Unable to make directory: " + tmp_dir.toString());
175 }
176
177 String username = System.getProperty("user.name");
178 if ((username != null) && (username != "")) {
179 File user_tmp_dir = new File(Utility.TMP_DIR + File.separator + username);
180 if (!user_tmp_dir.exists()) {
181 if (!user_tmp_dir.mkdir()) {
182 System.err.println("Warning: Unable to make directory: " + user_tmp_dir.toString());
183 }
184 }
185 }
186 }
187
188 File metadata_directory = new File(Utility.METADATA_DIR);
189 if (!metadata_directory.exists()) {
190 // dig out metadata.zip from JAR file and unzip it
191 Utility.unzipFromJar(Utility.METADATA_ZIP, gli_user_directory.toString());
192 }
193
194 File plug_dat = new File(Utility.BASE_DIR + "plugins.dat");
195 if (!plug_dat.exists()) {
196 JarTools.extractFromJar("plugins.dat", Utility.BASE_DIR, false);
197 }
198
199 File class_dat = new File(Utility.BASE_DIR + "classifiers.dat");
200 if (!class_dat.exists()) {
201 JarTools.extractFromJar("classifiers.dat", Utility.BASE_DIR, false);
202 }
203 }
204
205 init(go.gsdl_path, go.gsdl3_path, go.local_library_path, go.library_url_string, go.debug,
206 go.perl_path, go.no_load, go.filename, go.site_name, go.servlet_path, go.wget_path);
207 }
208
209
210 public void init(String gsdl_path, String gsdl3_path, String local_library_path,
211 String library_url_string, boolean debug_enabled, String perl_path,
212 boolean no_load, String open_collection,
213 String site_name, String servlet_path, String wget_path)
214 {
215 if (gsdl3_path != null && !gsdl3_path.equals("")) {
216 this.GS3 = true;
217 } else {
218 gsdl3_path = null;
219 }
220
221 // Create the debug stream if required
222 if (debug_enabled) {
223 DebugStream.enableDebugging();
224
225 Calendar now = Calendar.getInstance();
226 String debug_file_path = "debug" + now.get(Calendar.DATE) + "-" + now.get(Calendar.MONTH) + "-" + now.get(Calendar.YEAR) + ".txt";
227
228 // Debug file is created in the user's GLI directory
229 debug_file_path = Utility.getGLIUserFolder().toString() + File.separator + debug_file_path;
230 DebugStream.println("Debug file path: " + debug_file_path);
231 DebugStream.setDebugFile(debug_file_path);
232 DebugStream.print(System.getProperties());
233 }
234
235 try {
236 // Load GLI config file
237 new Configuration(gsdl_path, gsdl3_path, site_name);
238 if (Configuration.just_updated_config_xml_file) {
239 // Delete the plugins.dat and classifiers.dat files
240 PluginManager.clearPluginCache();
241 ClassifierManager.clearClassifierCache();
242 }
243
244 if (GS3) {
245 // Load Greenstone 3 servelt configuration
246 servlet_config = new ServletConfiguration(gsdl3_path);
247 }
248
249 // Check we know where Perl is
250 Configuration.perl_path = perl_path;
251 if (isGsdlRemote && Utility.isWindows() && Configuration.perl_path != null) {
252 if (Configuration.perl_path.toLowerCase().endsWith("perl.exe")) {
253 Configuration.perl_path = Configuration.perl_path.substring(0, Configuration.perl_path.length() - "perl.exe".length());
254 }
255 if (Configuration.perl_path.endsWith(File.separator)) {
256 Configuration.perl_path = Configuration.perl_path.substring(0, Configuration.perl_path.length() - File.separator.length());
257 }
258 }
259
260 if (GS3 && Configuration.servlet_path == null) {
261 Configuration.servlet_path = servlet_config.getServletPath(Configuration.site_name);
262 }
263
264 // the feedback dialog has been loaded with a default locale,
265 // now set the user specified one
266 if (feedback_enabled && feedback_dialog != null) {
267 feedback_dialog.setLocale(Configuration.getLocale("general.locale", true));
268 }
269
270 // Read Dictionary
271 new Dictionary(Configuration.getLocale("general.locale", true), Configuration.getFont("general.font", true));
272
273 // check that we are using Sun Java
274 String java_vendor = System.getProperty("java.vendor");
275 if (!java_vendor.equals("Sun Microsystems Inc.")) {
276 System.err.println(Dictionary.get("General.NotSunJava", java_vendor));
277 }
278
279 if (gsdl_path == null) {
280 missingGSDL();
281 }
282
283 // Start up the local library server, if that's what we want
284 if (Utility.isWindows() && local_library_path != null && !GS3) {
285 LocalLibraryServer.start(gsdl_path, local_library_path);
286 }
287
288 // The "-library_url" option overwrites anything in the config files
289 if (library_url_string != null && library_url_string.length() > 0) {
290 try {
291 System.err.println("Setting library_url to " + library_url_string + "...");
292 Configuration.library_url = new URL(library_url_string);
293 }
294 catch (MalformedURLException error) {
295 DebugStream.printStackTrace(error);
296 }
297 }
298
299 // Check that we now know the Greenstone library URL, since we need this for previewing collections
300 DebugStream.println("Configuration.library_url = " + Configuration.library_url);
301 if (Configuration.library_url == null) {
302 missingEXEC();
303 }
304
305 // Check for ImageMagick
306 if (Gatherer.isGsdlRemote) {
307 DebugStream.println("Not checking for ImageMagick.");
308 }
309 else if (!(new ImageMagickTest()).found()) {
310 // Time for a warning message
311 missingImageMagick();
312 }
313
314 if (Gatherer.isGsdlRemote) {
315 DebugStream.println("Not checking for perl path/exe");
316 }
317 else {
318 // Perl path is a little different as it is perfectly ok to
319 // start the GLI without providing a perl path
320 boolean found_perl = false;
321 if (Configuration.perl_path != null) {
322 // See if the file pointed to actually exists
323 File perl_file = new File(Configuration.perl_path);
324 found_perl = perl_file.exists();
325 perl_file = null;
326 }
327 if (Configuration.perl_path == null || !found_perl) {
328 // Run test to see if we can run perl as is.
329 PerlTest perl_test = new PerlTest();
330 if (perl_test.found()) {
331 // If so replace the perl path with the system
332 // default (or null for unix).
333 Configuration.perl_path = perl_test.toString();
334 found_perl = true;
335 }
336 }
337 if (!found_perl) {
338 // Time for an error message.
339 missingPERL();
340 }
341 }
342
343 boolean download_workflow = Configuration.get("workflow.download", false);
344 if (download_workflow) {
345 // If the WGet path hasn't been specified by the user, try the Greenstone one
346 if (wget_path == null) {
347 File wget_file = new File(Utility.getWGetPath(gsdl_path));
348 if (wget_file.exists()) {
349 wget_path = Utility.getWGetPath(gsdl_path);
350 }
351 }
352
353 // If we still don't have a WGet path, give up (there isn't anything else we can do)
354 String wget_version_str = null;
355 if (wget_path == null) {
356 wget_version_str = StaticStrings.NO_WGET_STR;
357 missingWGET();
358 }
359 // Otherwise check the version of WGet
360 else {
361 wget_version_str = testWGetVersion(wget_path);
362 if (wget_version_str.equals(StaticStrings.WGET_OLD_STR)) {
363 oldWGET();
364 }
365 }
366
367 // Store the new values in the configuration
368 DebugStream.println("WGet path: " + wget_path);
369 Configuration.setWGetPath(wget_path);
370 Configuration.setWGetVersion(wget_version_str);
371 }
372
373 // Set the default font for all Swing components.
374 FontUIResource default_font = Configuration.getFont("general.font", true);
375 Enumeration keys = UIManager.getDefaults().keys();
376 while (keys.hasMoreElements()) {
377 Object key = keys.nextElement();
378 Object value = UIManager.get(key);
379 if (value instanceof FontUIResource) {
380 UIManager.put(key, default_font);
381 }
382 }
383
384 // Set up proxy
385 setProxy();
386 // Now we set up an Authenticator
387 Authenticator.setDefault(new GAuthenticator());
388
389 assoc_man = new FileAssociationManager();
390 // Create File Manager
391 f_man = new FileManager();
392 // Create Collection Manager
393 c_man = new CollectionManager();
394
395 if (GS3) {
396 if (site_name==null) {
397 site_name = Configuration.site_name;
398 servlet_path = null; // need to reset this
399 }
400 if (servlet_path == null) {
401 servlet_path = Configuration.getServletPath();
402 }
403 }
404
405 open_collection_file_path = open_collection;
406 if (open_collection_file_path == null) {
407 open_collection_file_path = Configuration.getString("general.open_collection", true);
408 }
409 if (no_load || open_collection_file_path.equals("")) {
410 open_collection_file_path = null;
411 }
412 }
413 catch (Exception exception) {
414 DebugStream.printStackTrace(exception);
415 }
416
417 // Create GUI Manager (last) or else suffer the death of a thousand NPE's
418 g_man = new GUIManager(size);
419 }
420
421
422 public void openGUI()
423 {
424 // Size and place the frame on the screen
425 Rectangle bounds = Configuration.getBounds("general.bounds", true);
426 if (bounds == null) {
427 // Choose a sensible default value
428 bounds = new Rectangle(0, 0, 640, 480);
429 }
430
431 // Ensure width and height are reasonable
432 size = bounds.getSize();
433 if (size.width < 640) {
434 size.width = 640;
435 }
436 else if (size.width > Configuration.screen_size.width) {
437 size.width = Configuration.screen_size.width;
438 }
439 if (size.height < 480) {
440 size.height = 480;
441 }
442 else if (size.height > Configuration.screen_size.height) {
443 size.height = Configuration.screen_size.height;
444 }
445
446 if (!g_man_built) {
447
448 g_man.display();
449
450 // Place the window in the desired location on the screen, if this is do-able (not under most linux window managers apparently. In fact you're lucky if they listen to any of your screen size requests).
451 g_man.setLocation(bounds.x, bounds.y);
452 g_man.setVisible(true);
453
454 // After the window has been made visible, check that it is in the correct place
455 // sometimes java places a window not in the correct place,
456 // but with an offset. If so, we work out what the offset is
457 // and change the desired location to take that into account
458 Point location = g_man.getLocation();
459 int x_offset = bounds.x - location.x;
460 int y_offset = bounds.y - location.y;
461 // If not, offset the window to move it into the correct location
462 if (x_offset > 0 || y_offset > 0) {
463 ///ystem.err.println("changing the location to "+(bounds.x + x_offset)+" "+ (bounds.y + y_offset));
464 g_man.setLocation(bounds.x + x_offset, bounds.y + y_offset);
465 }
466
467 // The 'after-display' triggers several events which don't occur until after the visual components are actually available on screen. Examples of these would be the various html renderings, as they can't happen offscreen.
468 g_man.afterDisplay();
469 g_man_built = true;
470 }
471 else {
472 g_man.setVisible(true);
473 }
474 }
475
476
477 /** Exits the Gatherer after ensuring that things needing saving are saved.
478 * @see java.io.FileOutputStream
479 * @see java.io.PrintStream
480 * @see java.lang.Exception
481 * @see javax.swing.JOptionPane
482 * @see org.greenstone.gatherer.Configuration
483 * @see org.greenstone.gatherer.collection.CollectionManager
484 * @see org.greenstone.gatherer.gui.GUIManager
485 */
486 public void exit() {
487 exit = true;
488 // If we have an open collection make note of it.
489 Configuration.setString("general.open_collection", true, null);
490 if(c_man.ready()) {
491 ///ystem.err.println("Collection open.");
492 if(c_man.saved()) {
493 ///ystem.err.println("Collection has been recently saved, so I'll remember it for next time.");
494 Configuration.setString("general.open_collection", true, c_man.getCollectionFilePath());
495 }
496 c_man.closeCollection();
497 }
498 if(assoc_man != null) {
499 assoc_man.save();
500 assoc_man = null;
501 }
502
503 // Store the current position and size (if reasonable) of the Gatherer for next time
504 Rectangle bounds = g_man.getBounds();
505 Configuration.setBounds("general.bounds", true, bounds);
506
507 // Save configuration.
508 Configuration.save();
509
510 // Get the gui to deallocate
511 g_man.setVisible(false);
512 g_man.destroy();
513 g_man_built = false;
514
515 // Flush debug
516 DebugStream.closeDebugStream();
517
518 // If we started a server, we should try to stop it.
519 if (LocalLibraryServer.isRunning() == true) {
520 LocalLibraryServer.stop();
521 }
522
523 // Make sure we haven't started up any processes that are still running
524 if (apps.size() == 0) {
525 if (Gatherer.isApplet) {
526 // If we're running as an applet we don't actually quit, just delete the main GLI window
527 g_man = null;
528 }
529 else {
530 // This is the end...
531 System.exit(0);
532 }
533 }
534 else {
535 JOptionPane.showMessageDialog(g_man, Dictionary.get("General.Outstanding_Processes"), Dictionary.get("General.Outstanding_Processes_Title"), JOptionPane.ERROR_MESSAGE);
536 g_man.setVisible(false);
537 }
538 }
539
540
541 static public String getCollectDirectoryPath()
542 {
543 if (non_standard_collect_directory_path != null) {
544 return non_standard_collect_directory_path;
545 }
546
547 if (!GS3) {
548 return Configuration.gsdl_path + "collect" + File.separator;
549 }
550 else {
551 return getSitesDirectoryPath() + Configuration.site_name + File.separator + "collect" + File.separator;
552 }
553 }
554
555
556 static public String getSitesDirectoryPath()
557 {
558 return Configuration.gsdl3_path + File.separator + "web" + File.separator + "sites" + File.separator;
559 }
560
561
562 static public void setCollectDirectoryPath(String collect_directory_path)
563 {
564 non_standard_collect_directory_path = collect_directory_path;
565 if (!non_standard_collect_directory_path.endsWith(File.separator)) {
566 non_standard_collect_directory_path = non_standard_collect_directory_path + File.separator;
567 }
568 }
569
570
571 static public void refresh(int refresh_reason)
572 {
573 if (g_man != null) {
574 g_man.refresh(refresh_reason, c_man.ready());
575 }
576
577 // Now is a good time to force a garbage collect
578 System.gc();
579 }
580
581
582 // used to send reload coll messages to the tomcat server
583 static public void configGS3Server(String site, String command) {
584
585 try {
586 // need to add the servlet name to the exec address
587 String raw_url = Configuration.library_url.toString() + Configuration.getServletPath() + command;
588 URL url = new URL(raw_url);
589 DebugStream.println("Action: " + raw_url);
590 HttpURLConnection library_connection = (HttpURLConnection) url.openConnection();
591 int response_code = library_connection.getResponseCode();
592 if(HttpURLConnection.HTTP_OK <= response_code && response_code < HttpURLConnection.HTTP_MULT_CHOICE) {
593 DebugStream.println("200 - Complete.");
594 }
595 else {
596 DebugStream.println("404 - Failed.");
597 }
598 url = null;
599 }
600 catch (Exception exception) {
601 DebugStream.printStackTrace(exception);
602 }
603 }
604
605
606 /** Used to 'spawn' a new child application when a file is double clicked.
607 * @param file The file to open
608 * @see org.greenstone.gatherer.Gatherer.ExternalApplication
609 */
610 public void spawnApplication(File file) {
611 String [] commands = assoc_man.getCommand(file);
612 if(commands != null) {
613 ExternalApplication app = new ExternalApplication(commands);
614 apps.add(app);
615 app.start();
616 }
617 else {
618 ///ystem.err.println("No open command available.");
619 }
620 }
621
622
623 public void spawnApplication(String command)
624 {
625 ExternalApplication app = new ExternalApplication(command);
626 apps.add(app);
627 app.start();
628 }
629
630
631 /** Used to 'spawn' a new browser application or reset an existing one when the preview button is clicked
632 * @param url The url to open the browser at
633 * @see org.greenstone.gatherer.Gatherer.BrowserApplication
634 */
635 public void spawnBrowser(String url) {
636 String command = assoc_man.getBrowserCommand(url);
637 if (command != null) {
638 BrowserApplication app = new BrowserApplication(command, url);
639 apps.add(app);
640 app.start();
641 }
642 else {
643 ///ystem.err.println("No browser command available.");
644 }
645 }
646
647
648 /** Prints a warning message about a missing library path, which means the final collection cannot be previewed in the Gatherer.
649 */
650 static public void missingEXEC() {
651 WarningDialog dialog;
652 if (GS3) {
653 dialog = new WarningDialog("warning.MissingEXEC_GS3", "MissingEXEC_GS3.Title", Dictionary.get("MissingEXEC_GS3.Message"), "general.library_url", false);
654 }
655 else {
656 dialog = new WarningDialog("warning.MissingEXEC", "MissingEXEC.Title", Dictionary.get("MissingEXEC.Message"), "general.library_url", false);
657 }
658 dialog.setValueField(new URLField(Configuration.getColor("coloring.editable_foreground", false), Configuration.getColor("coloring.editable_background", false), Configuration.getColor("coloring.error_foreground", false), Configuration.getColor("coloring.error_background", false)));
659 dialog.display();
660 dialog.dispose();
661 dialog = null;
662
663 String library_url_string = Configuration.getString("general.library_url", true);
664 if (!library_url_string.equals("")) {
665 try {
666 Configuration.library_url = new URL(library_url_string);
667 }
668 catch (MalformedURLException exception) {
669 DebugStream.printStackTrace(exception);
670 }
671 }
672 }
673
674
675 /** Prints a warning message about a missing GSDL path, which although not fatal pretty much ensures nothing will work properly in the GLI.
676 */
677 static public void missingGSDL() {
678 WarningDialog dialog = new WarningDialog("warning.MissingGSDL", "MissingGSDL.Title", Dictionary.get("MissingGSDL.Message"), null, false);
679 dialog.display();
680 dialog.dispose();
681 dialog = null;
682 }
683
684 /** Prints a warning message about missing a valid ImageMagick path, which although not fatal means building image collections won't work */
685 static public void missingImageMagick() {
686 WarningDialog dialog = new WarningDialog("warning.MissingImageMagick", "MissingImageMagick.Title", Dictionary.get("MissingImageMagick.Message"), null, false);
687 dialog.display();
688 dialog.dispose();
689 dialog = null;
690 }
691
692 /** Prints a warning message about missing a valid PERL path, which although not fatal pretty much ensures no collection creation/building will work properly in the GLI. */
693 static public void missingPERL() {
694 WarningDialog dialog = new WarningDialog("warning.MissingPERL", "MissingPERL.Title", Dictionary.get("MissingPERL.Message"), null, false);
695 dialog.display();
696 dialog.dispose();
697 dialog = null;
698 }
699
700 /** Prints a warning message about missing a valid WGet path, which although not fatal means mirroring won't work */
701 static public void missingWGET() {
702 WarningDialog dialog = new WarningDialog("warning.MissingWGET", "MissingWGET.Title", Dictionary.get("MissingWGET.Message"), null, false);
703 dialog.display();
704 dialog.dispose();
705 dialog = null;
706 }
707
708 /** Prints a warning message about having an old version of WGet. not fatal, but mirroring may not work properly */
709 static public void oldWGET() {
710 WarningDialog dialog = new WarningDialog("warning.OldWGET", "OldWGET.Title", Dictionary.get("OldWGET.Message"), null, false);
711 dialog.display();
712 dialog.dispose();
713 dialog = null;
714 }
715
716
717 /** Sets up the proxy connection by setting JVM Environment flags and creating a new Authenticator.
718 * @see java.lang.Exception
719 * @see java.lang.System
720 * @see java.net.Authenticator
721 * @see org.greenstone.gatherer.Configuration
722 * @see org.greenstone.gatherer.GAuthenticator
723 */
724 static public void setProxy() {
725 try {// Can throw several exceptions
726 if(Configuration.get("general.use_proxy", true)) {
727 System.setProperty("http.proxyType", "4");
728 System.setProperty("http.proxyHost", Configuration.getString("general.proxy_host", true));
729 System.setProperty("http.proxyPort", Configuration.getString("general.proxy_port", true));
730 System.setProperty("http.proxySet", "true");
731 } else {
732 System.setProperty("http.proxySet", "false");
733 }
734 } catch (Exception error) {
735 DebugStream.println("Error in Gatherer.initProxy(): " + error);
736 DebugStream.printStackTrace(error);
737 }
738 }
739
740
741 // TODO fill this in
742 private String testWGetVersion(String wget_path) {
743 return StaticStrings.WGET_STR;
744 }
745
746 /** This private class contains an instance of an external application running within a JVM shell. It is important that this process sits in its own thread, but its more important that when we exit the Gatherer we don't actually System.exit(0) the Gatherer object until the user has volunteerily ended all of these child processes. Otherwise when we quit the Gatherer any changes the users may have made in external programs will be lost and the child processes are automatically deallocated. */
747 private class ExternalApplication
748 extends Thread {
749 private Process process = null;
750 /** The initial command string given to this sub-process. */
751 private String command = null;
752 private String[] commands = null;
753 /** Constructor.
754 * @param command The initial command <strong>String</strong>.
755 */
756 public ExternalApplication(String command) {
757 this.command = command;
758 }
759
760 public ExternalApplication(String[] commands) {
761 this.commands = commands;
762 }
763 /** We start the child process inside a new thread so it doesn't block the rest of Gatherer.
764 * @see java.lang.Exception
765 * @see java.lang.Process
766 * @see java.lang.Runtime
767 * @see java.lang.System
768 * @see java.util.Vector
769 */
770 public void run() {
771 // Call an external process using the args.
772 try {
773 if(commands != null) {
774 StringBuffer whole_command = new StringBuffer();
775 for(int i = 0; i < commands.length; i++) {
776 whole_command.append(commands[i]);
777 whole_command.append(" ");
778 }
779 DebugStream.println("Running " + whole_command.toString());
780 Runtime rt = Runtime.getRuntime();
781 process = rt.exec(commands);
782 process.waitFor();
783 }
784 else {
785 DebugStream.println("Running " + command);
786 Runtime rt = Runtime.getRuntime();
787 process = rt.exec(command);
788 process.waitFor();
789 }
790 }
791 catch (Exception exception) {
792 DebugStream.printStackTrace(exception);
793 }
794 // Remove ourself from Gatherer list of threads.
795 apps.remove(this);
796 // Call exit if we were the last outstanding child process thread.
797 if (apps.size() == 0 && exit == true) {
798 System.exit(0);
799 }
800 }
801 public void stopExternalApplication() {
802 if(process != null) {
803 process.destroy();
804 }
805 }
806 }
807 /** This private class contains an instance of an external application running within a JVM shell. It is important that this process sits in its own thread, but its more important that when we exit the Gatherer we don't actually System.exit(0) the Gatherer object until the user has volunteerily ended all of these child processes. Otherwise when we quit the Gatherer any changes the users may have made in external programs will be lost and the child processes are automatically deallocated. */
808 private class BrowserApplication
809 extends Thread {
810 private Process process = null;
811 /** The initial command string given to this sub-process. */
812 private String command = null;
813 private String url = null;
814 private String[] commands = null;
815
816 public BrowserApplication(String command, String url) {
817 StringTokenizer st = new StringTokenizer(command);
818 int num_tokens = st.countTokens();
819 this.commands = new String [num_tokens];
820 int i=0;
821 while (st.hasMoreTokens()) {
822 commands[i] = st.nextToken();
823 i++;
824 }
825 //this.commands = commands;
826 this.url = url;
827 }
828 /** We start the child process inside a new thread so it doesn't block the rest of Gatherer.
829 * @see java.lang.Exception
830 * @see java.lang.Process
831 * @see java.lang.Runtime
832 * @see java.lang.System
833 * @see java.util.Vector
834 */
835 public void run() {
836 // Call an external process using the args.
837 if(commands == null) {
838 apps.remove(this);
839 return;
840 }
841 try {
842 String prog_name = commands[0];
843 String lower_name = prog_name.toLowerCase();
844 if (lower_name.indexOf("mozilla") != -1 || lower_name.indexOf("netscape") != -1) {
845 DebugStream.println("found mozilla or netscape, trying remote it");
846 // mozilla and netscape, try using a remote command to get things in the same window
847 String [] new_commands = new String[] {prog_name, "-raise", "-remote", "openURL("+url+",new-tab)"};
848 printArray(new_commands);
849
850 Runtime rt = Runtime.getRuntime();
851 process = rt.exec(new_commands);
852 int exitCode = process.waitFor();
853 if (exitCode != 0) { // if Netscape or mozilla was not open
854 DebugStream.println("couldn't do remote, trying original command");
855 printArray(commands);
856 process = rt.exec(commands); // try the original command
857 }
858 } else {
859 // just run what we have been given
860 StringBuffer whole_command = new StringBuffer();
861 for(int i = 0; i < commands.length; i++) {
862 whole_command.append(commands[i]);
863 whole_command.append(" ");
864 }
865 DebugStream.println("Running " + whole_command.toString());
866 Runtime rt = Runtime.getRuntime();
867 process = rt.exec(commands);
868 process.waitFor();
869 }
870 }
871
872 catch (Exception exception) {
873 DebugStream.printStackTrace(exception);
874 }
875 // Remove ourself from Gatherer list of threads.
876 apps.remove(this);
877 // Call exit if we were the last outstanding child process thread.
878 if (apps.size() == 0 && exit == true) {
879 System.exit(0);
880 }
881 }
882 public void printArray(String [] array) {
883 for(int i = 0; i < array.length; i++) {
884 DebugStream.print(array[i]+" ");
885 System.err.println(array[i]+" ");
886 }
887 }
888 public void stopBrowserApplication() {
889 if(process != null) {
890 process.destroy();
891 }
892 }
893 }
894
895
896 private class ImageMagickTest
897 {
898 public boolean found()
899 {
900 try {
901 String[] command = new String[2];
902 command[0] = (Utility.isWindows() ? "identify.exe" : "identify");
903 command[1] = "-version";
904 Process image_magick_process = Runtime.getRuntime().exec(command);
905 image_magick_process.waitFor();
906 return (image_magick_process.exitValue() == 0);
907 }
908 catch (Exception exception) {
909 return false;
910 }
911 }
912 }
913
914
915 private class PerlTest
916 {
917 private String[] command = new String[2];
918
919 public PerlTest()
920 {
921 command[0] = (Utility.isWindows() ? Utility.PERL_EXECUTABLE_WINDOWS : Utility.PERL_EXECUTABLE_UNIX);
922 command[1] = "-version";
923 }
924
925 public boolean found()
926 {
927 try {
928 Process perl_process = Runtime.getRuntime().exec(command);
929 perl_process.waitFor();
930 return (perl_process.exitValue() == 0);
931 }
932 catch (Exception exception) {
933 return false;
934 }
935 }
936
937 public String toString() {
938 return command[0];
939 }
940 }
941}
Note: See TracBrowser for help on using the repository browser.