Changeset 5000
- Timestamp:
- 2003-07-22T13:23:35+12:00 (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gli/src/org/greenstone/gatherer/Gatherer.java
r4676 r5000 1 package org.greenstone.gatherer;2 1 /** 3 2 *######################################################################### … … 7 6 * University of Waikato, New Zealand. 8 7 * 9 * <BR><BR>10 *11 8 * Author: John Thompson, Greenstone Digital Library, University of Waikato 12 9 * 13 * <BR><BR>14 *15 10 * Copyright (C) 1999 New Zealand Digital Library Project 16 *17 * <BR><BR>18 11 * 19 12 * This program is free software; you can redistribute it and/or modify … … 22 15 * (at your option) any later version. 23 16 * 24 * <BR><BR>25 *26 17 * This program is distributed in the hope that it will be useful, 27 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 28 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 29 20 * GNU General Public License for more details. 30 *31 * <BR><BR>32 21 * 33 22 * You should have received a copy of the GNU General Public License … … 36 25 *######################################################################## 37 26 */ 27 package org.greenstone.gatherer; 28 /************************************************************************************** 29 * Written: ??/??/02 30 * Revised: ??/??/02 - Commented 31 * ??/??/03 - Added support for local library server 32 * 20/07/03 - Rewrote argument parsing so that spaces no longer cause GLI to die. Also added time out when starting local library. 33 **************************************************************************************/ 34 38 35 import com.l2fprod.gui.*; 39 36 import com.l2fprod.gui.plaf.skin.*; 40 37 import com.l2fprod.util.*; 41 42 38 import java.awt.*; 39 import java.awt.event.*; 43 40 import java.io.*; 44 41 import java.lang.*; … … 47 44 import javax.swing.*; 48 45 import javax.swing.plaf.*; 46 import javax.swing.text.*; 49 47 import org.greenstone.gatherer.Configuration; 50 48 import org.greenstone.gatherer.GAuthenticator; … … 60 58 import org.greenstone.gatherer.util.ArrayTools; 61 59 import org.greenstone.gatherer.util.GSDLSiteConfig; 60 import org.greenstone.gatherer.util.StaticStrings; 62 61 import org.greenstone.gatherer.util.Utility; 63 62 import sun.misc.*; … … 67 66 */ 68 67 public class Gatherer { 68 69 static final private String SKIN_DEFINITION_FILE = "lib/greenaqua/greenaqua.xml"; 70 69 71 /** Has the exit flag been set? <i>true</i> if so, <i>false</i> otherwise. */ 70 72 public boolean exit = false; … … 105 107 /** The name of the Gatherers configuration file. */ 106 108 static private String CONFIG_FILE_NAME = "gatherer.cfg"; 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 107 119 /** Constructor. Make the three main modules, c_man, f_man and g_man, and any other necessary classes such as Dictionary. 108 120 * @param size The desired size of the Gatherer window as a <strong>Dimension</strong>. … … 134 146 135 147 // This will hopefully catch ctrl-c and terminate, and exit gracefully. However it is platform specific, and may not be supported by some JVMs. 136 /** It does, but I get blo ddy sick of it working when the Gatherer hangs.148 /** It does, but I get bloody sick of it working when the Gatherer hangs. 137 149 CTRLCHandler handler = new CTRLCHandler(); 138 150 Signal.handle(new Signal("INT"), handler); … … 405 417 } 406 418 407 /** Some startup arguments to the Gatherer have been encoded, where ' ' is replaced with '%', in order to allow arguments containing spaces to be parsed correctly by the JVM, and this method restores these arguments to thier original state.408 * @param encoded An encoded <strong>String</strong>.409 * @return The decoded <strong>String</strong>.410 */411 static public String decode(String encoded) {412 return encoded.replace('%', ' ');413 }414 419 /** The entry point into the Gatherer. Parses arguments. 415 420 * @param args A collection of arguments that may include: initial screen size, dictionary, path to the GSDL etc. … … 421 426 * @see org.greenstone.gatherer.Gatherer 422 427 * @see org.greenstone.gatherer.gui.Splash 428 * @see org.greenstone.gatherer.util.StaticStrings 423 429 */ 424 430 static public void main(String[] args) { … … 439 445 String perl_path = null; 440 446 // Parse arguments 441 for(int i = 0; i < args.length; i++) { 442 if(args[i].equals("-gsdl")) { 443 gsdl_path = decode(args[i+1]); 444 if(!gsdl_path.endsWith(File.separator)) { 445 gsdl_path = gsdl_path + File.separator; 446 } 447 } 448 if(args[i].equals("-load")) { 449 filename = decode(args[i+1]); 450 } 451 else if(args[i].equals("-library") && (i + 1) < args.length) { 452 exec_path = args[i+1]; 453 // If we are on a non-windows system, and thus the local server is unavailable, we can append http:// if no protocol found. 454 if(exec_path.lastIndexOf(":", 5) == -1) { 455 exec_path = "http://" + exec_path; 456 } 457 // If the user has given us an address, but it ends with a '/' we assume we're using the greenstone library.cgi 458 if(exec_path.startsWith("http://") && exec_path.endsWith("/")) { 459 exec_path = exec_path + "library"; 460 } 461 } 462 else if(args[i].equals("-perl")) { 463 perl_path = decode(args[i+1]); 464 // Test whether this points to the Perl bin directory or the Perl executable itself. 465 File perl_file = new File(perl_path); 466 if(perl_file.isDirectory()) { 467 // If this is windows we create a child file perl.exe, otherwise we create perl 468 if(Utility.isWindows()) { 469 perl_file = new File(perl_file, Utility.PERL_EXECUTABLE_WINDOWS); 470 } 471 else { 472 perl_file = new File(perl_file, Utility.PERL_EXECUTABLE_UNIX); 473 } 474 // And store this new path. 475 perl_path = perl_file.getAbsolutePath(); 476 perl_file = null; 477 } 478 // Otherwise its fine as it is 479 ///ystem.err.println("Perl executable is: " + perl_path); 480 } 481 else if(args[i].equals("--help") || args[i].equals("-help") || args[i].equals("?") || args[i].equals("/?") || args[i].equals("/help")) { 482 printUsage(dictionary); 483 System.exit(0); 484 } 485 else if(args[i].equals("--debug") || args[i].equals("-debug")) { 486 debug = true; 487 } 488 // Don't load any previous collection. Convenient for me 489 else if(args[i].equals("-no_load")) { 490 no_load = true; 491 } 492 // Check if they want it skinned. 493 else if(args[i].equals("-skinlf")) { 494 // SkinLF 495 try { 496 SkinLookAndFeel.setSkin(SkinLookAndFeel.loadThemePackDefinition(SkinUtils.toURL(new File("lib/greenaqua/greenaqua.xml")))); 497 SkinLookAndFeel.enable(); 498 } 499 catch (Exception error) { 500 ///ystem.err.println("Error: " + error); 501 error.printStackTrace(); 502 } 503 } 504 } 447 int argument_index = 0; 448 String next_token = null; 449 while(argument_index < args.length) { 450 // 1. We start by attempting to parse an argument name. An argument must start with a '-', and should not contain spaces. If anything else is encountered it is ignored. 451 String argument_name = null; 452 if(next_token == null) { 453 next_token = args[argument_index]; 454 argument_index++; 455 } 456 if(next_token.startsWith(StaticStrings.MINUS_CHARACTER)) { 457 // Trim second '-' just to be kind to Unixy-type people 458 if(next_token.startsWith(StaticStrings.MINUS_CHARACTER + StaticStrings.MINUS_CHARACTER)) { 459 argument_name = next_token.substring(1); 460 } 461 else { 462 argument_name = next_token; 463 } 464 } 465 next_token = null; 466 // 2. If we now have an argument name we continue by attempting to parse a value. A value is taken to be the sequence of space seperated Strings between the last argument name and up to but not including the next argument name. Of course an argument needn't have any value (ie -debug, -help), in which case value will be null. 467 if(argument_name != null) { 468 String argument_value = null; 469 StringBuffer argument_value_buffer = new StringBuffer(""); 470 while(argument_index < args.length && next_token == null) { 471 next_token = args[argument_index]; 472 argument_index++; 473 // If we just parsed an arbitary String then append it to value, followed by a single space 474 if(!next_token.startsWith(StaticStrings.MINUS_CHARACTER)) { 475 argument_value_buffer.append(next_token); 476 argument_value_buffer.append(StaticStrings.SPACE_CHARACTER); 477 next_token = null; 478 } 479 // If the argument token retrieved is an argument name, then leave it in next_token, which will cause the argument parsing process to move onto the next step. 480 } 481 // If a value now exists in argument buffer, retrieve it. Remove the last character as it will be an erroneous space. 482 if(argument_value_buffer.length() > 0) { 483 argument_value = argument_value_buffer.substring(0, argument_value_buffer.length() - 1); 484 } 485 486 // 3. We now have the argument name, and any associated value. We are ready to store the data in the appropriate variables. 487 Gatherer.println("Parsed Argument: name=" + argument_name + (argument_value != null ? (", value=" + argument_value) : ", no value")); 488 // 3a. First those arguments that have no associated value 489 if(argument_value == null) { 490 if(argument_name.equals(StaticStrings.HELP_ARGUMENT)) { 491 printUsage(dictionary); 492 System.exit(0); 493 } 494 // Run GLI in debug mode. Produces debug log plus extra messages. 495 else if(argument_name.equals(StaticStrings.DEBUG_ARGUMENT)) { 496 debug = true; 497 } 498 // Forces no loading on previous collection. 499 else if(argument_name.equals(StaticStrings.NO_LOAD_ARGUMENT)) { 500 no_load = true; 501 filename = null; 502 } 503 // Specify the use of Greenstone LAF. 504 else if(argument_name.equals(StaticStrings.SKIN_ARGUMENT)) { 505 // SkinLF 506 try { 507 SkinLookAndFeel.setSkin(SkinLookAndFeel.loadThemePackDefinition(SkinUtils.toURL(new File(SKIN_DEFINITION_FILE)))); 508 SkinLookAndFeel.enable(); 509 } 510 catch (Exception error) { 511 ///ystem.err.println("Error: " + error); 512 error.printStackTrace(); 513 } 514 } 515 } 516 // 3b. Now for those that do 517 else { 518 // Parse the path to the GSDL. Required argument. 519 if(argument_name.equals(StaticStrings.GSDL_ARGUMENT)) { 520 if(argument_value.endsWith(File.separator)) { 521 gsdl_path = argument_value; 522 } 523 else { 524 gsdl_path = argument_value + File.separator; 525 } 526 } 527 // Specify a collection to load initially. Could be used for file associations. 528 else if(argument_name.equals(StaticStrings.LOAD_ARGUMENT)) { 529 filename = argument_value; 530 no_load = false; 531 } 532 // Parse the url to a running web server, or a file path to the local library server. 533 else if(argument_name.equals(StaticStrings.LIBRARY_ARGUMENT)) { 534 exec_path = argument_value; 535 // If there is no colon in first five characters of the exec_path (which would either be an existing protocol, or a windows file path to say a local library), we can append the protocol http://. 536 if(argument_value.lastIndexOf(StaticStrings.COLON_CHARACTER, 5) == -1) { 537 exec_path = StaticStrings.HTTP_PROTOCOL_STR + argument_value; 538 } 539 else { 540 exec_path = argument_value; 541 } 542 // If the user has given us an address, but it ends with a '/' we assume we're using the greenstone library.cgi 543 if(exec_path.startsWith(StaticStrings.HTTP_PROTOCOL_STR) && exec_path.endsWith(StaticStrings.URL_SEPARATOR_CHARACTER)) { 544 exec_path = exec_path + StaticStrings.LIBRARY_STR; 545 } 546 } 547 // Parse the path to PERL. If not provided its assumes perl should be availble on the PATH. 548 else if(argument_name.equals(StaticStrings.PERL_ARGUMENT)) { 549 perl_path = argument_value; 550 // Test whether this points to the Perl bin directory or the Perl executable itself. 551 File perl_file = new File(perl_path); 552 if(perl_file.isDirectory()) { 553 // If this is windows we create a child file perl.exe, otherwise we create perl 554 if(Utility.isWindows()) { 555 perl_file = new File(perl_file, Utility.PERL_EXECUTABLE_WINDOWS); 556 } 557 else { 558 perl_file = new File(perl_file, Utility.PERL_EXECUTABLE_UNIX); 559 } 560 // And store this new path. 561 perl_path = perl_file.getAbsolutePath(); 562 perl_file = null; 563 } 564 // Otherwise its fine as it is 565 } 566 } 567 } 568 // Argument name was null, nothing to be done. 569 } 570 next_token = null; 571 // Arguments all parsed. 505 572 506 573 // Splash screen. … … 509 576 // We take appropriate action when an empty gsdl_path is detected. 510 577 if(gsdl_path == null) { 511 578 // Check for the presence of the path.cfg file. 512 579 File path_file = new File("path.cfg"); 513 580 if(path_file.exists()) { … … 664 731 665 732 private void startServerEXE() { 666 if(config.exec_file != null && config.exec_address == null && Utility.isWindows()) { 667 // First of all we create a GSDLSiteCFG object and check if a URL is already present, in which case the server is already running. 668 gsdlsite_cfg = new GSDLSiteConfig(config.exec_file); 669 String url = gsdlsite_cfg.getURL(); 670 // If its already running then set exec address. 671 if(url != null) { 672 try { 673 config.exec_address = new URL(url); 674 } 675 catch(Exception error) { 676 } 677 } 678 // Otherwise its time to run the server in a spawned process. 679 if(config.exec_address == null && config.exec_file.exists()) { 680 // Configure for immediate entry. Note that this only works if the gsdlsite.cfg file exists. 681 gsdlsite_cfg.set(); 682 // Spawn server 683 String[] command = new String[2]; 684 command[0] = config.exec_file.getAbsolutePath(); 685 command[1] = gsdlsite_cfg.getSiteConfigFilename(); 686 server = new ExternalApplication(command); 687 server.start(); 688 command = null; 689 // Now we have to wait until program has started. We do this by reloading and checking 690 try { 691 gsdlsite_cfg.load(); 692 while((url = gsdlsite_cfg.getURL()) == null) { 693 synchronized(this) { 694 wait(1000); 733 if(config.exec_file != null && config.exec_address == null && Utility.isWindows()) { 734 // First of all we create a GSDLSiteCFG object and check if a URL is already present, in which case the server is already running. 735 gsdlsite_cfg = new GSDLSiteConfig(config.exec_file); 736 String url = gsdlsite_cfg.getURL(); 737 // If its already running then set exec address. 738 if(url != null) { 739 try { 740 config.exec_address = new URL(url); 741 } 742 catch(Exception error) { 743 } 744 } 745 // Otherwise its time to run the server in a spawned process. 746 if(config.exec_address == null && config.exec_file.exists()) { 747 // Configure for immediate entry. Note that this only works if the gsdlsite.cfg file exists. 748 gsdlsite_cfg.set(); 749 // Spawn server 750 String[] command = new String[2]; 751 command[0] = config.exec_file.getAbsolutePath(); 752 command[1] = gsdlsite_cfg.getSiteConfigFilename(); 753 server = new ExternalApplication(command); 754 server.start(); 755 command = null; 756 // Now we have to wait until program has started. We do this by reloading and checking 757 ///ystem.err.print("Waiting until the local library has loaded"); 758 try { 759 gsdlsite_cfg.load(); 760 761 int try_again = JOptionPane.YES_OPTION; 762 int attempt_count = 0; 763 while(gsdlsite_cfg.getURL() == null && try_again == JOptionPane.YES_OPTION) { 764 ///ystem.err.print("."); 765 if(attempt_count == 60) { 766 try_again = JOptionPane.showConfirmDialog(Gatherer.g_man, dictionary.get("Server.QuitTimeOut"), dictionary.get("General.Warning"), JOptionPane.YES_NO_OPTION); 767 } 768 else { 769 synchronized(this) { 770 wait(1000); // Wait one second (give or take) 771 } 772 gsdlsite_cfg.load(); 773 attempt_count++; 774 } 775 } 776 777 if(gsdlsite_cfg.getURL() != null) { 778 // Ta-da. Now the url should be available. 779 config.exec_address = new URL(url); 780 781 // A quick test involves opening a connection to get the home page for this collection. If this fails then we try changing the url to be localhost. 782 try { 783 Gatherer.println("Try connecting to server on config url."); 784 URLConnection connection = config.exec_address.openConnection(); 785 connection.getContent(); 786 } 787 catch(IOException bad_url_connection) { 788 try { 789 Gatherer.println("Try connecting to server on local host."); 790 config.exec_address = new URL(gsdlsite_cfg.getLocalHostURL ()); 791 URLConnection connection = config.exec_address.openConnection(); 792 connection.getContent(); 793 } 794 catch(IOException worse_url_connection) { 795 Gatherer.println("Can't connect to server on either address."); 796 config.exec_address = null; 797 config.exec_file = null; 798 } 799 } 800 } 801 // Unable to start local library. Show appropriate message. 802 else { 803 missingEXEC(dictionary); 804 } 805 } 806 catch (Exception error) { 807 error.printStackTrace(); 808 } 695 809 } 696 gsdlsite_cfg.load();697 }698 // Ta-da. Now the url should be available.699 config.exec_address = new URL(url);700 701 // A quick test involves opening a connection to get the home page for this collection. If this fails then we try changing the url to be localhost.702 try {703 Gatherer.println("Try connecting to server on config url.");704 URLConnection connection = config.exec_address.openConnection();705 connection.getContent();706 }707 catch(IOException bad_url_connection) {708 try {709 Gatherer.println("Try connecting to server on local host.");710 config.exec_address = new URL(gsdlsite_cfg.getLocalHostURL());711 URLConnection connection = config.exec_address.openConnection();712 connection.getContent();713 }714 catch(IOException worse_url_connection) {715 Gatherer.println("Can't connect to server on either address.");716 config.exec_address = null;717 config.exec_file = null;718 }719 }720 }721 catch (Exception error) {722 error.printStackTrace();723 }724 }725 810 // Can't do a damb thing. 726 }727 Gatherer.println("Having started server.exe, exec_address is: " + config.exec_address);811 } 812 Gatherer.println("Having started server.exe, exec_address is: " + config.exec_address); 728 813 } 729 814 … … 739 824 gsdlsite_cfg.load(); 740 825 int try_again = JOptionPane.YES_OPTION; 741 while(try_again == JOptionPane.YES_OPTION) {742 826 int attempt_count = 0; 743 while(gsdlsite_cfg.getURL() != null && attempt_count < 60) { 744 synchronized(this) { 745 wait(1000); // Wait one second (give or take) 746 } 747 gsdlsite_cfg.load(); 748 attempt_count++; 827 while(gsdlsite_cfg.getURL() != null && try_again == JOptionPane.YES_OPTION) { 828 if(attempt_count == 60) { 829 try_again = JOptionPane.showConfirmDialog(Gatherer.g_man, dictionary.get("Server.QuitTimeOut"), dictionary.get("General.Warning"), JOptionPane.YES_NO_OPTION); 830 } 831 else { 832 synchronized(this) { 833 wait(1000); // Wait one second (give or take) 834 } 835 gsdlsite_cfg.load(); 836 attempt_count++; 837 } 749 838 } 750 if(attempt_count == 60) { 751 try_again = JOptionPane.showConfirmDialog(Gatherer.g_man, dictionary.get("Server.QuitTimeOut"), dictionary.get("General.Warning"), JOptionPane.YES_NO_OPTION); 752 } 753 else { 754 try_again = JOptionPane.NO_OPTION; 755 } 756 } 757 if(gsdlsite_cfg.getURL() != null) { 758 JOptionPane.showMessageDialog(Gatherer.g_man, dictionary.get("Server.QuitManual"), dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE); 759 } 839 //if(gsdlsite_cfg.getURL() != null) { 840 //JOptionPane.showMessageDialog(Gatherer.g_man, dictionary.get("Server.QuitManual"), dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE); 841 //} 760 842 } 761 843 catch (Exception error) {
Note:
See TracChangeset
for help on using the changeset viewer.