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

Last change on this file since 31777 was 31777, checked in by ak19, 7 years ago

Related to bugfix of previous commit. Removing commented out working first solution.

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