source: debug-testing/gli-ctrlC-issue/DownloadPane.java@ 31737

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

Creating a folder to add files that are in a convenient state for debugging problems we haven't resolved yet. And adding files for debugging the issue of launching GLI from DOS, but Ctrl-C being ineffective until you exit GLI, which is when the Ctrl-C finally registers.

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