source: main/trunk/gli/src/org/greenstone/gatherer/remote/RemoteGreenstoneServer.java@ 22691

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

Cleaner exit when the client tries to a remote greenstone server that is not running (first noticed when the greenstone version is requested).

  • Property svn:keywords set to Author Date Id Revision
File size: 33.1 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * Author: Michael Dewsnip, NZDL Project, University of Waikato
9 *
10 * Copyright (C) 2005 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 */
27
28package org.greenstone.gatherer.remote;
29
30import java.io.*;
31import java.net.*;
32import java.util.*;
33import java.util.zip.*;
34import javax.swing.*;
35import java.io.ByteArrayOutputStream;
36import org.greenstone.gatherer.Configuration;
37import org.greenstone.gatherer.DebugStream;
38import org.greenstone.gatherer.Dictionary;
39import org.greenstone.gatherer.FedoraInfo;
40import org.greenstone.gatherer.GAuthenticator;
41import org.greenstone.gatherer.Gatherer;
42import org.greenstone.gatherer.collection.CollectionManager;
43import org.greenstone.gatherer.shell.GShell;
44import org.greenstone.gatherer.util.UnzipTools;
45import org.greenstone.gatherer.util.Utility;
46import org.apache.commons.httpclient.HttpClient;
47import org.apache.commons.httpclient.methods.PostMethod;
48import org.apache.commons.httpclient.methods.GetMethod;
49import org.apache.commons.httpclient.HttpException;
50import org.apache.commons.httpclient.methods.multipart.FilePart;
51import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
52import org.apache.commons.httpclient.methods.multipart.Part;
53import org.apache.commons.httpclient.methods.multipart.*;
54import org.apache.commons.httpclient.params.*;
55import org.apache.commons.httpclient.HttpStatus;
56
57
58public class RemoteGreenstoneServer
59{
60 // A PasswordAuthentication object is created whenever it is required
61 static private PasswordAuthentication remote_greenstone_server_authentication = null;
62 // static private PasswordAuthentication remote_greenstone_server_authentication = new PasswordAuthentication(System.getProperty("user.name"), new char[] { });
63
64 // the language and region environment variables (in "lang_REGION" form)
65 // this is necessary in order for the client and server sides to zip and unzip
66 // using the same settings
67 public final String lang_region;
68
69 private ActionQueue remote_greenstone_server_action_queue;
70 private RemoteGreenstoneServer.ProgressBar progress_bar;
71
72 public RemoteGreenstoneServer() {
73 // Create the progress_bar first since ActionQueue uses it in its thread
74 // (the thread will start immediately).
75 progress_bar = new RemoteGreenstoneServer.ProgressBar();
76 remote_greenstone_server_action_queue = new ActionQueue();
77
78 String langReg = System.getenv("LANG");
79 lang_region = (langReg == null) ? "" : langReg;
80 }
81
82 // ----------------------------------------------------------------------------------------------------
83 // PUBLIC LAYER
84 // ----------------------------------------------------------------------------------------------------
85 public String deleteCollection(String collection_name)
86 {
87 return performAction(new RemoteGreenstoneServerAction.DeleteCollectionAction(collection_name));
88 }
89
90
91 public String deleteCollectionFile(String collection_name, File collection_file)
92 {
93 return performAction(new RemoteGreenstoneServerAction.DeleteCollectionFileAction(collection_name, collection_file));
94 }
95
96
97 public String downloadCollection(String collection_name)
98 {
99 return performAction(new RemoteGreenstoneServerAction.DownloadCollectionAction(collection_name));
100 }
101
102
103 public String downloadCollectionArchives(String collection_name)
104 {
105 return performAction(new RemoteGreenstoneServerAction.DownloadCollectionArchivesAction(collection_name));
106 }
107
108
109 public String downloadCollectionConfigurations()
110 {
111 return performAction(new RemoteGreenstoneServerAction.DownloadCollectionConfigurationsAction());
112 }
113
114
115 public String downloadCollectionFile(String collection_name, File collection_file)
116 {
117 return performAction(new RemoteGreenstoneServerAction.DownloadCollectionFileAction(collection_name, collection_file));
118 }
119
120 // get web.xml from the server -- for a remote gli of GS3
121 public String downloadWebXMLFile()
122 {
123 return performAction(new RemoteGreenstoneServerAction.DownloadWebXMLFileAction());
124 }
125
126 public String getScriptOptions(String script_name, String script_arguments)
127 {
128 return performAction(new RemoteGreenstoneServerAction.GetScriptOptionsAction(script_name, script_arguments));
129 }
130
131 //get all available site names from the server -- for a remote gli of GS3
132 public String getSiteNames()
133 {
134 return performAction(new RemoteGreenstoneServerAction.GetSiteNamesAction());
135 }
136
137 public String moveCollectionFile(String collection_name, File source_collection_file, File target_collection_file)
138 {
139 return performAction(new RemoteGreenstoneServerAction.MoveCollectionFileAction(
140 collection_name, source_collection_file, target_collection_file));
141 }
142
143
144 public String newCollectionDirectory(String collection_name, File new_collection_directory)
145 {
146 return performAction(new RemoteGreenstoneServerAction.NewCollectionDirectoryAction(
147 collection_name, new_collection_directory));
148 }
149
150
151 public String runScript(String collection_name, String script_name, String script_arguments, GShell shell)
152 {
153 return performAction(new RemoteGreenstoneServerAction.RunScriptAction(
154 collection_name, script_name, script_arguments, shell));
155 }
156
157
158 public String uploadCollectionFile(String collection_name, File collection_file)
159 {
160 return performAction(new RemoteGreenstoneServerAction.UploadCollectionFilesAction(
161 collection_name, new File[] { collection_file }));
162 }
163
164
165 public String uploadCollectionFiles(String collection_name, File[] collection_files)
166 {
167 return performAction(new RemoteGreenstoneServerAction.UploadCollectionFilesAction(collection_name, collection_files));
168 }
169
170
171 public String uploadFilesIntoCollection(String collection_name, File[] source_files, File target_collection_directory)
172 {
173 return performAction(new RemoteGreenstoneServerAction.UploadFilesIntoCollectionAction(
174 collection_name, source_files, target_collection_directory));
175 }
176
177 public boolean exists(String collection_name, File collection_file)
178 {
179 String result = performAction(new RemoteGreenstoneServerAction.ExistsAction(collection_name, collection_file));
180 if(result.indexOf("exists") != -1) {
181 return true;
182 }
183 else if(result.indexOf("does not exist") != -1) {
184 return false;
185 }
186 return false;
187 }
188
189 public int getGreenstoneVersion()
190 {
191 // returns message "Greenstone version is: <version number of the Greenstone remote server>"
192 String result = performAction(new RemoteGreenstoneServerAction.VersionAction());
193 int index = result.indexOf(":");
194 if(index != -1) {
195 result = result.substring(index+1).trim(); // skip the space after colon, must remove surrounding spaces
196 }
197 // if space is returned, then the request failed (the server may not have been running)
198 int greenstoneVersion = result.equals("") ? -1 : Integer.parseInt(result);
199 return greenstoneVersion;
200 }
201
202 /** For constructing the preview command (the library URL) with */
203 public String getLibraryURL(String serverHomeURL)
204 {
205 // returns message "Greenstone library URL suffix is: <e.g. /greenstone3/library or /gsdl/cgi-bin/library>"
206 String libSuffix = performAction(new RemoteGreenstoneServerAction.LibraryURLSuffixAction());
207 int index = libSuffix.indexOf(":");
208 if(index != -1) {
209 libSuffix = libSuffix.substring(index+1).trim(); // skip the space after colon and remove surrounding spaces
210 }
211
212 // serverHomeURL is of the form, http://domain/other/stuff. We want the prefix upto & including domain
213 // and prepend that to the libraryURLSuffix
214 index = -1;
215 for(int i = 0; i < 3; i++) {
216 index = serverHomeURL.indexOf("/", index+1);
217 if(index == -1) { // shouldn't happen, but if it does, we'll be in an infinite loop
218 break;
219 }
220 }
221 serverHomeURL = serverHomeURL.substring(0, index);
222 return serverHomeURL + libSuffix;
223 }
224
225 // ----------------------------------------------------------------------------------------------------
226
227
228 public void exit()
229 {
230 System.err.println("Exiting, number of jobs on queue: " + remote_greenstone_server_action_queue.size());
231
232 // If there are still jobs on the queue we must wait for the jobs to finish
233 while (remote_greenstone_server_action_queue.size() > 0) {
234 synchronized (remote_greenstone_server_action_queue) {
235 try {
236 DebugStream.println("Waiting for queue to become empty...");
237 remote_greenstone_server_action_queue.wait(500);
238 }
239 catch (InterruptedException exception) {}
240 }
241 }
242 }
243
244
245 // ----------------------------------------------------------------------------------------------------
246 // QUEUE LAYER
247 // ----------------------------------------------------------------------------------------------------
248
249
250 /** Returns null if we cannot wait for the action to finish, "" if the action failed, or the action output. */
251 private String performAction(RemoteGreenstoneServerAction remote_greenstone_server_action)
252 {
253 // Check for whether the queue thread stopped running because
254 // the user cancelled out. If so, exit GLI.
255 if(remote_greenstone_server_action_queue.hasExited()) {
256 remote_greenstone_server_action_queue.clear();
257 //remote_greenstone_server_action_queue = null;
258 Gatherer.exit();
259 return "";
260 }
261
262 // Add the action to the queue
263 remote_greenstone_server_action_queue.addAction(remote_greenstone_server_action);
264 String threadName = Thread.currentThread().getName();
265
266 // If we're running in the GUI thread we must return immediately
267 // We cannot wait for the action to complete because this will block any GUI updates
268 if (SwingUtilities.isEventDispatchThread()) {
269 System.err.println(threadName
270 + "\tACTION QUEUED: In event dispatch thread, returning immediately...\n\t"
271 + remote_greenstone_server_action);
272 return null;
273 }
274
275 // Otherwise wait until the action is processed
276 try {
277 synchronized (remote_greenstone_server_action) {
278 while(!remote_greenstone_server_action.processed) {
279 //System.err.println("Waiting for action to complete...: " + remote_greenstone_server_action);
280 DebugStream.println("Waiting for action to complete...");
281 remote_greenstone_server_action.wait(); // wait to be notified when the action has been processed
282 }
283 }
284 } catch (Exception e) {
285 System.err.println("RemoteGreenstoneServer.performAction() - exception: " + e);
286 e.printStackTrace();
287 }
288
289 // Return "" if the action failed
290 if (!remote_greenstone_server_action.processed_successfully) {
291 return "";
292 }
293 // Otherwise return the action output
294 return remote_greenstone_server_action.action_output;
295 }
296
297
298 // ----------------------------------------------------------------------------------------------------
299 // PROGRESS BAR
300 // ----------------------------------------------------------------------------------------------------
301
302 static class ProgressBar
303 extends JProgressBar
304 {
305 public ProgressBar()
306 {
307 setBackground(Configuration.getColor("coloring.collection_tree_background", false));
308 setForeground(Configuration.getColor("coloring.collection_tree_foreground", false));
309 setString(Dictionary.get("FileActions.No_Activity"));
310 setStringPainted(true);
311 }
312
313 /** synchronized to avoid conflicts since several threads access this */
314 synchronized public void setAction(String action)
315 {
316 if (action != null) {
317 DebugStream.println(action);
318 }
319
320 // We cannot call this from the GUI thread otherwise the progress bar won't start
321 if (SwingUtilities.isEventDispatchThread()) {
322 System.err.println("ERROR: RemoteGreenstoneServerProgressBar.setAction() called from event dispatch thread!");
323 return;
324 }
325
326 // Set the string on the progress bar, and start or stop it
327 if (action == null) {
328 setString(Dictionary.get("FileActions.No_Activity"));
329 setIndeterminate(false);
330 }
331 else {
332 setString(action);
333 setIndeterminate(true);
334 }
335 }
336 }
337
338 /** synchronized to avoid conflicts since several threads access this */
339 synchronized public RemoteGreenstoneServer.ProgressBar getProgressBar()
340 {
341 return progress_bar;
342 }
343
344
345 // ----------------------------------------------------------------------------------------------------
346 // AUTHENTICATION LAYER
347 // ----------------------------------------------------------------------------------------------------
348
349 static private class RemoteGreenstoneServerAuthenticateTask
350 extends Thread
351 {
352 public void run()
353 {
354 remote_greenstone_server_authentication = new RemoteGreenstoneServerAuthenticator().getAuthentication();
355 }
356
357
358 static private class RemoteGreenstoneServerAuthenticator
359 extends GAuthenticator
360 {
361 public PasswordAuthentication getAuthentication(String username, String password)
362 {
363 return getPasswordAuthentication(username,password);
364 }
365
366 public PasswordAuthentication getAuthentication()
367 {
368 return getPasswordAuthentication();
369 }
370
371 protected String getMessageString()
372 {
373 if (Gatherer.GS3){
374 return (Dictionary.get("RemoteGreenstoneServer.Authentication_Message_gs3") + " " + Configuration.site_name);
375 }
376 return Dictionary.get("RemoteGreenstoneServer.Authentication_Message");
377 }
378 }
379 }
380
381 public void set_remote_greenstone_server_authentication_to_null() {
382 remote_greenstone_server_authentication = null;
383 }
384
385 private void authenticateUser()
386 throws RemoteGreenstoneServerAction.ActionCancelledException
387 {
388 // If we don't have any authentication information then ask for it now
389 if (remote_greenstone_server_authentication == null) {
390 try {
391 // We have to do this on the GUI thread
392 SwingUtilities.invokeAndWait(new RemoteGreenstoneServerAuthenticateTask());
393 }
394 catch (Exception exception) {
395 System.err.println("Exception occurred when authenticating the user: " + exception);
396 DebugStream.printStackTrace(exception);
397 }
398
399 // If it is still null then the user has cancelled the authentication, so the action is cancelled
400 if (remote_greenstone_server_authentication == null) {
401 throw new RemoteGreenstoneServerAction.ActionCancelledException();
402 }
403 }
404 }
405
406
407 public String getUsername()
408 {
409 if (remote_greenstone_server_authentication != null) {
410 return remote_greenstone_server_authentication.getUserName();
411 }
412
413 return null;
414 }
415
416
417 // ----------------------------------------------------------------------------------------------------
418 // REQUEST LAYER
419 // ----------------------------------------------------------------------------------------------------
420
421
422 /** Returns the command output if the action completed, throws some kind of exception otherwise. */
423 String downloadFile(String gliserver_args, String file_path)
424 throws Exception
425 {
426 while (true) {
427 // Check that Configuration.gliserver_url is set
428 if (Configuration.gliserver_url == null) {
429 throw new Exception("Empty gliserver URL: please set this in Preferences before continuing.");
430 }
431
432 // Ask for authentication information (if necessary), then perform the action
433 authenticateUser();
434 String gliserver_url_string = Configuration.gliserver_url.toString();
435 String command_output = downloadFileInternal(gliserver_url_string, gliserver_args, file_path);
436
437 // Debugging - print any ok messages to stderr
438 //System.err.println("**** RECEIVED (sendCommandToServer()): " + command_output);
439
440 // Check the first line to see if authentication has failed; if so, go around the loop again
441 if (command_output.startsWith("ERROR: Authentication failed:")) {
442 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Error", command_output.substring("ERROR: ".length())), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.ERROR_MESSAGE);
443 remote_greenstone_server_authentication = null;
444 continue;
445 }
446 // Check if the collection is locked by someone else; if so, see if the user wants to steal the lock
447 else if (command_output.startsWith("ERROR: Collection is locked by: ")) {
448 if (JOptionPane.showConfirmDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Steal_Lock_Message", command_output.substring("ERROR: Collection is locked by: ".length())), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) {
449 // The user has decided to cancel the action
450 throw new RemoteGreenstoneServerAction.ActionCancelledException();
451 }
452
453 // The user has decided to steal the lock... rerun the command with "&steal_lock="
454 gliserver_args += "&steal_lock=";
455 continue;
456 }
457 // Handle other types of errors by throwing an exception
458 else if (command_output.startsWith("ERROR: ")) {
459 throw new Exception(command_output.substring("ERROR: ".length()));
460 }
461
462 // There were no exceptions thrown so the action must have succeeded
463 return command_output;
464 }
465 }
466
467 /** Returns true or false depending on whether authentication is required for the cmd
468 * string embedded in the given gliserver_args. No authentication is required for either
469 * of the commands greenstone-server-version and get-library-url-suffix. */
470 private boolean isAuthenticationRequired(String gliserver_args) {
471 return ((gliserver_args.indexOf("greenstone-server-version") == -1)
472 && (gliserver_args.indexOf("get-library-url-suffix") == -1));
473 }
474
475
476 /** Returns the command output if the action completed, throws some kind of exception otherwise.
477 * Package access, so that RemoteGreenstoneServerAction.java can call this.
478 */
479 String sendCommandToServer(String gliserver_args, GShell shell)
480 throws Exception
481 {
482 while (true) {
483
484 // Check that Configuration.gliserver_url is set
485 if (Configuration.gliserver_url == null) {
486 throw new Exception("Empty gliserver URL: please set this in Preferences before continuing.");
487 }
488
489 // Ask for authentication information (if necessary), then perform the action
490 if(isAuthenticationRequired(gliserver_args)) {
491 authenticateUser();
492 }
493 String gliserver_url_string = Configuration.gliserver_url.toString();
494 String command_output = sendCommandToServerInternal(gliserver_url_string, gliserver_args, shell);
495
496 // Debugging - print any ok messages to stderr
497 //if(!(command_output.trim().startsWith("<"))) {
498 //System.err.println("**** RECEIVED (sendCommandToServer()): " + command_output);
499 //}
500
501 // Check the first line to see if authentication has failed; if so, go around the loop again
502 if (command_output.startsWith("ERROR: Authentication failed:")) {
503 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Error", command_output.substring("ERROR: ".length())), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.ERROR_MESSAGE);
504 remote_greenstone_server_authentication = null;
505 continue;
506 }
507 // Check if the collection is locked by someone else; if so, see if the user wants to steal the lock
508 else if (command_output.startsWith("ERROR: Collection is locked by: ")) {
509 if (JOptionPane.showConfirmDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Steal_Lock_Message", command_output.substring("ERROR: Collection is locked by: ".length())), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) {
510 // The user has decided to cancel the action
511 throw new RemoteGreenstoneServerAction.ActionCancelledException();
512 }
513
514 // The user has decided to steal the lock... rerun the command with "&steal_lock="
515 gliserver_args += "&steal_lock=";
516 continue;
517 }
518 // Handle other types of errors by throwing an exception
519 else if (command_output.startsWith("ERROR: ")) {
520 throw new Exception(command_output.substring("ERROR: ".length()));
521 } else if (command_output.indexOf("ERROR: ") != -1) { // check if ERROR occurs anywhere else in the output
522 throw new Exception(command_output);
523 }
524
525
526 // There were no exceptions thrown so the action must have succeeded
527 return command_output;
528 }
529 }
530
531
532 /** Returns the command output if the action completed, throws some kind of exception otherwise. */
533 String uploadFile(String gliserver_args, String file_path)
534 throws Exception
535 {
536 while (true) {
537 // Check that Configuration.gliserver_url is set
538 if (Configuration.gliserver_url == null) {
539 throw new Exception("Empty gliserver URL: please set this in Preferences before continuing.");
540 }
541
542 // Ask for authentication information (if necessary), then perform the action
543 authenticateUser();
544 String gliserver_url_string = Configuration.gliserver_url.toString();
545 String command_output = uploadFileInternal(gliserver_url_string, gliserver_args, file_path);
546 // System.err.println("Command output: " + command_output);
547
548 // Check the first line to see if authentication has failed; if so, go around the loop again
549 if (command_output.startsWith("ERROR: Authentication failed:")) {
550 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Error", command_output.substring("ERROR: ".length())), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.ERROR_MESSAGE);
551 remote_greenstone_server_authentication = null;
552 continue;
553 }
554 // Check if the collection is locked by someone else; if so, see if the user wants to steal the lock
555 else if (command_output.startsWith("ERROR: Collection is locked by: ")) {
556 if (JOptionPane.showConfirmDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Steal_Lock_Message", command_output.substring("ERROR: Collection is locked by: ".length())), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) {
557 // The user has decided to cancel the action
558 throw new RemoteGreenstoneServerAction.ActionCancelledException();
559 }
560
561 // The user has decided to steal the lock... rerun the command with "&steal_lock="
562 gliserver_args += "&steal_lock=";
563 continue;
564 }
565 // Handle other types of errors by throwing an exception
566 else if (command_output.startsWith("ERROR: ")) {
567 throw new Exception(command_output.substring("ERROR: ".length()));
568 }
569
570 // There were no exceptions thrown so the action must have succeeded
571 return command_output;
572 }
573 }
574
575
576 // ----------------------------------------------------------------------------------------------------
577 // NETWORK LAYER
578 // ----------------------------------------------------------------------------------------------------
579
580
581 /** Returns the command output if the action completed, throws some kind of exception otherwise. */
582 private String downloadFileInternal(String download_cgi, String cgi_args, String file_path)
583 throws Exception
584 {
585 DebugStream.println("gliserver URL: " + download_cgi);
586 System.err.println("gliserver args: " + cgi_args);
587
588 // Add username and password, and a timestamp
589 cgi_args += "&un=" + remote_greenstone_server_authentication.getUserName();
590 cgi_args += "&pw=" + new String(remote_greenstone_server_authentication.getPassword());
591 cgi_args += "&ts=" + System.currentTimeMillis();
592 if (Gatherer.GS3){
593 cgi_args += "&site=" + Configuration.site_name;
594 }
595
596 URL download_url = new URL(download_cgi);
597 URLConnection dl_connection = download_url.openConnection();
598 dl_connection.setDoOutput(true);
599 OutputStream dl_os = dl_connection.getOutputStream();
600
601 PrintWriter dl_out = new PrintWriter(dl_os);
602 dl_out.println(cgi_args);
603 dl_out.close();
604
605 // Download result from running cgi script
606 InputStream dl_is = dl_connection.getInputStream();
607 BufferedInputStream dl_bis = new BufferedInputStream(dl_is);
608 DataInputStream dl_dbis = new DataInputStream(dl_bis);
609
610 String first_line = "";
611 byte[] buf = new byte[1024];
612 int len = dl_dbis.read(buf);
613 if (len >= 0) {
614 String first_chunk = new String(buf, 0, len);
615 // first_line = first_chunk.substring(0, ((first_chunk.indexOf("\n") != -1) ? first_chunk.indexOf("\n") : len));
616 first_line = first_chunk.substring(0, ((first_chunk.indexOf("\n") != -1) ? first_chunk.indexOf("\n") : ((first_chunk.length()<len) ? first_chunk.length():len)));
617 // Save the data to file
618 FileOutputStream zip_fos = new FileOutputStream(file_path);
619 BufferedOutputStream zip_bfos = new BufferedOutputStream(zip_fos);
620
621 while (len >= 0) {
622 zip_bfos.write(buf, 0, len);
623 len = dl_dbis.read(buf);
624 }
625
626 zip_bfos.close();
627 zip_fos.close();
628 }
629
630 dl_dbis.close();
631 dl_bis.close();
632 dl_is.close();
633 return first_line;
634 }
635
636
637 /** Returns the command output if the action completed, throws some kind of exception otherwise. */
638 private String sendCommandToServerInternal(String gliserver_url_string, String cgi_args, GShell shell)
639 throws Exception
640 {
641 DebugStream.println("gliserver URL: " + gliserver_url_string);
642 System.err.println("gliserver args: " + cgi_args);
643
644 // Add username and password, and a timestamp
645 if(isAuthenticationRequired(cgi_args)) {
646 cgi_args += "&un=" + remote_greenstone_server_authentication.getUserName();
647 cgi_args += "&pw=" + new String(remote_greenstone_server_authentication.getPassword());
648 }
649 cgi_args += "&ts=" + System.currentTimeMillis();
650 if (Gatherer.GS3){
651 cgi_args += "&site=" + Configuration.site_name;
652 }
653
654 URL gliserver_url = new URL(gliserver_url_string + "?" + cgi_args);
655 URLConnection gliserver_connection = gliserver_url.openConnection();
656
657 // Read the output of the command from the server, and return it
658 StringBuffer command_output_buffer = new StringBuffer(2048);
659 InputStream gliserver_is = gliserver_connection.getInputStream();
660 BufferedReader gliserver_in = new BufferedReader(new InputStreamReader(gliserver_is, "UTF-8"));
661 String gliserver_output_line = gliserver_in.readLine();
662 while (gliserver_output_line != null) {
663 if (shell != null) {
664 shell.fireMessage(gliserver_output_line);
665 if (shell.hasSignalledStop()) {
666 throw new RemoteGreenstoneServerAction.ActionCancelledException();
667 }
668 }
669 command_output_buffer.append(gliserver_output_line + "\n");
670 gliserver_output_line = gliserver_in.readLine();
671 }
672 gliserver_in.close();
673
674 return command_output_buffer.toString();
675 }
676
677
678 /** Returns the command output if the action completed, throws some kind of exception otherwise. */
679 private String uploadFileInternal(String upload_cgi, String cgi_args, String file_path)
680 throws Exception
681 {
682 System.err.println("gliserver URL: " + upload_cgi);
683 System.err.println("gliserver args: " + cgi_args);
684
685 //For a remote GS3
686 //GS3 is running on Tomcat, and Tomcat requires a connection timeout to be set up at the client
687 //side while uploading files. As HttpURLConnection couldn't set the connection timeout, HttpClient.jar
688 //from Jakarta is applied to solve this problem only for uploading files.
689 if (Gatherer.GS3) {
690
691 // Setup the POST method
692 PostMethod httppost = new PostMethod(upload_cgi+"?"+cgi_args); // cgi_args: QUERY_STRING on perl server side
693
694 // construct the multipartrequest form
695 String[] cgi_array=cgi_args.split("&");// get parameter-value pairs from cgi_args string
696 Part[] parts=new Part[cgi_array.length+5];
697
698 // The FilePart: consisting of the (cgi-arg) name and (optional) filename in the Content-Disposition
699 // of the POST request Header (see CGI.pm), and the actual zip file itself. It uses the defaults:
700 // Content-Type: application/octet-stream; charset=ISO-8859-1,Content-Transfer-Encoding: binary
701 parts[0]= new FilePart("uploaded_file", "zipFile", new File(file_path));
702
703 parts[1]= new StringPart("un", remote_greenstone_server_authentication.getUserName());
704 parts[2]= new StringPart("pw", new String(remote_greenstone_server_authentication.getPassword()));
705 parts[3]= new StringPart("ts", String.valueOf(System.currentTimeMillis()));
706 parts[4]= new StringPart("site", Configuration.site_name);
707 // find all parameters of cgi-args and add them into Part[]
708 for (int i=0; i<cgi_array.length;i++){
709 parts[5+i]=new StringPart(cgi_array[i].substring(0,cgi_array[i].indexOf("=")),cgi_array[i].substring(cgi_array[i].indexOf("=")+1,cgi_array[i].length()));
710 }
711
712 // set MultipartRequestEntity on the POST method
713 httppost.setRequestEntity(new MultipartRequestEntity(parts, httppost.getParams()));
714
715 // See file gli/request.txt for the multipart request that's been generated:
716 //httppost.getRequestEntity().writeRequest(new FileOutputStream("request.txt", true)); // true: appends
717
718 //set up the HttpClient connection
719 HttpClient client=new HttpClient();
720 client.getParams().setBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE, false);
721 client.getParams().setConnectionManagerTimeout(200000); //set the connection timeout
722 // get the output of the command from the server
723 String command_output = "";
724 try{
725 client.executeMethod(httppost);
726 if (httppost.getStatusCode() == HttpStatus.SC_OK) {
727 command_output = httppost.getStatusLine().toString();
728 } else {
729 command_output = httppost.getStatusLine().toString();
730 System.out.println("Unexpected failure: " + httppost.getStatusLine().toString());
731 }
732 }catch(IOException e){
733 e.printStackTrace();
734 }finally{
735 httppost.releaseConnection();
736 }
737 return command_output;
738 }
739
740 //For a remote GS2
741 // Add username and password, and a timestamp
742 cgi_args += "&un=" + remote_greenstone_server_authentication.getUserName();
743 cgi_args += "&pw=" + new String(remote_greenstone_server_authentication.getPassword());
744 cgi_args += "&ts=" + System.currentTimeMillis();
745
746 // Open a HTTP connection to the URL
747 URL url = new URL(upload_cgi);
748 HttpURLConnection gliserver_connection = (HttpURLConnection) url.openConnection();
749
750 gliserver_connection.setDoInput(true); // Allow Inputs
751 gliserver_connection.setDoOutput(true); // Allow Outputs
752 gliserver_connection.setUseCaches(false); // Don't use a cached copy.
753
754 gliserver_connection.setRequestProperty("Connection", "Keep-Alive");
755
756 // Send zip file to server
757 File file = new File(file_path);
758 FileInputStream fileInputStream = new FileInputStream(file);
759
760 // Add file size argument, because IIS 6 needs a lot of help
761 int file_size = fileInputStream.available();
762 cgi_args += "&fs=" + file_size;
763
764 DataOutputStream dos = new DataOutputStream(gliserver_connection.getOutputStream());
765 dos.writeBytes(cgi_args + "\n");
766
767 // create a buffer of maximum size
768 final int maxBufferSize = 1024;
769 int bytesAvailable = file_size;
770 int bufferSize = Math.min(bytesAvailable, maxBufferSize);
771 byte[] buffer = new byte[bufferSize];
772
773 // read file and write it into form...
774 // !! This uses a lot of memory when the file being uploaded is big -- Java seems to need to keep
775 // the entire file in the DataOutputStream? (Use Runtime.getRuntime().totalMemory() to see)
776 int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
777 while (bytesRead > 0) {
778 dos.write(buffer, 0, bytesRead);
779 bytesAvailable = fileInputStream.available();
780 bufferSize = Math.min(bytesAvailable, maxBufferSize);
781 bytesRead = fileInputStream.read(buffer, 0, bufferSize);
782 }
783
784 // close streams
785 fileInputStream.close();
786 dos.flush();
787 dos.close();
788
789 // Read the output of the command from the server, and return it
790 String command_output = "";
791 InputStream gliserver_is = gliserver_connection.getInputStream();
792 BufferedReader gliserver_in = new BufferedReader(new InputStreamReader(gliserver_is, "UTF-8"));
793 String gliserver_output_line = gliserver_in.readLine();
794 while (gliserver_output_line != null) {
795 command_output += gliserver_output_line + "\n";
796 gliserver_output_line = gliserver_in.readLine();
797 }
798 gliserver_in.close();
799
800 return command_output;
801 }
802
803
804 // ----------------------------------------------------------------------------------------------------
805 // UTILITIES
806 // ----------------------------------------------------------------------------------------------------
807
808
809 public String getPathRelativeToDirectory(File file, String directory_path)
810 {
811 String file_path = file.getAbsolutePath();
812 if (!file_path.startsWith(directory_path)) {
813 System.err.println("ERROR: File path " + file_path + " is not a child of " + directory_path);
814 return file_path;
815 }
816
817 String relative_file_path = file_path.substring(directory_path.length());
818 if (relative_file_path.startsWith(File.separator)) {
819 relative_file_path = relative_file_path.substring(File.separator.length());
820 }
821 return relative_file_path;
822 }
823}
Note: See TracBrowser for help on using the repository browser.