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

Last change on this file since 34113 was 34113, checked in by ak19, 4 years ago
  1. tomcat.port no longer exists in build.properties after https also supported. GLI now goes through ProtocolPortProperties.java (which supports legacy tomcat.port) to work out the port number and the protocol, just like GS3 runtime code has been doing for a while now. The greenstone3 context is also not to be hardcoded to greenstone3, but to be read in from the build.properties file. 2. Have to add a copy of GS3 runtime src's ProtocolPortProperties.java into GLI. Anything better than such code duplication? GLI also has what is largely a copy of SafeProcess.java, although there may be minor diffs there with the GS3 runtime code version. 3. Removed unused imports from FedoraLogin.java.
  • Property svn:keywords set to Author Date Id Revision
File size: 72.2 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 local 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 multipleFilenameEncodingsNotSupported();
588 FilenameEncoding.MULTIPLE_FILENAME_ENCODINGS_SUPPORTED = false;
589 FilenameEncoding.URL_FILE_SEPARATOR = File.separator;
590 } else {
591 FilenameEncoding.MULTIPLE_FILENAME_ENCODINGS_SUPPORTED = true;
592 FilenameEncoding.URL_FILE_SEPARATOR = "/"; // URL file separator is always "/"
593 }
594
595 // Set the default font for all Swing components.
596 FontUIResource default_font = Configuration.getFont("general.font", true);
597 Enumeration keys = UIManager.getDefaults().keys();
598 while (keys.hasMoreElements()) {
599 Object key = keys.nextElement();
600 Object value = UIManager.get(key);
601 if (value instanceof FontUIResource) {
602 UIManager.put(key, default_font);
603 }
604 }
605
606 // At this point (which is where this code originally used to be), we can set up the proxy for the
607 // non-remote case. The remote Greenstone server would already have setup its proxy when required.
608 if(!isGsdlRemote) {
609 setProxy();
610 // Now we set up an Authenticator
611 Authenticator.setDefault(new GAuthenticator());
612 }
613 assoc_man = new FileAssociationManager();
614 // Create File Manager
615 f_man = new FileManager();
616 // Create Collection Manager
617 c_man = new CollectionManager();
618 // Create Recycle Bin
619 recycle_bin = new RecycleBin();
620
621 if (GS3) {
622 if (site_name==null) {
623 site_name = Configuration.site_name;
624 servlet_path = null; // need to reset this
625 }
626 if (servlet_path == null) {
627 servlet_path = Configuration.getServletPath();
628 }
629 }
630
631
632 } catch (Exception exception) {
633 DebugStream.printStackTrace(exception);
634 }
635
636
637 // Create GUI Manager (last) or else suffer the death of a thousand NPE's
638 g_man = new GUIManager(size);
639
640 // Get a list of the core Greenstone classifiers and plugins
641 Classifiers.loadClassifiersList(null);
642 Plugins.loadPluginsList(null);
643
644 // Users may specify a non-standard collect directory (eg. when running one GLI in a network environment)
645 // Set to any custom collection directory provided to gli. This happens if gli was run as:
646 // ./gli.sh -collectdir </full/path/to/custom/collect>
647 if(collect_directory_path != null) {
648
649 // create a version of the collect_dir_path without a file-separator at end
650 String collectDir = collect_directory_path;
651 if(collectDir.endsWith(File.separator)) {
652 collectDir = collectDir.substring(0, collectDir.length()-1); // remove file separator at end
653 }
654
655 // update .gli/config.xml to contain the version of the path without file-separator at end
656 if(collect_directory_path.equals(getDefaultGSCollectDirectoryPath(false))) {
657 Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(),
658 true, "");
659 } else {
660 Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(),
661 true, collectDir);
662 }
663
664 // set non_standard_collect_directory_path variable. Ensures file_separator at end
665 Gatherer.setCollectDirectoryPath(collect_directory_path);
666
667 // Use version of path without file-separator at end to set collecthome in gsdlsite(3).cfg
668 if(collectDir != null) {
669 collectDir = "\""+collectDir+"\"";
670 }
671 Utility.updatePropertyConfigFile(getGsdlSiteConfigFile(), "collecthome", collectDir);
672 // if gsdlsite.cfg does not exist (if using server.exe for instance), the above method will just return
673 }
674
675 // If using a remote Greenstone we need to download the collection configurations now
676 if (Gatherer.isGsdlRemote) {
677 if (remoteGreenstoneServer.downloadCollectionConfigurations().equals("")) {
678 // !! Something went wrong downloading the collection configurations
679 System.err.println("Error: Could not download collection configurations.");
680 if(!Gatherer.isApplet) { // don't close the browser if it is an applet!
681 System.exit(0);
682 }
683 }
684 }
685 }
686
687
688 /** Returns the correct version of the (local or remote) Greenstone server if init() has already been called. */
689 public static int serverVersionNumber() {
690 return GS3 ? 3 : 2;
691 }
692
693 /** Returns "Server: version number" if init() has already been called. */
694 public static String getServerVersionAsString() {
695 return "Server: v" + serverVersionNumber();
696 }
697
698 public void openGUI()
699 {
700 // Size and place the frame on the screen
701 Rectangle bounds = Configuration.getBounds("general.bounds", true);
702 if (bounds == null) {
703 // Choose a sensible default value
704 bounds = new Rectangle(0, 0, 640, 480);
705 }
706
707 // Ensure width and height are reasonable
708 size = bounds.getSize();
709 if (size.width < 640) {
710 size.width = 640;
711 }
712 else if (size.width > Configuration.screen_size.width && Configuration.screen_size.width > 0) {
713 size.width = Configuration.screen_size.width;
714 }
715 if (size.height < 480) {
716 size.height = 480;
717 }
718 else if (size.height > Configuration.screen_size.height && Configuration.screen_size.height > 0) {
719 size.height = Configuration.screen_size.height;
720 }
721
722 if (!g_man_built) {
723
724 g_man.display();
725
726 // 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).
727 g_man.setLocation(bounds.x, bounds.y);
728 g_man.setVisible(true);
729
730 // After the window has been made visible, check that it is in the correct place
731 // sometimes java places a window not in the correct place,
732 // but with an offset. If so, we work out what the offset is
733 // and change the desired location to take that into account
734 Point location = g_man.getLocation();
735 int x_offset = bounds.x - location.x;
736 int y_offset = bounds.y - location.y;
737 // If not, offset the window to move it into the correct location
738 if (x_offset > 0 || y_offset > 0) {
739 ///ystem.err.println("changing the location to "+(bounds.x + x_offset)+" "+ (bounds.y + y_offset));
740 g_man.setLocation(bounds.x + x_offset, bounds.y + y_offset);
741 }
742
743 // 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.
744 g_man.afterDisplay();
745 g_man_built = true;
746 }
747 else {
748 g_man.setVisible(true);
749 }
750
751 // Get a list of the core Greenstone classifiers and plugins
752 /*Classifiers.loadClassifiersList(null);
753 Plugins.loadPluginsList(null);
754
755 // If using a remote Greenstone we need to download the collection configurations now
756 if (Gatherer.isGsdlRemote) {
757 if (remoteGreenstoneServer.downloadCollectionConfigurations().equals("")) {
758 // !! Something went wrong downloading the collection configurations
759 System.err.println("Error: Could not download collection configurations.");
760 System.exit(0);
761 }
762 }*/
763
764 // if we're tutorial testing GLI, want names assigned to the GUI components
765 TestingPreparation.setNamesRecursively(g_man);
766
767
768 // If there was a collection left open last time, reopen it
769 if (open_collection_file_path == null || new File(Gatherer.open_collection_file_path).isDirectory()) {
770
771 //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
772 setMenuBarEnabled(true);
773 } else {
774
775 // If there was a collection left open last time, reopen it
776 c_man.openCollectionFromLastTime();
777 }
778 }
779
780 public static void setMenuBarEnabled(boolean enabled) {
781 g_man.menu_bar.file.setEnabled(enabled);
782 g_man.menu_bar.edit.setEnabled(enabled);
783 }
784
785 /** Exits the Gatherer after ensuring that things needing saving are saved.
786 * @see java.io.FileOutputStream
787 * @see java.io.PrintStream
788 * @see java.lang.Exception
789 * @see javax.swing.JOptionPane
790 * @see org.greenstone.gatherer.Configuration
791 * @see org.greenstone.gatherer.collection.CollectionManager
792 * @see org.greenstone.gatherer.gui.GUIManager
793 */
794 static public void exit(int new_exit_status)
795 {
796 DebugStream.println("In Gatherer.exit()...");
797 exit = true;
798 if (new_exit_status != 0) {
799 // default exit_status is already 0
800 // only remember a new exit status if it is non-trivial
801 exit_status = new_exit_status;
802 }
803
804 // Save the file associations
805 if (assoc_man != null) {
806 assoc_man.save();
807 assoc_man = null;
808 }
809
810 // Get the gui to deallocate
811 if(g_man != null) {
812 g_man.destroy();
813 g_man_built = false;
814 }
815
816 // Flush debug
817 DebugStream.closeDebugStream();
818
819 // If we started a server, we should try to stop it.
820 if (LocalLibraryServer.isRunning() == true) {
821 LocalLibraryServer.stop();
822 }
823
824 // If we're using a remote Greenstone server we need to make sure that all jobs have completed first
825 if (isGsdlRemote) {
826 remoteGreenstoneServer.exit();
827 } else if (GS3) { // stop the local tomcat web server when running GS3
828 // can't call ant stop from its own thread - what if GLI has exited by then?
829 // issue call to ant stop from the main GLI thread
830 //GS3ServerThread thread = new GS3ServerThread(Configuration.gsdl_path, "stop");
831 //thread.start();
832 if(!GS3ServerThread.wasServerLaunchedOutsideGLI()) {
833 GS3ServerThread.stopServer();
834 } else {
835 System.err.println("@@@ Tomcat was launched outside GLI. Leaving it running...");
836 }
837
838 }
839
840 // Make sure we haven't started up any processes that are still running
841 if (apps.size() == 0) {
842 // If we're running as an applet we don't actually quit (just hide the main GLI window)
843 if (!Gatherer.isApplet) {
844 // This is the end...
845 System.exit(exit_status);
846 }
847 }
848 else {
849 JOptionPane.showMessageDialog(g_man, Dictionary.get("General.Outstanding_Processes"), Dictionary.get("General.Outstanding_Processes_Title"), JOptionPane.ERROR_MESSAGE);
850 g_man.setVisible(false);
851 }
852 }
853
854 static public void exit()
855 {
856 exit(0);
857 }
858
859 /** Returns the path of the current collect directory. */
860 static public String getCollectDirectoryPath()
861 {
862 if (non_standard_collect_directory_path != null) {
863 return non_standard_collect_directory_path;
864 }
865
866 return getDefaultGSCollectDirectoryPath(true); // file separator appended
867
868 }
869
870 // if we need to know whether the local server we are running is server.exe vs apache web server
871 static public boolean isPersistentServer() {
872 return (!isGsdlRemote && LocalLibraryServer.isPersistentServer());
873 }
874
875 /** Returns the path of the Greenstone "collect" directory. */
876 static public String getDefaultGSCollectDirectoryPath(boolean appendSeparator) {
877 String colDir;
878 if (GS3) {
879 colDir = getSitesDirectoryPath() + Configuration.site_name + File.separator + "collect";
880 }
881 else {
882 colDir = Configuration.gsdl_path + "collect";
883 }
884
885 if(appendSeparator) {
886 colDir += File.separator;
887 }
888 return colDir;
889 }
890
891 /** Returns the path of the GLI directory. */
892 static public String getGLIDirectoryPath()
893 {
894 return gli_directory_path;
895 }
896
897
898 /** Returns the path of the GLI "metadata" directory. */
899 static public String getGLIMetadataDirectoryPath()
900 {
901 return getGLIDirectoryPath() + "metadata" + File.separator;
902 }
903
904
905 /** Returns the path of the GLI user directory. */
906 static public String getGLIUserDirectoryPath()
907 {
908 return gli_user_directory_path;
909 }
910
911
912 /** Returns the path of the GLI user "cache" directory. */
913 static public String getGLIUserCacheDirectoryPath()
914 {
915 return getGLIUserDirectoryPath() + "cache" + File.separator;
916 }
917
918
919 /** Returns the path of the GLI user "log" directory. */
920 static public String getGLIUserLogDirectoryPath()
921 {
922 return getGLIUserDirectoryPath() + "log" + File.separator;
923 }
924
925
926 static public String getSitesDirectoryPath()
927 {
928 return Configuration.gsdl3_path + "sites" + File.separator;
929 }
930
931
932 static public void setCollectDirectoryPath(String collect_directory_path)
933 {
934 non_standard_collect_directory_path = collect_directory_path;
935 if (!non_standard_collect_directory_path.endsWith(File.separator)) {
936 non_standard_collect_directory_path = non_standard_collect_directory_path + File.separator;
937 }
938 }
939
940
941 static public void setGLIDirectoryPath(String gli_directory_path_arg)
942 {
943 gli_directory_path = gli_directory_path_arg;
944 }
945
946
947 static public void setGLIUserDirectoryPath(String gli_user_directory_path_arg)
948 {
949 gli_user_directory_path = gli_user_directory_path_arg;
950
951 // Ensure the GLI user directory exists
952 File gli_user_directory = new File(gli_user_directory_path);
953 if (!gli_user_directory.exists() && !gli_user_directory.mkdirs()) {
954 System.err.println("Error: Unable to make directory: " + gli_user_directory);
955 }
956 }
957
958
959 public static void initCollectDirectoryPath() {
960 String defaultColdir = getDefaultGSCollectDirectoryPath(false); // no file separator at end
961 String coldir = defaultColdir;
962 // If local GS and opening a collection outside the standard GS collect folder,
963 // need to open the non-standard collect folder that the collection resides in
964 if (!isGsdlRemote
965 && !open_collection_file_path.startsWith(defaultColdir))
966 {
967 File collectFolder = null;
968
969 if(!open_collection_file_path.equals("")) {
970 if(!open_collection_file_path.endsWith("gli.col")) { // then it's a collect folder
971 collectFolder = new File(open_collection_file_path);
972 } else {
973 // the filepath is a gli.col file. To get the collect folder: the 1st level up
974 // is the collection folder, 2 two levels up is the containing collect folder
975 collectFolder = new File(open_collection_file_path).getParentFile().getParentFile();
976 }
977
978 // Need to deal with colgroups as well: while there's an etc/collect.cfg
979 // in the current collectFolder, move one level up
980 String cfg_file = (Gatherer.GS3)? Utility.CONFIG_GS3_FILE : Utility.CONFIG_FILE;
981 if(new File(collectFolder.getAbsolutePath()+File.separator+cfg_file).exists()) { // colgroup
982 collectFolder = collectFolder.getParentFile();
983 }
984
985 // Inform the user that their collecthome is non-standard (not inside GS installation)
986 nonStandardCollectHomeMessage(collectFolder.getAbsolutePath(), defaultColdir); // display message
987 }
988
989 if(collectFolder == null || !collectFolder.exists()) {
990 // if GLI config file specified no collectDir (open_collection_file_path is "")
991 // OR if dealing with a local server but the collectdir no longer exists,
992 // use the default greenstone collect directory, and write that to affected files
993
994 open_collection_file_path = defaultColdir; // default GS collect dir
995 // Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(), true, "");
996 } else { // use the coldir value specified in the flags to GLI or from the last GLI session
997 coldir = collectFolder.getAbsolutePath();
998 }
999 // set it as the current folder
1000 setCollectDirectoryPath(coldir); // will ensure the required file separator at end
1001 }
1002
1003 if(!isGsdlRemote) {
1004 // LocalLibraryServer would already have set glisite.cfg to the correct collecthome for server.exe
1005 // Here we set collecthome in gsdl(3)site.cfg for the GS2 apache web server and GS3 tomcat server
1006 String gsdlsitecfg = getGsdlSiteConfigFile();
1007 // update the gsdlsite config file and store the old value for use when we exit GLI
1008 if(coldir.equals(defaultColdir)) {
1009 gsdlsite_collecthome = Utility.updatePropertyConfigFile(
1010 gsdlsitecfg, "collecthome", null);
1011 } else {
1012 gsdlsite_collecthome = Utility.updatePropertyConfigFile(
1013 gsdlsitecfg, "collecthome", "\""+coldir+"\""); // no file separator
1014 // if gsdlsite.cfg does not exist (if using server.exe for instance), the above method will just return
1015 }
1016 }
1017 }
1018
1019 /** depending on the version of GS being run, return the path to the current GS' installation's gsdl(3)site.cfg */
1020 public static String getGsdlSiteConfigFile() {
1021 if(Gatherer.GS3) { // web/WEB-INF/cgi/gsdl3site.cfg
1022 return Configuration.gsdl3_path + File.separator + "WEB-INF"
1023 + File.separator + "cgi" + File.separator + "gsdl3site.cfg";
1024 } else { // cgi-bin/gsdlsite.cfg
1025 String gsdlarch = System.getenv("GSDLARCH");
1026 if(gsdlarch == null) {
1027 gsdlarch = "";
1028 }
1029 return Configuration.gsdl_path /* + File.separator */
1030 + "cgi-bin" + File.separator + client_operating_system+gsdlarch + File.separator + "gsdlsite.cfg";
1031 }
1032 }
1033
1034 public static void collectDirectoryHasChanged(
1035 String oldCollectPath, String newCollectPath, final Component container)
1036 {
1037 if(oldCollectPath.equals(newCollectPath)) {
1038 return; // nothing to be done
1039 }
1040
1041 // Will use a busy cursor if the process of changing the collect directory takes more
1042 // than half a second/500ms. See http://www.catalysoft.com/articles/busyCursor.html
1043 Cursor originalCursor = container.getCursor();
1044 java.util.TimerTask timerTask = new java.util.TimerTask() {
1045 public void run() {
1046 // set the cursor on the container:
1047 container.setCursor(new Cursor(Cursor.WAIT_CURSOR));
1048 }
1049 };
1050 java.util.Timer timer = new java.util.Timer();
1051
1052 try {
1053 timer.schedule(timerTask, 500);
1054
1055 // first save any open collection in the old location, then close it
1056 if(Gatherer.c_man.getCollection() != null) {
1057 Gatherer.g_man.saveThenCloseCurrentCollection(); // close the current collection first
1058 }
1059
1060 // change to new collect path
1061 if(newCollectPath.equals(getDefaultGSCollectDirectoryPath(true))) {
1062 Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(),
1063 true, "");
1064 } else {
1065 Configuration.setString("general.open_collection"+Configuration.gliPropertyNameSuffix(),
1066 true, newCollectPath);
1067 }
1068 Gatherer.setCollectDirectoryPath(newCollectPath);
1069
1070
1071 // refresh the Documents in Greenstone Collections
1072 //WorkspaceTreeModel.refreshGreenstoneCollectionsNode();
1073 Gatherer.g_man.refreshWorkspaceTreeGreenstoneCollections();
1074
1075 // The web server needs to be told where a new (non-standard) collecthome home is.
1076 // The web server reads collecthome from cgi-bin/<OS>/gsdlsite.cfg, where the property
1077 // collecthome can be specified if a non-standard collecthome is to be used. If no
1078 // such property is specified in the file, then it assumes the standard GS collecthome.
1079 // This method does nothing for a remote Greenstone.
1080 if(Gatherer.isGsdlRemote) {
1081 return;
1082 }
1083
1084 // non-destructive update of gsdl(3)site.cfg (comments preserved)
1085 String collectDir = Gatherer.getCollectDirectoryPath();
1086 //collectDir = "\"" + collectDir.substring(0, collectDir.length()-1) + "\""; // remove file separator at end
1087 collectDir = collectDir.substring(0, collectDir.length()-1); // remove file separator at end
1088 if(collectDir != null) {
1089 collectDir = "\""+collectDir+"\"";
1090 }
1091 Utility.updatePropertyConfigFile(getGsdlSiteConfigFile(), "collecthome", collectDir);
1092 // if gsdlsite.cfg does not exist (if using server.exe for instance), the above method will just return
1093
1094 if(!Gatherer.GS3 && Gatherer.isLocalLibrary) {
1095 // for Images in the collection to work, the apache web server
1096 // configuration's COLLECTHOME should be updated on collectdir change.
1097 // Does nothing for server.exe at the moment
1098
1099 LocalLibraryServer.reconfigure();
1100 }
1101 } finally { // Note try-finally section without catch:
1102 // "Java's finally clause is guaranteed to be executed even when
1103 // an exception is thrown and not caught in the current scope."
1104 // See http://www.catalysoft.com/articles/busyCursor.html
1105 // the following code fragment is guaranteed to restore the original
1106 // cursor now the custom actionPerformed() processing is complete, regardless
1107 // of whether the processing method terminates normally or throws an exception
1108 // and regardless of where in the call stack the exception is caught.
1109
1110 timer.cancel();
1111 container.setCursor(originalCursor);
1112 }
1113 }
1114
1115
1116 static public void refresh(int refresh_reason)
1117 {
1118 if (g_man != null) {
1119
1120 g_man.refresh(refresh_reason, c_man.ready());
1121 }
1122
1123 // Now is a good time to force a garbage collect
1124 System.gc();
1125 }
1126
1127
1128 // used to send reload coll messages to the tomcat server
1129 static public void configGS3Server(String site, String command) {
1130
1131 // Do not do configGS3Server for a GS3 solr collection. Not at present at least, when we're stopping
1132 // and starting the GS3 server from GLI for solr cols, since this function clears the solr.xml file.
1133 /*if(Gatherer.c_man.isSolrCollection()) {
1134 return;
1135 }*/
1136
1137 if (Configuration.library_url == null){
1138 System.out.println("Error: you have not provided the Greenstone Library address.");
1139 return;
1140
1141 }
1142
1143 try {
1144 // need to add the servlet name to the exec address
1145 String raw_url = Configuration.library_url.toString() + Configuration.getServletPath() + command;
1146 URL url = new URL(raw_url);
1147 DebugStream.println("Action: " + raw_url);
1148 HttpURLConnection library_connection = (HttpURLConnection) url.openConnection();
1149 int response_code = library_connection.getResponseCode();
1150 if(HttpURLConnection.HTTP_OK <= response_code && response_code < HttpURLConnection.HTTP_MULT_CHOICE) {
1151 DebugStream.println("200 - Complete.");
1152 }
1153 else {
1154 DebugStream.println("404 - Failed.");
1155 }
1156 url = null;
1157 }
1158 catch(java.net.ConnectException connectException) {
1159 JOptionPane.showMessageDialog(g_man, Dictionary.get("Preferences.Connection.Library_Path_Connection_Failure", Configuration.library_url.toString()), Dictionary.get("General.Warning"), JOptionPane.WARNING_MESSAGE);
1160 DebugStream.println(connectException.getMessage());
1161 }
1162 catch (Exception exception) {
1163 DebugStream.printStackTrace(exception);
1164 }
1165 }
1166
1167
1168 /** Used to 'spawn' a new child application when a file is double clicked.
1169 * @param file The file to open
1170 * @see org.greenstone.gatherer.Gatherer.ExternalApplication
1171 */
1172 static public void spawnApplication(File file) {
1173 String [] commands = assoc_man.getCommand(file);
1174 if(commands != null) {
1175 ExternalApplication app = new ExternalApplication(commands);
1176 apps.add(app);
1177 app.start();
1178 }
1179 else {
1180 ///ystem.err.println("No open command available.");
1181 }
1182 }
1183
1184
1185 static public void spawnApplication(String command)
1186 {
1187 ExternalApplication app = new ExternalApplication(command);
1188 apps.add(app);
1189 app.start();
1190 }
1191
1192 static public void spawnApplication(String command, String ID)
1193 {
1194 ExternalApplication app = new ExternalApplication(command, ID);
1195 apps.add(app);
1196 app.start();
1197 }
1198
1199 static public void spawnApplication(String[] commands, String ID)
1200 {
1201 ExternalApplication app = new ExternalApplication(commands, ID);
1202 apps.add(app);
1203 app.start();
1204 }
1205
1206 static public void terminateApplication(String ID) {
1207 for(int i = 0; i < apps.size(); i++) {
1208 ExternalApplication app = (ExternalApplication)apps.get(i);
1209 if(app.getID() != null && app.getID().equals(ID)) {
1210 app.stopExternalApplication();
1211 apps.remove(app);
1212 }
1213 }
1214 }
1215
1216
1217 /** Used to 'spawn' a new browser application or reset an existing one when the preview button is clicked
1218 * @param url The url to open the browser at
1219 * @see org.greenstone.gatherer.Gatherer.BrowserApplication
1220 */
1221 static public void spawnBrowser(String url) {
1222 String command = assoc_man.getBrowserCommand(url);
1223 if (command != null) {
1224 BrowserApplication app = new BrowserApplication(command, url);
1225 apps.add(app);
1226 app.start();
1227 }
1228 else {
1229 ///ystem.err.println("No browser command available.");
1230 }
1231 }
1232
1233
1234 /** Prints a warning message about a missing library path, which means the final collection cannot be previewed in the Gatherer.
1235 */
1236 static public void missingEXEC() {
1237 try {
1238 SwingUtilities.invokeAndWait(new Runnable() {
1239 public void run() {
1240 WarningDialog dialog;
1241 String configPropertyName = "general.library_url"+Configuration.gliPropertyNameSuffix();
1242
1243 if (GS3) {
1244 // Warning dialog with no cancel button and no "turn off warning" checkbox
1245 dialog = new WarningDialog("warning.MissingEXEC", Dictionary.get("MissingEXEC_GS3.Title"), Dictionary.get("MissingEXEC_GS3.Message"), configPropertyName, false, false);
1246 } else { // local case
1247 dialog = new WarningDialog("warning.MissingEXEC", Dictionary.get("MissingEXEC.Title"), Dictionary.get("MissingEXEC.Message"), configPropertyName, false);
1248 }
1249
1250 JTextField field = new URLField.Text(Configuration.getColor("coloring.editable_foreground", false), Configuration.getColor("coloring.editable_background", false));
1251
1252 // Set the default library URL to the tomcat server and port number
1253 // specified in the build.properties located in the gsdl3_src_path
1254 if (GS3) {
1255 // defaults
1256 String host = "localhost";
1257 String port = "8383";
1258 String context = "greenstone3";
1259 String protocol = "http";
1260
1261 File buildPropsFile = new File(Configuration.gsdl3_src_path + File.separator + "build.properties");
1262 if(buildPropsFile.exists()) {
1263 Properties props = new Properties();
1264 try{
1265 props.load(new FileInputStream(buildPropsFile));
1266 host = props.getProperty("tomcat.server", host);
1267 context = props.getProperty("greenstone.context", context);
1268 ProtocolPortProperties protocolPortProps = new ProtocolPortProperties(props); // can throw Exception
1269 // Use ProtocolPortProperties to get the tomcat port and protocol used
1270 protocol = protocolPortProps.getProtocol();
1271 port = protocolPortProps.getPort();
1272 }catch(Exception e){
1273 DebugStream.println("Could not load build.properties file");
1274 System.err.println("Could not load build.properties file");
1275 }
1276 props = null;
1277 }
1278 String defaultURL = protocol+"://"+host+":"+port+"/"+context;
1279 field.setText(defaultURL);
1280 field.selectAll();
1281 }
1282 dialog.setValueField(field);
1283 dialog.display();
1284 dialog.dispose();
1285 dialog = null;
1286
1287 String library_url_string = Configuration.getString(configPropertyName, true);
1288 if (!library_url_string.equals("")) {
1289 try {
1290 // WarningDialog does not allow invalid URLs, so the following is ignored:
1291 // make sure the URL the user provided contains the http:// prefix
1292 // and then save the corrected URL
1293 if(!library_url_string.startsWith("http://")
1294 && !library_url_string.startsWith("https://")) {
1295 library_url_string = "http://"+library_url_string;
1296 Configuration.setString(configPropertyName, true, configPropertyName);
1297 }
1298 Configuration.library_url = new URL(library_url_string);
1299 }
1300 catch (MalformedURLException exception) {
1301 DebugStream.printStackTrace(exception);
1302 }
1303 }
1304 }
1305 });
1306 } catch(Exception e) { //InterruptedException or InvocationTargetException
1307 e.printStackTrace();
1308 }
1309 }
1310
1311
1312
1313 /** Prints a warning message about a missing library path, which means the final collection cannot be previewed in the Gatherer.
1314 */
1315 static private void popupFedoraInfo() {
1316 try {
1317 SwingUtilities.invokeAndWait(new Runnable() {
1318 public void run() {
1319 FedoraLogin dialog = new FedoraLogin("Fedora Login", false);
1320
1321 if (Configuration.library_url == null) {
1322
1323 String library_url_string = dialog.getLibraryURL();
1324 if (!library_url_string.equals("")) {
1325 try {
1326 Configuration.library_url = new URL(library_url_string);
1327 }
1328 catch (MalformedURLException exception) {
1329 DebugStream.printStackTrace(exception);
1330 }
1331 }
1332 }
1333
1334 boolean showLogin = true;
1335 do {
1336 if(!dialog.loginRequested()) { // user pressed cancel to exit the FedoraLogin dialog
1337 System.exit(0);
1338 } else {
1339 showLogin = dialog.loginRequested();
1340 String hostname = dialog.getHostname();
1341 String port = dialog.getPort();
1342 String username = dialog.getUsername();
1343 String password = dialog.getPassword();
1344 String protocol = dialog.getProtocol();
1345
1346 Configuration.fedora_info.setHostname(hostname);
1347 Configuration.fedora_info.setPort(port);
1348 Configuration.fedora_info.setUsername(username);
1349 Configuration.fedora_info.setPassword(password);
1350 Configuration.fedora_info.setProtocol(protocol);
1351
1352 String ping_url_str = protocol + "://" + hostname + ":" + port + "/fedora";
1353 String login_str = username + ":" + password;
1354
1355 String login_encoding = Base64.encodeBytes(login_str.getBytes());
1356
1357 try {
1358 URL ping_url = new URL(ping_url_str);
1359 URLConnection uc = ping_url.openConnection();
1360 uc.setRequestProperty ("Authorization", "Basic " + login_encoding);
1361 // Attempt to access some content ...
1362 InputStream content = (InputStream)uc.getInputStream();
1363
1364 // if no exception occurred in the above, we would have come here:
1365 showLogin = false;
1366 dialog.dispose();
1367 }
1368 catch (Exception exception) {
1369 // TODO: move into dictionary
1370 String[] errorMessage = {"Failed to connect to the Fedora server.", "It might not be running, or",
1371 "incorrect username and/or password."};
1372 dialog.setErrorMessage(errorMessage);
1373 //DebugStream.printStackTrace(exception);
1374 // exception occurred, show the dialog again (do this after printing to
1375 // debugStream, else the above does not get done for some reason).
1376 dialog.setVisible(true);
1377 }
1378 }
1379 } while(showLogin);
1380
1381 dialog = null; // no more need of the dialog
1382
1383 // Now we are connected.
1384 }
1385 });
1386 } catch(Exception e) { //InterruptedException or InvocationTargetException
1387 e.printStackTrace();
1388 }
1389 }
1390
1391
1392
1393 static private void requestGLIServerURL()
1394 {
1395 try {
1396 SwingUtilities.invokeAndWait(new Runnable() {
1397 public void run() {
1398 WarningDialog dialog;
1399 String[] defaultURLs = {
1400 "http://localhost:8080/greenstone3/cgi-bin/gliserver.pl",
1401 "http://localhost:8080/gsdl/cgi-bin/gliserver.pl"
1402 };
1403
1404 // Warning dialog with no cancel button and no "turn off warning" checkbox
1405 // (since user-input of the gliserver script is mandatory)
1406 dialog = new WarningDialog("warning.MissingGLIServer", Dictionary.get("MissingGLIServer.Title"), Dictionary.get("MissingGLIServer.Message"), "general.gliserver_url", false, false);
1407
1408 dialog.setValueField(new URLField.DropDown(Configuration.getColor("coloring.editable_foreground", false),
1409 Configuration.getColor("coloring.editable_background", false),
1410 defaultURLs, "general.gliserver_url",
1411 "general.open_collection"+Configuration.gliPropertyNameSuffix(),
1412 "gliserver.pl"));
1413
1414 if (Gatherer.default_gliserver_url!=null){
1415 dialog.setValueField(Gatherer.default_gliserver_url.toString());
1416 }
1417
1418 // A WarningDialog cannot always be made to respond (let alone to exit the program) on close. We
1419 // handle the response of this particular WarningDialog here: a URL for gliserver.pl is a crucial
1420 // piece of user-provided data. Therefore, if no URL was entered for gliserver.pl, it'll exit safely.
1421 dialog.addWindowListener(new WindowAdapter() {
1422 public void windowClosing(WindowEvent e) {
1423 Gatherer.exit();
1424 }
1425 });
1426
1427 dialog.display();
1428 dialog.dispose();
1429 dialog = null;
1430
1431
1432 String gliserver_url_string = Configuration.getString("general.gliserver_url", true);
1433 if (!gliserver_url_string.equals("")) {
1434 try {
1435 Configuration.gliserver_url = new URL(gliserver_url_string);
1436 Configuration.setString("general.gliserver_url", true, gliserver_url_string);
1437 }
1438 catch (MalformedURLException exception) {
1439 DebugStream.printStackTrace(exception);
1440 }
1441 }
1442 }
1443 });
1444 } catch(Exception e) { //InterruptedException or InvocationTargetException
1445 e.printStackTrace();
1446 }
1447 }
1448
1449
1450 /** Prints a warning message about a missing GSDL path, which although not fatal pretty much ensures nothing will work properly in the GLI.
1451 */
1452 static private void missingGSDL() {
1453 try {
1454 SwingUtilities.invokeAndWait(new Runnable() {
1455 public void run() {
1456 WarningDialog dialog = new WarningDialog("warning.MissingGSDL", Dictionary.get("MissingGSDL.Title"), Dictionary.get("MissingGSDL.Message"), null, false);
1457 dialog.display();
1458 dialog.dispose();
1459 dialog = null;
1460 }
1461 });
1462 } catch(Exception e) { //InterruptedException or InvocationTargetException
1463 e.printStackTrace();
1464 }
1465 }
1466
1467 /** Prints a warning message about missing a valid ImageMagick path, which although not fatal means building image collections won't work */
1468 static private void missingImageMagick() {
1469 try {
1470 SwingUtilities.invokeAndWait(new Runnable() {
1471 public void run() {
1472 WarningDialog dialog = new WarningDialog("warning.MissingImageMagick", Dictionary.get("MissingImageMagick.Title"), Dictionary.get("MissingImageMagick.Message"), null, false);
1473 dialog.display();
1474 dialog.dispose();
1475 dialog = null;
1476 }
1477 });
1478 } catch(Exception e) { //InterruptedException or InvocationTargetException
1479 e.printStackTrace();
1480 }
1481 }
1482
1483 /** Prints a message informing the user where they can get PDFBox from to process PDF files of v1.5 and greater */
1484 static private void missingPDFBox(final String zipExtension, final String extFolder) {
1485 try {
1486 SwingUtilities.invokeAndWait(new Runnable() {
1487 public void run() {
1488
1489 // point to the correct version of the PDFBox extension for this Greenstone release
1490 String releaseTag = "";
1491 if(!PROGRAM_VERSION.equals("trunk")) { // assume it's a release version
1492 releaseTag = "main/tags/"+PROGRAM_VERSION+"/";
1493 }
1494
1495 WarningDialog dialog = new WarningDialog("warning.MissingPDFBox", Dictionary.get("MissingPDFBox.Title"), Dictionary.get("MissingPDFBox.Message", new String[]{releaseTag, zipExtension, extFolder}), null, false);
1496 dialog.display();
1497 dialog.dispose();
1498 dialog = null;
1499 }
1500 });
1501 } catch(Exception e) { //InterruptedException or InvocationTargetException
1502 e.printStackTrace();
1503 }
1504 }
1505
1506 /** 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. */
1507 static private void missingPERL() {
1508 try {
1509 SwingUtilities.invokeAndWait(new Runnable() {
1510 public void run() {
1511 WarningDialog dialog = new WarningDialog("warning.MissingPERL", Dictionary.get("MissingPERL.Title"), Dictionary.get("MissingPERL.Message"), null, false);
1512 dialog.display();
1513 dialog.dispose();
1514 dialog = null;
1515 }
1516 });
1517 } catch(Exception e) { //InterruptedException or InvocationTargetException
1518 e.printStackTrace();
1519 }
1520 }
1521
1522 /** Prints a message informing the user that their collecthome is non-standard (not inside GS installation) */
1523 static private void nonStandardCollectHomeMessage(final String open_collection_file_path, final String defaultColDir) {
1524 try {
1525 SwingUtilities.invokeAndWait(new Runnable() {
1526 public void run() {
1527 WarningDialog dialog = new WarningDialog("warning.NonStandardCollectHome", Dictionary.get("NonStandardCollectHome.Title"), Dictionary.get("NonStandardCollectHome.Message", new String[]{open_collection_file_path, defaultColDir}), null, false);
1528 dialog.display();
1529 dialog.dispose();
1530 dialog = null;
1531 }
1532 });
1533 } catch(Exception e) { //InterruptedException or InvocationTargetException
1534 e.printStackTrace();
1535 }
1536 }
1537
1538 /** Prints a warning message about the OS not supporting multiple filename encodings. */
1539 static private void multipleFilenameEncodingsNotSupported() {
1540 try {
1541 SwingUtilities.invokeAndWait(new Runnable() {
1542 public void run() {
1543 WarningDialog dialog = new WarningDialog("warning.NoEncodingSupport",
1544 Dictionary.get("NoEncodingSupport.Title"),
1545 Dictionary.get("NoEncodingSupport.Message"), null, false);
1546 dialog.display();
1547 dialog.dispose();
1548 dialog = null;
1549 }
1550 });
1551 } catch(Exception e) { //InterruptedException or InvocationTargetException
1552 e.printStackTrace();
1553 }
1554 }
1555
1556 /** Sets up the proxy connection by setting JVM Environment flags and creating a new Authenticator.
1557 * @see java.lang.Exception
1558 * @see java.lang.System
1559 * @see java.net.Authenticator
1560 * @see org.greenstone.gatherer.Configuration
1561 * @see org.greenstone.gatherer.GAuthenticator
1562 */
1563 static public void setProxy() {
1564 try {// Can throw several exceptions
1565 boolean use_proxy = Configuration.get("general.use_proxy", true);
1566
1567 setProxyForProtocol("http", use_proxy);
1568 setProxyForProtocol("https", use_proxy);
1569 setProxyForProtocol("ftp", use_proxy);
1570
1571 } catch (Exception error) {
1572 DebugStream.println("Error in Gatherer.initProxy(): " + error);
1573 DebugStream.printStackTrace(error);
1574 }
1575 }
1576
1577 private static void setProxyForProtocol(String protocol, boolean use_proxy) throws Exception {
1578 // These are Java properties, therefore see
1579 // https://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html
1580 // https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html
1581 // https://stackoverflow.com/questions/14243590/proxy-settings-in-java
1582
1583 // Just need to warn the user that we're overriding proxy settings using custom defined proxy settings
1584 // and returning to using the original proxy settings when custom defined proxy settings are turned off
1585 // We don't actually need to store/restore the original settings, as Java system vars like http.proxyHost
1586 // http.proxyPort don't seem to be set even if on GLI startup the env vars like http(s)_proxy were already set.
1587
1588
1589 if(use_proxy) {
1590 if(System.getenv(protocol+"_proxy") != null) {
1591 System.err.println("Overriding original "+protocol+" proxy settings");
1592 }
1593
1594 // set the custom proxy defined through GLI for this protocol
1595 System.setProperty(protocol+".proxyHost", Configuration.getString("general."+protocol.toUpperCase()+"_proxy_host", true));
1596 System.setProperty(protocol+".proxyPort", Configuration.getString("general."+protocol.toUpperCase()+"_proxy_port", true));
1597
1598 // Not sure what proxyType is. And proxySet ceased to exist since JDK 6 or before. See links above.
1599 // But we used to set them both for HTTP before, so still doing so for proxyType, since it may or may not exist
1600 // But proxySet doesn't exist anymore, so not continuing with that.
1601 if(protocol.equals("http")) {
1602 System.setProperty(protocol+".proxyType", "4");
1603 //System.setProperty(protocol+".proxySet", "true");
1604 }
1605
1606 }
1607
1608 else { // use_proxy=false, not using proxy defined through GLI, so
1609 // either unset proxy vars for this protocol, or restore any original settings for them
1610
1611 if(System.getenv(protocol+"_proxy") != null) {
1612 System.err.println("Restoring original "+protocol+" proxy settings");
1613 }
1614
1615 System.setProperty(protocol+".proxyHost", "");
1616 System.setProperty(protocol+".proxyPort", "");
1617 //if(protocol.equals("http")) {
1618 //System.setProperty(protocol+".proxySet", "false");
1619 //}
1620 }
1621 }
1622
1623
1624 /** 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. */
1625 static private class ExternalApplication
1626 extends Thread {
1627 private SafeProcess process = null;
1628 /** The initial command string given to this sub-process. */
1629 private String command = null;
1630 private String[] commands = null;
1631
1632 private String ID = null;
1633
1634 /** Constructor.
1635 * @param command The initial command <strong>String</strong>.
1636 */
1637 public ExternalApplication(String command) {
1638 this.command = command;
1639 }
1640
1641 public ExternalApplication(String[] commands) {
1642 this.commands = commands;
1643 }
1644
1645 public ExternalApplication(String command, String ID) {
1646 this.command = command;
1647 this.ID = ID;
1648 }
1649
1650 public ExternalApplication(String[] commands, String ID) {
1651 this.commands = commands;
1652 this.ID = ID;
1653 }
1654
1655 public String getID() {
1656 return ID;
1657 }
1658
1659 /** We start the child process inside a new thread so it doesn't block the rest of Gatherer.
1660 * @see java.lang.Exception
1661 * @see java.lang.Process
1662 * @see java.lang.Runtime
1663 * @see java.lang.System
1664 * @see java.util.Vector
1665 */
1666 public void run() {
1667 // Call an external process using the args.
1668 try {
1669 if(commands != null) {
1670 StringBuffer whole_command = new StringBuffer();
1671 for(int i = 0; i < commands.length; i++) {
1672 // get rid of any quotes around parameters in file associations
1673 if(commands[i].startsWith("\"") || commands[i].startsWith("\'")) {
1674 commands[i] = commands[i].substring(1);
1675 }
1676 if(commands[i].endsWith("\"") || commands[i].endsWith("\'")) {
1677 commands[i] = commands[i].substring(0, commands[i].length()-1);
1678 }
1679
1680 if (i>0) {
1681 whole_command.append(" ");
1682 }
1683 whole_command.append(commands[i]);
1684 }
1685 DebugStream.println("Running " + whole_command.toString());
1686 process = new SafeProcess(commands);
1687 }
1688 else {
1689 DebugStream.println("Running " + command);
1690 process = new SafeProcess(command);
1691 }
1692 process.runProcess();
1693 }
1694 catch (Exception exception) {
1695 DebugStream.printStackTrace(exception);
1696 }
1697 // Remove ourself from Gatherer list of threads.
1698 apps.remove(this);
1699 // Call exit if we were the last outstanding child process thread.
1700 if (apps.size() == 0 && exit == true) {
1701 // In my opinion (DB) there is no need to exit here,
1702 // the 'run' method ending naturally brings this
1703 // thread to an end. In fact it is potentially
1704 // dangerous to exit here, as the main thread in the
1705 // Gatherer class may be stopped prematurely. As it so
1706 // happens the point at which the ExternalApplication thread
1707 // is asked to stop (Back in the main Gatherer thread) is after
1708 // various configuration files have been saved.
1709 //
1710 // A similar argument holds for BrowserApplication thread below.
1711 System.exit(exit_status);
1712 }
1713 }
1714 public void stopExternalApplication() {
1715 if(process != null) {
1716 SafeProcess.log("*** stopExternalApplication called.");
1717 process.cancelRunningProcess();
1718 }
1719 }
1720 }
1721 /** 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. */
1722 static private class BrowserApplication
1723 extends Thread {
1724 private SafeProcess process = null;
1725 /** The initial command string given to this sub-process. */
1726 private String command = null;
1727 private String url = null;
1728 private String[] commands = null;
1729
1730 public BrowserApplication(String command, String url) {
1731 StringTokenizer st = new StringTokenizer(command);
1732 int num_tokens = st.countTokens();
1733 this.commands = new String [num_tokens];
1734 int i=0;
1735 while (st.hasMoreTokens()) {
1736 commands[i] = st.nextToken();
1737 i++;
1738 }
1739 //this.commands = commands;
1740 this.url = url;
1741 }
1742 /** We start the child process inside a new thread so it doesn't block the rest of Gatherer.
1743 * @see java.lang.Exception
1744 * @see java.lang.Process
1745 * @see java.lang.Runtime
1746 * @see java.lang.System
1747 * @see java.util.Vector
1748 */
1749 public void run() {
1750 // Call an external process using the args.
1751 if(commands == null) {
1752 apps.remove(this);
1753 return;
1754 }
1755 try {
1756 String prog_name = commands[0];
1757 String lower_name = prog_name.toLowerCase();
1758 if (lower_name.indexOf("mozilla") != -1 || lower_name.indexOf("netscape") != -1) {
1759 DebugStream.println("found mozilla or netscape, trying remote it");
1760 // mozilla and netscape, try using a remote command to get things in the same window
1761 String [] new_commands = new String[] {prog_name, "-raise", "-remote", "openURL("+url+",new-tab)"};
1762 printArray(new_commands);
1763
1764 process = new SafeProcess(new_commands);
1765 int exitCode = process.runProcess();
1766 if (exitCode != 0) { // if Netscape or mozilla was not open
1767 DebugStream.println("couldn't do remote, trying original command");
1768 printArray(commands);
1769 process = null;
1770 process = new SafeProcess(commands); // try the original command
1771 process.runProcess();
1772 }
1773 } else {
1774 // just run what we have been given
1775 StringBuffer whole_command = new StringBuffer();
1776 for(int i = 0; i < commands.length; i++) {
1777 whole_command.append(commands[i]);
1778 whole_command.append(" ");
1779 }
1780 DebugStream.println("Running " + whole_command.toString());
1781 process = new SafeProcess(commands);
1782 process.runProcess();
1783 }
1784 }
1785
1786 catch (Exception exception) {
1787 DebugStream.printStackTrace(exception);
1788 }
1789 // Remove ourself from Gatherer list of threads.
1790 apps.remove(this);
1791 // Call exit if we were the last outstanding child process thread.
1792 if (apps.size() == 0 && exit == true) {
1793 System.exit(exit_status);
1794 }
1795 }
1796 public void printArray(String [] array) {
1797 for(int i = 0; i < array.length; i++) {
1798 DebugStream.print(array[i]+" ");
1799 System.err.println(array[i]+" ");
1800 }
1801 }
1802 public void stopBrowserApplication() {
1803 if(process != null) {
1804 SafeProcess.log("*** stopBrowserApplication called.");
1805 process.cancelRunningProcess();
1806 }
1807 }
1808 }
1809
1810
1811 private class ImageMagickTest
1812 {
1813 public boolean found()
1814 {
1815 // at this stage, GLI has already sourced setup.bash, and the necessary
1816 // env variables will be available to the perl process we're about to launch
1817 boolean found = false;
1818
1819
1820 // run the command `/path/to/perl -S gs-magick.pl identify -version`
1821 ArrayList cmd_list = new ArrayList();
1822 if (!Gatherer.isGsdlRemote) {
1823 if(Configuration.perl_path != null) {
1824 cmd_list.add(Configuration.perl_path);
1825 } else {
1826 System.err.println("***** ImageMagickTest Warning: Perl_path not set, calling 'perl' instead.");
1827 cmd_list.add("perl");
1828 }
1829 cmd_list.add("-S");
1830 }
1831 cmd_list.add("gs-magick.pl");
1832 if(Utility.isWindows()) {
1833 cmd_list.add("identify.exe");
1834 } else {
1835 cmd_list.add("identify");
1836 }
1837 cmd_list.add("-version");
1838
1839 String[] command_parts = (String[]) cmd_list.toArray(new String[0]);
1840
1841 String cmd_str = "";
1842 for(int i = 0; i < command_parts.length; i++) {
1843 cmd_str += command_parts[i] + " ";
1844 }
1845 DebugStream.println("***** Running ImageMagickTest command: " + cmd_str);
1846
1847 SafeProcess image_magick_process = new SafeProcess(command_parts);
1848 int exitValue = image_magick_process.runProcess(); // default process iostream handling
1849 //new way of detection of ImageMagick
1850 // Inspect the standard output of the process and seach for two particular occurrences: Version and ImageMagick.
1851 String output = image_magick_process.getStdOutput().toLowerCase();
1852 if (output.indexOf("version") != -1 || output.indexOf("imagemagick") != -1) {
1853 found = true;
1854 } // else found var remains false
1855
1856 return found;
1857 //return (image_magick_process.exitValue() == 0);
1858
1859 }
1860 }
1861
1862
1863 private class PerlTest
1864 {
1865 private String[] command = new String[2];
1866
1867 public PerlTest()
1868 {
1869 command[0] = (Utility.isWindows() ? Utility.PERL_EXECUTABLE_WINDOWS : Utility.PERL_EXECUTABLE_UNIX);
1870 command[1] = "-version";
1871 }
1872
1873 public boolean found()
1874 {
1875 try {
1876 SafeProcess perl_process = new SafeProcess(command);
1877 int exitValue = perl_process.runBasicProcess();
1878 return (exitValue == 0);
1879 }
1880 catch (Exception exception) {
1881 return false;
1882 }
1883 }
1884
1885 public String toString() {
1886 return command[0];
1887 }
1888 }
1889
1890}
Note: See TracBrowser for help on using the repository browser.