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

Last change on this file since 19229 was 19229, checked in by ak19, 15 years ago

Helpful debug statement (commented out).

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