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

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

if Configuration.library_url is given, assume a default Configuration.gliserver_urlGatherer.java

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