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

Last change on this file since 13584 was 13447, checked in by qq6, 17 years ago

change version number from 2.71 to 2.72

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