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

Last change on this file since 34544 was 34544, checked in by ak19, 3 years ago

The UTF-8 locale warning when starting GLI just after a successful GS install is thought to be alarming. So switched off. It will not be triggered to appear at any other juncture at this point, however.

  • Property svn:keywords set to Author Date Id Revision
File size: 72.4 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.ProtocolPortProperties;
54import org.greenstone.gatherer.greenstone3.ServletConfiguration;
55import org.greenstone.gatherer.gui.GUIManager;
56import org.greenstone.gatherer.gui.URLField;
57import org.greenstone.gatherer.gui.WarningDialog;
58import org.greenstone.gatherer.gui.FedoraLogin;
59import org.greenstone.gatherer.gui.TestingPreparation;
60import org.greenstone.gatherer.metadata.FilenameEncoding;
61import org.greenstone.gatherer.remote.RemoteGreenstoneServer;
62import org.greenstone.gatherer.util.GS3ServerThread;
63import org.greenstone.gatherer.util.JarTools;
64import org.greenstone.gatherer.util.SafeProcess;
65import org.greenstone.gatherer.util.StaticStrings;
66import org.greenstone.gatherer.util.Utility;
67
68
69/** Containing the top-level "core" for the Gatherer, this class is the
70* common core for the GLI application and applet. It first parses the
71* command line arguments, preparing to update the configuration as
72* required. Next it loads several important support classes such as the
73* Configuration and Dictionary. Finally it creates the other important
74* managers and sends them on their way.
75* @author John Thompson, Greenstone Digital Library, University of Waikato
76* @version 2.3
77*/
78public class Gatherer
79{
80 /** The name of the GLI. */
81 static final public String PROGRAM_NAME = "Greenstone Librarian Interface";
82 /** The current version of the GLI.
83 * Note: the gs3-release-maker relies on this variable being declared
84 * in a line which matches this java regex:
85 * ^(.*)String\s*PROGRAM_VERSION\s*=\s*"trunk";
86 * If change the declaration and it no longer matches the regex, please
87 * change the regex in the gs3-release-maker code and in this message
88 */
89
90 static final public String PROGRAM_VERSION = "trunk";
91
92 static private Dimension size = new Dimension(800, 540);
93 static public RemoteGreenstoneServer remoteGreenstoneServer = null;
94
95 /** Has the exit flag been set? */
96 static final public int EXIT_THEN_RESTART= 2;
97 static public boolean exit = false;
98 static public int exit_status = 0;
99
100 static private String gli_directory_path = null;
101 static private String gli_user_directory_path = null;
102
103 static public String client_operating_system = null;
104
105 /** All of the external applications that must exit before we close the Gatherer. */
106 static private Vector apps = new Vector();
107 static private String non_standard_collect_directory_path = null;
108 static public String open_collection_file_path = null;
109 static public String gsdlsite_collecthome = "";
110 /** A public reference to the FileAssociationManager. */
111 static public FileAssociationManager assoc_man;
112 /** A public reference to the CollectionManager. */
113 static public CollectionManager c_man;
114 /** A public reference to the RecycleBin. */
115 static public RecycleBin recycle_bin;
116 /** a reference to the Servlet Configuration is GS3 */
117 static public ServletConfiguration servlet_config;
118 /** A public reference to the FileManager. */
119 static public FileManager f_man;
120 /** A public reference to the GUIManager. */
121 static public GUIManager g_man = null;
122 static private boolean g_man_built = false;
123
124 /** We are using the GLI for GS3 */
125 static public boolean GS3 = false;
126
127 static public boolean isApplet = false;
128 static public boolean isGsdlRemote = false;
129 static public boolean isLocalLibrary = false;
130
131 // for storing the original proxy settings on GLI startup
132 private static Properties startup_proxy_settings = new Properties();
133
134 /* TODO: If we're using local GLI, collections are built locally. If we're using client-GLI
135 * and it contains a gs2build folder in it, then localBuild will also be true (if this is not
136 * turned off in Preferences). If we're remote and this is turned off in Prefs, build remotely. */
137 /*static public boolean buildingLocally = true;*/
138 /** If we're using local GLI, we can always download. If we're using client-GLI, we can only
139 * download if we have a gs2build folder inside it. And if we don't turn off downloadEnabling
140 * in the preferences.
141 */
142 static public boolean isDownloadEnabled = true;
143
144 // feedback stuff
145 /** is the feedback feature enabled? */
146 static public boolean feedback_enabled = true;
147 /** the action recorder dialog */
148 static public ActionRecorderDialog feedback_dialog = null;
149
150 // Refresh reasons
151 static public final int COLLECTION_OPENED = 0;
152 static public final int COLLECTION_CLOSED = 1;
153 static public final int COLLECTION_REBUILT = 2;
154 static public final int PREFERENCES_CHANGED = 3;
155
156 //////kk added////////
157 static public String cgiBase="";
158 /////////////////
159
160 /** Magic to allow Enter to fire the default button. */
161 static {
162 KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
163 Keymap map = JTextComponent.getKeymap(JTextComponent.DEFAULT_KEYMAP);
164 map.removeKeyStrokeBinding(enter);
165 }
166
167 static private URL default_gliserver_url=null;
168
169 public Gatherer(String[] args)
170 {
171 // Display the version to make error reports a lot more useful
172 System.err.println("Version: " + PROGRAM_VERSION + "\n");
173
174 JarTools.initialise(this);
175
176 GetOpt go = new GetOpt(args);
177
178 // Remember the GSDLOS value
179 client_operating_system = go.client_operating_system;
180
181 // If feedback is enabled, set up the recorder dialog
182 if (go.feedback_enabled) {
183 // Use the default locale for now - this will be changed by the Gatherer run method
184 feedback_enabled = true;
185 feedback_dialog = new ActionRecorderDialog(Locale.getDefault());
186 }
187
188 // Are we using a remote Greenstone?
189 if (go.use_remote_greenstone) {
190 isGsdlRemote = true;
191
192 // We don't have a local Greenstone!
193 go.gsdl3_path=null;
194 go.gsdl3_src_path=null;
195
196 // Don't set go.gsdl_path to null, since gdsl_path may still be set
197 // if we have a client-gli containing gs2build folder.
198 // However, keep track of whether we can download.
199 if(go.gsdl_path == null) {
200 isDownloadEnabled = false;
201 }
202
203 // We have to use our own collect directory since we can't use the Greenstone one
204 setCollectDirectoryPath(getGLIUserDirectoryPath() + "collect" + File.separator);
205 }
206 // We have a local Greenstone. OR we have a gs2build folder inside
207 // the client-GLI folder (with which the Download panel becomes enabled)
208 if(isDownloadEnabled) {
209 LocalGreenstone.setDirectoryPath(go.gsdl_path);
210 }
211
212 // Users may specify a non-standard collect directory (eg. when running one GLI in a network environment)
213 // Processing of custom non-standard collect directory passed into gli now happens in init()
214 //if (go.collect_directory_path != null) { setCollectDirectoryPath(go.collect_directory_path); }
215
216 // More special code for running with a remote Greenstone
217 if (isGsdlRemote) {
218 if (go.fedora_info.isActive()) {
219 Configuration.TEMPLATE_CONFIG_XML = "xml/" + Configuration.FEDORA_CONFIG_PREFIX + "configRemote.xml";
220 }
221 else {
222 Configuration.TEMPLATE_CONFIG_XML = "xml/configRemote.xml";
223 }
224
225 Configuration.CONFIG_XML = "configRemote.xml";
226
227 File collect_directory = new File(Gatherer.getCollectDirectoryPath());
228 if (!collect_directory.exists() && !collect_directory.mkdir()) {
229 System.err.println("Warning: Unable to make directory: " + collect_directory);
230 }
231 }
232 else {
233 if (go.fedora_info.isActive()) {
234 Configuration.TEMPLATE_CONFIG_XML = "xml/" + Configuration.FEDORA_CONFIG_PREFIX + Configuration.CONFIG_XML;
235 }
236 // else, the CONFIG_XML uses the default config file, which is for the local GS server
237 }
238
239 if(go.testing_mode) {
240 TestingPreparation.TEST_MODE = true;
241 }
242
243 init(go.gsdl_path, go.gsdl3_path, go.gsdl3_src_path,
244 go.fedora_info,
245 go.local_library_path, go.library_url_string,
246 go.gliserver_url_string, go.debug, go.perl_path, go.no_load, go.filename, go.site_name,
247 go.servlet_path, go.collect_directory_path);
248 }
249
250
251 public void init(String gsdl_path, String gsdl3_path, String gsdl3_src_path,
252 FedoraInfo fedora_info,
253 String local_library_path,
254 String library_url_string, String gliserver_url_string, boolean debug_enabled,
255 String perl_path, boolean no_load, String open_collection,
256 String site_name, String servlet_path, String collect_directory_path)
257 {
258 if (gsdl3_path != null && !gsdl3_path.equals("")) {
259 this.GS3 = true;
260 } else {
261 gsdl3_path = null;
262 gsdl3_src_path = null;
263 }
264
265 // Create the debug stream if required
266 if (debug_enabled) {
267 DebugStream.enableDebugging();
268
269 Calendar now = Calendar.getInstance();
270 String debug_file_path = "debug" + now.get(Calendar.DATE) + "-" + now.get(Calendar.MONTH) + "-" + now.get(Calendar.YEAR) + ".txt";
271
272 // Debug file is created in the user's GLI directory
273 debug_file_path = getGLIUserDirectoryPath() + debug_file_path;
274 DebugStream.println("Debug file path: " + debug_file_path);
275 DebugStream.setDebugFile(debug_file_path);
276 DebugStream.print(System.getProperties());
277 }
278
279 // Delete plugins.dat and classifiers.dat files from previous versions of the GLI (no longer used)
280 File plugins_dat_file = new File(Gatherer.getGLIUserDirectoryPath() + "plugins.dat");
281 if (plugins_dat_file.exists()) {
282 System.err.println("Deleting plugins.dat file...");
283 Utility.delete(plugins_dat_file);
284 }
285 File classifiers_dat_file = new File(Gatherer.getGLIUserDirectoryPath() + "classifiers.dat");
286 if (classifiers_dat_file.exists()) {
287 System.err.println("Deleting classifiers.dat file...");
288 Utility.delete(classifiers_dat_file);
289 }
290
291 try {
292 // Load GLI config file
293 new Configuration(getGLIUserDirectoryPath(), gsdl_path, gsdl3_path, gsdl3_src_path, site_name,
294 fedora_info);
295
296 // Check we know where Perl is
297 Configuration.perl_path = perl_path;
298 if (isGsdlRemote && !isDownloadEnabled && Utility.isWindows() && Configuration.perl_path != null) {
299 if (Configuration.perl_path.toLowerCase().endsWith("perl.exe")) {
300 Configuration.perl_path = Configuration.perl_path.substring(0, Configuration.perl_path.length() - "perl.exe".length());
301 }
302 if (Configuration.perl_path.endsWith(File.separator)) {
303 Configuration.perl_path = Configuration.perl_path.substring(0, Configuration.perl_path.length() - File.separator.length());
304 }
305 }
306
307 // the feedback dialog has been loaded with a default locale,
308 // now set the user specified one
309 if (feedback_enabled && feedback_dialog != null) {
310 feedback_dialog.setLocale(Configuration.getLocale("general.locale", true));
311 }
312
313 // Read Dictionary
314 new Dictionary(Configuration.getLocale("general.locale", true), Configuration.getFont("general.font", true));
315
316 // check that we are using Sun Java
317 String java_vendor = System.getProperty("java.vendor");
318 if (!java_vendor.equals("Sun Microsystems Inc.")
319 && !java_vendor.equals("Oracle Corporation")) {
320 System.err.println(Dictionary.get("General.NotSunJava", java_vendor));
321 }
322
323 // Unless we're using remote building, we need to know where the local Greenstone is
324 if (!isGsdlRemote && gsdl_path == null) {
325 missingGSDL();
326 }
327
328 if (fedora_info.isActive()) {
329
330 // if we have either a remote GS 2/3 server, or if we are dealing with a
331 // local GS2, or else if it's a local GS3 but with fedora installed elsewhere,
332 // we ask for fedora login details now
333 File fedora_webapp = new File(gsdl3_src_path+File.separator+"packages"+File.separator+"tomcat"+File.separator+"webapps"+File.separator+"fedora");
334
335 if(isGsdlRemote || !GS3 || !fedora_webapp.exists()) {
336 popupFedoraInfo();
337 }
338
339 // else if we have a local GS3 with fedora installed within it, we'll be starting
340 // up fedora further below, together with the local tomcat
341 }
342
343 // the no_load flag to GLI is processed at the end of handling open_collection_file_path
344 open_collection_file_path = open_collection;
345 if (open_collection_file_path == null) {
346 open_collection_file_path = Configuration.getString(
347 "general.open_collection"+Configuration.gliPropertyNameSuffix(), true);
348 }
349
350 initCollectDirectoryPath();
351
352 if (no_load || (isGsdlRemote && open_collection_file_path.equals(""))) {
353 open_collection_file_path = null;
354 }
355
356
357 // Before calling setProxy, store anything already present
358 // Downloading happens on the machine where GLI is running from, even with clientgli
359 // For downloading with wget, we use ftp/http(s)_proxy env vars, so check if they're
360 // already set
361 if(System.getenv("http_proxy") != null) System.err.println("http_proxy already set");
362 if(System.getenv("https_proxy") != null) System.err.println("https_proxy already set");
363 if(System.getenv("ftp_proxy") != null) System.err.println("ftp_proxy already set");
364
365
366 // Finally, we're ready to find out the version of the remote Greenstone server
367 if(isGsdlRemote) {
368 // instantiate the RemoteGreenstoneServer object first
369 remoteGreenstoneServer = new RemoteGreenstoneServer();
370
371 // Set up proxy
372 setProxy();
373 // Now we set up an Authenticator
374 Authenticator.setDefault(new GAuthenticator());
375
376 int greenstoneVersion = 2;
377 requestGLIServerURL();
378 gliserver_url_string = Configuration.gliserver_url.toString();
379
380 greenstoneVersion = remoteGreenstoneServer.getGreenstoneVersion();
381 // Display the version to make error reports a lot more useful
382 System.err.println("Remote Greenstone server version: " + greenstoneVersion);
383 if(greenstoneVersion == -1) { // remote server not running
384 Gatherer.exit();
385 }
386 if(greenstoneVersion >= 3) {
387 this.GS3 = true;
388 Configuration.prepareForGS3();
389 }
390
391 if(fedora_info.isActive()) {
392 // when GS server is remote, FEDORA_HOME resides on the remote server side,
393 // but we know the library URL from user-provided information
394 library_url_string = fedora_info.getLibraryURL();
395 } else {
396 library_url_string = remoteGreenstoneServer.getLibraryURL(Configuration.gliserver_url.toString());
397 }
398 // write it into the config file
399 Configuration.setString("general.library_url", true, library_url_string);
400 }
401 else { // local greenstone: add shutdown hooks to forcibly stop the server on irregular termination
402 // And start up the local library server, if that's what we want
403
404 // The Java virtual machine shuts down in response to two kinds of events:
405 // - The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or
406 // - The virtual machine is terminated in response to a user interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.
407 // https://coderanch.com/t/328888/java/Killing-process-spawned-Runtime-exec
408 // So here we add a shutdown hook to take care of Ctrl-C situations where GLI is irregularly terminated
409 // Sadly, the shutdownhook never gets called on Windows, whether GS2 or GS3,
410 // when a Ctrl-C is sent to the DOS prompt that launched GLI. Because GLI on Windows
411 // currently waits to respond to a Ctrl-C until AFTER GLI is already (properly) exited
412 Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
413 public void run() {
414
415 if(Gatherer.exit != true) { // unexpected termination, such as Ctrl-C won't set Gatherer.exit
416 // so still need to at least issue the call to stop any running GS server
417
418 System.err.println("ShutDownHook called...");
419
420 if (GS3) { // issue the ant call to stop any running GS3
421 // (tomcat and networked Derby Server) by calling GS3ServerThread.stopServer()
422 if(!GS3ServerThread.wasServerLaunchedOutsideGLI()) {
423 System.err.println("Attempting to forcibly terminate the GS server...");
424 GS3ServerThread.stopServer();
425 } else {
426 System.err.println("@@@ Tomcat was launched outside GLI. Leaving it running...");
427 }
428 } else { // issue the call to stop any running GS2 local library server
429 if (LocalLibraryServer.isRunning() == true) {
430 System.err.println("Attempting to forcibly terminate the GS server...");
431 LocalLibraryServer.forceStopServer();
432 }
433 }
434 }
435 }
436 }));
437
438
439 if (!GS3) {
440 isLocalLibrary = LocalLibraryServer.start(gsdl_path, local_library_path);
441
442 }
443 else { // local GS3, start the local tomcat
444
445 if(!GS3ServerThread.wasServerLaunchedOutsideGLI()) {
446 //System.err.println("@@@@ Launching tomcat from GLI");
447 GS3ServerThread thread = new GS3ServerThread(gsdl3_src_path, "restart");
448 thread.start();
449 }
450
451 // If fedora installed inside this local GS3, then ask for fedora login details now.
452 if (fedora_info.isActive()) {
453 File fedora_webapp = new File(gsdl3_src_path+File.separator+"packages"+File.separator+"tomcat"+File.separator+"webapps"+File.separator+"fedora");
454
455 if(fedora_webapp.exists()) {
456 System.err.println("**** Waiting for the local Greenstone server to start up fedora...");
457 popupFedoraInfo();
458 }
459 }
460 }
461 // else web library: GS server is local, but doesn't use the webserver included with GS2
462 }
463
464 // The "-library_url" option overwrites anything in the config files
465 if (library_url_string != null && library_url_string.length() > 0) {
466 try {
467 System.err.println("Setting library_url to " + library_url_string + "...");
468 Configuration.library_url = new URL(library_url_string);
469 }
470 catch (MalformedURLException error) {
471 DebugStream.printStackTrace(error);
472 }
473 }
474
475
476 // Check that we now know the Greenstone library URL, since we need this for previewing collections
477 // It is not necessary if an independent GSI was launched and the user hasn't pressed Enter Library yet
478 DebugStream.println("Configuration.library_url = " + Configuration.library_url);
479 if (Configuration.library_url == null) {
480 if(isLocalLibrary) {
481 if(!LocalLibraryServer.isURLPending()) {
482 missingEXEC();
483 }
484 // else LocalLibraryServer is expecting a URL soon, so don't need to display the dialog
485 } else { // GS2 webLibrary or GS3 or remote Greenstone
486 missingEXEC();
487 }
488 }
489
490 // The "-gliserver_url" option overwrites anything in the config files
491 if (gliserver_url_string != null && gliserver_url_string.length() > 0) {
492 try {
493 System.err.println("Setting gliserver_url to " + gliserver_url_string + "...");
494 Configuration.gliserver_url = new URL(gliserver_url_string);
495 }
496 catch (MalformedURLException error) {
497 DebugStream.printStackTrace(error);
498 }
499 }
500
501 // If we're using a remote Greenstone we need to know where the gliserver script is
502 DebugStream.println("Configuration.gliserver_url = " + Configuration.gliserver_url);
503
504 if (GS3) {
505 // Load Greenstone 3 servlet configuration
506 if (isGsdlRemote){
507 servlet_config = new ServletConfiguration(Configuration.gli_user_directory_path);
508 }else{
509 servlet_config= new ServletConfiguration(gsdl3_path);
510 }
511 }
512
513 if (GS3 && Configuration.servlet_path == null) {
514 Configuration.servlet_path = servlet_config.getServletPath(Configuration.site_name);
515 }
516
517 // ensure that a directory called 'cache' exists in the GLI user directory
518 File user_cache_dir = new File(Gatherer.getGLIUserCacheDirectoryPath());
519 System.err.println("User cache dir: " + Gatherer.getGLIUserCacheDirectoryPath());
520 if (!user_cache_dir.exists() && !user_cache_dir.mkdir()) {
521 System.err.println("Warning: Unable to make directory: " + user_cache_dir);
522 }
523
524
525 if (Gatherer.isGsdlRemote) {
526 DebugStream.println("Not checking for perl path/exe");
527 }
528 else {
529 // Perl path is a little different as it is perfectly ok to
530 // start the GLI without providing a perl path
531 boolean found_perl = false;
532 if (Configuration.perl_path != null) {
533 // See if the file pointed to actually exists
534 File perl_file = new File(Configuration.perl_path);
535 found_perl = perl_file.exists();
536 perl_file = null;
537 }
538 if (Configuration.perl_path == null || !found_perl) {
539 // Run test to see if we can run perl as is.
540 PerlTest perl_test = new PerlTest();
541 if (perl_test.found()) {
542 // If so replace the perl path with the system
543 // default (or null for unix).
544 Configuration.perl_path = perl_test.toString();
545 found_perl = true;
546 }
547 }
548 if (!found_perl) {
549 // Time for an error message.
550 missingPERL();
551 }
552 }
553
554
555 // Check for ImageMagick - dependent on perl_path
556 if (Gatherer.isGsdlRemote) {
557 DebugStream.println("Not checking for ImageMagick.");
558 }
559 else if (!(new ImageMagickTest()).found()) {
560 // Time for a warning message
561 missingImageMagick();
562 }
563
564 // Check for PDFBox
565 if (Gatherer.isGsdlRemote) {
566 DebugStream.println("Not checking for PDFBox.");
567 }
568 else {
569 String gs_dir = gsdl_path; // for GS3, pdf-box is in gs2build/ext (not in GS3/ext), for GS2 it's also in GS2/ext
570 File pdfboxExtensionFolder = new File(gs_dir+File.separator+"ext"+File.separator+"pdf-box");
571 if (!(pdfboxExtensionFolder.exists() && pdfboxExtensionFolder.isDirectory())) {
572 // The user doesn't have PDFBox, inform them of it
573 String zipExtension = Utility.isWindows() ? "zip" : "tar.gz";
574 missingPDFBox(zipExtension, pdfboxExtensionFolder.getParent());
575 }
576 }
577
578 // Check that the locale can support multiple filename encodings
579 //System.err.println("#### Java identifies current Locale as (file.encoding): "
580 // + System.getProperty("file.encoding"));
581 if(System.getProperty("file.encoding").equals("UTF-8")){
582 // If the locale is UTF-8, Java will interpret all filename bytes as UTF-8,
583 // which is a destructive process as it will convert characters not recognised
584 // by UTF-8 into the invalid character, rather than preserving the bytecodes.
585 // This has the effect that non-UTF8 encoded filenames on a system set to a
586 // UTF-8 locale are not 'seen' by Java (if they contain non-ASCII characters).
587
588 // This message popping up first thing after a successful GS install is thought
589 // to be unnecessarily alarming. Turning off.
590 //multipleFilenameEncodingsNotSupported();
591 FilenameEncoding.MULTIPLE_FILENAME_ENCODINGS_SUPPORTED = false;
592 FilenameEncoding.URL_FILE_SEPARATOR = File.separator;
593 } else {
594 FilenameEncoding.MULTIPLE_FILENAME_ENCODINGS_SUPPORTED = true;
595 FilenameEncoding.URL_FILE_SEPARATOR = "/"; // URL file separator is always "/"
596 }
597
598 // Set the default font for all Swing components.
599 FontUIResource default_font = Configuration.getFont("general.font", true);
600 Enumeration keys = UIManager.getDefaults().keys();
601 while (keys.hasMoreElements()) {
602 Object key = keys.nextElement();
603 Object value = UIManager.get(key);
604 if (value instanceof FontUIResource) {
605 UIManager.put(key, default_font);
606 }
607 }
608
609 // At this point (which is where this code originally used to be), we can set up the proxy for the
610 // non-remote case. The remote Greenstone server would already have setup its proxy when required.
611 if(!isGsdlRemote) {
612 setProxy();
613 // Now we set up an Authenticator
614 Authenticator.setDefault(new GAuthenticator());
615 }
616 assoc_man = new FileAssociationManager();
617 // Create File Manager
618 f_man = new FileManager();
619 // Create Collection Manager
620 c_man = new CollectionManager();
621 // Create Recycle Bin
622 recycle_bin = new RecycleBin();
623
624 if (GS3) {
625 if (site_name==null) {
626 site_name = Configuration.site_name;
627 servlet_path = null; // need to reset this
628 }
629 if (servlet_path == null) {
630 servlet_path = Configuration.getServletPath();
631 }
632 }
633
634
635 } catch (Exception exception) {
636 DebugStream.printStackTrace(exception);
637 }
638
639
640 // Create GUI Manager (last) or else suffer the death of a thousand NPE's
641 g_man = new GUIManager(size);
642
643 // Get a list of the core Greenstone classifiers and plugins
644 Classifiers.loadClassifiersList(null);
645 Plugins.loadPluginsList(null);
646
647 // Users may specify a non-standard collect directory (eg. when running one GLI in a network environment)
648 // Set to any custom collection directory provided to gli. This happens if gli was run as:
649 // ./gli.sh -collectdir </full/path/to/custom/collect>
650 if(collect_directory_path != null) {
651
652 // create a version of the collect_dir_path without a file-separator at end
653 String collectDir = collect_directory_path;
654 if(collectDir.endsWith(File.separator)) {
655 collectDir = collectDir.substring(0, collectDir.length()-1); // remove file separator at end
656 }
657
658 // update .gli/config.xml to contain the version of the path without file-separator at end
659 if(collect_directory_path.equals(getDefaultGSCollectDirectoryPath(false))) {
660 Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(),
661 true, "");
662 } else {
663 Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(),
664 true, collectDir);
665 }
666
667 // set non_standard_collect_directory_path variable. Ensures file_separator at end
668 Gatherer.setCollectDirectoryPath(collect_directory_path);
669
670 // Use version of path without file-separator at end to set collecthome in gsdlsite(3).cfg
671 if(collectDir != null) {
672 collectDir = "\""+collectDir+"\"";
673 }
674 Utility.updatePropertyConfigFile(getGsdlSiteConfigFile(), "collecthome", collectDir);
675 // if gsdlsite.cfg does not exist (if using server.exe for instance), the above method will just return
676 }
677
678 // If using a remote Greenstone we need to download the collection configurations now
679 if (Gatherer.isGsdlRemote) {
680 if (remoteGreenstoneServer.downloadCollectionConfigurations().equals("")) {
681 // !! Something went wrong downloading the collection configurations
682 System.err.println("Error: Could not download collection configurations.");
683 if(!Gatherer.isApplet) { // don't close the browser if it is an applet!
684 System.exit(0);
685 }
686 }
687 }
688 }
689
690
691 /** Returns the correct version of the (local or remote) Greenstone server if init() has already been called. */
692 public static int serverVersionNumber() {
693 return GS3 ? 3 : 2;
694 }
695
696 /** Returns "Server: version number" if init() has already been called. */
697 public static String getServerVersionAsString() {
698 return "Server: v" + serverVersionNumber();
699 }
700
701 public void openGUI()
702 {
703 // Size and place the frame on the screen
704 Rectangle bounds = Configuration.getBounds("general.bounds", true);
705 if (bounds == null) {
706 // Choose a sensible default value
707 bounds = new Rectangle(0, 0, 640, 480);
708 }
709
710 // Ensure width and height are reasonable
711 size = bounds.getSize();
712 if (size.width < 640) {
713 size.width = 640;
714 }
715 else if (size.width > Configuration.screen_size.width && Configuration.screen_size.width > 0) {
716 size.width = Configuration.screen_size.width;
717 }
718 if (size.height < 480) {
719 size.height = 480;
720 }
721 else if (size.height > Configuration.screen_size.height && Configuration.screen_size.height > 0) {
722 size.height = Configuration.screen_size.height;
723 }
724
725 if (!g_man_built) {
726
727 g_man.display();
728
729 // 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).
730 g_man.setLocation(bounds.x, bounds.y);
731 g_man.setVisible(true);
732
733 // After the window has been made visible, check that it is in the correct place
734 // sometimes java places a window not in the correct place,
735 // but with an offset. If so, we work out what the offset is
736 // and change the desired location to take that into account
737 Point location = g_man.getLocation();
738 int x_offset = bounds.x - location.x;
739 int y_offset = bounds.y - location.y;
740 // If not, offset the window to move it into the correct location
741 if (x_offset > 0 || y_offset > 0) {
742 ///ystem.err.println("changing the location to "+(bounds.x + x_offset)+" "+ (bounds.y + y_offset));
743 g_man.setLocation(bounds.x + x_offset, bounds.y + y_offset);
744 }
745
746 // 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.
747 g_man.afterDisplay();
748 g_man_built = true;
749 }
750 else {
751 g_man.setVisible(true);
752 }
753
754 // Get a list of the core Greenstone classifiers and plugins
755 /*Classifiers.loadClassifiersList(null);
756 Plugins.loadPluginsList(null);
757
758 // If using a remote Greenstone we need to download the collection configurations now
759 if (Gatherer.isGsdlRemote) {
760 if (remoteGreenstoneServer.downloadCollectionConfigurations().equals("")) {
761 // !! Something went wrong downloading the collection configurations
762 System.err.println("Error: Could not download collection configurations.");
763 System.exit(0);
764 }
765 }*/
766
767 // if we're tutorial testing GLI, want names assigned to the GUI components
768 TestingPreparation.setNamesRecursively(g_man);
769
770
771 // If there was a collection left open last time, reopen it
772 if (open_collection_file_path == null || new File(Gatherer.open_collection_file_path).isDirectory()) {
773
774 //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's disabled until the collection finishes loading. They will be enabled in collectionManager.java
775 setMenuBarEnabled(true);
776 } else {
777
778 // If there was a collection left open last time, reopen it
779 c_man.openCollectionFromLastTime();
780 }
781 }
782
783 public static void setMenuBarEnabled(boolean enabled) {
784 g_man.menu_bar.file.setEnabled(enabled);
785 g_man.menu_bar.edit.setEnabled(enabled);
786 }
787
788 /** Exits the Gatherer after ensuring that things needing saving are saved.
789 * @see java.io.FileOutputStream
790 * @see java.io.PrintStream
791 * @see java.lang.Exception
792 * @see javax.swing.JOptionPane
793 * @see org.greenstone.gatherer.Configuration
794 * @see org.greenstone.gatherer.collection.CollectionManager
795 * @see org.greenstone.gatherer.gui.GUIManager
796 */
797 static public void exit(int new_exit_status)
798 {
799 DebugStream.println("In Gatherer.exit()...");
800 exit = true;
801 if (new_exit_status != 0) {
802 // default exit_status is already 0
803 // only remember a new exit status if it is non-trivial
804 exit_status = new_exit_status;
805 }
806
807 // Save the file associations
808 if (assoc_man != null) {
809 assoc_man.save();
810 assoc_man = null;
811 }
812
813 // Get the gui to deallocate
814 if(g_man != null) {
815 g_man.destroy();
816 g_man_built = false;
817 }
818
819 // Flush debug
820 DebugStream.closeDebugStream();
821
822 // If we started a server, we should try to stop it.
823 if (LocalLibraryServer.isRunning() == true) {
824 LocalLibraryServer.stop();
825 }
826
827 // If we're using a remote Greenstone server we need to make sure that all jobs have completed first
828 if (isGsdlRemote) {
829 remoteGreenstoneServer.exit();
830 } else if (GS3) { // stop the local tomcat web server when running GS3
831 // can't call ant stop from its own thread - what if GLI has exited by then?
832 // issue call to ant stop from the main GLI thread
833 //GS3ServerThread thread = new GS3ServerThread(Configuration.gsdl_path, "stop");
834 //thread.start();
835 if(!GS3ServerThread.wasServerLaunchedOutsideGLI()) {
836 GS3ServerThread.stopServer();
837 } else {
838 System.err.println("@@@ Tomcat was launched outside GLI. Leaving it running...");
839 }
840
841 }
842
843 // Make sure we haven't started up any processes that are still running
844 if (apps.size() == 0) {
845 // If we're running as an applet we don't actually quit (just hide the main GLI window)
846 if (!Gatherer.isApplet) {
847 // This is the end...
848 System.exit(exit_status);
849 }
850 }
851 else {
852 JOptionPane.showMessageDialog(g_man, Dictionary.get("General.Outstanding_Processes"), Dictionary.get("General.Outstanding_Processes_Title"), JOptionPane.ERROR_MESSAGE);
853 g_man.setVisible(false);
854 }
855 }
856
857 static public void exit()
858 {
859 exit(0);
860 }
861
862 /** Returns the path of the current collect directory. */
863 static public String getCollectDirectoryPath()
864 {
865 if (non_standard_collect_directory_path != null) {
866 return non_standard_collect_directory_path;
867 }
868
869 return getDefaultGSCollectDirectoryPath(true); // file separator appended
870
871 }
872
873 // if we need to know whether the local server we are running is server.exe vs apache web server
874 static public boolean isPersistentServer() {
875 return (!isGsdlRemote && LocalLibraryServer.isPersistentServer());
876 }
877
878 /** Returns the path of the Greenstone "collect" directory. */
879 static public String getDefaultGSCollectDirectoryPath(boolean appendSeparator) {
880 String colDir;
881 if (GS3) {
882 colDir = getSitesDirectoryPath() + Configuration.site_name + File.separator + "collect";
883 }
884 else {
885 colDir = Configuration.gsdl_path + "collect";
886 }
887
888 if(appendSeparator) {
889 colDir += File.separator;
890 }
891 return colDir;
892 }
893
894 /** Returns the path of the GLI directory. */
895 static public String getGLIDirectoryPath()
896 {
897 return gli_directory_path;
898 }
899
900
901 /** Returns the path of the GLI "metadata" directory. */
902 static public String getGLIMetadataDirectoryPath()
903 {
904 return getGLIDirectoryPath() + "metadata" + File.separator;
905 }
906
907
908 /** Returns the path of the GLI user directory. */
909 static public String getGLIUserDirectoryPath()
910 {
911 return gli_user_directory_path;
912 }
913
914
915 /** Returns the path of the GLI user "cache" directory. */
916 static public String getGLIUserCacheDirectoryPath()
917 {
918 return getGLIUserDirectoryPath() + "cache" + File.separator;
919 }
920
921
922 /** Returns the path of the GLI user "log" directory. */
923 static public String getGLIUserLogDirectoryPath()
924 {
925 return getGLIUserDirectoryPath() + "log" + File.separator;
926 }
927
928
929 static public String getSitesDirectoryPath()
930 {
931 return Configuration.gsdl3_path + "sites" + File.separator;
932 }
933
934
935 static public void setCollectDirectoryPath(String collect_directory_path)
936 {
937 non_standard_collect_directory_path = collect_directory_path;
938 if (!non_standard_collect_directory_path.endsWith(File.separator)) {
939 non_standard_collect_directory_path = non_standard_collect_directory_path + File.separator;
940 }
941 }
942
943
944 static public void setGLIDirectoryPath(String gli_directory_path_arg)
945 {
946 gli_directory_path = gli_directory_path_arg;
947 }
948
949
950 static public void setGLIUserDirectoryPath(String gli_user_directory_path_arg)
951 {
952 gli_user_directory_path = gli_user_directory_path_arg;
953
954 // Ensure the GLI user directory exists
955 File gli_user_directory = new File(gli_user_directory_path);
956 if (!gli_user_directory.exists() && !gli_user_directory.mkdirs()) {
957 System.err.println("Error: Unable to make directory: " + gli_user_directory);
958 }
959 }
960
961
962 public static void initCollectDirectoryPath() {
963 String defaultColdir = getDefaultGSCollectDirectoryPath(false); // no file separator at end
964 String coldir = defaultColdir;
965 // If local GS and opening a collection outside the standard GS collect folder,
966 // need to open the non-standard collect folder that the collection resides in
967 if (!isGsdlRemote
968 && !open_collection_file_path.startsWith(defaultColdir))
969 {
970 File collectFolder = null;
971
972 if(!open_collection_file_path.equals("")) {
973 if(!open_collection_file_path.endsWith("gli.col")) { // then it's a collect folder
974 collectFolder = new File(open_collection_file_path);
975 } else {
976 // the filepath is a gli.col file. To get the collect folder: the 1st level up
977 // is the collection folder, 2 two levels up is the containing collect folder
978 collectFolder = new File(open_collection_file_path).getParentFile().getParentFile();
979 }
980
981 // Need to deal with colgroups as well: while there's an etc/collect.cfg
982 // in the current collectFolder, move one level up
983 String cfg_file = (Gatherer.GS3)? Utility.CONFIG_GS3_FILE : Utility.CONFIG_FILE;
984 if(new File(collectFolder.getAbsolutePath()+File.separator+cfg_file).exists()) { // colgroup
985 collectFolder = collectFolder.getParentFile();
986 }
987
988 // Inform the user that their collecthome is non-standard (not inside GS installation)
989 nonStandardCollectHomeMessage(collectFolder.getAbsolutePath(), defaultColdir); // display message
990 }
991
992 if(collectFolder == null || !collectFolder.exists()) {
993 // if GLI config file specified no collectDir (open_collection_file_path is "")
994 // OR if dealing with a local server but the collectdir no longer exists,
995 // use the default greenstone collect directory, and write that to affected files
996
997 open_collection_file_path = defaultColdir; // default GS collect dir
998 // Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(), true, "");
999 } else { // use the coldir value specified in the flags to GLI or from the last GLI session
1000 coldir = collectFolder.getAbsolutePath();
1001 }
1002 // set it as the current folder
1003 setCollectDirectoryPath(coldir); // will ensure the required file separator at end
1004 }
1005
1006 if(!isGsdlRemote) {
1007 // LocalLibraryServer would already have set glisite.cfg to the correct collecthome for server.exe
1008 // Here we set collecthome in gsdl(3)site.cfg for the GS2 apache web server and GS3 tomcat server
1009 String gsdlsitecfg = getGsdlSiteConfigFile();
1010 // update the gsdlsite config file and store the old value for use when we exit GLI
1011 if(coldir.equals(defaultColdir)) {
1012 gsdlsite_collecthome = Utility.updatePropertyConfigFile(
1013 gsdlsitecfg, "collecthome", null);
1014 } else {
1015 gsdlsite_collecthome = Utility.updatePropertyConfigFile(
1016 gsdlsitecfg, "collecthome", "\""+coldir+"\""); // no file separator
1017 // if gsdlsite.cfg does not exist (if using server.exe for instance), the above method will just return
1018 }
1019 }
1020 }
1021
1022 /** depending on the version of GS being run, return the path to the current GS' installation's gsdl(3)site.cfg */
1023 public static String getGsdlSiteConfigFile() {
1024 if(Gatherer.GS3) { // web/WEB-INF/cgi/gsdl3site.cfg
1025 return Configuration.gsdl3_path + File.separator + "WEB-INF"
1026 + File.separator + "cgi" + File.separator + "gsdl3site.cfg";
1027 } else { // cgi-bin/gsdlsite.cfg
1028 String gsdlarch = System.getenv("GSDLARCH");
1029 if(gsdlarch == null) {
1030 gsdlarch = "";
1031 }
1032 return Configuration.gsdl_path /* + File.separator */
1033 + "cgi-bin" + File.separator + client_operating_system+gsdlarch + File.separator + "gsdlsite.cfg";
1034 }
1035 }
1036
1037 public static void collectDirectoryHasChanged(
1038 String oldCollectPath, String newCollectPath, final Component container)
1039 {
1040 if(oldCollectPath.equals(newCollectPath)) {
1041 return; // nothing to be done
1042 }
1043
1044 // Will use a busy cursor if the process of changing the collect directory takes more
1045 // than half a second/500ms. See http://www.catalysoft.com/articles/busyCursor.html
1046 Cursor originalCursor = container.getCursor();
1047 java.util.TimerTask timerTask = new java.util.TimerTask() {
1048 public void run() {
1049 // set the cursor on the container:
1050 container.setCursor(new Cursor(Cursor.WAIT_CURSOR));
1051 }
1052 };
1053 java.util.Timer timer = new java.util.Timer();
1054
1055 try {
1056 timer.schedule(timerTask, 500);
1057
1058 // first save any open collection in the old location, then close it
1059 if(Gatherer.c_man.getCollection() != null) {
1060 Gatherer.g_man.saveThenCloseCurrentCollection(); // close the current collection first
1061 }
1062
1063 // change to new collect path
1064 if(newCollectPath.equals(getDefaultGSCollectDirectoryPath(true))) {
1065 Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(),
1066 true, "");
1067 } else {
1068 Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(),
1069 true, newCollectPath);
1070 }
1071 Gatherer.setCollectDirectoryPath(newCollectPath);
1072
1073
1074 // refresh the Documents in Greenstone Collections
1075 //WorkspaceTreeModel.refreshGreenstoneCollectionsNode();
1076 Gatherer.g_man.refreshWorkspaceTreeGreenstoneCollections();
1077
1078 // The web server needs to be told where a new (non-standard) collecthome home is.
1079 // The web server reads collecthome from cgi-bin/<OS>/gsdlsite.cfg, where the property
1080 // collecthome can be specified if a non-standard collecthome is to be used. If no
1081 // such property is specified in the file, then it assumes the standard GS collecthome.
1082 // This method does nothing for a remote Greenstone.
1083 if(Gatherer.isGsdlRemote) {
1084 return;
1085 }
1086
1087 // non-destructive update of gsdl(3)site.cfg (comments preserved)
1088 String collectDir = Gatherer.getCollectDirectoryPath();
1089 //collectDir = "\"" + collectDir.substring(0, collectDir.length()-1) + "\""; // remove file separator at end
1090 collectDir = collectDir.substring(0, collectDir.length()-1); // remove file separator at end
1091 if(collectDir != null) {
1092 collectDir = "\""+collectDir+"\"";
1093 }
1094 Utility.updatePropertyConfigFile(getGsdlSiteConfigFile(), "collecthome", collectDir);
1095 // if gsdlsite.cfg does not exist (if using server.exe for instance), the above method will just return
1096
1097 if(!Gatherer.GS3 && Gatherer.isLocalLibrary) {
1098 // for Images in the collection to work, the apache web server
1099 // configuration's COLLECTHOME should be updated on collectdir change.
1100 // Does nothing for server.exe at the moment
1101
1102 LocalLibraryServer.reconfigure();
1103 }
1104 } finally { // Note try-finally section without catch:
1105 // "Java's finally clause is guaranteed to be executed even when
1106 // an exception is thrown and not caught in the current scope."
1107 // See http://www.catalysoft.com/articles/busyCursor.html
1108 // the following code fragment is guaranteed to restore the original
1109 // cursor now the custom actionPerformed() processing is complete, regardless
1110 // of whether the processing method terminates normally or throws an exception
1111 // and regardless of where in the call stack the exception is caught.
1112
1113 timer.cancel();
1114 container.setCursor(originalCursor);
1115 }
1116 }
1117
1118
1119 static public void refresh(int refresh_reason)
1120 {
1121 if (g_man != null) {
1122
1123 g_man.refresh(refresh_reason, c_man.ready());
1124 }
1125
1126 // Now is a good time to force a garbage collect
1127 System.gc();
1128 }
1129
1130
1131 // used to send reload coll messages to the tomcat server
1132 static public void configGS3Server(String site, String command) {
1133
1134 // Do not do configGS3Server for a GS3 solr collection. Not at present at least, when we're stopping
1135 // and starting the GS3 server from GLI for solr cols, since this function clears the solr.xml file.
1136 /*if(Gatherer.c_man.isSolrCollection()) {
1137 return;
1138 }*/
1139
1140 if (Configuration.library_url == null){
1141 System.out.println("Error: you have not provided the Greenstone Library address.");
1142 return;
1143
1144 }
1145
1146 try {
1147 // need to add the servlet name to the exec address
1148 String raw_url = Configuration.library_url.toString() + Configuration.getServletPath() + command;
1149 URL url = new URL(raw_url);
1150 DebugStream.println("Action: " + raw_url);
1151 HttpURLConnection library_connection = (HttpURLConnection) url.openConnection();
1152 int response_code = library_connection.getResponseCode();
1153 if(HttpURLConnection.HTTP_OK <= response_code && response_code < HttpURLConnection.HTTP_MULT_CHOICE) {
1154 DebugStream.println("200 - Complete.");
1155 }
1156 else {
1157 DebugStream.println("404 - Failed.");
1158 }
1159 url = null;
1160 }
1161 catch(java.net.ConnectException connectException) {
1162 JOptionPane.showMessageDialog(g_man, Dictionary.get("Preferences.Connection.Library_Path_Connection_Failure", Configuration.library_url.toString()), Dictionary.get("General.Warning"), JOptionPane.WARNING_MESSAGE);
1163 DebugStream.println(connectException.getMessage());
1164 }
1165 catch (Exception exception) {
1166 DebugStream.printStackTrace(exception);
1167 }
1168 }
1169
1170
1171 /** Used to 'spawn' a new child application when a file is double clicked.
1172 * @param file The file to open
1173 * @see org.greenstone.gatherer.Gatherer.ExternalApplication
1174 */
1175 static public void spawnApplication(File file) {
1176 String [] commands = assoc_man.getCommand(file);
1177 if(commands != null) {
1178 ExternalApplication app = new ExternalApplication(commands);
1179 apps.add(app);
1180 app.start();
1181 }
1182 else {
1183 ///ystem.err.println("No open command available.");
1184 }
1185 }
1186
1187
1188 static public void spawnApplication(String command)
1189 {
1190 ExternalApplication app = new ExternalApplication(command);
1191 apps.add(app);
1192 app.start();
1193 }
1194
1195 static public void spawnApplication(String command, String ID)
1196 {
1197 ExternalApplication app = new ExternalApplication(command, ID);
1198 apps.add(app);
1199 app.start();
1200 }
1201
1202 static public void spawnApplication(String[] commands, String ID)
1203 {
1204 ExternalApplication app = new ExternalApplication(commands, ID);
1205 apps.add(app);
1206 app.start();
1207 }
1208
1209 static public void terminateApplication(String ID) {
1210 for(int i = 0; i < apps.size(); i++) {
1211 ExternalApplication app = (ExternalApplication)apps.get(i);
1212 if(app.getID() != null && app.getID().equals(ID)) {
1213 app.stopExternalApplication();
1214 apps.remove(app);
1215 }
1216 }
1217 }
1218
1219
1220 /** Used to 'spawn' a new browser application or reset an existing one when the preview button is clicked
1221 * @param url The url to open the browser at
1222 * @see org.greenstone.gatherer.Gatherer.BrowserApplication
1223 */
1224 static public void spawnBrowser(String url) {
1225 String command = assoc_man.getBrowserCommand(url);
1226 if (command != null) {
1227 BrowserApplication app = new BrowserApplication(command, url);
1228 apps.add(app);
1229 app.start();
1230 }
1231 else {
1232 ///ystem.err.println("No browser command available.");
1233 }
1234 }
1235
1236
1237 /** Prints a warning message about a missing library path, which means the final collection cannot be previewed in the Gatherer.
1238 */
1239 static public void missingEXEC() {
1240 try {
1241 SwingUtilities.invokeAndWait(new Runnable() {
1242 public void run() {
1243 WarningDialog dialog;
1244 String configPropertyName = "general.library_url"+Configuration.gliPropertyNameSuffix();
1245
1246 if (GS3) {
1247 // Warning dialog with no cancel button and no "turn off warning" checkbox
1248 dialog = new WarningDialog("warning.MissingEXEC", Dictionary.get("MissingEXEC_GS3.Title"), Dictionary.get("MissingEXEC_GS3.Message"), configPropertyName, false, false);
1249 } else { // local case
1250 dialog = new WarningDialog("warning.MissingEXEC", Dictionary.get("MissingEXEC.Title"), Dictionary.get("MissingEXEC.Message"), configPropertyName, false);
1251 }
1252
1253 JTextField field = new URLField.Text(Configuration.getColor("coloring.editable_foreground", false), Configuration.getColor("coloring.editable_background", false));
1254
1255 // Set the default library URL to the tomcat server and port number
1256 // specified in the build.properties located in the gsdl3_src_path
1257 if (GS3) {
1258 // defaults
1259 String host = "localhost";
1260 String port = "8383";
1261 String context = "greenstone3";
1262 String protocol = "http";
1263
1264 File buildPropsFile = new File(Configuration.gsdl3_src_path + File.separator + "build.properties");
1265 if(buildPropsFile.exists()) {
1266 Properties props = new Properties();
1267 try{
1268 props.load(new FileInputStream(buildPropsFile));
1269 host = props.getProperty("tomcat.server", host);
1270 context = props.getProperty("greenstone.context", context);
1271 ProtocolPortProperties protocolPortProps = new ProtocolPortProperties(props); // can throw Exception
1272 // Use ProtocolPortProperties to get the tomcat port and protocol used
1273 protocol = protocolPortProps.getProtocol();
1274 port = protocolPortProps.getPort();
1275 }catch(Exception e){
1276 DebugStream.println("Could not load build.properties file");
1277 System.err.println("Could not load build.properties file");
1278 }
1279 props = null;
1280 }
1281 String defaultURL = protocol+"://"+host+":"+port+"/"+context;
1282 field.setText(defaultURL);
1283 field.selectAll();
1284 }
1285 dialog.setValueField(field);
1286 dialog.display();
1287 dialog.dispose();
1288 dialog = null;
1289
1290 String library_url_string = Configuration.getString(configPropertyName, true);
1291 if (!library_url_string.equals("")) {
1292 try {
1293 // WarningDialog does not allow invalid URLs, so the following is ignored:
1294 // make sure the URL the user provided contains the http:// prefix
1295 // and then save the corrected URL
1296 if(!library_url_string.startsWith("http://")
1297 && !library_url_string.startsWith("https://")) {
1298 library_url_string = "http://"+library_url_string;
1299 Configuration.setString(configPropertyName, true, configPropertyName);
1300 }
1301 Configuration.library_url = new URL(library_url_string);
1302 }
1303 catch (MalformedURLException exception) {
1304 DebugStream.printStackTrace(exception);
1305 }
1306 }
1307 }
1308 });
1309 } catch(Exception e) { //InterruptedException or InvocationTargetException
1310 e.printStackTrace();
1311 }
1312 }
1313
1314
1315
1316 /** Prints a warning message about a missing library path, which means the final collection cannot be previewed in the Gatherer.
1317 */
1318 static private void popupFedoraInfo() {
1319 try {
1320 SwingUtilities.invokeAndWait(new Runnable() {
1321 public void run() {
1322 FedoraLogin dialog = new FedoraLogin("Fedora Login", false);
1323
1324 if (Configuration.library_url == null) {
1325
1326 String library_url_string = dialog.getLibraryURL();
1327 if (!library_url_string.equals("")) {
1328 try {
1329 Configuration.library_url = new URL(library_url_string);
1330 }
1331 catch (MalformedURLException exception) {
1332 DebugStream.printStackTrace(exception);
1333 }
1334 }
1335 }
1336
1337 boolean showLogin = true;
1338 do {
1339 if(!dialog.loginRequested()) { // user pressed cancel to exit the FedoraLogin dialog
1340 System.exit(0);
1341 } else {
1342 showLogin = dialog.loginRequested();
1343 String hostname = dialog.getHostname();
1344 String port = dialog.getPort();
1345 String username = dialog.getUsername();
1346 String password = dialog.getPassword();
1347 String protocol = dialog.getProtocol();
1348
1349 Configuration.fedora_info.setHostname(hostname);
1350 Configuration.fedora_info.setPort(port);
1351 Configuration.fedora_info.setUsername(username);
1352 Configuration.fedora_info.setPassword(password);
1353 Configuration.fedora_info.setProtocol(protocol);
1354
1355 String ping_url_str = protocol + "://" + hostname + ":" + port + "/fedora";
1356 String login_str = username + ":" + password;
1357
1358 String login_encoding = Base64.encodeBytes(login_str.getBytes());
1359
1360 try {
1361 URL ping_url = new URL(ping_url_str);
1362 URLConnection uc = ping_url.openConnection();
1363 uc.setRequestProperty ("Authorization", "Basic " + login_encoding);
1364 // Attempt to access some content ...
1365 InputStream content = (InputStream)uc.getInputStream();
1366
1367 // if no exception occurred in the above, we would have come here:
1368 showLogin = false;
1369 dialog.dispose();
1370 }
1371 catch (Exception exception) {
1372 // TODO: move into dictionary
1373 String[] errorMessage = {"Failed to connect to the Fedora server.", "It might not be running, or",
1374 "incorrect username and/or password."};
1375 dialog.setErrorMessage(errorMessage);
1376 //DebugStream.printStackTrace(exception);
1377 // exception occurred, show the dialog again (do this after printing to
1378 // debugStream, else the above does not get done for some reason).
1379 dialog.setVisible(true);
1380 }
1381 }
1382 } while(showLogin);
1383
1384 dialog = null; // no more need of the dialog
1385
1386 // Now we are connected.
1387 }
1388 });
1389 } catch(Exception e) { //InterruptedException or InvocationTargetException
1390 e.printStackTrace();
1391 }
1392 }
1393
1394
1395
1396 static private void requestGLIServerURL()
1397 {
1398 try {
1399 SwingUtilities.invokeAndWait(new Runnable() {
1400 public void run() {
1401 WarningDialog dialog;
1402 String[] defaultURLs = {
1403 "http://localhost:8080/greenstone3/cgi-bin/gliserver.pl",
1404 "http://localhost:8080/gsdl/cgi-bin/gliserver.pl"
1405 };
1406
1407 // Warning dialog with no cancel button and no "turn off warning" checkbox
1408 // (since user-input of the gliserver script is mandatory)
1409 dialog = new WarningDialog("warning.MissingGLIServer", Dictionary.get("MissingGLIServer.Title"), Dictionary.get("MissingGLIServer.Message"), "general.gliserver_url", false, false);
1410
1411 dialog.setValueField(new URLField.DropDown(Configuration.getColor("coloring.editable_foreground", false),
1412 Configuration.getColor("coloring.editable_background", false),
1413 defaultURLs, "general.gliserver_url",
1414 "general.open_collection"+Configuration.gliPropertyNameSuffix(),
1415 "gliserver.pl"));
1416
1417 if (Gatherer.default_gliserver_url!=null){
1418 dialog.setValueField(Gatherer.default_gliserver_url.toString());
1419 }
1420
1421 // A WarningDialog cannot always be made to respond (let alone to exit the program) on close. We
1422 // handle the response of this particular WarningDialog here: a URL for gliserver.pl is a crucial
1423 // piece of user-provided data. Therefore, if no URL was entered for gliserver.pl, it'll exit safely.
1424 dialog.addWindowListener(new WindowAdapter() {
1425 public void windowClosing(WindowEvent e) {
1426 Gatherer.exit();
1427 }
1428 });
1429
1430 dialog.display();
1431 dialog.dispose();
1432 dialog = null;
1433
1434
1435 String gliserver_url_string = Configuration.getString("general.gliserver_url", true);
1436 if (!gliserver_url_string.equals("")) {
1437 try {
1438 Configuration.gliserver_url = new URL(gliserver_url_string);
1439 Configuration.setString("general.gliserver_url", true, gliserver_url_string);
1440 }
1441 catch (MalformedURLException exception) {
1442 DebugStream.printStackTrace(exception);
1443 }
1444 }
1445 }
1446 });
1447 } catch(Exception e) { //InterruptedException or InvocationTargetException
1448 e.printStackTrace();
1449 }
1450 }
1451
1452
1453 /** Prints a warning message about a missing GSDL path, which although not fatal pretty much ensures nothing will work properly in the GLI.
1454 */
1455 static private void missingGSDL() {
1456 try {
1457 SwingUtilities.invokeAndWait(new Runnable() {
1458 public void run() {
1459 WarningDialog dialog = new WarningDialog("warning.MissingGSDL", Dictionary.get("MissingGSDL.Title"), Dictionary.get("MissingGSDL.Message"), null, false);
1460 dialog.display();
1461 dialog.dispose();
1462 dialog = null;
1463 }
1464 });
1465 } catch(Exception e) { //InterruptedException or InvocationTargetException
1466 e.printStackTrace();
1467 }
1468 }
1469
1470 /** Prints a warning message about missing a valid ImageMagick path, which although not fatal means building image collections won't work */
1471 static private void missingImageMagick() {
1472 try {
1473 SwingUtilities.invokeAndWait(new Runnable() {
1474 public void run() {
1475 WarningDialog dialog = new WarningDialog("warning.MissingImageMagick", Dictionary.get("MissingImageMagick.Title"), Dictionary.get("MissingImageMagick.Message"), null, false);
1476 dialog.display();
1477 dialog.dispose();
1478 dialog = null;
1479 }
1480 });
1481 } catch(Exception e) { //InterruptedException or InvocationTargetException
1482 e.printStackTrace();
1483 }
1484 }
1485
1486 /** Prints a message informing the user where they can get PDFBox from to process PDF files of v1.5 and greater */
1487 static private void missingPDFBox(final String zipExtension, final String extFolder) {
1488 try {
1489 SwingUtilities.invokeAndWait(new Runnable() {
1490 public void run() {
1491
1492 // point to the correct version of the PDFBox extension for this Greenstone release
1493 String releaseTag = "";
1494 if(!PROGRAM_VERSION.equals("trunk")) { // assume it's a release version
1495 releaseTag = "main/tags/"+PROGRAM_VERSION+"/";
1496 }
1497
1498 WarningDialog dialog = new WarningDialog("warning.MissingPDFBox", Dictionary.get("MissingPDFBox.Title"), Dictionary.get("MissingPDFBox.Message", new String[]{releaseTag, zipExtension, extFolder}), null, false);
1499 dialog.display();
1500 dialog.dispose();
1501 dialog = null;
1502 }
1503 });
1504 } catch(Exception e) { //InterruptedException or InvocationTargetException
1505 e.printStackTrace();
1506 }
1507 }
1508
1509 /** 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. */
1510 static private void missingPERL() {
1511 try {
1512 SwingUtilities.invokeAndWait(new Runnable() {
1513 public void run() {
1514 WarningDialog dialog = new WarningDialog("warning.MissingPERL", Dictionary.get("MissingPERL.Title"), Dictionary.get("MissingPERL.Message"), null, false);
1515 dialog.display();
1516 dialog.dispose();
1517 dialog = null;
1518 }
1519 });
1520 } catch(Exception e) { //InterruptedException or InvocationTargetException
1521 e.printStackTrace();
1522 }
1523 }
1524
1525 /** Prints a message informing the user that their collecthome is non-standard (not inside GS installation) */
1526 static private void nonStandardCollectHomeMessage(final String open_collection_file_path, final String defaultColDir) {
1527 try {
1528 SwingUtilities.invokeAndWait(new Runnable() {
1529 public void run() {
1530 WarningDialog dialog = new WarningDialog("warning.NonStandardCollectHome", Dictionary.get("NonStandardCollectHome.Title"), Dictionary.get("NonStandardCollectHome.Message", new String[]{open_collection_file_path, defaultColDir}), null, false);
1531 dialog.display();
1532 dialog.dispose();
1533 dialog = null;
1534 }
1535 });
1536 } catch(Exception e) { //InterruptedException or InvocationTargetException
1537 e.printStackTrace();
1538 }
1539 }
1540
1541 /** Prints a warning message about the OS not supporting multiple filename encodings. */
1542 static private void multipleFilenameEncodingsNotSupported() {
1543 try {
1544 SwingUtilities.invokeAndWait(new Runnable() {
1545 public void run() {
1546 WarningDialog dialog = new WarningDialog("warning.NoEncodingSupport",
1547 Dictionary.get("NoEncodingSupport.Title"),
1548 Dictionary.get("NoEncodingSupport.Message"), null, false);
1549 dialog.display();
1550 dialog.dispose();
1551 dialog = null;
1552 }
1553 });
1554 } catch(Exception e) { //InterruptedException or InvocationTargetException
1555 e.printStackTrace();
1556 }
1557 }
1558
1559 /** Sets up the proxy connection by setting JVM Environment flags and creating a new Authenticator.
1560 * @see java.lang.Exception
1561 * @see java.lang.System
1562 * @see java.net.Authenticator
1563 * @see org.greenstone.gatherer.Configuration
1564 * @see org.greenstone.gatherer.GAuthenticator
1565 */
1566 static public void setProxy() {
1567 try {// Can throw several exceptions
1568 boolean use_proxy = Configuration.get("general.use_proxy", true);
1569
1570 setProxyForProtocol("http", use_proxy);
1571 setProxyForProtocol("https", use_proxy);
1572 setProxyForProtocol("ftp", use_proxy);
1573
1574 } catch (Exception error) {
1575 DebugStream.println("Error in Gatherer.initProxy(): " + error);
1576 DebugStream.printStackTrace(error);
1577 }
1578 }
1579
1580 private static void setProxyForProtocol(String protocol, boolean use_proxy) throws Exception {
1581 // These are Java properties, therefore see
1582 // https://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html
1583 // https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html
1584 // https://stackoverflow.com/questions/14243590/proxy-settings-in-java
1585
1586 // Just need to warn the user that we're overriding proxy settings using custom defined proxy settings
1587 // and returning to using the original proxy settings when custom defined proxy settings are turned off
1588 // We don't actually need to store/restore the original settings, as Java system vars like http.proxyHost
1589 // http.proxyPort don't seem to be set even if on GLI startup the env vars like http(s)_proxy were already set.
1590
1591
1592 if(use_proxy) {
1593 if(System.getenv(protocol+"_proxy") != null) {
1594 System.err.println("Overriding original "+protocol+" proxy settings");
1595 }
1596
1597 // set the custom proxy defined through GLI for this protocol
1598 System.setProperty(protocol+".proxyHost", Configuration.getString("general."+protocol.toUpperCase()+"_proxy_host", true));
1599 System.setProperty(protocol+".proxyPort", Configuration.getString("general."+protocol.toUpperCase()+"_proxy_port", true));
1600
1601 // Not sure what proxyType is. And proxySet ceased to exist since JDK 6 or before. See links above.
1602 // But we used to set them both for HTTP before, so still doing so for proxyType, since it may or may not exist
1603 // But proxySet doesn't exist anymore, so not continuing with that.
1604 if(protocol.equals("http")) {
1605 System.setProperty(protocol+".proxyType", "4");
1606 //System.setProperty(protocol+".proxySet", "true");
1607 }
1608
1609 }
1610
1611 else { // use_proxy=false, not using proxy defined through GLI, so
1612 // either unset proxy vars for this protocol, or restore any original settings for them
1613
1614 if(System.getenv(protocol+"_proxy") != null) {
1615 System.err.println("Restoring original "+protocol+" proxy settings");
1616 }
1617
1618 System.setProperty(protocol+".proxyHost", "");
1619 System.setProperty(protocol+".proxyPort", "");
1620 //if(protocol.equals("http")) {
1621 //System.setProperty(protocol+".proxySet", "false");
1622 //}
1623 }
1624 }
1625
1626
1627 /** 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 voluntarily 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. */
1628 static private class ExternalApplication
1629 extends Thread {
1630 private SafeProcess process = null;
1631 /** The initial command string given to this sub-process. */
1632 private String command = null;
1633 private String[] commands = null;
1634
1635 private String ID = null;
1636
1637 /** Constructor.
1638 * @param command The initial command <strong>String</strong>.
1639 */
1640 public ExternalApplication(String command) {
1641 this.command = command;
1642 }
1643
1644 public ExternalApplication(String[] commands) {
1645 this.commands = commands;
1646 }
1647
1648 public ExternalApplication(String command, String ID) {
1649 this.command = command;
1650 this.ID = ID;
1651 }
1652
1653 public ExternalApplication(String[] commands, String ID) {
1654 this.commands = commands;
1655 this.ID = ID;
1656 }
1657
1658 public String getID() {
1659 return ID;
1660 }
1661
1662 /** We start the child process inside a new thread so it doesn't block the rest of Gatherer.
1663 * @see java.lang.Exception
1664 * @see java.lang.Process
1665 * @see java.lang.Runtime
1666 * @see java.lang.System
1667 * @see java.util.Vector
1668 */
1669 public void run() {
1670 // Call an external process using the args.
1671 try {
1672 if(commands != null) {
1673 StringBuffer whole_command = new StringBuffer();
1674 for(int i = 0; i < commands.length; i++) {
1675 // get rid of any quotes around parameters in file associations
1676 if(commands[i].startsWith("\"") || commands[i].startsWith("\'")) {
1677 commands[i] = commands[i].substring(1);
1678 }
1679 if(commands[i].endsWith("\"") || commands[i].endsWith("\'")) {
1680 commands[i] = commands[i].substring(0, commands[i].length()-1);
1681 }
1682
1683 if (i>0) {
1684 whole_command.append(" ");
1685 }
1686 whole_command.append(commands[i]);
1687 }
1688 DebugStream.println("Running " + whole_command.toString());
1689 process = new SafeProcess(commands);
1690 }
1691 else {
1692 DebugStream.println("Running " + command);
1693 process = new SafeProcess(command);
1694 }
1695 process.runProcess();
1696 }
1697 catch (Exception exception) {
1698 DebugStream.printStackTrace(exception);
1699 }
1700 // Remove ourself from Gatherer list of threads.
1701 apps.remove(this);
1702 // Call exit if we were the last outstanding child process thread.
1703 if (apps.size() == 0 && exit == true) {
1704 // In my opinion (DB) there is no need to exit here,
1705 // the 'run' method ending naturally brings this
1706 // thread to an end. In fact it is potentially
1707 // dangerous to exit here, as the main thread in the
1708 // Gatherer class may be stopped prematurely. As it so
1709 // happens the point at which the ExternalApplication thread
1710 // is asked to stop (Back in the main Gatherer thread) is after
1711 // various configuration files have been saved.
1712 //
1713 // A similar argument holds for BrowserApplication thread below.
1714 System.exit(exit_status);
1715 }
1716 }
1717 public void stopExternalApplication() {
1718 if(process != null) {
1719 SafeProcess.log("*** stopExternalApplication called.");
1720 process.cancelRunningProcess();
1721 }
1722 }
1723 }
1724 /** 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. */
1725 static private class BrowserApplication
1726 extends Thread {
1727 private SafeProcess process = null;
1728 /** The initial command string given to this sub-process. */
1729 private String command = null;
1730 private String url = null;
1731 private String[] commands = null;
1732
1733 public BrowserApplication(String command, String url) {
1734 StringTokenizer st = new StringTokenizer(command);
1735 int num_tokens = st.countTokens();
1736 this.commands = new String [num_tokens];
1737 int i=0;
1738 while (st.hasMoreTokens()) {
1739 commands[i] = st.nextToken();
1740 i++;
1741 }
1742 //this.commands = commands;
1743 this.url = url;
1744 }
1745 /** We start the child process inside a new thread so it doesn't block the rest of Gatherer.
1746 * @see java.lang.Exception
1747 * @see java.lang.Process
1748 * @see java.lang.Runtime
1749 * @see java.lang.System
1750 * @see java.util.Vector
1751 */
1752 public void run() {
1753 // Call an external process using the args.
1754 if(commands == null) {
1755 apps.remove(this);
1756 return;
1757 }
1758 try {
1759 String prog_name = commands[0];
1760 String lower_name = prog_name.toLowerCase();
1761 if (lower_name.indexOf("mozilla") != -1 || lower_name.indexOf("netscape") != -1) {
1762 DebugStream.println("found mozilla or netscape, trying remote it");
1763 // mozilla and netscape, try using a remote command to get things in the same window
1764 String [] new_commands = new String[] {prog_name, "-raise", "-remote", "openURL("+url+",new-tab)"};
1765 printArray(new_commands);
1766
1767 process = new SafeProcess(new_commands);
1768 int exitCode = process.runProcess();
1769 if (exitCode != 0) { // if Netscape or mozilla was not open
1770 DebugStream.println("couldn't do remote, trying original command");
1771 printArray(commands);
1772 process = null;
1773 process = new SafeProcess(commands); // try the original command
1774 process.runProcess();
1775 }
1776 } else {
1777 // just run what we have been given
1778 StringBuffer whole_command = new StringBuffer();
1779 for(int i = 0; i < commands.length; i++) {
1780 whole_command.append(commands[i]);
1781 whole_command.append(" ");
1782 }
1783 DebugStream.println("Running " + whole_command.toString());
1784 process = new SafeProcess(commands);
1785 process.runProcess();
1786 }
1787 }
1788
1789 catch (Exception exception) {
1790 DebugStream.printStackTrace(exception);
1791 }
1792 // Remove ourself from Gatherer list of threads.
1793 apps.remove(this);
1794 // Call exit if we were the last outstanding child process thread.
1795 if (apps.size() == 0 && exit == true) {
1796 System.exit(exit_status);
1797 }
1798 }
1799 public void printArray(String [] array) {
1800 for(int i = 0; i < array.length; i++) {
1801 DebugStream.print(array[i]+" ");
1802 System.err.println(array[i]+" ");
1803 }
1804 }
1805 public void stopBrowserApplication() {
1806 if(process != null) {
1807 SafeProcess.log("*** stopBrowserApplication called.");
1808 process.cancelRunningProcess();
1809 }
1810 }
1811 }
1812
1813
1814 private class ImageMagickTest
1815 {
1816 public boolean found()
1817 {
1818 // at this stage, GLI has already sourced setup.bash, and the necessary
1819 // env variables will be available to the perl process we're about to launch
1820 boolean found = false;
1821
1822
1823 // run the command `/path/to/perl -S gs-magick.pl identify -version`
1824 ArrayList cmd_list = new ArrayList();
1825 if (!Gatherer.isGsdlRemote) {
1826 if(Configuration.perl_path != null) {
1827 cmd_list.add(Configuration.perl_path);
1828 } else {
1829 System.err.println("***** ImageMagickTest Warning: Perl_path not set, calling 'perl' instead.");
1830 cmd_list.add("perl");
1831 }
1832 cmd_list.add("-S");
1833 }
1834 cmd_list.add("gs-magick.pl");
1835 if(Utility.isWindows()) {
1836 cmd_list.add("identify.exe");
1837 } else {
1838 cmd_list.add("identify");
1839 }
1840 cmd_list.add("-version");
1841
1842 String[] command_parts = (String[]) cmd_list.toArray(new String[0]);
1843
1844 String cmd_str = "";
1845 for(int i = 0; i < command_parts.length; i++) {
1846 cmd_str += command_parts[i] + " ";
1847 }
1848 DebugStream.println("***** Running ImageMagickTest command: " + cmd_str);
1849
1850 SafeProcess image_magick_process = new SafeProcess(command_parts);
1851 int exitValue = image_magick_process.runProcess(); // default process iostream handling
1852 //new way of detection of ImageMagick
1853 // Inspect the standard output of the process and seach for two particular occurrences: Version and ImageMagick.
1854 String output = image_magick_process.getStdOutput().toLowerCase();
1855 if (output.indexOf("version") != -1 || output.indexOf("imagemagick") != -1) {
1856 found = true;
1857 } // else found var remains false
1858
1859 return found;
1860 //return (image_magick_process.exitValue() == 0);
1861
1862 }
1863 }
1864
1865
1866 private class PerlTest
1867 {
1868 private String[] command = new String[2];
1869
1870 public PerlTest()
1871 {
1872 command[0] = (Utility.isWindows() ? Utility.PERL_EXECUTABLE_WINDOWS : Utility.PERL_EXECUTABLE_UNIX);
1873 command[1] = "-version";
1874 }
1875
1876 public boolean found()
1877 {
1878 try {
1879 SafeProcess perl_process = new SafeProcess(command);
1880 int exitValue = perl_process.runBasicProcess();
1881 return (exitValue == 0);
1882 }
1883 catch (Exception exception) {
1884 return false;
1885 }
1886 }
1887
1888 public String toString() {
1889 return command[0];
1890 }
1891 }
1892
1893}
Note: See TracBrowser for help on using the repository browser.