source: other-projects/FileTransfer-WebSocketPair/testGXTWithGreenstone/src/org/greenstone/gatherer/gui/DownloadPane.java@ 33053

Last change on this file since 33053 was 33053, checked in by ak19, 5 years ago

I still had some stuff of Nathan Kelly's (FileTransfer-WebSocketPair) sitting on my USB. Had already commited the Themes folder at the time, 2 years back. Not sure if he wanted this additional folder commited. But I didn't want to delete it and decided it will be better off on SVN. When we use his project, if we find we didn't need this test folder, we can remove it from svn then.

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