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

Last change on this file since 10726 was 10726, checked in by mdewsnip, 19 years ago

(MAJOR CHANGE) This is the remote Greenstone building functionality implemented for the West Yorkshire Fire and Rescue Service. It allows collections to be built without having a local version of Greenstone, using either a stand-alone version of the GLI or the applet.

The collections are stored on the server (allowing people to collaborate on collections -- but not at the same time), and only what is necessary to let the user edit the collection is downloaded. Any changes to the collection are uploaded to the server.

An access restriction mechanism is implemented which uses the standard Greenstone user database to control who has access to collections.

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