source: main/trunk/gli/src/org/greenstone/gatherer/gui/DownloadPane.java@ 29972

Last change on this file since 29972 was 29972, checked in by ak19, 9 years ago

More dynamic processing of downloaders. GLI used to use a fixed set of downloaders, now downloadinfo.pl is first called with the listall flag to get all the downloaders that are non-abstract, then these are added to the interface.

  • Property svn:keywords set to Author Date Id Revision
File size: 28.7 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 * <BR><BR>
9 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37package org.greenstone.gatherer.gui;
38
39import java.awt.*;
40import java.awt.event.*;
41import java.io.*;
42import java.net.*;
43import java.util.*;
44import javax.swing.*;
45import javax.swing.border.*;
46import javax.swing.event.*;
47import javax.swing.tree.*;
48import org.greenstone.gatherer.Configuration;
49import org.greenstone.gatherer.DebugStream;
50import org.greenstone.gatherer.Dictionary;
51import org.greenstone.gatherer.Gatherer;
52import org.greenstone.gatherer.file.WorkspaceTree;
53import org.greenstone.gatherer.greenstone.LocalGreenstone;
54import org.greenstone.gatherer.util.StaticStrings;
55import org.greenstone.gatherer.util.Utility;
56import org.greenstone.gatherer.download.Download;
57import org.greenstone.gatherer.download.DownloadScrollPane;
58import org.greenstone.gatherer.download.ServerInfoDialog;
59import org.greenstone.gatherer.util.XMLTools;
60import org.greenstone.gatherer.cdm.*;
61import org.greenstone.gatherer.gui.*;
62import org.w3c.dom.*;
63import org.xml.sax.*;
64import org.greenstone.gatherer.GAuthenticator;
65
66/**
67 * @author John Thompson, Greenstone Digital Library, University of Waikato
68 * @version 2.1
69 */
70public class DownloadPane
71 extends JPanel {
72
73 static final private Dimension LABEL_SIZE = new Dimension(225, 25);
74 static final private Dimension TREE_SIZE = new Dimension(150, 500);
75 //static final private String CONTENTS[] = { "DOWNLOAD.MODE.WebDownload", "DOWNLOAD.MODE.MediaWikiDownload", "DOWNLOAD.MODE.OAIDownload", "DOWNLOAD.MODE.ZDownload" , "DOWNLOAD.MODE.SRWDownload"};
76 private String CONTENTS[] = null;
77
78 private boolean download_button_enabled = false;
79 private boolean ready = false;
80
81 private JPanel options_pane;
82 // TODO should use Vector to store all loaded downloads!!
83
84 private DesignTree tree;
85 private HashMap download_map;
86 private ServerInfoDialog server_info;
87 private JScrollPane list_scroll;
88 private DownloadScrollPane getter;
89 private String mode = null;
90 private TreePath previous_path;
91 private String proxy_url = "";
92
93 /** Main System code */
94 public DownloadPane() {
95 super();
96 JScrollPane scrol_tmp;
97 this.setComponentOrientation(Dictionary.getOrientation());
98 // TODO: Download the WDownload and the download panel fixed!!
99 getter = new DownloadScrollPane();
100 getter.start();
101 list_scroll = getter.getDownloadJobList();
102 list_scroll.setComponentOrientation(Dictionary.getOrientation());
103 // TODO should use Vector to store all loaded downloads!!
104 String lang = Configuration.getLanguage();
105 download_map = new HashMap();
106
107 ArrayList<String> downloaderNamesList = getDownloads(lang);
108 int size = downloaderNamesList.size();
109 CONTENTS = new String[size];
110 for(int i = 0; i < size; i++) {
111 String downloadName = downloaderNamesList.get(i); // e.g. "WebDownload"
112 CONTENTS[i] = "DOWNLOAD.MODE."+downloadName.replace("3950", ""); // A special case is Z3950Download,
113 // which has to be stored in CONTENTS array as DOWNLOAD.MODE.ZDownload
114
115 String shortName = downloadName.replace("Download", ""); // e.g. "Web"
116 download_map.put(shortName, loadDownload(downloadName,lang));
117 }
118
119 // Creation
120 tree = new DesignTree();
121 tree.setComponentOrientation(Dictionary.getOrientation());
122 options_pane = new JPanel();
123 options_pane.setComponentOrientation(Dictionary.getOrientation());
124
125 JButton clear_cache_button = new GLIButton(Dictionary.get("Mirroring.ClearCache"), Dictionary.get("Mirroring.ClearCache_Tooltip"));
126 clear_cache_button.setEnabled(true);
127 clear_cache_button.setMnemonic(KeyEvent.VK_C);
128
129 JButton download_button = new GLIButton(Dictionary.get("Mirroring.Download"), Dictionary.get("Mirroring.Download_Tooltip"));
130 download_button.setEnabled(true);
131 download_button.setMnemonic(KeyEvent.VK_D);
132
133 JButton information_button = new GLIButton(Dictionary.get("Download.ServerInformation"), Dictionary.get("Download.ServerInformation_Tooltip"));
134 information_button.setEnabled(true);
135 information_button.setMnemonic(KeyEvent.VK_S);
136
137
138 JButton preferences_button = new GLIButton(Dictionary.get("Mirroring.Preferences"), Dictionary.get("Mirroring.Preferences_Tooltip"));
139 preferences_button.setEnabled(true);
140 preferences_button.setMnemonic(KeyEvent.VK_P);
141
142 // Connect
143 clear_cache_button.addActionListener(new ClearCacheListener());
144 download_button.addActionListener(new DownloadButtonListener());
145 preferences_button.addActionListener(new PreferencesButtonActionListener());
146 information_button.addActionListener(new InformationButtonActionListener());
147 tree.addTreeSelectionListener(new TreeListener());
148
149 // Add to Panel
150 JPanel button_pane = new JPanel();
151 button_pane.setComponentOrientation(Dictionary.getOrientation());
152 button_pane.setLayout(new GridLayout(1,4)); // GridLayout so button pane resizes with window-width
153 button_pane.setBorder(BorderFactory.createEtchedBorder());
154 button_pane.add(clear_cache_button);
155 button_pane.add(download_button);
156 button_pane.add(information_button);
157 button_pane.add(preferences_button);
158
159 JPanel tree_pane = new JPanel();
160 tree_pane.setComponentOrientation(Dictionary.getOrientation());
161 tree_pane.setLayout(new BorderLayout());
162 scrol_tmp = new JScrollPane(tree);
163 scrol_tmp.setComponentOrientation(Dictionary.getOrientation());
164 tree_pane.add(scrol_tmp, BorderLayout.CENTER);
165 tree_pane.setPreferredSize(TREE_SIZE);
166
167
168 Color colour_two = Configuration.getColor("coloring.collection_tree_background", false);
169 options_pane.setBackground(colour_two);
170 options_pane.setBorder(BorderFactory.createEtchedBorder());
171
172
173 JScrollPane options_scroll_pane = new JScrollPane(options_pane);
174 options_scroll_pane.setComponentOrientation(Dictionary.getOrientation());
175 JSplitPane mode_pane = new JSplitPane();
176 mode_pane.setComponentOrientation(Dictionary.getOrientation());
177 mode_pane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
178 if (Dictionary.getOrientation().isLeftToRight()){
179 mode_pane.add(tree_pane,JSplitPane.LEFT);
180 mode_pane.add(options_scroll_pane,JSplitPane.RIGHT);
181 mode_pane.setDividerLocation(TREE_SIZE.width);
182 }else{
183 mode_pane.add(tree_pane,JSplitPane.RIGHT);
184 mode_pane.add(options_scroll_pane,JSplitPane.LEFT);
185 mode_pane.setDividerLocation(1-TREE_SIZE.width);
186 }
187
188
189 JPanel edit_pane = new JPanel();
190 edit_pane.setComponentOrientation(Dictionary.getOrientation());
191 edit_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(2,0,0,0), BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Download Setting"), BorderFactory.createEmptyBorder(2,2,2,2))));
192 edit_pane.setLayout(new BorderLayout());
193 edit_pane.add(mode_pane,BorderLayout.CENTER);
194 edit_pane.add(button_pane,BorderLayout.PAGE_END);
195
196 // Add to "this"
197 setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
198 setLayout(new GridLayout(2,1));
199 add(edit_pane);
200 add(list_scroll);
201
202 mode = "Web";
203 generateOptions(options_pane,(Download)download_map.get(mode));
204 previous_path = tree.getSelectionPath();
205 }
206
207 /** System Utilities */
208 public void modeChanged(int gli_mode) {
209 // do nothing at this stage - should we be renewing download options??
210 }
211
212 private void addHeader(String name, Color color, JPanel target_pane) {
213 JPanel header = new JPanel();
214 header.setComponentOrientation(Dictionary.getOrientation());
215 header.setBackground(color);
216 JPanel inner_pane = new JPanel();
217 inner_pane.setComponentOrientation(Dictionary.getOrientation());
218 inner_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5,5,5,5), BorderFactory.createRaisedBevelBorder()));
219 inner_pane.setBackground(color);
220 JLabel header_label = new JLabel("<html><strong>" + name + "</strong></html>");
221 header_label.setComponentOrientation(Dictionary.getOrientation());
222 header_label.setBackground(Configuration.getColor("coloring.collection_heading_background", false));
223 header_label.setHorizontalAlignment(JLabel.CENTER);
224 header_label.setOpaque(true);
225
226 // Layout
227 inner_pane.setLayout(new BorderLayout());
228 inner_pane.add(header_label, BorderLayout.CENTER);
229
230 header.setLayout(new BorderLayout());
231 header.add(inner_pane, BorderLayout.CENTER);
232 target_pane.add(header);
233 }
234
235 private ArrayList<String> getDownloads(String lang) {
236 ArrayList downloaders = null;
237 Document document = null;
238 Process process = null;
239
240 try {
241 if (Gatherer.isGsdlRemote) {
242 String output = Gatherer.remoteGreenstoneServer.getScriptOptions("downloadinfo.pl", "&listall");
243 Reader reader = new StringReader(output);
244 document = XMLTools.parseXML(reader);
245 }
246 else {
247 ArrayList args_list = new ArrayList();
248 String args[] = null;
249 if(Configuration.perl_path != null) {
250 args_list.add(Configuration.perl_path);
251 } else if(Utility.isWindows()) {
252 args_list.add("Perl.exe");
253 } else {
254 args_list.add("perl");
255 }
256 args_list.add("-S");
257 args_list.add(LocalGreenstone.getBinScriptDirectoryPath()+"downloadinfo.pl");
258 args_list.add("-listall");
259 args_list.add("-xml");
260 args_list.add("-language");
261 args_list.add(lang);
262
263 // Create the process.
264 args = (String []) args_list.toArray(new String[0]);
265 Runtime runtime = Runtime.getRuntime();
266 DebugStream.println("Getting Download Info: "+args_list);
267 process = runtime.exec(args);
268
269 InputStream input_stream = process.getErrorStream();
270 document = XMLTools.parseXML(input_stream);
271 }
272
273
274 }
275 catch (Exception error) {
276 System.err.println("Failed when trying to parse downloadinfo.pl -listall");
277 error.printStackTrace();
278 }
279 finally {
280 Utility.closeProcess(process);
281 }
282
283 if(document != null) {
284 //return parseXML(document.getDocumentElement());
285 Element downloadList = document.getDocumentElement();
286 int length = -1;
287 if(downloadList.hasAttribute("length")) {
288 length = Integer.parseInt(downloadList.getAttribute("length"));
289 downloaders = new ArrayList<String>(length);
290
291 for (Node node = downloadList.getFirstChild(); node != null; node = node.getNextSibling()) {
292 // goes through each <DownloadInfo> of listAll
293
294 String download_name = null;
295
296 for(Node infoNode = node.getFirstChild();
297 infoNode != null; infoNode = infoNode.getNextSibling()) {
298
299 String node_name = infoNode.getNodeName();
300 if(node_name.equalsIgnoreCase("Name")) { // <Name>WebDownload</Name>
301 download_name = XMLTools.getValue(infoNode);
302 }
303 // skip all the downloaders that are Abstract, as these are pure superclasses
304 else if(node_name.equalsIgnoreCase("Abstract")) {
305 String isAbstract = XMLTools.getValue(infoNode);
306
307 if(isAbstract.equalsIgnoreCase("no") && download_name != null) {
308 downloaders.add(download_name);
309 }
310 }
311 }
312 }
313 }
314 }
315
316 return downloaders;
317 }
318
319 /** Supporting Functions */
320 private Download loadDownload(String download_name, String lang) {
321 Document document = null;
322 Process process = null;
323 try {
324 if (Gatherer.isGsdlRemote) {
325 String output = Gatherer.remoteGreenstoneServer.getScriptOptions("downloadinfo.pl", "&downloader="+download_name); //OR: "&listall";
326 Reader reader = new StringReader(output);
327 document = XMLTools.parseXML(reader);
328 }
329 else {
330 ArrayList args_list = new ArrayList();
331 String args[] = null;
332 if(Configuration.perl_path != null) {
333 args_list.add(Configuration.perl_path);
334 } else if(Utility.isWindows()) {
335 args_list.add("Perl.exe");
336 } else {
337 args_list.add("perl");
338 }
339 args_list.add("-S");
340 args_list.add(LocalGreenstone.getBinScriptDirectoryPath()+"downloadinfo.pl");
341 args_list.add("-xml");
342 args_list.add("-language");
343 args_list.add(lang);
344 args_list.add(download_name);
345
346 // Create the process.
347 args = (String []) args_list.toArray(new String[0]);
348 Runtime runtime = Runtime.getRuntime();
349 DebugStream.println("Getting Download Info: "+args_list);
350 process = runtime.exec(args);
351
352 InputStream input_stream = process.getErrorStream();
353 document = XMLTools.parseXML(input_stream);
354 }
355
356 }
357 catch (Exception error) {
358 System.err.println("Failed when trying to parse: " + download_name);
359 error.printStackTrace();
360 }
361 finally {
362 Utility.closeProcess(process);
363 }
364
365 if(document != null) {
366 return parseXML(document.getDocumentElement());
367 }
368
369 return null;
370 }
371
372 private Download parseXML(Node root) {
373 Download download = new Download();
374 String node_name = null;
375 for (Node node = root.getFirstChild(); node != null; node = node.getNextSibling()) {
376 node_name = node.getNodeName();
377 if(node_name.equalsIgnoreCase("Name")) {
378 String name = XMLTools.getValue(node);
379 download.setName(name);
380 }
381 else if (node_name.equalsIgnoreCase("Desc")) {
382 download.setDescription(XMLTools.getValue(node));
383 }
384 else if (node_name.equalsIgnoreCase("Abstract")) {
385 download.setIsAbstract(XMLTools.getValue(node).equalsIgnoreCase(StaticStrings.YES_STR));
386 }
387 else if(node_name.equalsIgnoreCase("Arguments")) {
388 for(Node arg = node.getFirstChild(); arg != null; arg = arg.getNextSibling()) {
389 node_name = arg.getNodeName();
390 if(node_name.equalsIgnoreCase("Option")) {
391 Argument argument = new Argument((Element)arg);
392 argument.parseXML((Element)arg);
393 argument.setValue(argument.getDefaultValue());
394 download.addArgument(argument);
395 }
396
397 }
398 }
399 else if(node_name.equalsIgnoreCase("DownloadInfo")) {
400 Download super_download = parseXML(node);
401 download.setSuper(super_download);
402 }
403 }
404
405 if(download.getName() != null) {
406 return download;
407 }
408 return null;
409 }
410
411 /** Update the previous setup */
412 private boolean updateArguments(boolean checkRequired)
413 {
414 boolean cont = true;
415 for(int i = 0; i < options_pane.getComponentCount(); i++) {
416
417 Component component = options_pane.getComponent(i);
418 if(component instanceof ArgumentControl) {
419 cont = cont && ((ArgumentControl)component).updateArgument(checkRequired);
420 }
421 }
422
423 if(cont){return true; }
424
425 return false;
426 }
427
428 /** Generate Controls for Options */
429 /* at some stage we should think about which options should be shown for
430 * different modes. Currently, always show all options (unless hidden)*/
431 private void generateOptions(JPanel options_pane, ArgumentContainer data) {
432 options_pane.removeAll();
433 /** Create the current option panel */
434
435 ArrayList arguments = data.getArguments(true, false);
436 int mode = Configuration.getMode();
437 ArrayList added_arguments = new ArrayList();
438
439 for(int i = 0; i < arguments.size(); i++) {
440 Argument argument = (Argument) arguments.get(i);
441
442 if (argument.isHiddenGLI()) continue;
443 ArgumentControl argument_control = new ArgumentControl(argument,false,null);
444 added_arguments.add(argument_control);
445 }
446
447
448 options_pane.setLayout(new GridLayout(added_arguments.size(),1));
449 for(int i = 0; i < added_arguments.size(); i++) {
450 options_pane.add((ArgumentControl)added_arguments.get(i));
451
452 }
453 }
454
455 /** Behaviour Functions */
456 public void afterDisplay() {
457 ready = true;
458 }
459
460
461 public void gainFocus() {
462 if(!ready) {
463 return;
464 }
465
466 // It is also a good time to determine if the download should be enabled - ie if its allowed to be enabled and a valid URL is present in the field.
467 download_button_enabled = true;
468 //download_button.setEnabled(download_button_enabled);
469 }
470
471
472
473 public void refresh(int refresh_reason, boolean ready)
474 {
475 }
476
477 /** Private classes */
478 /** This tree provides a 'table of contents' for the various components of the design process (collection configuration in more technical terms). */
479 private class DesignTree extends JTree {
480
481 private DesignNode root = null;
482 /** Constructor. Automatically generates all of the nodes, in the order of CONTENTS. */
483 public DesignTree() {
484 super();
485 this.setComponentOrientation(Dictionary.getOrientation());
486 resetModel(Configuration.getMode());
487 expandRow(0);
488 setRootVisible(false);
489 setSelectionRow(0);
490 }
491
492 /** Reset the model used by the design page contents tree. This is necessary to hide the partitions entry when in lower detail modes
493 * @param mode the current detail mode as an int
494 */
495 public void resetModel(int mode) {
496 root = new DesignNode("DOWNLOAD.MODE.Root");
497 // Now add the design categories.
498 for(int i = 0; i < CONTENTS.length; i++) {
499 root.add(new DesignNode(CONTENTS[i]));
500 }
501 this.setModel(new DefaultTreeModel(root));
502 updateUI();
503 }
504 /** Set the current view to the one specified.
505 * @param type the name of the desired view as a String
506 */
507 public void setSelectedView(String type) {
508 type = Dictionary.get(type);
509 for(int i = 0; i < root.getChildCount(); i++) {
510 DesignNode child = (DesignNode) root.getChildAt(i);
511 if(child.toString().equals(type)) {
512 TreePath path = new TreePath(child.getPath());
513 setSelectionPath(path);
514 }
515 }
516 }
517 }
518
519 /** A tree node that retains a reference to one of the possible design sub-views relating to the different sub-managers. */
520 private class DesignNode extends DefaultMutableTreeNode {
521 /** Constructor.
522 * @param object The <strong>Object</strong> assigned to this node.
523 */
524 public DesignNode(String object) {
525 super(object);
526 }
527 /** Retrieve a textual representation of the object.
528 * @return a String
529 */
530 public String toString() {
531 // return Dictionary.get("CDM.GUI." + (String)getUserObject());
532 return Dictionary.get((String) getUserObject());
533 }
534 }
535
536 /** Listens for selection changes in the 'contents' tree, and switches to the appropriate view. */
537 private class TreeListener
538 implements TreeSelectionListener {
539 /** Called whenever the selection changes, we must update the view so it matches the node selected.
540 * @param event A <strong>TreeSelectionEvent</strong> containing more information about the tree selection.
541 * @see org.greenstone.gatherer.cdm.ClassifierManager
542 * @see org.greenstone.gatherer.cdm.CollectionDesignManager
543 * @see org.greenstone.gatherer.cdm.CollectionMetaManager
544 * @see org.greenstone.gatherer.cdm.FormatManager
545 * @see org.greenstone.gatherer.cdm.LanguageManager
546 * @see org.greenstone.gatherer.cdm.MetadataSetView
547 * @see org.greenstone.gatherer.cdm.SubcollectionManager
548 * @see org.greenstone.gatherer.cdm.TranslationView
549 * @see org.greenstone.gatherer.cdm.PlugInManager
550 */
551 public void valueChanged(TreeSelectionEvent event) {
552 if(!tree.isSelectionEmpty()) {
553 TreePath path = tree.getSelectionPath();
554
555 DesignNode node = (DesignNode)path.getLastPathComponent();
556 String type = (String)node.getUserObject();
557 Gatherer.g_man.wait(true);
558
559 // type has the value DOWNLOAD.MODE.<downloader>Download,
560 // mode should then be of the form <downloader>
561 mode = type.replace("DOWNLOAD.MODE.", "").replace("Download", "");
562 generateOptions(options_pane,(Download)download_map.get(mode));
563
564 tree.setSelectionPath(path);
565 previous_path = path;
566 repaint();
567
568 Gatherer.g_man.wait(false);
569 }
570 }
571 }
572
573 private class ClearCacheListener
574 implements ActionListener {
575 public void actionPerformed(ActionEvent event) {
576 // Retrieve the cache folder and delete it.
577 Utility.delete(Utility.getCacheDir());
578 // ...and refresh the node in the workspace tree to show it's all gone
579 Gatherer.g_man.refreshWorkspaceTree(WorkspaceTree.DOWNLOADED_FILES_CHANGED);
580 }
581 }
582
583 private class DownloadButtonListener
584 implements ActionListener {
585 public void actionPerformed(ActionEvent event) {
586
587 if(checkURL(true) && checkProxy() == true) {
588
589 // Proxy settings are now set. Check that the url is not a redirect, else get
590 // redirect url (we do this step in order to avoid some unintuitive behaviour from wget)
591 Download current_download = (Download)download_map.get(mode);
592 Argument arg_url = current_download.getArgument("url");
593 if(arg_url != null) { // it's null for z3950 and possibly for other downloaders
594 String url_str = arg_url.getValue();
595 String redirect_url_str = getRedirectURL(url_str);
596
597 // only update the Argument and its GUI ArgumentControl if the URL
598 // has in fact changed
599 if(!url_str.equals(redirect_url_str)) {
600 arg_url.setValue(redirect_url_str);
601 updateArgument(arg_url, redirect_url_str);
602 }
603 }
604 getter.newDownloadJob((Download)download_map.get(mode) ,mode,proxy_url);
605 }
606 }
607 }
608
609 /**
610 * The Java code here will retrieve the page at the given url. If the response code is
611 * a redirect, it will get the redirect url so that wget may be called with the proper url.
612 * This preprocessing of the URL is necessary because:
613 * Wget does not behave the way the browser does when faced with urls of the form
614 * http://www.englishhistory.net/tudor/citizens and if that page does not exist.
615 * The directory listing with a slash at the end (http://www.englishhistory.net/tudor/citizens/)
616 * does exist, however. In order to prevent wget from assuming that the root URL
617 * to traverse is http://www.englishhistory.net/tudor/ instead of the intended
618 * http://www.englishhistory.net/tudor/citizens/, we need give wget the redirect location
619 * that's returned when we initially make a request for http://www.englishhistory.net/tudor/citizens
620 * The proper url is sent back in the Location header, allowing us to bypass wget's
621 * unexpected behaviour.
622 * This method ensures that urls like http://www.nzdl.org/niupepa also continue to work:
623 * there is no http://www.nzdl.org/niupepa/ page, because this url actually redirects to an
624 * entirely different URL.
625 * @return the redirect url for the given url if any redirection is involved, or the
626 * url_str.
627 */
628 private String getRedirectURL(String url_str) {
629 HttpURLConnection connection = null;
630 if(url_str.startsWith("http:")) { // only test http urls
631 try {
632 URL url = new URL(url_str);
633 connection = (HttpURLConnection)url.openConnection(); //new HttpURLConnection(url);
634 // don't let it automatically follow redirects, since we want to
635 // find out whether we are dealing with redirects in the first place
636 connection.setInstanceFollowRedirects(false);
637
638 // now check for whether we get a redirect response
639 // HTTP Codes 3xx are redirects, http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
640 int responseCode = connection.getResponseCode();
641 if(responseCode >= 300 && responseCode < 400) {
642 String responseMsg = connection.getResponseMessage();
643
644 // Get the Location header since this specifies the new location of the resource
645 String location = connection.getHeaderField("Location");
646
647 // this becomes the url that wget should download from
648 url_str = location.trim();
649 }
650
651 connection.disconnect();
652 } catch(Exception e) {
653 if(connection != null) {
654 connection.disconnect();
655 }
656 System.err.println("Checking redirection. Tried to connect to "
657 + url_str + ",\nbut got exception: " + e);
658 }
659 }
660
661 return url_str;
662 }
663
664
665 /** For a string-based Argument whose value has changed, this method
666 * updates the GUI ArgumentControl's value correspondingly. */
667 private void updateArgument(Argument arg, String value) {
668 for(int i = 0; i < options_pane.getComponentCount(); i++) {
669 Component component = options_pane.getComponent(i);
670 if(component instanceof ArgumentControl) {
671 ArgumentControl control = (ArgumentControl)component;
672 if(control.getArgument() == arg) {
673 control.setValue(value);
674 control.repaint();
675 }
676 }
677 }
678 }
679
680 private boolean checkURL(boolean checkRequired){
681
682 if (!updateArguments(checkRequired)){
683 return false;
684 }
685
686 Download current_download = (Download)download_map.get(mode);
687 Argument arg_url = current_download.getArgument("url");
688
689 if (arg_url == null) return true;
690
691 String url_str = arg_url.getValue();
692 URL url = null;
693 try {
694 url = new URL(url_str);
695 }
696 catch(MalformedURLException error) {
697 JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("Mirroring.Invalid_URL"), Dictionary.get("Mirroring.Invalid_URL_Title"), JOptionPane.ERROR_MESSAGE);
698 return false;
699 }
700
701 return true;
702 }
703
704
705 private boolean checkProxy(){
706
707 proxy_url = null;
708
709 Download current_download = (Download)download_map.get(mode);
710
711 Argument arg = current_download.getArgument("proxy_on");
712
713 if (arg == null) return true;
714
715 // Determine if we have to use a proxy.
716 if(Configuration.get("general.use_proxy", true)) {
717
718 String proxy_host = Configuration.getString("general.proxy_host", true);
719 String proxy_port = Configuration.getString("general.proxy_port", true);
720 // Find out whether the user has already authenticated themselves
721 String user_pass = "";
722 String address = proxy_host + ":" + proxy_port;
723
724 int count = 0;
725 // Only for wget, need to avoid a second automatic authentication popup (first asks
726 // the proxy authentication for wget, and the second will ask the same for the realm)
727 // Once the authentication has been reused, it will set the GAuthenticator state back to REGULAR
728 GAuthenticator.setMode(GAuthenticator.DOWNLOAD);
729 while(count < 3 && (user_pass = (String) GAuthenticator.authentications.get(address)) == null) {
730 Authenticator.requestPasswordAuthentication(proxy_host, null, Integer.parseInt(proxy_port), "http://", Dictionary.get("WGet.Prompt"), "HTTP");
731 count++;
732 }
733 if(count >= 3) {
734 return false;
735 }
736
737 if(user_pass.indexOf("@") != -1) {
738
739 // Write the use proxy command - we don't do this anymore, instead we set environment variables - hopefully these can't be spied on like the following can (using ps) - actually the environment stuff didn't work for windows, so lets go back to this
740 if (Utility.isWindows()) {
741
742 arg.setValue("true");
743 arg.setAssigned(true);
744
745 arg = current_download.getArgument("proxy_host");
746 arg.setValue(proxy_host);
747 arg.setAssigned(true);
748
749 arg = current_download.getArgument("proxy_port");
750 arg.setValue(proxy_port);
751 arg.setAssigned(true);
752
753 arg = current_download.getArgument("user_name");
754 arg.setValue(user_pass.substring(0, user_pass.indexOf("@")));
755 arg.setAssigned(true);
756
757 arg = current_download.getArgument("user_password");
758 arg.setValue(user_pass.substring(user_pass.indexOf("@") + 1));
759 arg.setAssigned(true);
760 }
761 else{
762 String user_name = user_pass.substring(0, user_pass.indexOf("@"));
763 String user_pwd = user_pass.substring(user_pass.indexOf("@") + 1);
764 proxy_url = user_name+":"+user_pwd+"@"+proxy_host+":"+proxy_port+"/";
765
766 }
767
768 return true;
769 }
770 else{
771 return false;
772 }
773
774 }
775
776 return true;
777 }
778
779 /*
780 private class PreferencesButtonActionListener
781 implements ActionListener {
782 public void actionPerformed(ActionEvent event) {
783 new Preferences(Preferences.CONNECTION_PREFS);
784 }
785 }*/
786
787 private class InformationButtonActionListener
788 implements ActionListener {
789 public void actionPerformed(ActionEvent event) {
790 //turn off the check for find argument
791 Download current_download = (Download)download_map.get(mode);
792
793 if (!checkProxy() || !checkURL(false) )return;
794
795
796 if(server_info != null) {
797 server_info.dispose();
798 }
799
800
801 Argument arg_url = current_download.getArgument("url");
802 String str_url = "";
803
804 if( arg_url!= null && arg_url.isAssigned()) {
805 str_url = arg_url.getValue();
806 }
807
808
809 server_info = new ServerInfoDialog(str_url ,proxy_url, mode,(Download)download_map.get(mode));
810
811 }
812 }
813
814 private class PreferencesButtonActionListener
815 implements ActionListener {
816 public void actionPerformed(ActionEvent event) {
817 new Preferences(Preferences.CONNECTION_PREFS);
818 }
819 }
820}
Note: See TracBrowser for help on using the repository browser.