source: gli/branches/3.03/src/org/greenstone/gatherer/Gatherer.java@ 14579

Last change on this file since 14579 was 14579, checked in by oranfry, 17 years ago

the default version is now 'trunk'

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