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

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

Turned class RemoteGreenstoneServer.java from an all-static class into a regular OOP class. It is now also split into three files (the other two being ActionQueue.java and RemoteGreenstoneServerAction.java).

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