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

Last change on this file since 23143 was 23143, checked in by ak19, 14 years ago

More changes to making collectdir movable: 1. When not working with a remote GS or server.exe: if the collecthome set in GLI is not the same as the one in gsdlsite.cfg used by the apache web server, then a dialog pops up on exiting GLI allowing the user to set the collecthome value for both GLI (in the user's GLI config.xml) and the server (in gsdlsite.cfg). 2. Collecthome line in gsdlsite.cfg is removed if it is the default GS collect folder. (Just as a recent commit stores an empty string for the open_collection element in the GLI config.xml file if no collection is left open on exiting GLI and the collect folder is the default GS collect directory.) 3. Some bug fixes.

  • Property svn:keywords set to Author Date Id Revision
File size: 56.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.*;
38
39
40import org.greenstone.gatherer.Configuration;
41import org.greenstone.gatherer.GAuthenticator;
42import org.greenstone.gatherer.FedoraInfo;
43import org.greenstone.gatherer.collection.CollectionManager;
44import org.greenstone.gatherer.feedback.ActionRecorderDialog;
45import org.greenstone.gatherer.feedback.Base64;
46import org.greenstone.gatherer.file.FileManager;
47import org.greenstone.gatherer.file.FileAssociationManager;
48import org.greenstone.gatherer.file.RecycleBin;
49import org.greenstone.gatherer.greenstone.Classifiers;
50import org.greenstone.gatherer.greenstone.LocalGreenstone;
51import org.greenstone.gatherer.greenstone.LocalLibraryServer;
52import org.greenstone.gatherer.greenstone.Plugins;
53import org.greenstone.gatherer.greenstone3.ServletConfiguration;
54import org.greenstone.gatherer.gui.GUIManager;
55import org.greenstone.gatherer.gui.URLField;
56import org.greenstone.gatherer.gui.WarningDialog;
57import org.greenstone.gatherer.gui.FedoraLogin;
58import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
59import org.greenstone.gatherer.util.JarTools;
60import org.greenstone.gatherer.util.StaticStrings;
61import org.greenstone.gatherer.util.Utility;
62
63
64/** Containing the top-level "core" for the Gatherer, this class is the
65 * common core for the GLI application and applet. It first parses the
66 * command line arguments, preparing to update the configuration as
67 * required. Next it loads several important support classes such as the
68 * Configuration and Dictionary. Finally it creates the other important
69 * managers and sends them on their way.
70 * @author John Thompson, Greenstone Digital Library, University of Waikato
71 * @version 2.3
72 */
73public class Gatherer
74{
75 /** The name of the GLI. */
76 static final public String PROGRAM_NAME = "Greenstone Librarian Interface";
77 /** The current version of the GLI.
78 * Note: the gs3-release-maker relies on this variable being declared
79 * in a line which maches this java regex:
80 * ^(.*)String\s*PROGRAM_VERSION\s*=\s*"trunk";
81 * If change the declaration and it no longer matches the regex, please
82 * change the regex in the gs3-release-maker code and in this message
83 */
84
85 static final public String PROGRAM_VERSION = "trunk";
86
87 static private Dimension size = new Dimension(800, 540);
88 static public RemoteGreenstoneServer remoteGreenstoneServer = null;
89
90 /** Has the exit flag been set? */
91 static final public int EXIT_THEN_RESTART= 2;
92 static public boolean exit = false;
93 static public int exit_status = 0;
94
95 static private String gli_directory_path = null;
96 static private String gli_user_directory_path = null;
97
98 static public String client_operating_system = null;
99
100 /** All of the external applications that must exit before we close the Gatherer. */
101 static private Vector apps = new Vector();
102 static private String non_standard_collect_directory_path = null;
103 static public String open_collection_file_path = null;
104 static public String gsdlsite_collecthome = "";
105 /** A public reference to the FileAssociationManager. */
106 static public FileAssociationManager assoc_man;
107 /** A public reference to the CollectionManager. */
108 static public CollectionManager c_man;
109 /** A public reference to the RecycleBin. */
110 static public RecycleBin recycle_bin;
111 /** a reference to the Servlet Configuration is GS3 */
112 static public ServletConfiguration servlet_config;
113 /** A public reference to the FileManager. */
114 static public FileManager f_man;
115 /** A public reference to the GUIManager. */
116 static public GUIManager g_man = null;
117 static private boolean g_man_built = false;
118
119 /** We are using the GLI for GS3 */
120 static public boolean GS3 = false;
121
122 static public boolean isApplet = false;
123 static public boolean isGsdlRemote = false;
124 static public boolean isLocalLibrary = false;
125
126 /* TODO: If we're using local GLI, collections are built locally. If we're using client-GLI
127 * and it contains a gs2build folder in it, then localBuild will also be true (if this is not
128 * turned off in Preferences). If we're remote and this is turned off in Prefs, build remotely. */
129 /*static public boolean buildingLocally = true;*/
130 /** If we're using local GLI, we can always download. If we're using client-GLI, we can only
131 * download if we have a gs2build folder inside it. And if we don't turn off downloadEnabling
132 * in the preferences.
133 */
134 static public boolean isDownloadEnabled = true;
135
136 // feedback stuff
137 /** is the feedback feature enabled? */
138 static public boolean feedback_enabled = true;
139 /** the action recorder dialog */
140 static public ActionRecorderDialog feedback_dialog = null;
141
142 // Refresh reasons
143 static public final int COLLECTION_OPENED = 0;
144 static public final int COLLECTION_CLOSED = 1;
145 static public final int COLLECTION_REBUILT = 2;
146 static public final int PREFERENCES_CHANGED = 3;
147
148 //////kk added////////
149 static public String cgiBase="";
150 /////////////////
151
152 /** Magic to allow Enter to fire the default button. */
153 static {
154 KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
155 Keymap map = JTextComponent.getKeymap(JTextComponent.DEFAULT_KEYMAP);
156 map.removeKeyStrokeBinding(enter);
157 }
158
159 static private URL default_gliserver_url=null;
160
161 public Gatherer(String[] args)
162 {
163 // Display the version to make error reports a lot more useful
164 System.err.println("Version: " + PROGRAM_VERSION + "\n");
165
166 JarTools.initialise(this);
167
168 GetOpt go = new GetOpt(args);
169
170 // Remember the GSDLOS value
171 client_operating_system = go.client_operating_system;
172
173 // If feedback is enabled, set up the recorder dialog
174 if (go.feedback_enabled) {
175 // Use the default locale for now - this will be changed by the Gatherer run method
176 feedback_enabled = true;
177 feedback_dialog = new ActionRecorderDialog(Locale.getDefault());
178 }
179
180 // Are we using a remote Greenstone?
181 if (go.use_remote_greenstone) {
182 isGsdlRemote = true;
183
184 // We don't have a local Greenstone!
185 go.gsdl3_path=null;
186 go.gsdl3_src_path=null;
187
188 // Don't set go.gsdl_path to null, since gdsl_path may still be set
189 // if we have a client-gli containing gs2build folder.
190 // However, keep track of whether we can download.
191 if(go.gsdl_path == null) {
192 isDownloadEnabled = false;
193 }
194
195 // We have to use our own collect directory since we can't use the Greenstone one
196 setCollectDirectoryPath(getGLIUserDirectoryPath() + "collect" + File.separator);
197 }
198 // We have a local Greenstone. OR we have a gs2build folder inside
199 // the client-GLI folder (with which the Download panel becomes enabled)
200 if(isDownloadEnabled) {
201 LocalGreenstone.setDirectoryPath(go.gsdl_path);
202 }
203
204 // Users may specify a non-standard collect directory (eg. when running one GLI in a network environment)
205 if (go.collect_directory_path != null) {
206 setCollectDirectoryPath(go.collect_directory_path);
207 }
208
209 // More special code for running with a remote Greenstone
210 if (isGsdlRemote) {
211 if (go.fedora_info.isActive()) {
212 Configuration.TEMPLATE_CONFIG_XML = "xml/" + Configuration.FEDORA_CONFIG_PREFIX + "configRemote.xml";
213 }
214 else {
215 Configuration.TEMPLATE_CONFIG_XML = "xml/configRemote.xml";
216 }
217
218 Configuration.CONFIG_XML = "configRemote.xml";
219
220 File collect_directory = new File(Gatherer.getCollectDirectoryPath());
221 if (!collect_directory.exists() && !collect_directory.mkdir()) {
222 System.err.println("Warning: Unable to make directory: " + collect_directory);
223 }
224 }
225 else {
226 if (go.fedora_info.isActive()) {
227 Configuration.TEMPLATE_CONFIG_XML = "xml/" + Configuration.FEDORA_CONFIG_PREFIX + Configuration.CONFIG_XML;
228 }
229 // else, the CONFIG_XML uses the default config file, which is for the local GS server
230 }
231
232 init(go.gsdl_path, go.gsdl3_path, go.gsdl3_src_path,
233 go.fedora_info,
234 go.local_library_path, go.library_url_string,
235 go.gliserver_url_string, go.debug, go.perl_path, go.no_load, go.filename, go.site_name,
236 go.servlet_path);
237 }
238
239
240 public void init(String gsdl_path, String gsdl3_path, String gsdl3_src_path,
241 FedoraInfo fedora_info,
242 String local_library_path,
243 String library_url_string, String gliserver_url_string, boolean debug_enabled,
244 String perl_path, boolean no_load, String open_collection,
245 String site_name, String servlet_path)
246 {
247 if (gsdl3_path != null && !gsdl3_path.equals("")) {
248 this.GS3 = true;
249 } else {
250 gsdl3_path = null;
251 gsdl3_src_path = null;
252 }
253
254 // Create the debug stream if required
255 if (debug_enabled) {
256 DebugStream.enableDebugging();
257
258 Calendar now = Calendar.getInstance();
259 String debug_file_path = "debug" + now.get(Calendar.DATE) + "-" + now.get(Calendar.MONTH) + "-" + now.get(Calendar.YEAR) + ".txt";
260
261 // Debug file is created in the user's GLI directory
262 debug_file_path = getGLIUserDirectoryPath() + debug_file_path;
263 DebugStream.println("Debug file path: " + debug_file_path);
264 DebugStream.setDebugFile(debug_file_path);
265 DebugStream.print(System.getProperties());
266 }
267
268 // Delete plugins.dat and classifiers.dat files from previous versions of the GLI (no longer used)
269 File plugins_dat_file = new File(Gatherer.getGLIUserDirectoryPath() + "plugins.dat");
270 if (plugins_dat_file.exists()) {
271 System.err.println("Deleting plugins.dat file...");
272 Utility.delete(plugins_dat_file);
273 }
274 File classifiers_dat_file = new File(Gatherer.getGLIUserDirectoryPath() + "classifiers.dat");
275 if (classifiers_dat_file.exists()) {
276 System.err.println("Deleting classifiers.dat file...");
277 Utility.delete(classifiers_dat_file);
278 }
279
280 try {
281 // Load GLI config file
282 new Configuration(getGLIUserDirectoryPath(), gsdl_path, gsdl3_path, gsdl3_src_path, site_name,
283 fedora_info);
284
285 // Check we know where Perl is
286 Configuration.perl_path = perl_path;
287 if (isGsdlRemote && !isDownloadEnabled && Utility.isWindows() && Configuration.perl_path != null) {
288 if (Configuration.perl_path.toLowerCase().endsWith("perl.exe")) {
289 Configuration.perl_path = Configuration.perl_path.substring(0, Configuration.perl_path.length() - "perl.exe".length());
290 }
291 if (Configuration.perl_path.endsWith(File.separator)) {
292 Configuration.perl_path = Configuration.perl_path.substring(0, Configuration.perl_path.length() - File.separator.length());
293 }
294 }
295
296 // the feedback dialog has been loaded with a default locale,
297 // now set the user specified one
298 if (feedback_enabled && feedback_dialog != null) {
299 feedback_dialog.setLocale(Configuration.getLocale("general.locale", true));
300 }
301
302 // Read Dictionary
303 new Dictionary(Configuration.getLocale("general.locale", true), Configuration.getFont("general.font", true));
304
305 // check that we are using Sun Java
306 String java_vendor = System.getProperty("java.vendor");
307 if (!java_vendor.equals("Sun Microsystems Inc.")) {
308 System.err.println(Dictionary.get("General.NotSunJava", java_vendor));
309 }
310
311 // Unless we're using remote building, we need to know where the local Greenstone is
312 if (!isGsdlRemote && gsdl_path == null) {
313 missingGSDL();
314 }
315
316 if (fedora_info.isActive()) {
317 popupFedoraInfo();
318 }
319
320 // the no_load flag to GLI is processed at the end of handling open_collection_file_path
321 open_collection_file_path = open_collection;
322 if (open_collection_file_path == null) {
323 open_collection_file_path = Configuration.getString(
324 "general.open_collection"+Configuration.gliPropertyNameSuffix(), true);
325 }
326
327 initCollectDirectoryPath(open_collection);
328
329 if (no_load || (isGsdlRemote && open_collection_file_path.equals(""))) {
330 open_collection_file_path = null;
331 }
332
333 // Finally, we're ready to find out the version of the remote Greenstone server
334 if(isGsdlRemote) {
335 // instantiate the RemoteGreenstoneServer object first
336 remoteGreenstoneServer = new RemoteGreenstoneServer();
337
338 // Set up proxy
339 setProxy();
340 // Now we set up an Authenticator
341 Authenticator.setDefault(new GAuthenticator());
342
343 int greenstoneVersion = 2;
344 requestGLIServerURL();
345 gliserver_url_string = Configuration.gliserver_url.toString();
346
347 greenstoneVersion = remoteGreenstoneServer.getGreenstoneVersion();
348 // Display the version to make error reports a lot more useful
349 System.err.println("Remote Greenstone server version: " + greenstoneVersion);
350 if(greenstoneVersion == -1) { // remote server not running
351 Gatherer.exit();
352 }
353 if(greenstoneVersion >= 3) {
354 this.GS3 = true;
355 Configuration.prepareForGS3();
356 }
357
358 if(fedora_info.isActive()) {
359 // when GS server is remote, FEDORA_HOME resides on the remote server side,
360 // but we know the library URL from user-provided information
361 library_url_string = fedora_info.getLibraryURL();
362 } else {
363 library_url_string = remoteGreenstoneServer.getLibraryURL(Configuration.gliserver_url.toString());
364 }
365 // write it into the config file
366 Configuration.setString("general.library_url", true, library_url_string);
367 }
368 else { // local greenstone: Start up the local library server, if that's what we want
369 if (!GS3) {
370 isLocalLibrary = LocalLibraryServer.start(gsdl_path, local_library_path);
371 }
372 // else web library: GS server is local, but doesn't use the webserver included with GS2
373 }
374
375 // The "-library_url" option overwrites anything in the config files
376 if (library_url_string != null && library_url_string.length() > 0) {
377 try {
378 System.err.println("Setting library_url to " + library_url_string + "...");
379 Configuration.library_url = new URL(library_url_string);
380 }
381 catch (MalformedURLException error) {
382 DebugStream.printStackTrace(error);
383 }
384 }
385
386
387 // Check that we now know the Greenstone library URL, since we need this for previewing collections
388 // It is not necessary if an independent GSI was launched and the user hasn't pressed Enter Library yet
389 DebugStream.println("Configuration.library_url = " + Configuration.library_url);
390 if (Configuration.library_url == null) {
391 if(isLocalLibrary) {
392 if(!LocalLibraryServer.isURLPending()) {
393 missingEXEC();
394 }
395 // else LocalLibraryServer is expecting a URL soon, so don't need to display the dialog
396 } else { // GS2 webLibrary or GS3 or remote Greenstone
397 missingEXEC();
398 }
399 }
400
401 // The "-gliserver_url" option overwrites anything in the config files
402 if (gliserver_url_string != null && gliserver_url_string.length() > 0) {
403 try {
404 System.err.println("Setting gliserver_url to " + gliserver_url_string + "...");
405 Configuration.gliserver_url = new URL(gliserver_url_string);
406 }
407 catch (MalformedURLException error) {
408 DebugStream.printStackTrace(error);
409 }
410 }
411
412 // If we're using a remote Greenstone we need to know where the gliserver script is
413 DebugStream.println("Configuration.gliserver_url = " + Configuration.gliserver_url);
414
415 if (GS3) {
416 // Load Greenstone 3 servlet configuration
417 if (isGsdlRemote){
418 servlet_config = new ServletConfiguration(Configuration.gli_user_directory_path);
419 }else{
420 servlet_config= new ServletConfiguration(gsdl3_path);
421 }
422 }
423
424 if (GS3 && Configuration.servlet_path == null) {
425 Configuration.servlet_path = servlet_config.getServletPath(Configuration.site_name);
426 }
427
428 // ensure that a directory called 'cache' exists in the GLI user directory
429 File user_cache_dir = new File(Gatherer.getGLIUserCacheDirectoryPath());
430 System.err.println("User cache dir: " + Gatherer.getGLIUserCacheDirectoryPath());
431 if (!user_cache_dir.exists() && !user_cache_dir.mkdir()) {
432 System.err.println("Warning: Unable to make directory: " + user_cache_dir);
433 }
434
435 // Check for ImageMagick
436 if (Gatherer.isGsdlRemote) {
437 DebugStream.println("Not checking for ImageMagick.");
438 }
439 else if (!(new ImageMagickTest()).found()) {
440 // Time for a warning message
441 missingImageMagick();
442 }
443
444 if (Gatherer.isGsdlRemote) {
445 DebugStream.println("Not checking for perl path/exe");
446 }
447 else {
448 // Perl path is a little different as it is perfectly ok to
449 // start the GLI without providing a perl path
450 boolean found_perl = false;
451 if (Configuration.perl_path != null) {
452 // See if the file pointed to actually exists
453 File perl_file = new File(Configuration.perl_path);
454 found_perl = perl_file.exists();
455 perl_file = null;
456 }
457 if (Configuration.perl_path == null || !found_perl) {
458 // Run test to see if we can run perl as is.
459 PerlTest perl_test = new PerlTest();
460 if (perl_test.found()) {
461 // If so replace the perl path with the system
462 // default (or null for unix).
463 Configuration.perl_path = perl_test.toString();
464 found_perl = true;
465 }
466 }
467 if (!found_perl) {
468 // Time for an error message.
469 missingPERL();
470 }
471 }
472
473 // Set the default font for all Swing components.
474 FontUIResource default_font = Configuration.getFont("general.font", true);
475 Enumeration keys = UIManager.getDefaults().keys();
476 while (keys.hasMoreElements()) {
477 Object key = keys.nextElement();
478 Object value = UIManager.get(key);
479 if (value instanceof FontUIResource) {
480 UIManager.put(key, default_font);
481 }
482 }
483
484 // At this point (which is where this code originally used to be), we can set up the proxy for the
485 // non-remote case. The remote Greenstone server would already have setup its proxy when required.
486 if(!isGsdlRemote) {
487 setProxy();
488 // Now we set up an Authenticator
489 Authenticator.setDefault(new GAuthenticator());
490 }
491 assoc_man = new FileAssociationManager();
492 // Create File Manager
493 f_man = new FileManager();
494 // Create Collection Manager
495 c_man = new CollectionManager();
496 // Create Recycle Bin
497 recycle_bin = new RecycleBin();
498
499 if (GS3) {
500 if (site_name==null) {
501 site_name = Configuration.site_name;
502 servlet_path = null; // need to reset this
503 }
504 if (servlet_path == null) {
505 servlet_path = Configuration.getServletPath();
506 }
507 }
508
509
510 } catch (Exception exception) {
511 DebugStream.printStackTrace(exception);
512 }
513
514
515 // Create GUI Manager (last) or else suffer the death of a thousand NPE's
516 g_man = new GUIManager(size);
517
518 // Get a list of the core Greenstone classifiers and plugins
519 Classifiers.loadClassifiersList(null);
520 Plugins.loadPluginsList(null);
521
522 // If using a remote Greenstone we need to download the collection configurations now
523 if (Gatherer.isGsdlRemote) {
524 if (remoteGreenstoneServer.downloadCollectionConfigurations().equals("")) {
525 // !! Something went wrong downloading the collection configurations
526 System.err.println("Error: Could not download collection configurations.");
527 if(!Gatherer.isApplet) { // don't close the browser if it is an applet!
528 System.exit(0);
529 }
530 }
531 }
532 }
533
534
535 /** Returns the correct version of the (local or remote) Greenstone server if init() has already been called. */
536 public static int serverVersionNumber() {
537 return GS3 ? 3 : 2;
538 }
539
540 /** Returns "Server: version number" if init() has already been called. */
541 public static String getServerVersionAsString() {
542 return "Server: v" + serverVersionNumber();
543 }
544
545 public void openGUI()
546 {
547 // Size and place the frame on the screen
548 Rectangle bounds = Configuration.getBounds("general.bounds", true);
549 if (bounds == null) {
550 // Choose a sensible default value
551 bounds = new Rectangle(0, 0, 640, 480);
552 }
553
554 // Ensure width and height are reasonable
555 size = bounds.getSize();
556 if (size.width < 640) {
557 size.width = 640;
558 }
559 else if (size.width > Configuration.screen_size.width && Configuration.screen_size.width > 0) {
560 size.width = Configuration.screen_size.width;
561 }
562 if (size.height < 480) {
563 size.height = 480;
564 }
565 else if (size.height > Configuration.screen_size.height && Configuration.screen_size.height > 0) {
566 size.height = Configuration.screen_size.height;
567 }
568
569 if (!g_man_built) {
570
571 g_man.display();
572
573 // 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).
574 g_man.setLocation(bounds.x, bounds.y);
575 g_man.setVisible(true);
576
577 // After the window has been made visible, check that it is in the correct place
578 // sometimes java places a window not in the correct place,
579 // but with an offset. If so, we work out what the offset is
580 // and change the desired location to take that into account
581 Point location = g_man.getLocation();
582 int x_offset = bounds.x - location.x;
583 int y_offset = bounds.y - location.y;
584 // If not, offset the window to move it into the correct location
585 if (x_offset > 0 || y_offset > 0) {
586 ///ystem.err.println("changing the location to "+(bounds.x + x_offset)+" "+ (bounds.y + y_offset));
587 g_man.setLocation(bounds.x + x_offset, bounds.y + y_offset);
588 }
589
590 // 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.
591 g_man.afterDisplay();
592 g_man_built = true;
593 }
594 else {
595 g_man.setVisible(true);
596 }
597
598 // Get a list of the core Greenstone classifiers and plugins
599 /*Classifiers.loadClassifiersList(null);
600 Plugins.loadPluginsList(null);
601
602 // If using a remote Greenstone we need to download the collection configurations now
603 if (Gatherer.isGsdlRemote) {
604 if (remoteGreenstoneServer.downloadCollectionConfigurations().equals("")) {
605 // !! Something went wrong downloading the collection configurations
606 System.err.println("Error: Could not download collection configurations.");
607 System.exit(0);
608 }
609 }*/
610
611 // If there was a collection left open last time, reopen it
612 if (open_collection_file_path == null || new File(Gatherer.open_collection_file_path).isDirectory()) {
613
614 //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
615 setMenuBarEnabled(true);
616 } else {
617
618 // If there was a collection left open last time, reopen it
619 c_man.openCollectionFromLastTime();
620 }
621 }
622
623 public static void setMenuBarEnabled(boolean enabled) {
624 g_man.menu_bar.file.setEnabled(enabled);
625 g_man.menu_bar.edit.setEnabled(enabled);
626 }
627
628 /** Exits the Gatherer after ensuring that things needing saving are saved.
629 * @see java.io.FileOutputStream
630 * @see java.io.PrintStream
631 * @see java.lang.Exception
632 * @see javax.swing.JOptionPane
633 * @see org.greenstone.gatherer.Configuration
634 * @see org.greenstone.gatherer.collection.CollectionManager
635 * @see org.greenstone.gatherer.gui.GUIManager
636 */
637 static public void exit(int new_exit_status)
638 {
639 DebugStream.println("In Gatherer.exit()...");
640 exit = true;
641 if (new_exit_status != 0) {
642 // default exit_status is already 0
643 // only remember a new exit status if it is non-trivial
644 exit_status = new_exit_status;
645 }
646
647 // Save the file associations
648 if (assoc_man != null) {
649 assoc_man.save();
650 assoc_man = null;
651 }
652
653 // Get the gui to deallocate
654 if(g_man != null) {
655 g_man.destroy();
656 g_man_built = false;
657 }
658
659 // Flush debug
660 DebugStream.closeDebugStream();
661
662 // If we started a server, we should try to stop it.
663 if (LocalLibraryServer.isRunning() == true) {
664 LocalLibraryServer.stop();
665 }
666
667 // If we're using a remote Greenstone server we need to make sure that all jobs have completed first
668 if (isGsdlRemote) {
669 remoteGreenstoneServer.exit();
670 }
671
672 // Make sure we haven't started up any processes that are still running
673 if (apps.size() == 0) {
674 // If we're running as an applet we don't actually quit (just hide the main GLI window)
675 if (!Gatherer.isApplet) {
676 // This is the end...
677 System.exit(exit_status);
678 }
679 }
680 else {
681 JOptionPane.showMessageDialog(g_man, Dictionary.get("General.Outstanding_Processes"), Dictionary.get("General.Outstanding_Processes_Title"), JOptionPane.ERROR_MESSAGE);
682 g_man.setVisible(false);
683 }
684 }
685
686 static public void exit()
687 {
688 exit(0);
689 }
690
691 /** Returns the path of the current collect directory. */
692 static public String getCollectDirectoryPath()
693 {
694 if (non_standard_collect_directory_path != null) {
695 return non_standard_collect_directory_path;
696 }
697
698 return getDefaultGSCollectDirectoryPath(true); // file separator appended
699
700 }
701
702 // if we need to know whether the local server we are running is server.exe vs apache web server
703 static public boolean isPersistentServer() {
704 return (!isGsdlRemote && LocalLibraryServer.isPersistentServer());
705 }
706
707 /** Returns the path of the Greenstone "collect" directory. */
708 static public String getDefaultGSCollectDirectoryPath(boolean appendSeparator) {
709 String colDir;
710 if (GS3) {
711 colDir = getSitesDirectoryPath() + Configuration.site_name + File.separator + "collect";
712 }
713 else {
714 colDir = Configuration.gsdl_path + "collect";
715 }
716
717 if(appendSeparator) {
718 colDir += File.separator;
719 }
720 return colDir;
721 }
722
723 /** Returns the path of the GLI directory. */
724 static public String getGLIDirectoryPath()
725 {
726 return gli_directory_path;
727 }
728
729
730 /** Returns the path of the GLI "metadata" directory. */
731 static public String getGLIMetadataDirectoryPath()
732 {
733 return getGLIDirectoryPath() + "metadata" + File.separator;
734 }
735
736
737 /** Returns the path of the GLI user directory. */
738 static public String getGLIUserDirectoryPath()
739 {
740 return gli_user_directory_path;
741 }
742
743
744 /** Returns the path of the GLI user "cache" directory. */
745 static public String getGLIUserCacheDirectoryPath()
746 {
747 return getGLIUserDirectoryPath() + "cache" + File.separator;
748 }
749
750
751 /** Returns the path of the GLI user "log" directory. */
752 static public String getGLIUserLogDirectoryPath()
753 {
754 return getGLIUserDirectoryPath() + "log" + File.separator;
755 }
756
757
758 static public String getSitesDirectoryPath()
759 {
760 return Configuration.gsdl3_path + "sites" + File.separator;
761 }
762
763
764 static public void setCollectDirectoryPath(String collect_directory_path)
765 {
766 non_standard_collect_directory_path = collect_directory_path;
767 if (!non_standard_collect_directory_path.endsWith(File.separator)) {
768 non_standard_collect_directory_path = non_standard_collect_directory_path + File.separator;
769 }
770 }
771
772
773 static public void setGLIDirectoryPath(String gli_directory_path_arg)
774 {
775 gli_directory_path = gli_directory_path_arg;
776 }
777
778
779 static public void setGLIUserDirectoryPath(String gli_user_directory_path_arg)
780 {
781 gli_user_directory_path = gli_user_directory_path_arg;
782
783 // Ensure the GLI user directory exists
784 File gli_user_directory = new File(gli_user_directory_path);
785 if (!gli_user_directory.exists() && !gli_user_directory.mkdirs()) {
786 System.err.println("Error: Unable to make directory: " + gli_user_directory);
787 }
788 }
789
790
791 public static void initCollectDirectoryPath(String open_collection) {
792 String defaultColdir = getDefaultGSCollectDirectoryPath(false); // no file separator at end
793 String coldir = defaultColdir;
794 // If local GS and opening a collection outside the standard GS collect folder,
795 // need to open the non-standard collect folder that the collection resides in
796 if (!isGsdlRemote
797 && !open_collection_file_path.startsWith(defaultColdir))
798 {
799 File collectFolder = null;
800
801 if(!open_collection_file_path.equals("")) {
802 if(!open_collection_file_path.endsWith("gli.col")) { // then it's a collect folder
803 collectFolder = new File(open_collection_file_path);
804 } else {
805 // the filepath is a gli.col file. To get the collect folder: the 1st level up
806 // is the collection folder, 2 two levels up is the containing collect folder
807 collectFolder = new File(open_collection_file_path).getParentFile().getParentFile();
808 }
809
810 // Need to deal with colgroups as well: while there's an etc/collect.cfg
811 // in the current collectFolder, move one level up
812 String cfg_file = (Gatherer.GS3)? Utility.CONFIG_GS3_FILE : Utility.CONFIG_FILE;
813 if(new File(collectFolder.getAbsolutePath()+File.separator+cfg_file).exists()) { // colgroup
814 collectFolder = collectFolder.getParentFile();
815 }
816 }
817
818 if(collectFolder == null || !collectFolder.exists()) {
819 // if GLI config file specified no collectDir (open_collection_file_path is "")
820 // OR if dealing with a local server but the collectdir no longer exists,
821 // use the default greenstone collect directory, and write that to affected files
822
823 open_collection_file_path = defaultColdir; // default GS collect dir
824 // Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(), true, "");
825 } else { // use the coldir value specified in the flags to GLI or from the last GLI session
826 coldir = collectFolder.getAbsolutePath();
827 }
828 // set it as the current folder
829 setCollectDirectoryPath(coldir); // will ensure the required file separator at end
830 }
831
832 if(!isGsdlRemote) {
833 // LocalLibraryServer would already have set glisite.cfg to the correct collecthome for server.exe
834 // Here we set collecthome in gsdl(3)site.cfg for the GS2 apache web server and GS3 tomcat server
835 String gsdlsitecfg = getGsdlSiteConfigFile();
836 // update the gsdlsite config file and store the old value for use when we exit GLI
837 if(coldir.equals(defaultColdir)) {
838 gsdlsite_collecthome = Utility.updatePropertyConfigFile(
839 gsdlsitecfg, "collecthome", null);
840 } else {
841 gsdlsite_collecthome = Utility.updatePropertyConfigFile(
842 gsdlsitecfg, "collecthome", coldir); // no file separator
843 // if gsdlsite.cfg does not exist (if using server.exe for instance), the above method will just return
844 }
845 }
846 }
847
848 /** depending on the version of GS being run, return the path to the current GS' installation's gsdl(3)site.cfg */
849 public static String getGsdlSiteConfigFile() {
850 if(Gatherer.GS3) { // web/WEB-INF/cgi/gsdl3site.cfg
851 return Configuration.gsdl3_path + File.separator + "WEB-INF"
852 + File.separator + "cgi" + File.separator + "gsdl3site.cfg";
853 } else { // cgi-bin/gsdlsite.cfg
854 return Configuration.gsdl_path + File.separator
855 + "cgi-bin" + File.separator + "gsdlsite.cfg";
856 }
857 }
858
859 public static void collectDirectoryHasChanged(
860 String oldCollectPath, String newCollectPath, final Component container)
861 {
862 if(oldCollectPath.equals(newCollectPath)) {
863 return; // nothing to be done
864 }
865
866 // Will use a busy cursor if the process of changing the collect directory takes more
867 // than half a second/500ms. See http://www.catalysoft.com/articles/busyCursor.html
868 Cursor originalCursor = container.getCursor();
869 java.util.TimerTask timerTask = new java.util.TimerTask() {
870 public void run() {
871 // set the cursor on the container:
872 container.setCursor(new Cursor(Cursor.WAIT_CURSOR));
873 }
874 };
875 java.util.Timer timer = new java.util.Timer();
876
877 try {
878 timer.schedule(timerTask, 500);
879
880 // first save any open collection in the old location, then close it
881 if(Gatherer.c_man.getCollection() != null) {
882 Gatherer.g_man.saveThenCloseCurrentCollection(); // close the current collection first
883 }
884
885 // change to new collect path
886 if(newCollectPath.equals(getDefaultGSCollectDirectoryPath(true))) {
887 Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(),
888 true, "");
889 } else {
890 Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(),
891 true, newCollectPath);
892 }
893 Gatherer.setCollectDirectoryPath(newCollectPath);
894
895
896 // refresh the Documents in Greenstone Collections
897 //WorkspaceTreeModel.refreshGreenstoneCollectionsNode();
898 Gatherer.g_man.refreshWorkspaceTreeGreenstoneCollections();
899
900 // The web server needs to be told where a new (non-standard) collecthome home is.
901 // The web server reads collecthome from cgi-bin/gsdlsite.cfg, where the property
902 // collecthome can be specified if a non-standard collecthome is to be used. If no
903 // such property is specified in the file, then it assumes the standard GS collecthome.
904 // This method does nothing for a remote Greenstone.
905 if(Gatherer.isGsdlRemote) {
906 return;
907 }
908
909 // non-destructive update of gsdl(3)site.cfg (comments preserved)
910 String collectDir = Gatherer.getCollectDirectoryPath();
911 //collectDir = "\"" + collectDir.substring(0, collectDir.length()-1) + "\""; // remove file separator at end
912 collectDir = collectDir.substring(0, collectDir.length()-1); // remove file separator at end
913 Utility.updatePropertyConfigFile(getGsdlSiteConfigFile(), "collecthome", collectDir);
914 // if gsdlsite.cfg does not exist (if using server.exe for instance), the above method will just return
915
916 if(!Gatherer.GS3 && Gatherer.isLocalLibrary) {
917 // for Images in the collection to work, the apache web server
918 // configuration's COLLECTHOME should be updated on collectdir change.
919 // Does nothing for server.exe at the moment
920
921 LocalLibraryServer.reconfigure();
922 }
923 } finally { // Note try-finally section without catch:
924 // "Java's finally clause is guaranteed to be executed even when
925 // an exception is thrown and not caught in the current scope."
926 // See http://www.catalysoft.com/articles/busyCursor.html
927 // the following code fragment is guaranteed to restore the original
928 // cursor now the custom actionPerformed() processing is complete, regardless
929 // of whether the processing method terminates normally or throws an exception
930 // and regardedless of where in the call stack the exception is caught.
931
932 timer.cancel();
933 container.setCursor(originalCursor);
934 }
935 }
936
937
938 static public void refresh(int refresh_reason)
939 {
940 if (g_man != null) {
941
942 g_man.refresh(refresh_reason, c_man.ready());
943 }
944
945 // Now is a good time to force a garbage collect
946 System.gc();
947 }
948
949
950 // used to send reload coll messages to the tomcat server
951 static public void configGS3Server(String site, String command) {
952 if (Configuration.library_url == null){
953 System.out.println("Error: you have not provided the Greenstone Library address.");
954 return;
955
956 }
957
958 try {
959 // need to add the servlet name to the exec address
960 String raw_url = Configuration.library_url.toString() + Configuration.getServletPath() + command;
961 URL url = new URL(raw_url);
962 DebugStream.println("Action: " + raw_url);
963 HttpURLConnection library_connection = (HttpURLConnection) url.openConnection();
964 int response_code = library_connection.getResponseCode();
965 if(HttpURLConnection.HTTP_OK <= response_code && response_code < HttpURLConnection.HTTP_MULT_CHOICE) {
966 DebugStream.println("200 - Complete.");
967 }
968 else {
969 DebugStream.println("404 - Failed.");
970 }
971 url = null;
972 }
973 catch(java.net.ConnectException connectException) {
974 JOptionPane.showMessageDialog(g_man, Dictionary.get("Preferences.Connection.Library_Path_Connection_Failure", Configuration.library_url.toString()), Dictionary.get("General.Warning"), JOptionPane.WARNING_MESSAGE);
975 DebugStream.println(connectException.getMessage());
976 }
977 catch (Exception exception) {
978 DebugStream.printStackTrace(exception);
979 }
980 }
981
982
983 /** Used to 'spawn' a new child application when a file is double clicked.
984 * @param file The file to open
985 * @see org.greenstone.gatherer.Gatherer.ExternalApplication
986 */
987 static public void spawnApplication(File file) {
988 String [] commands = assoc_man.getCommand(file);
989 if(commands != null) {
990 ExternalApplication app = new ExternalApplication(commands);
991 apps.add(app);
992 app.start();
993 }
994 else {
995 ///ystem.err.println("No open command available.");
996 }
997 }
998
999
1000 static public void spawnApplication(String command)
1001 {
1002 ExternalApplication app = new ExternalApplication(command);
1003 apps.add(app);
1004 app.start();
1005 }
1006
1007 static public void spawnApplication(String command, String ID)
1008 {
1009 ExternalApplication app = new ExternalApplication(command, ID);
1010 apps.add(app);
1011 app.start();
1012 }
1013
1014 static public void spawnApplication(String[] commands, String ID)
1015 {
1016 ExternalApplication app = new ExternalApplication(commands, ID);
1017 apps.add(app);
1018 app.start();
1019 }
1020
1021 static public void terminateApplication(String ID) {
1022 for(int i = 0; i < apps.size(); i++) {
1023 ExternalApplication app = (ExternalApplication)apps.get(i);
1024 if(app.getID() != null && app.getID().equals(ID)) {
1025 app.stopExternalApplication();
1026 apps.remove(app);
1027 }
1028 }
1029 }
1030
1031
1032 /** Used to 'spawn' a new browser application or reset an existing one when the preview button is clicked
1033 * @param url The url to open the browser at
1034 * @see org.greenstone.gatherer.Gatherer.BrowserApplication
1035 */
1036 static public void spawnBrowser(String url) {
1037 String command = assoc_man.getBrowserCommand(url);
1038 if (command != null) {
1039 BrowserApplication app = new BrowserApplication(command, url);
1040 apps.add(app);
1041 app.start();
1042 }
1043 else {
1044 ///ystem.err.println("No browser command available.");
1045 }
1046 }
1047
1048
1049 /** Prints a warning message about a missing library path, which means the final collection cannot be previewed in the Gatherer.
1050 */
1051 static public void missingEXEC() {
1052 WarningDialog dialog;
1053 String configPropertyName = "general.library_url"+Configuration.gliPropertyNameSuffix();
1054
1055 if (GS3) {
1056 // Warning dialog with no cancel button and no "turn off warning" checkbox
1057 dialog = new WarningDialog("warning.MissingEXEC", Dictionary.get("MissingEXEC_GS3.Title"), Dictionary.get("MissingEXEC_GS3.Message"), configPropertyName, false, false);
1058 } else { // local case
1059 dialog = new WarningDialog("warning.MissingEXEC", Dictionary.get("MissingEXEC.Title"), Dictionary.get("MissingEXEC.Message"), configPropertyName, false);
1060 }
1061
1062 JTextField field = new URLField.Text(Configuration.getColor("coloring.editable_foreground", false), Configuration.getColor("coloring.editable_background", false));
1063
1064 // Set the default library URL to the tomcat server and port number
1065 // specified in the build.properties located in the gsdl3_src_path
1066 if (GS3) {
1067 String host = "localhost";
1068 String port = "8080";
1069
1070 File buildPropsFile = new File(Configuration.gsdl3_src_path + File.separator + "build.properties");
1071 if(buildPropsFile.exists()) {
1072 Properties props = new Properties();
1073 try{
1074 props.load(new FileInputStream(buildPropsFile));
1075 host = props.getProperty("tomcat.server", host);
1076 port = props.getProperty("tomcat.port", port);
1077 }catch(Exception e){
1078 DebugStream.println("Could not load build.properties file");
1079 System.err.println("Could not load build.properties file");
1080 }
1081 props = null;
1082 }
1083 String defaultURL = "http://"+host+":"+port+"/"+"greenstone3";
1084 field.setText(defaultURL);
1085 field.selectAll();
1086 }
1087 dialog.setValueField(field);
1088 dialog.display();
1089 dialog.dispose();
1090 dialog = null;
1091
1092 String library_url_string = Configuration.getString(configPropertyName, true);
1093 if (!library_url_string.equals("")) {
1094 try {
1095 // WarningDialog does not allow invalid URLs, so the following is ignored:
1096 // make sure the URL the user provided contains the http:// prefix
1097 // and then save the corrected URL
1098 if(!library_url_string.startsWith("http://")
1099 && !library_url_string.startsWith("https://")) {
1100 library_url_string = "http://"+library_url_string;
1101 Configuration.setString(configPropertyName, true, configPropertyName);
1102 }
1103 Configuration.library_url = new URL(library_url_string);
1104 }
1105 catch (MalformedURLException exception) {
1106 DebugStream.printStackTrace(exception);
1107 }
1108 }
1109 }
1110
1111
1112
1113 /** Prints a warning message about a missing library path, which means the final collection cannot be previewed in the Gatherer.
1114 */
1115 static private void popupFedoraInfo() {
1116
1117 FedoraLogin dialog = new FedoraLogin("Fedora Login", false);
1118
1119 if (Configuration.library_url == null) {
1120
1121 String library_url_string = dialog.getLibraryURL();
1122 if (!library_url_string.equals("")) {
1123 try {
1124 Configuration.library_url = new URL(library_url_string);
1125 }
1126 catch (MalformedURLException exception) {
1127 DebugStream.printStackTrace(exception);
1128 }
1129 }
1130 }
1131
1132 boolean showLogin = true;
1133 do {
1134 if(!dialog.loginRequested()) { // user pressed cancel to exit the FedoraLogin dialog
1135 System.exit(0);
1136 } else {
1137 showLogin = dialog.loginRequested();
1138 String hostname = dialog.getHostname();
1139 String port = dialog.getPort();
1140 String username = dialog.getUsername();
1141 String password = dialog.getPassword();
1142 String protocol = dialog.getProtocol();
1143
1144 Configuration.fedora_info.setHostname(hostname);
1145 Configuration.fedora_info.setPort(port);
1146 Configuration.fedora_info.setUsername(username);
1147 Configuration.fedora_info.setPassword(password);
1148 Configuration.fedora_info.setProtocol(protocol);
1149
1150 String ping_url_str = protocol + "://" + hostname + ":" + port + "/fedora";
1151 String login_str = username + ":" + password;
1152
1153 String login_encoding = Base64.encodeBytes(login_str.getBytes());
1154
1155 try {
1156 URL ping_url = new URL(ping_url_str);
1157 URLConnection uc = ping_url.openConnection();
1158 uc.setRequestProperty ("Authorization", "Basic " + login_encoding);
1159 // Attempt to access some content ...
1160 InputStream content = (InputStream)uc.getInputStream();
1161
1162 // if no exception occurred in the above, we would have come here:
1163 showLogin = false;
1164 dialog.dispose();
1165 }
1166 catch (Exception exception) {
1167 // TODO: move into dictionary
1168 String[] errorMessage = {"Failed to connect to the Fedora server.", "It might not be running, or",
1169 "incorrect username and/or password."};
1170 dialog.setErrorMessage(errorMessage);
1171 //DebugStream.printStackTrace(exception);
1172 // exception occurred, show the dialog again (do this after printing to
1173 // debugStream, else the above does not get done for some reason).
1174 dialog.setVisible(true);
1175 }
1176 }
1177 } while(showLogin);
1178
1179 dialog = null; // no more need of the dialog
1180
1181 // Now we are connected.
1182 }
1183
1184
1185
1186 static private void requestGLIServerURL()
1187 {
1188 WarningDialog dialog;
1189 String[] defaultURLs = {
1190 "http://localhost:8080/greenstone3/cgi-bin/gliserver.pl",
1191 "http://localhost:8080/gsdl/cgi-bin/gliserver.pl"
1192 };
1193
1194 // Warning dialog with no cancel button and no "turn off warning" checkbox
1195 // (since user-input of the gliserver script is mandatory)
1196 dialog = new WarningDialog("warning.MissingGLIServer", Dictionary.get("MissingGLIServer.Title"), Dictionary.get("MissingGLIServer.Message"), "general.gliserver_url", false, false);
1197
1198 dialog.setValueField(new URLField.DropDown(Configuration.getColor("coloring.editable_foreground", false),
1199 Configuration.getColor("coloring.editable_background", false),
1200 defaultURLs, "general.gliserver_url",
1201 "general.open_collection"+Configuration.gliPropertyNameSuffix(),
1202 "gliserver.pl"));
1203
1204 if (Gatherer.default_gliserver_url!=null){
1205 dialog.setValueField(Gatherer.default_gliserver_url.toString());
1206 }
1207
1208 // A WarningDialog cannot always be made to respond (let alone to exit the program) on close. We
1209 // handle the response of this particular WarningDialog here: a URL for gliserver.pl is a crucial
1210 // piece of user-provided data. Therefore, if no URL was entered for gliserver.pl, it'll exit safely.
1211 dialog.addWindowListener(new WindowAdapter() {
1212 public void windowClosing(WindowEvent e) {
1213 Gatherer.exit();
1214 }
1215 });
1216
1217 dialog.display();
1218 dialog.dispose();
1219 dialog = null;
1220
1221
1222 String gliserver_url_string = Configuration.getString("general.gliserver_url", true);
1223 if (!gliserver_url_string.equals("")) {
1224 try {
1225 Configuration.gliserver_url = new URL(gliserver_url_string);
1226 Configuration.setString("general.gliserver_url", true, gliserver_url_string);
1227 }
1228 catch (MalformedURLException exception) {
1229 DebugStream.printStackTrace(exception);
1230 }
1231 }
1232 }
1233
1234
1235 /** Prints a warning message about a missing GSDL path, which although not fatal pretty much ensures nothing will work properly in the GLI.
1236 */
1237 static private void missingGSDL() {
1238 WarningDialog dialog = new WarningDialog("warning.MissingGSDL", Dictionary.get("MissingGSDL.Title"), Dictionary.get("MissingGSDL.Message"), null, false);
1239 dialog.display();
1240 dialog.dispose();
1241 dialog = null;
1242 }
1243
1244 /** Prints a warning message about missing a valid ImageMagick path, which although not fatal means building image collections won't work */
1245 static private void missingImageMagick() {
1246 WarningDialog dialog = new WarningDialog("warning.MissingImageMagick", Dictionary.get("MissingImageMagick.Title"), Dictionary.get("MissingImageMagick.Message"), null, false);
1247 dialog.display();
1248 dialog.dispose();
1249 dialog = null;
1250 }
1251
1252 /** 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. */
1253 static private void missingPERL() {
1254 WarningDialog dialog = new WarningDialog("warning.MissingPERL", Dictionary.get("MissingPERL.Title"), Dictionary.get("MissingPERL.Message"), null, false);
1255 dialog.display();
1256 dialog.dispose();
1257 dialog = null;
1258 }
1259
1260
1261 /** Sets up the proxy connection by setting JVM Environment flags and creating a new Authenticator.
1262 * @see java.lang.Exception
1263 * @see java.lang.System
1264 * @see java.net.Authenticator
1265 * @see org.greenstone.gatherer.Configuration
1266 * @see org.greenstone.gatherer.GAuthenticator
1267 */
1268 static public void setProxy() {
1269 try {// Can throw several exceptions
1270 if(Configuration.get("general.use_proxy", true)) {
1271 System.setProperty("http.proxyType", "4");
1272 System.setProperty("http.proxyHost", Configuration.getString("general.proxy_host", true));
1273 System.setProperty("http.proxyPort", Configuration.getString("general.proxy_port", true));
1274 System.setProperty("http.proxySet", "true");
1275 } else {
1276 System.setProperty("http.proxyHost", "");
1277 System.setProperty("http.proxyPort", "");
1278 System.setProperty("http.proxySet", "false");
1279 }
1280 } catch (Exception error) {
1281 DebugStream.println("Error in Gatherer.initProxy(): " + error);
1282 DebugStream.printStackTrace(error);
1283 }
1284 }
1285
1286
1287 /** 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. */
1288 static private class ExternalApplication
1289 extends Thread {
1290 private Process process = null;
1291 /** The initial command string given to this sub-process. */
1292 private String command = null;
1293 private String[] commands = null;
1294
1295 private String ID = null;
1296
1297 /** Constructor.
1298 * @param command The initial command <strong>String</strong>.
1299 */
1300 public ExternalApplication(String command) {
1301 this.command = command;
1302 }
1303
1304 public ExternalApplication(String[] commands) {
1305 this.commands = commands;
1306 }
1307
1308 public ExternalApplication(String command, String ID) {
1309 this.command = command;
1310 this.ID = ID;
1311 }
1312
1313 public ExternalApplication(String[] commands, String ID) {
1314 this.commands = commands;
1315 this.ID = ID;
1316 }
1317
1318 public String getID() {
1319 return ID;
1320 }
1321
1322 /** We start the child process inside a new thread so it doesn't block the rest of Gatherer.
1323 * @see java.lang.Exception
1324 * @see java.lang.Process
1325 * @see java.lang.Runtime
1326 * @see java.lang.System
1327 * @see java.util.Vector
1328 */
1329 public void run() {
1330 // Call an external process using the args.
1331 try {
1332 if(commands != null) {
1333 StringBuffer whole_command = new StringBuffer();
1334 for(int i = 0; i < commands.length; i++) {
1335 whole_command.append(commands[i]);
1336 whole_command.append(" ");
1337 }
1338 DebugStream.println("Running " + whole_command.toString());
1339 Runtime rt = Runtime.getRuntime();
1340 process = rt.exec(commands);
1341 process.waitFor();
1342 }
1343 else {
1344 DebugStream.println("Running " + command);
1345 Runtime rt = Runtime.getRuntime();
1346 process = rt.exec(command);
1347 process.waitFor();
1348 }
1349 }
1350 catch (Exception exception) {
1351 DebugStream.printStackTrace(exception);
1352 }
1353 // Remove ourself from Gatherer list of threads.
1354 apps.remove(this);
1355 // Call exit if we were the last outstanding child process thread.
1356 if (apps.size() == 0 && exit == true) {
1357 // In my opinion (DB) there is no need to exit here,
1358 // the 'run' method ending naturally brings this
1359 // thread to an end. In fact it is potentially
1360 // dangerous to exit here, as the main thread in the
1361 // Gatherer class may be stopped prematurely. As it so
1362 // happens the point at which the ExternalApplication thread
1363 // is asked to stop (Back in the main Gatherer thread) is after
1364 // various configuration files have been saved.
1365 //
1366 // A similar argument holds for BrowserApplication thread below.
1367 System.exit(exit_status);
1368 }
1369 }
1370 public void stopExternalApplication() {
1371 if(process != null) {
1372 process.destroy();
1373 }
1374 }
1375 }
1376 /** 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. */
1377 static private class BrowserApplication
1378 extends Thread {
1379 private Process process = null;
1380 /** The initial command string given to this sub-process. */
1381 private String command = null;
1382 private String url = null;
1383 private String[] commands = null;
1384
1385 public BrowserApplication(String command, String url) {
1386 StringTokenizer st = new StringTokenizer(command);
1387 int num_tokens = st.countTokens();
1388 this.commands = new String [num_tokens];
1389 int i=0;
1390 while (st.hasMoreTokens()) {
1391 commands[i] = st.nextToken();
1392 i++;
1393 }
1394 //this.commands = commands;
1395 this.url = url;
1396 }
1397 /** We start the child process inside a new thread so it doesn't block the rest of Gatherer.
1398 * @see java.lang.Exception
1399 * @see java.lang.Process
1400 * @see java.lang.Runtime
1401 * @see java.lang.System
1402 * @see java.util.Vector
1403 */
1404 public void run() {
1405 // Call an external process using the args.
1406 if(commands == null) {
1407 apps.remove(this);
1408 return;
1409 }
1410 try {
1411 String prog_name = commands[0];
1412 String lower_name = prog_name.toLowerCase();
1413 if (lower_name.indexOf("mozilla") != -1 || lower_name.indexOf("netscape") != -1) {
1414 DebugStream.println("found mozilla or netscape, trying remote it");
1415 // mozilla and netscape, try using a remote command to get things in the same window
1416 String [] new_commands = new String[] {prog_name, "-raise", "-remote", "openURL("+url+",new-tab)"};
1417 printArray(new_commands);
1418
1419 Runtime rt = Runtime.getRuntime();
1420 process = rt.exec(new_commands);
1421 int exitCode = process.waitFor();
1422 if (exitCode != 0) { // if Netscape or mozilla was not open
1423 DebugStream.println("couldn't do remote, trying original command");
1424 printArray(commands);
1425 process = rt.exec(commands); // try the original command
1426 }
1427 } else {
1428 // just run what we have been given
1429 StringBuffer whole_command = new StringBuffer();
1430 for(int i = 0; i < commands.length; i++) {
1431 whole_command.append(commands[i]);
1432 whole_command.append(" ");
1433 }
1434 DebugStream.println("Running " + whole_command.toString());
1435 Runtime rt = Runtime.getRuntime();
1436 process = rt.exec(commands);
1437 process.waitFor();
1438 }
1439 }
1440
1441 catch (Exception exception) {
1442 DebugStream.printStackTrace(exception);
1443 }
1444 // Remove ourself from Gatherer list of threads.
1445 apps.remove(this);
1446 // Call exit if we were the last outstanding child process thread.
1447 if (apps.size() == 0 && exit == true) {
1448 System.exit(exit_status);
1449 }
1450 }
1451 public void printArray(String [] array) {
1452 for(int i = 0; i < array.length; i++) {
1453 DebugStream.print(array[i]+" ");
1454 System.err.println(array[i]+" ");
1455 }
1456 }
1457 public void stopBrowserApplication() {
1458 if(process != null) {
1459 process.destroy();
1460 }
1461 }
1462 }
1463
1464
1465 private class ImageMagickTest
1466 {
1467 public boolean found()
1468 {
1469 try {
1470 String[] command = new String[2];
1471 command[0] = (Utility.isWindows() ? "identify.exe" : "identify");
1472 command[1] = "-version";
1473 Process image_magick_process = Runtime.getRuntime().exec(command);
1474 image_magick_process.waitFor();
1475
1476 //new way of detection of ImageMagick
1477 InputStreamReader isr = new InputStreamReader(image_magick_process.getInputStream());
1478
1479 BufferedReader br = new BufferedReader(isr);
1480 // Capture the standard output stream and seach for two particular occurances: Version and ImageMagick.
1481
1482 String line = br.readLine();
1483 if (line == null) {
1484 return false;
1485 }
1486 String lc_line = line.toLowerCase();
1487 if (lc_line.indexOf("version") != -1 || lc_line.indexOf("imagemagick") != -1) {
1488 return true;
1489 } else {
1490 return false;
1491 }
1492
1493 //return (image_magick_process.exitValue() == 0);
1494 }
1495 catch (IOException exception) {
1496 return false;
1497 }
1498 catch (InterruptedException exception) {
1499 return false;
1500 }
1501 }
1502 }
1503
1504
1505 private class PerlTest
1506 {
1507 private String[] command = new String[2];
1508
1509 public PerlTest()
1510 {
1511 command[0] = (Utility.isWindows() ? Utility.PERL_EXECUTABLE_WINDOWS : Utility.PERL_EXECUTABLE_UNIX);
1512 command[1] = "-version";
1513 }
1514
1515 public boolean found()
1516 {
1517 try {
1518 Process perl_process = Runtime.getRuntime().exec(command);
1519 perl_process.waitFor();
1520 return (perl_process.exitValue() == 0);
1521 }
1522 catch (Exception exception) {
1523 return false;
1524 }
1525 }
1526
1527 public String toString() {
1528 return command[0];
1529 }
1530 }
1531}
Note: See TracBrowser for help on using the repository browser.