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

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

GLI and gliserver.pl have been updated together to deal with inconsistent Zipping environment. When testing on Linux, LANG variable was set on the GLI (client) side but not set on server side. This resulted in special characters in filenames being unzipped differently from their originals on the client side, or if the LANG env var had been set to be the same on the server end as it was on the client end when the zipping took place. Now the client passes the LANG variable to every upload and download gliserver command. The client gets and stores the LANG variable only once though (on creating the RemoteGreenstoneServer object) since the System.getenv() method is deprecated.

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