source: main/trunk/gli/src/org/greenstone/gatherer/greenstone/LocalLibraryServer.java@ 22661

Last change on this file since 22661 was 22661, checked in by ak19, 14 years ago

Next set of changes for ticket 152: moveable collectdir (so that collect dir can be on a pen drive). These are changes for when GLI's LocalLibraryServer tells server.jar to reconfigure itself (to update the COLLECTHOME alias in the apache web server's httpd.conf file when the collectdir has changed) and restart the server.

  • Property svn:keywords set to Author Date Id Revision
File size: 32.3 KB
Line 
1/**
2 *############################################################################
3 * A component of the Greenstone Librarian Interface, part of the Greenstone
4 * digital library suite from the New Zealand Digital Library Project at the
5 * University of Waikato, New Zealand.
6 *
7 * Author: Michael Dewsnip, NZDL Project, University of Waikato, NZ
8 *
9 * Copyright (C) 2004 New Zealand Digital Library Project
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *############################################################################
25 */
26
27package org.greenstone.gatherer.greenstone;
28
29
30import java.io.*;
31import java.lang.*;
32import java.net.*;
33import java.util.*;
34import javax.swing.*;
35import org.greenstone.gatherer.Configuration;
36import org.greenstone.gatherer.DebugStream;
37import org.greenstone.gatherer.Dictionary;
38import org.greenstone.gatherer.Gatherer;
39import org.greenstone.gatherer.util.PortFinder;
40import org.greenstone.gatherer.util.Utility;
41
42
43public class LocalLibraryServer
44{
45 static final private int WAITING_TIME = 20; // number of seconds to wait for the server to start and stop
46
47 static final private String ADD_COMMAND = "?a=config&cmd=add-collection&c=";
48 static final private String RELEASE_COMMAND = "?a=config&cmd=release-collection&c=";
49 static final private String QUIT_COMMAND = "?a=config&cmd=kill";
50
51 static private LLSSiteConfig llssite_cfg_file = null;
52 static private File local_library_server_file = null;
53
54 static private boolean running = false;
55 static private String ID = "greenstone-server"; // a sort of process ID
56
57 // Need to use sockets to tell the server program to terminate when on Linux
58 // The socket port number that we will use to communicate the termination
59 static private int port;
60 static private Socket clientSocket = null;
61 static private Writer clientSocketWriter = null;
62
63 // The server is persistent if it does not have to reload all the values
64 // over and over again each time. Tomcat is persistent and fastcgi is too,
65 // but the Apache webserver is not persistent by default.
66 // Change the initialisation of this value depending on whether fastcgi is
67 // on. At the moment, this does not apply to the Apache local library server.
68 static private boolean isPersistentServer = false;
69
70 static public void addCollection(String collection_name)
71 {
72 if (isPersistentServer) {
73 config(ADD_COMMAND + collection_name);
74 }
75 }
76
77
78 // Used to send messages to the local library
79 static private void config(String command)
80 {
81 if (!isPersistentServer) {
82 return;
83 }
84 if (Configuration.library_url == null) {
85 System.err.println("Error: Trying to configure local library with null Configuration.library_url!");
86 return;
87 }
88
89 try {
90 URL url = new URL(Configuration.library_url.toString() + command);
91 HttpURLConnection library_connection = (HttpURLConnection) url.openConnection();
92
93 // It's very important that we read the output of the command
94 // This ensures that the command has actually finished
95 // (The response code is returned immediately)
96 InputStream library_is = library_connection.getInputStream();
97 BufferedReader library_in = new BufferedReader(new InputStreamReader(library_is, "UTF-8"));
98 String library_output_line = library_in.readLine();
99 while (library_output_line != null) {
100 DebugStream.println("Local library server output: " + library_output_line);
101 library_output_line = library_in.readLine();
102 }
103 library_in.close();
104
105 int response_code = library_connection.getResponseCode();
106 if (response_code >= HttpURLConnection.HTTP_OK && response_code < HttpURLConnection.HTTP_MULT_CHOICE) {
107 DebugStream.println("200 - Complete.");
108 }
109 else {
110 DebugStream.println("404 - Failed.");
111 }
112 }
113 catch (Exception exception) {
114 DebugStream.printStackTrace(exception);
115 }
116 }
117
118 // Used to send messages to the local library server wrapper to the Apache web server (server.jar)
119 static private boolean sendMessageToServer(String message) {
120 if(isPersistentServer) {
121 return false;
122 }
123
124 if(port == -1) {
125 return false;
126 }
127
128 try {
129 if(clientSocket == null) {
130 clientSocket = new Socket("localhost", port);
131 }
132 if(clientSocketWriter == null) {
133 clientSocketWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
134 }
135 clientSocketWriter.write(message);
136 clientSocketWriter.flush();
137
138 } catch (Exception e) {
139 System.err.println("An exception occurred when trying to send the message: " + message
140 + "\nto the LocalLibraryServer.\n" + e);
141 return false;
142 }
143 return true;
144 }
145
146 static public boolean isRunning()
147 {
148 if (!running) return false; // if the url is pending, then running would also be false (server not started up yet)
149
150 llssite_cfg_file.load(true);
151 String url = llssite_cfg_file.getURL();
152 if (url == null) return false;
153
154 // Called by Gatherer to check whether we need to stop the server.
155 // if the url is pending, then the GSI hasn't started the server up yet
156 // Already covered in !running
157 //if (url.equals(LLSSiteConfig.URL_PENDING)) return false;
158
159 return true;
160 }
161
162
163 static public void releaseCollection(String collection_name)
164 {
165 if (isPersistentServer) {
166 config(RELEASE_COMMAND + collection_name);
167 }
168 }
169
170 static public boolean start(String gsdl_path, String local_library_server_file_path)
171 {
172 // Check the local library server file (server.exe or gs2-server.sh) exists
173 if(local_library_server_file_path == null) {
174 return false;
175 }
176 local_library_server_file = new File(local_library_server_file_path);
177 if (local_library_server_file.exists()) {
178 if(local_library_server_file.getName().equals("server.exe")) {
179 isPersistentServer = true;
180 } // else it may be gs2-web-server.bat
181 }
182 else { // local_library_server_file does not exist
183 DebugStream.println("No local library at given file path.");
184
185 if(Utility.isWindows()) { // test for server.exe and gs2-web-server.bat
186 local_library_server_file = new File(gsdl_path + "server.exe");
187 if (local_library_server_file.exists()) {
188 isPersistentServer = true;
189 } else {
190 local_library_server_file = new File(gsdl_path + "gs2-web-server.bat");
191 if (!local_library_server_file.exists()) {
192 DebugStream.println("No local library at all.");
193 return false;
194 }
195 }
196 } else { // linux
197 local_library_server_file = new File(gsdl_path + "gs2-server.sh");
198 if (!local_library_server_file.exists()) {
199 DebugStream.println("No local library at all.");
200 return false;
201 }
202 }
203 }
204
205 if(!isPersistentServer) {
206 // In the case of the Local Library Server on Linux or on Win where there's no server.exe, do an extra test:
207 // If GS2 was not configured with --enable-apache-httpd, then there is no apache webserver folder,
208 // even though the gs2-server.sh file would still be there. That means if the folder is absent
209 // we still have no local library server.
210
211 File localServerFolder = new File(gsdl_path, "apache-httpd");
212 if (!localServerFolder.exists() && !localServerFolder.isDirectory()) {
213 DebugStream.println("The web server does not exist at "
214 + localServerFolder.getAbsolutePath() + "\nNo local library at all. Trying web library");
215 return false;
216 } // else apache-httpd folder exists
217 }
218
219 llssite_cfg_file = new LLSSiteConfig(local_library_server_file);
220 if(!llssite_cfg_file.isConfigFileSet()) {
221 return false;
222 }
223
224 // from now on return true: we're in local_library_mode (even if the server is not running)
225
226
227 // If the user launched the GSI independent of GLI, but user has not pressed
228 // Enter Library yet, then we will obtain the previewURL later.
229 if(LocalLibraryServer.isURLPending()) {
230 // running is still false when the URL is pending because only GSI is running, not the server
231 return true;
232 } else if(llssite_cfg_file.isIndependentGSI()) {
233 // there is a url, it's not pending, and it is llssite.cfg: meaning GSI has started up
234 running = true;
235 return true;
236 }
237
238 // Spawn local library server process
239 final String QUOTES = Utility.isWindows() ? "\"" : ""; // need to embed path in quotes on Windows for spaces (interferes on Linux)
240 String local_library_server_command = QUOTES+local_library_server_file.getAbsolutePath()+QUOTES + getExtraLaunchArguments(llssite_cfg_file);
241 if(Utility.isWindows() && !isPersistentServer) { // launching gs2-web-server.bat (Windows) needs cmd start
242 local_library_server_command = "cmd.exe /c start \"GSI\" " + local_library_server_command;
243 }
244
245 // Check if the server is already running
246 String url = llssite_cfg_file.getURL();
247 if (url != null) {
248 // If it is already running then set the Greenstone web server address and we're done
249 // E.g. if previously GLI was not properly shut down, the URL property (signifying
250 // the server is still running) would still be in the glisite_cfg file.
251 try {
252 Configuration.library_url = new URL(url);
253 running = true;
254
255 // Run the server interface
256 Gatherer.spawnApplication(local_library_server_command, ID);
257 return true;
258 }
259 catch (MalformedURLException exception) {
260 DebugStream.printStackTrace(exception);
261 }
262 }
263
264 // Configure the server for immediate entry
265 //llssite_cfg_file.set();
266
267 // Spawn local library server process
268 Gatherer.spawnApplication(local_library_server_command, ID);
269
270 // Wait until program has started
271 try {
272 //System.err.println("**** testing server...");
273 testServerRunning(); // will set running = true when the server is up and running successfully
274 //System.err.println("**** Is server running: " + running);
275 } catch (IOException bad_url_connection) {
276 try {
277 // If this fails then we try changing the url to be localhost
278 Configuration.library_url = new URL(llssite_cfg_file.getLocalHostURL());
279 DebugStream.println("Try connecting to server on local host: '" + Configuration.library_url + "'");
280 URLConnection connection = Configuration.library_url.openConnection();
281 connection.getContent();
282 running = true;
283
284 } catch (IOException worse_url_connection) {
285 DebugStream.println("Can't connect to server on either address.");
286 Configuration.library_url = null;
287 running = false;
288 }
289 }
290
291 return true;
292 }
293
294 /** Call this when the collect directory has changed. Only works when using
295 * the web server launched by GLI. */
296 static public void reconfigure() {
297 if(isPersistentServer) {
298 System.err.println("***** Reconfigure is not yet implemented for server.exe");
299 return;
300 }
301
302 // can't control the GSI/server if it was launched independent of GLI
303 if(llssite_cfg_file.isIndependentGSI()) {
304 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("Server.Reconfigure"), Dictionary.get("General.Reconfigure"), JOptionPane.INFORMATION_MESSAGE);
305 return;
306 }
307
308 // someone may have closed the web server
309 if(checkServerRunning()) { // need a server to be running in order for us to send a reconfigure message to it
310 return; // it has reconfigured and restarted the server
311 }
312
313 // If it was already running, tell the server a reconfigure is required on next restart
314 // and then restart
315 if(running && sendMessageToServer("RECONFIGURE\n")) {
316 // restart
317 if(running) {
318 running = false;
319
320 if(sendMessageToServer("RESTART\n")) { //if(sendMessageToServer("RECONFIGURE\n")) {
321 // wait for the server to update the URL in the gli config file
322 llssite_cfg_file.setLastModified();
323
324 int attempt_count = 0;
325 while (!llssite_cfg_file.isModified()) {
326 new OneSecondWait(); // Wait one second (give or take)
327 attempt_count++;
328
329 // After waiting for the specified time, ask the user whether they want to wait for that long again
330 if (attempt_count == WAITING_TIME) {
331 break; // can't be waiting forever, we'll be waiting again below
332 }
333 }
334
335 try {
336 testServerRunning(); // will set running = true when the server is up and running successfully
337 } catch (IOException bad_url_connection) {
338 try {
339 // If this fails then we try changing the url to be localhost
340 Configuration.library_url = new URL(llssite_cfg_file.getLocalHostURL());
341 DebugStream.println("Try connecting to server on local host: '" + Configuration.library_url + "'");
342 URLConnection connection = Configuration.library_url.openConnection();
343 connection.getContent();
344 running = true;
345
346 } catch (IOException worse_url_connection) {
347 DebugStream.println("Can't connect to server on either address.");
348 Configuration.library_url = null;
349 running = false;
350 }
351 }
352 }
353 }
354 } else {
355 System.err.println("GLI was unable to send a reconfigure request to the local library server."
356 + "\nPlease reconfigure and restart the local Greenstone server manually.");
357 }
358 }
359
360
361 static public void stop()
362 {
363 if (!running) {
364 // also the case if the URL is pending in an independently launched GSI
365 return;
366 }
367
368 // don't (can't) shutdown the GSI/server if it was launched independent of GLI
369 if(llssite_cfg_file.isIndependentGSI()) {
370 return;
371 }
372
373 // Send the command for it to exit.
374 if (isPersistentServer) {
375 config(QUIT_COMMAND);
376 } else {
377 boolean success = sendMessageToServer("QUIT\n");
378 try {
379 if(clientSocketWriter != null) {
380 clientSocketWriter.close();
381 clientSocketWriter = null;
382 }
383 clientSocket = null;
384 } catch(Exception e) {
385 System.err.println("An exception occurred when trying to close the socket"
386 + "\nto the LocalLibraryServer.\n" + e);
387 }
388 if(success) {
389 Gatherer.terminateApplication(ID);
390 } else {
391 System.err.println("Unable to stop the server, since there's no communication port to send the quit msg over."
392 + "\nPlease stop the local Greenstone server manually.");
393 }
394 }
395
396 // Wait until program has stopped, by reloading and checking the URL field
397 llssite_cfg_file.load(false);
398 int attempt_count = 0;
399 String url = llssite_cfg_file.getURL();
400 while (url != null && !url.equals(LLSSiteConfig.URL_PENDING)) { // if pending, the server is already stopped (not running)
401 new OneSecondWait(); // Wait one second (give or take)
402 llssite_cfg_file.load(false);
403 attempt_count++;
404
405 // After waiting for the specified time, ask the user whether they want to wait for that long again
406 if (attempt_count == WAITING_TIME) {
407 int try_again = JOptionPane.showConfirmDialog(Gatherer.g_man, Dictionary.get("Server.QuitTimeOut", Integer.toString(WAITING_TIME)),
408 Dictionary.get("General.Warning"), JOptionPane.YES_NO_OPTION);
409 if (try_again == JOptionPane.NO_OPTION) {
410 return;
411 }
412 attempt_count = 0;
413 }
414 // read the url again to see if it's updated
415 url = llssite_cfg_file.getURL();
416 }
417
418 // Restore the llssite_cfg.
419 llssite_cfg_file.restore();
420
421 // If the local server is still running then our changed values will get overwritten.
422 url = llssite_cfg_file.getURL();
423 if (url != null && !url.equals(LLSSiteConfig.URL_PENDING)) {
424 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("Server.QuitManual"), Dictionary.get("General.Error"), JOptionPane.ERROR_MESSAGE);
425 }
426
427 running = false;
428 }
429
430 static private String getExtraLaunchArguments(LLSSiteConfig site_cfg_file) {
431 String args = " " + site_cfg_file.getSiteConfigFilename();
432
433 if(isPersistentServer) {
434 return args;
435 }
436
437 // Else, when running the Local Apache Library Server on Linux/Win, need to provide a port argument
438 try {
439 PortFinder portFinder = new PortFinder(50100, 100);
440 port = portFinder.findPortInRange(false); // silent mode
441 } catch(Exception e) {
442 System.err.println("Exception when trying to find an available port: " + e);
443 port = -1;
444 }
445
446 return args + " --quitport=" + port;
447 }
448
449
450 // This method first tests whether there is a URL in the llssite_cfg_file
451 // and after that appears, it tests whether the URL is functional.
452 static private void testServerRunning() throws IOException {
453 // Wait until program has started, by reloading and checking the URL field
454 llssite_cfg_file.load(false);
455 int attempt_count = 0;
456 while (llssite_cfg_file.getURL() == null) {
457 new OneSecondWait(); // Wait one second (give or take)
458 //System.err.println("**** One Second Wait");
459 llssite_cfg_file.load(false);
460 attempt_count++;
461
462 // After waiting for the specified time, ask the user whether they want to wait for that long again
463 if (attempt_count == WAITING_TIME) {
464 int try_again = JOptionPane.showConfirmDialog(Gatherer.g_man, Dictionary.get("Server.StartUpTimeOut", Integer.toString(WAITING_TIME)),
465 Dictionary.get("General.Warning"), JOptionPane.YES_NO_OPTION);
466 if (try_again == JOptionPane.NO_OPTION) {
467 return;
468 }
469 attempt_count = 0;
470 }
471 }
472
473 // Ta-da. Now the url should be available
474 try {
475 Configuration.library_url = new URL(llssite_cfg_file.getURL());
476 }
477 catch (MalformedURLException exception) {
478 DebugStream.printStackTrace(exception);
479 }
480
481 // A quick test involves opening a connection to get the home page for this collection
482 try {
483 DebugStream.println("Try connecting to server on config url: '" + Configuration.library_url + "'");
484 URLConnection connection = Configuration.library_url.openConnection();
485 connection.getContent();
486 running = true;
487 }
488 catch (IOException bad_url_connection) {
489 throw bad_url_connection;
490 }
491
492
493 }
494
495 /** Returns true if we're waiting on the user to click on Enter Library button
496 * in an independently launched GSI (one not launched by GLI). */
497 static public boolean isURLPending() {
498 //if(Configuration.library_url != null) {
499 //System.err.println("**** Configuration.library_url: " + Configuration.library_url );
500 //return false; // don't need to do anything as we already have the url
501 //}
502
503 llssite_cfg_file.load(true); // don't force reload, load only if modified
504
505 String url = llssite_cfg_file.getURL();
506
507 if(url != null) {
508 if(url.equals(LLSSiteConfig.URL_PENDING)) {
509 running = false; // imagine if they restarted an external GSI
510 return true;
511 } else {
512 // a valid URL at last
513 try {
514 Configuration.library_url = new URL(url);
515 running = true;
516 }
517 catch (MalformedURLException exception) {
518 running = false;
519 exception.printStackTrace();
520 DebugStream.printStackTrace(exception);
521 }
522 return false;
523 }
524 }
525
526 // If either the URL is null--which means no independent GSI (Greenstone server interface
527 // app) was launched--or if the 'URL' doesn't say it's pending, then we're not waiting
528 return false;
529 }
530
531 /** @returns true if it had to restart the server. Returns false if it didn't restart it. */
532 static public boolean checkServerRunning() {
533 boolean serverRestarted = false;
534
535 if (!running) return false; // don't worry about it if it's not supposed to be running
536 llssite_cfg_file.load(true); // don't force reload, load only if modified
537
538 String url = llssite_cfg_file.getURL();
539 if(url != null) {
540 if(url.equals(LLSSiteConfig.URL_PENDING)) {
541 running = false;
542 return false;
543 }
544
545 // else, valid URL:
546 try {
547 Configuration.library_url = new URL(url);
548 running = true;
549 }
550 catch (MalformedURLException exception) {
551 running = false;
552 DebugStream.printStackTrace(exception);
553 exception.printStackTrace();
554 }
555 }
556 else { // NO URL in current ConfigFile, check the other configfile for a URL
557 // to see if the server was restarted using that file.
558 // Otherwise need to restart the server again with GLIsite.cfg
559 llssite_cfg_file.save(); // save the configfile, because we may be reloading another
560
561 if(llssite_cfg_file.usingLLS_configFile()) { // if a GSI is already using llssite_cfg, this would have loaded it in
562 url = llssite_cfg_file.getURL(); //if(isURLPending()) {
563 if(url.equals(LLSSiteConfig.URL_PENDING)) {
564 running = false;
565 } else {
566 running = true;
567 }
568 return false; // don't need to launch the server, one has been independently launched
569 } else {
570 // else we try using the glisite configfile
571 llssite_cfg_file.useGLISiteCfg(local_library_server_file);
572 //llssite_cfg_file.set();
573
574 // since we're going to restart the server, make sure to reset all
575 // the client socket and its writer (for communicating with the web server)
576 // will only be reinstantiated if they are first nulled
577 if(clientSocket != null) {
578 clientSocket = null;
579 }
580 if(clientSocketWriter != null) {
581 try{
582 clientSocketWriter.close();
583 clientSocketWriter = null;
584 } catch(Exception e) {
585 System.err.println("Unable to close the client socket outputstream.");
586 } finally {
587 clientSocketWriter = null;
588 }
589 }
590
591 // Spawn local library server process
592 running = false;
593 final String QUOTES = Utility.isWindows() ? "\"" : ""; // need to embed path in quotes on Windows for spaces (interferes on Linux)
594 String local_library_server_command = QUOTES+local_library_server_file.getAbsolutePath()+QUOTES + getExtraLaunchArguments(llssite_cfg_file);
595 if(Utility.isWindows() && !isPersistentServer) { // launching gs2-web-server.bat (Windows) needs cmd start
596 local_library_server_command = "cmd.exe /c start \"GSI\" " + local_library_server_command;
597 }
598 Gatherer.spawnApplication(local_library_server_command, ID);
599 try {
600 testServerRunning(); // don't return until the webserver is up and running
601 serverRestarted = true;
602 } catch (IOException bad_url_connection) {
603 DebugStream.println("Can't connect to server on address " + Configuration.library_url);
604 running = false;
605 }
606 }
607 }
608 return serverRestarted;
609 }
610
611 static private class OneSecondWait
612 {
613 public OneSecondWait()
614 {
615 synchronized(this) {
616 try {
617 wait(1000);
618 }
619 catch (InterruptedException exception) {
620 }
621 }
622 }
623 }
624
625
626 static public class LLSSiteConfig
627 extends LinkedHashMap
628 {
629 private File configFile;
630
631 private File llssite_cfg;
632 private File glisite_cfg;
633 private String autoenter_initial;
634 private String start_browser_initial;
635
636 private long lastModified = 0;
637
638 static final private String AUTOENTER = "autoenter";
639 static final private String COLON = ":";
640 static final private String ENTERLIB = "enterlib";
641 static final private String FALSE = "0";
642 static final private String GLISITE_CFG = "glisite.cfg";
643 static final private String GSDL = "greenstone"; // httpprefix is no longer /gsdl but /greenstone
644 static final private String LLSSITE_CFG = "llssite.cfg";
645 static final private String LOCAL_HOST = "http://localhost";
646 static final private String PORTNUMBER = "portnumber";
647 static final private String SEPARATOR = "/";
648 static final private String SPECIFIC_CONFIG = "--config=";
649 static final private String STARTBROWSER = "start_browser";
650 static final private String TRUE = "1";
651 static final private String URL = "url";
652
653 static final public String URL_PENDING = "URL_pending";
654
655
656 public LLSSiteConfig(File server_exe) {
657 debug("New LLSSiteConfig for: " + server_exe.getAbsolutePath());
658
659 llssite_cfg = new File(server_exe.getParentFile(), LLSSITE_CFG);
660 glisite_cfg = new File(server_exe.getParentFile(), GLISITE_CFG);
661
662 configFile = null;
663
664 autoenter_initial = null;
665 start_browser_initial = null;
666
667 // first test if server was started independently of GLI
668 // if so, the config file we'd be using would be llssite.cfg
669 if(!usingLLS_configFile()) { // if we were using llssite_cfg, this would have loaded it in
670 // else we try using the glisite configfile
671 useGLISiteCfg(server_exe);
672 }
673 }
674
675 /** Tries to get a glisite.cfg file and then loads it, setting it as the configFile */
676 public void useGLISiteCfg(File server_exe)
677 {
678 if(!glisite_cfg.exists()) { // create it from the templates or the llssite.cfg file
679
680 File llssite_cfg_in = new File(server_exe.getParentFile(), LLSSITE_CFG+".in");
681 File glisite_cfg_in = new File(server_exe.getParentFile(), GLISITE_CFG+".in");
682
683 // need to generate glisite_cfg from glisite_cfg_in, llssite_cfg or llssite.cfg.in
684 if(glisite_cfg_in.exists()) {
685 copyConfigFile(glisite_cfg_in, glisite_cfg, false);
686 }
687 else if(llssite_cfg_in.exists()) {
688 copyConfigFile(llssite_cfg_in, glisite_cfg_in, true); // adjust for glisite.cfg
689 copyConfigFile(glisite_cfg_in, glisite_cfg, false);
690 }
691 else if(llssite_cfg.exists()) {
692 copyConfigFile(llssite_cfg, glisite_cfg, true); // adjust for glisite.cfg
693 }
694 else {
695 debug("Neither the file glisite.cfg nor llssite.cfg can be found!");
696 }
697 }
698 // use the config file now
699 if(glisite_cfg.exists()) {
700 configFile = glisite_cfg;
701 load(false); // force reload
702 lastModified = configFile.lastModified();
703 }
704 }
705
706 /** Tests whether the server interface is up, running independently of GLI
707 * If so, we don't need to launch the server interface.
708 * The server interface may not have started up the server itself though
709 * (in which case the server URL would be URL_PENDING).
710 * This method returns true if the server interface has already started
711 * and, if so, it would have loaded in the llssite_cfg configFile.
712 */
713 public boolean usingLLS_configFile() {
714 if(!llssite_cfg.exists()) {
715 return false;
716 }
717
718 // Now to check if the configfile contains the URL line
719 configFile = llssite_cfg;
720 load(false); // force load
721
722 if(getURL() == null) {
723 configFile = null;
724 clear(); // we're not using llssite_cfg, so clear the values we just read
725 return false;
726 }
727
728 lastModified = configFile.lastModified();
729 return true;
730 }
731
732 /** To test we've actually instantiated this object meaningfully. If so, then configFile is set */
733 public boolean isConfigFileSet() {
734 return (configFile != null && configFile.exists());
735 }
736
737 /** @return true if GSI was started up independently and outside of GLI.
738 * In such a case, GLI would be using llssite_cfg. */
739 public boolean isIndependentGSI() {
740 return (configFile == llssite_cfg);
741 }
742
743 public boolean exists() {
744 return configFile.exists();
745 }
746
747 public String getLocalHostURL() {
748 StringBuffer url = new StringBuffer(LOCAL_HOST);
749 url.append(COLON);
750 url.append((String)get(PORTNUMBER));
751 String enterlib = (String)get(ENTERLIB);
752 if(!isPersistentServer || enterlib == null || enterlib.length() == 0) {
753 // Use the default /gsdl and hope for the best.
754 url.append(SEPARATOR);
755 url.append(GSDL);
756 }
757 else {
758 if(!enterlib.startsWith(SEPARATOR)) {
759 url.append(SEPARATOR);
760 }
761 url.append(enterlib);
762 }
763 enterlib = null;
764 debug("Found Local Library Address: " + url.toString());
765 return url.toString();
766 }
767
768 /** @return the cmd-line parameter for the configfile used to launch
769 * the server through GLI: --config <glisite.cfg/llssite.cfg file path>. */
770 public String getSiteConfigFilename() {
771 return SPECIFIC_CONFIG + configFile.getAbsolutePath();
772 }
773
774 public String getURL() {
775 // URL is made from url and portnumber
776 String url = (String) get(URL);
777
778 // server interface is already up, independent of GLI
779 // but it has not started the server (hence URL is pending)
780 if(url != null && url.equals(URL_PENDING)) {
781 return url;
782 }
783
784 if(!isPersistentServer) {
785 return url;
786 }
787
788 if(url != null) {
789 StringBuffer temp = new StringBuffer(url);
790 temp.append(COLON);
791 temp.append((String)get(PORTNUMBER));
792 String enterlib = (String)get(ENTERLIB);
793 if(enterlib == null || enterlib.length() == 0) {
794 // Use the default /greenstone prefix and hope for the best.
795 temp.append(SEPARATOR);
796 temp.append(GSDL);
797 }
798 else {
799 if(!enterlib.startsWith(SEPARATOR)) {
800 temp.append(SEPARATOR);
801 }
802 temp.append(enterlib);
803 }
804 enterlib = null;
805 url = temp.toString();
806 }
807 debug("Found Local Library Address: " + url);
808 return url;
809 }
810
811 public void setLastModified() {
812 if(isModified()) {
813 lastModified = configFile.lastModified();
814 }
815 }
816
817 public boolean isModified() {
818 return (lastModified != configFile.lastModified());
819 }
820
821 public void load(boolean reloadOnlyIfModified) {
822
823 if(configFile == null) {
824 debug(configFile.getAbsolutePath() + " cannot be found!");
825 }
826
827 if(isModified()) {
828 lastModified = configFile.lastModified();
829 } else if(reloadOnlyIfModified) {
830 return; // asked to reload only if modified. Don't reload since not modified
831 }
832
833 if(configFile.exists()) {
834 debug("Load: " + configFile.getAbsolutePath());
835 clear();
836 try {
837 BufferedReader in = new BufferedReader(new FileReader(configFile));
838 String line = null;
839 while((line = in.readLine()) != null) {
840 String key = null;
841 String value = null;
842 int index = -1;
843 if((index = line.indexOf("=")) != -1 && line.length() >= index + 1) {
844 key = line.substring(0, index);
845 value = line.substring(index + 1);
846 }
847 else {
848 key = line;
849 }
850 put(key, value);
851 }
852 in.close();
853 }
854 catch (Exception error) {
855 error.printStackTrace();
856 }
857 }
858 else {
859 debug(configFile.getAbsolutePath() + " cannot be found!");
860 }
861 }
862
863 /** Restore the autoenter value to its initial value, and remove url if present. */
864 public void restore() {
865 if(configFile != null) {
866 // Delete the file
867 configFile.delete();
868 }
869 else {
870 debug("Restore Initial Settings");
871 put(AUTOENTER, autoenter_initial);
872 put(STARTBROWSER, start_browser_initial);
873 remove(URL);
874 save();
875 }
876 }
877
878 public void set() {
879 debug("Set Session Settings");
880 if(autoenter_initial == null) {
881 autoenter_initial = (String) get(AUTOENTER);
882 debug("Remember autoenter was: " + autoenter_initial);
883 }
884 put(AUTOENTER, TRUE);
885 if(start_browser_initial == null) {
886 start_browser_initial = (String) get(STARTBROWSER);
887 debug("Remember start_browser was: " + start_browser_initial);
888 }
889 put(STARTBROWSER, FALSE);
890 save();
891 }
892
893 private void debug(String message) {
894 ///ystem.err.println(message);
895 }
896
897 private void save() {
898 //debug("Save: " + llssite_cfg.getAbsolutePath());
899 debug("Save: " + configFile.getAbsolutePath());
900 try {
901 //BufferedWriter out = new BufferedWriter(new FileWriter(llssite_cfg, false));
902 BufferedWriter out = new BufferedWriter(new FileWriter(configFile, false));
903 for(Iterator keys = keySet().iterator(); keys.hasNext(); ) {
904 String key = (String) keys.next();
905 String value = (String) get(key);
906 out.write(key, 0, key.length());
907 if(value != null) {
908 out.write('=');
909
910 // if the server is using llssite.cfg, don't overwrite its default
911 // autoenter and startbrowser values
912 if(configFile == llssite_cfg && (key == AUTOENTER || key == STARTBROWSER)) {
913 if(key == AUTOENTER) {
914 out.write(autoenter_initial, 0, autoenter_initial.length());
915 } else { // STARTBROWSER
916 out.write(start_browser_initial, 0, start_browser_initial.length());
917 }
918 } else {
919 out.write(value, 0, value.length());
920 }
921 }
922 out.newLine();
923 }
924 out.flush();
925 out.close();
926 }
927 catch (Exception error) {
928 error.printStackTrace();
929 }
930 }
931
932 private static void copyConfigFile(File source_cfg, File dest_cfg, boolean setToGliSiteDefaults) {
933 // source_cfg file should exist
934 // dest_cfg file should not yet exist
935 // If setToGliSiteDefaults is true, then GLIsite.cfg's default configuration
936 // is applied to concerned lines: autoenter=1, and startbrowser=0
937
938 try {
939 BufferedReader in = new BufferedReader(new FileReader(source_cfg));
940 BufferedWriter out = new BufferedWriter(new FileWriter(dest_cfg, false));
941
942 String line = null;
943 while((line = in.readLine()) != null) {
944
945 if(setToGliSiteDefaults) {
946 if(line.startsWith(AUTOENTER)) {
947 line = AUTOENTER+"=1";
948 }
949 else if(line.startsWith(STARTBROWSER)) {
950 line = STARTBROWSER+"=0";
951 }
952 }
953
954 // write out the line
955 out.write(line + "\n");
956 }
957
958 out.flush();
959 in.close();
960 out.close();
961 } catch(Exception e) {
962 System.err.println("Exception occurred when trying to copy the config file "
963 + source_cfg.getName() + " to " + dest_cfg.getName() + ": " + e);
964 e.printStackTrace();
965 }
966 }
967 }
968}
Note: See TracBrowser for help on using the repository browser.