Changeset 24232


Ignore:
Timestamp:
2011-07-05T16:05:32+12:00 (10 years ago)
Author:
sjm84
Message:

Starting gli will now run an "ant start" to start Tomcat

File:
1 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/gli/src/org/greenstone/gatherer/Gatherer.java

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