source: gli/branches/2.75/src/org/greenstone/gatherer/Gatherer.java@ 14769

Last change on this file since 14769 was 14769, checked in by oranfry, 16 years ago

checking-in version number changes

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