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

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

Clean exit out of client GLI if the user cancelled out of the authentication popup that appears at the start

  • Property svn:keywords set to Author Date Id Revision
File size: 33.5 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 try {
492 authenticateUser();
493 } catch (RemoteGreenstoneServerAction.ActionCancelledException e) {
494 // Authentication popup only appears at the start. If the user cancelled
495 // out of it, then another remote action always remains on the queue,
496 // preventing a clean exit. Need to clear queue before exit.
497 synchronized (remote_greenstone_server_action_queue) {
498 remote_greenstone_server_action_queue.clear();
499 }
500 Gatherer.exit();
501 }
502 }
503 String gliserver_url_string = Configuration.gliserver_url.toString();
504 String command_output = sendCommandToServerInternal(gliserver_url_string, gliserver_args, shell);
505
506 // Debugging - print any ok messages to stderr
507 //if(!(command_output.trim().startsWith("<"))) {
508 //System.err.println("**** RECEIVED (sendCommandToServer()): " + command_output);
509 //}
510
511 // Check the first line to see if authentication has failed; if so, go around the loop again
512 if (command_output.startsWith("ERROR: Authentication failed:")) {
513 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Error", command_output.substring("ERROR: ".length())), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.ERROR_MESSAGE);
514 remote_greenstone_server_authentication = null;
515 continue;
516 }
517 // Check if the collection is locked by someone else; if so, see if the user wants to steal the lock
518 else if (command_output.startsWith("ERROR: Collection is locked by: ")) {
519 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) {
520 // The user has decided to cancel the action
521 throw new RemoteGreenstoneServerAction.ActionCancelledException();
522 }
523
524 // The user has decided to steal the lock... rerun the command with "&steal_lock="
525 gliserver_args += "&steal_lock=";
526 continue;
527 }
528 // Handle other types of errors by throwing an exception
529 else if (command_output.startsWith("ERROR: ")) {
530 throw new Exception(command_output.substring("ERROR: ".length()));
531 } else if (command_output.indexOf("ERROR: ") != -1) { // check if ERROR occurs anywhere else in the output
532 throw new Exception(command_output);
533 }
534
535
536 // There were no exceptions thrown so the action must have succeeded
537 return command_output;
538 }
539 }
540
541
542 /** Returns the command output if the action completed, throws some kind of exception otherwise. */
543 String uploadFile(String gliserver_args, String file_path)
544 throws Exception
545 {
546 while (true) {
547 // Check that Configuration.gliserver_url is set
548 if (Configuration.gliserver_url == null) {
549 throw new Exception("Empty gliserver URL: please set this in Preferences before continuing.");
550 }
551
552 // Ask for authentication information (if necessary), then perform the action
553 authenticateUser();
554 String gliserver_url_string = Configuration.gliserver_url.toString();
555 String command_output = uploadFileInternal(gliserver_url_string, gliserver_args, file_path);
556 // System.err.println("Command output: " + command_output);
557
558 // Check the first line to see if authentication has failed; if so, go around the loop again
559 if (command_output.startsWith("ERROR: Authentication failed:")) {
560 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("RemoteGreenstoneServer.Error", command_output.substring("ERROR: ".length())), Dictionary.get("RemoteGreenstoneServer.Error_Title"), JOptionPane.ERROR_MESSAGE);
561 remote_greenstone_server_authentication = null;
562 continue;
563 }
564 // Check if the collection is locked by someone else; if so, see if the user wants to steal the lock
565 else if (command_output.startsWith("ERROR: Collection is locked by: ")) {
566 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) {
567 // The user has decided to cancel the action
568 throw new RemoteGreenstoneServerAction.ActionCancelledException();
569 }
570
571 // The user has decided to steal the lock... rerun the command with "&steal_lock="
572 gliserver_args += "&steal_lock=";
573 continue;
574 }
575 // Handle other types of errors by throwing an exception
576 else if (command_output.startsWith("ERROR: ")) {
577 throw new Exception(command_output.substring("ERROR: ".length()));
578 }
579
580 // There were no exceptions thrown so the action must have succeeded
581 return command_output;
582 }
583 }
584
585
586 // ----------------------------------------------------------------------------------------------------
587 // NETWORK LAYER
588 // ----------------------------------------------------------------------------------------------------
589
590
591 /** Returns the command output if the action completed, throws some kind of exception otherwise. */
592 private String downloadFileInternal(String download_cgi, String cgi_args, String file_path)
593 throws Exception
594 {
595 DebugStream.println("gliserver URL: " + download_cgi);
596 System.err.println("gliserver args: " + cgi_args);
597
598 // Add username and password, and a timestamp
599 cgi_args += "&un=" + remote_greenstone_server_authentication.getUserName();
600 cgi_args += "&pw=" + new String(remote_greenstone_server_authentication.getPassword());
601 cgi_args += "&ts=" + System.currentTimeMillis();
602 if (Gatherer.GS3){
603 cgi_args += "&site=" + Configuration.site_name;
604 }
605
606 URL download_url = new URL(download_cgi);
607 URLConnection dl_connection = download_url.openConnection();
608 dl_connection.setDoOutput(true);
609 OutputStream dl_os = dl_connection.getOutputStream();
610
611 PrintWriter dl_out = new PrintWriter(dl_os);
612 dl_out.println(cgi_args);
613 dl_out.close();
614
615 // Download result from running cgi script
616 InputStream dl_is = dl_connection.getInputStream();
617 BufferedInputStream dl_bis = new BufferedInputStream(dl_is);
618 DataInputStream dl_dbis = new DataInputStream(dl_bis);
619
620 String first_line = "";
621 byte[] buf = new byte[1024];
622 int len = dl_dbis.read(buf);
623 if (len >= 0) {
624 String first_chunk = new String(buf, 0, len);
625 // first_line = first_chunk.substring(0, ((first_chunk.indexOf("\n") != -1) ? first_chunk.indexOf("\n") : len));
626 first_line = first_chunk.substring(0, ((first_chunk.indexOf("\n") != -1) ? first_chunk.indexOf("\n") : ((first_chunk.length()<len) ? first_chunk.length():len)));
627 // Save the data to file
628 FileOutputStream zip_fos = new FileOutputStream(file_path);
629 BufferedOutputStream zip_bfos = new BufferedOutputStream(zip_fos);
630
631 while (len >= 0) {
632 zip_bfos.write(buf, 0, len);
633 len = dl_dbis.read(buf);
634 }
635
636 zip_bfos.close();
637 zip_fos.close();
638 }
639
640 dl_dbis.close();
641 dl_bis.close();
642 dl_is.close();
643 return first_line;
644 }
645
646
647 /** Returns the command output if the action completed, throws some kind of exception otherwise. */
648 private String sendCommandToServerInternal(String gliserver_url_string, String cgi_args, GShell shell)
649 throws Exception
650 {
651 DebugStream.println("gliserver URL: " + gliserver_url_string);
652 System.err.println("gliserver args: " + cgi_args);
653
654 // Add username and password, and a timestamp
655 if(isAuthenticationRequired(cgi_args)) {
656 cgi_args += "&un=" + remote_greenstone_server_authentication.getUserName();
657 cgi_args += "&pw=" + new String(remote_greenstone_server_authentication.getPassword());
658 }
659 cgi_args += "&ts=" + System.currentTimeMillis();
660 if (Gatherer.GS3){
661 cgi_args += "&site=" + Configuration.site_name;
662 }
663
664 URL gliserver_url = new URL(gliserver_url_string + "?" + cgi_args);
665 URLConnection gliserver_connection = gliserver_url.openConnection();
666
667 // Read the output of the command from the server, and return it
668 StringBuffer command_output_buffer = new StringBuffer(2048);
669 InputStream gliserver_is = gliserver_connection.getInputStream();
670 BufferedReader gliserver_in = new BufferedReader(new InputStreamReader(gliserver_is, "UTF-8"));
671 String gliserver_output_line = gliserver_in.readLine();
672 while (gliserver_output_line != null) {
673 if (shell != null) {
674 shell.fireMessage(gliserver_output_line);
675 if (shell.hasSignalledStop()) {
676 throw new RemoteGreenstoneServerAction.ActionCancelledException();
677 }
678 }
679 command_output_buffer.append(gliserver_output_line + "\n");
680 gliserver_output_line = gliserver_in.readLine();
681 }
682 gliserver_in.close();
683
684 return command_output_buffer.toString();
685 }
686
687
688 /** Returns the command output if the action completed, throws some kind of exception otherwise. */
689 private String uploadFileInternal(String upload_cgi, String cgi_args, String file_path)
690 throws Exception
691 {
692 System.err.println("gliserver URL: " + upload_cgi);
693 System.err.println("gliserver args: " + cgi_args);
694
695 //For a remote GS3
696 //GS3 is running on Tomcat, and Tomcat requires a connection timeout to be set up at the client
697 //side while uploading files. As HttpURLConnection couldn't set the connection timeout, HttpClient.jar
698 //from Jakarta is applied to solve this problem only for uploading files.
699 if (Gatherer.GS3) {
700
701 // Setup the POST method
702 PostMethod httppost = new PostMethod(upload_cgi+"?"+cgi_args); // cgi_args: QUERY_STRING on perl server side
703
704 // construct the multipartrequest form
705 String[] cgi_array=cgi_args.split("&");// get parameter-value pairs from cgi_args string
706 Part[] parts=new Part[cgi_array.length+5];
707
708 // The FilePart: consisting of the (cgi-arg) name and (optional) filename in the Content-Disposition
709 // of the POST request Header (see CGI.pm), and the actual zip file itself. It uses the defaults:
710 // Content-Type: application/octet-stream; charset=ISO-8859-1,Content-Transfer-Encoding: binary
711 parts[0]= new FilePart("uploaded_file", "zipFile", new File(file_path));
712
713 parts[1]= new StringPart("un", remote_greenstone_server_authentication.getUserName());
714 parts[2]= new StringPart("pw", new String(remote_greenstone_server_authentication.getPassword()));
715 parts[3]= new StringPart("ts", String.valueOf(System.currentTimeMillis()));
716 parts[4]= new StringPart("site", Configuration.site_name);
717 // find all parameters of cgi-args and add them into Part[]
718 for (int i=0; i<cgi_array.length;i++){
719 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()));
720 }
721
722 // set MultipartRequestEntity on the POST method
723 httppost.setRequestEntity(new MultipartRequestEntity(parts, httppost.getParams()));
724
725 // See file gli/request.txt for the multipart request that's been generated:
726 //httppost.getRequestEntity().writeRequest(new FileOutputStream("request.txt", true)); // true: appends
727
728 //set up the HttpClient connection
729 HttpClient client=new HttpClient();
730 client.getParams().setBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE, false);
731 client.getParams().setConnectionManagerTimeout(200000); //set the connection timeout
732 // get the output of the command from the server
733 String command_output = "";
734 try{
735 client.executeMethod(httppost);
736 if (httppost.getStatusCode() == HttpStatus.SC_OK) {
737 command_output = httppost.getStatusLine().toString();
738 } else {
739 command_output = httppost.getStatusLine().toString();
740 System.out.println("Unexpected failure: " + httppost.getStatusLine().toString());
741 }
742 }catch(IOException e){
743 e.printStackTrace();
744 }finally{
745 httppost.releaseConnection();
746 }
747 return command_output;
748 }
749
750 //For a remote GS2
751 // Add username and password, and a timestamp
752 cgi_args += "&un=" + remote_greenstone_server_authentication.getUserName();
753 cgi_args += "&pw=" + new String(remote_greenstone_server_authentication.getPassword());
754 cgi_args += "&ts=" + System.currentTimeMillis();
755
756 // Open a HTTP connection to the URL
757 URL url = new URL(upload_cgi);
758 HttpURLConnection gliserver_connection = (HttpURLConnection) url.openConnection();
759
760 gliserver_connection.setDoInput(true); // Allow Inputs
761 gliserver_connection.setDoOutput(true); // Allow Outputs
762 gliserver_connection.setUseCaches(false); // Don't use a cached copy.
763
764 gliserver_connection.setRequestProperty("Connection", "Keep-Alive");
765
766 // Send zip file to server
767 File file = new File(file_path);
768 FileInputStream fileInputStream = new FileInputStream(file);
769
770 // Add file size argument, because IIS 6 needs a lot of help
771 int file_size = fileInputStream.available();
772 cgi_args += "&fs=" + file_size;
773
774 DataOutputStream dos = new DataOutputStream(gliserver_connection.getOutputStream());
775 dos.writeBytes(cgi_args + "\n");
776
777 // create a buffer of maximum size
778 final int maxBufferSize = 1024;
779 int bytesAvailable = file_size;
780 int bufferSize = Math.min(bytesAvailable, maxBufferSize);
781 byte[] buffer = new byte[bufferSize];
782
783 // read file and write it into form...
784 // !! This uses a lot of memory when the file being uploaded is big -- Java seems to need to keep
785 // the entire file in the DataOutputStream? (Use Runtime.getRuntime().totalMemory() to see)
786 int bytesRead = fileInputStream.read(buffer, 0, bufferSize);
787 while (bytesRead > 0) {
788 dos.write(buffer, 0, bytesRead);
789 bytesAvailable = fileInputStream.available();
790 bufferSize = Math.min(bytesAvailable, maxBufferSize);
791 bytesRead = fileInputStream.read(buffer, 0, bufferSize);
792 }
793
794 // close streams
795 fileInputStream.close();
796 dos.flush();
797 dos.close();
798
799 // Read the output of the command from the server, and return it
800 String command_output = "";
801 InputStream gliserver_is = gliserver_connection.getInputStream();
802 BufferedReader gliserver_in = new BufferedReader(new InputStreamReader(gliserver_is, "UTF-8"));
803 String gliserver_output_line = gliserver_in.readLine();
804 while (gliserver_output_line != null) {
805 command_output += gliserver_output_line + "\n";
806 gliserver_output_line = gliserver_in.readLine();
807 }
808 gliserver_in.close();
809
810 return command_output;
811 }
812
813
814 // ----------------------------------------------------------------------------------------------------
815 // UTILITIES
816 // ----------------------------------------------------------------------------------------------------
817
818
819 public String getPathRelativeToDirectory(File file, String directory_path)
820 {
821 String file_path = file.getAbsolutePath();
822 if (!file_path.startsWith(directory_path)) {
823 System.err.println("ERROR: File path " + file_path + " is not a child of " + directory_path);
824 return file_path;
825 }
826
827 String relative_file_path = file_path.substring(directory_path.length());
828 if (relative_file_path.startsWith(File.separator)) {
829 relative_file_path = relative_file_path.substring(File.separator.length());
830 }
831 return relative_file_path;
832 }
833}
Note: See TracBrowser for help on using the repository browser.