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

Last change on this file since 24505 was 24505, checked in by ak19, 13 years ago

Still part of the changes for introducing the --mode=gli flag that's passed to the GS2 server so that we can merge the two cfg files glisite and llssite. 1. Bugfix: need to trim the mode parameter read in the from the file, because some whitespace was left at the end of it. 2. Now the url property in the config file is also to be prefixed with the mode, so that GLI's LocalLibraryServer can work out whether GLI launched the GSI or whether it was launched independently (outside GLI).

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