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 | */
|
---|
37 | package org.greenstone.gatherer.gui;
|
---|
38 |
|
---|
39 | import java.awt.*;
|
---|
40 | import java.awt.event.*;
|
---|
41 | import java.io.File;
|
---|
42 | import java.net.*;
|
---|
43 | import java.util.*;
|
---|
44 | import javax.swing.*;
|
---|
45 | import javax.swing.border.*;
|
---|
46 | import javax.swing.event.*;
|
---|
47 | import javax.swing.tree.*;
|
---|
48 | import org.greenstone.gatherer.Dictionary;
|
---|
49 | import org.greenstone.gatherer.Gatherer;
|
---|
50 | import org.greenstone.gatherer.WGet;
|
---|
51 | import org.greenstone.gatherer.file.FileNode;
|
---|
52 | import org.greenstone.gatherer.gui.GLIButton;
|
---|
53 | import org.greenstone.gatherer.util.Utility;
|
---|
54 |
|
---|
55 | /**
|
---|
56 | * @author John Thompson, Greenstone Digital Library, University of Waikato
|
---|
57 | * @version 2.1
|
---|
58 | */
|
---|
59 | public class MirrorPane
|
---|
60 | extends JPanel {
|
---|
61 |
|
---|
62 | private JButton download_button;
|
---|
63 | private JCheckBox higher_checkbox;
|
---|
64 | private JCheckBox requisite_checkbox;
|
---|
65 | private JCheckBox same_host_checkbox;
|
---|
66 | private JScrollPane list_scroll;
|
---|
67 | private JComboBox depth_combobox;
|
---|
68 | private JTextField url_textfield;
|
---|
69 | private Vector depth_model;
|
---|
70 | private WGet getter;
|
---|
71 |
|
---|
72 | public MirrorPane() {
|
---|
73 | super();
|
---|
74 | // Create a new wget thread
|
---|
75 | getter = new WGet();
|
---|
76 | getter.start();
|
---|
77 | // And retrieve its list of pending jobs
|
---|
78 | list_scroll = getter.getJobList();
|
---|
79 |
|
---|
80 | // Create
|
---|
81 | JPanel edit_pane = new JPanel();
|
---|
82 | JPanel details_pane = new JPanel();
|
---|
83 |
|
---|
84 | JPanel url_pane = new JPanel();
|
---|
85 | JLabel url_label = new JLabel();
|
---|
86 | url_label.setPreferredSize(Utility.LABEL_SIZE);
|
---|
87 | Dictionary.registerText(url_label, "Mirroring.Source_URL");
|
---|
88 | url_textfield = new JTextField();
|
---|
89 | Dictionary.registerTooltip(url_textfield, "Mirroring.Source_URL_Tooltip");
|
---|
90 |
|
---|
91 | depth_model = new Vector();
|
---|
92 | /* @todo - add to dictionary */
|
---|
93 | depth_model.add(new DepthEntry(0, "0 (this page only)"));
|
---|
94 | /* @todo - add to dictionary */
|
---|
95 | depth_model.add(new DepthEntry(1, "1"));
|
---|
96 | /* @todo - add to dictionary */
|
---|
97 | depth_model.add(new DepthEntry(2, "2"));
|
---|
98 | /* @todo - add to dictionary */
|
---|
99 | depth_model.add(new DepthEntry(3, "3"));
|
---|
100 | /* @todo - add to dictionary */
|
---|
101 | depth_model.add(new DepthEntry(4, "4"));
|
---|
102 | /* @todo - add to dictionary */
|
---|
103 | depth_model.add(new DepthEntry(5, "5"));
|
---|
104 | /* @todo - add to dictionary */
|
---|
105 | depth_model.add(new DepthEntry(-1, "Unlimited"));
|
---|
106 | JPanel depth_pane = new JPanel();
|
---|
107 | JLabel depth_label = new JLabel();
|
---|
108 | Dictionary.registerText(depth_label, "Mirroring.Download_Depth");
|
---|
109 | depth_combobox = new JComboBox(depth_model);
|
---|
110 | Dictionary.registerTooltip(depth_combobox, "Mirroring.Download_Depth_Tooltip");
|
---|
111 |
|
---|
112 | requisite_checkbox = new JCheckBox();
|
---|
113 | Dictionary.registerText(requisite_checkbox, "Mirroring.Download_Hidden");
|
---|
114 |
|
---|
115 | higher_checkbox = new JCheckBox();
|
---|
116 | Dictionary.registerText(higher_checkbox, "Mirroring.Higher_Directories");
|
---|
117 |
|
---|
118 | same_host_checkbox = new JCheckBox();
|
---|
119 | same_host_checkbox.setSelected(true);
|
---|
120 | Dictionary.registerText(same_host_checkbox, "Mirroring.Same_Host");
|
---|
121 |
|
---|
122 | /* @todo - add to dictionary */
|
---|
123 | JLabel further_label = new JLabel("For further options see File->Preferences->Connection");
|
---|
124 |
|
---|
125 | JPanel button_pane = new JPanel();
|
---|
126 | download_button = new GLIButton();
|
---|
127 | download_button.setMnemonic(KeyEvent.VK_ENTER);
|
---|
128 | Dictionary.registerBoth(download_button, "Mirroring.Download", "Mirroring.Download_Tooltip");
|
---|
129 |
|
---|
130 | // Connect
|
---|
131 | download_button.addActionListener(new DownloadButtonListener());
|
---|
132 |
|
---|
133 | // Layout
|
---|
134 | url_pane.setLayout(new BorderLayout());
|
---|
135 | url_pane.add(url_label, BorderLayout.WEST);
|
---|
136 | url_pane.add(url_textfield, BorderLayout.CENTER);
|
---|
137 |
|
---|
138 | depth_pane.setLayout(new GridLayout(1,3));
|
---|
139 | depth_pane.add(depth_label);
|
---|
140 | depth_pane.add(new JPanel());
|
---|
141 | depth_pane.add(depth_combobox);
|
---|
142 |
|
---|
143 | details_pane.setLayout(new GridLayout(6,1,0,5));
|
---|
144 | details_pane.add(url_pane);
|
---|
145 | details_pane.add(depth_pane);
|
---|
146 | details_pane.add(requisite_checkbox);
|
---|
147 | details_pane.add(higher_checkbox);
|
---|
148 | details_pane.add(same_host_checkbox);
|
---|
149 | details_pane.add(further_label);
|
---|
150 |
|
---|
151 | button_pane.setLayout(new GridLayout(1,3));
|
---|
152 | button_pane.add(new JPanel());
|
---|
153 | button_pane.add(new JPanel());
|
---|
154 | button_pane.add(download_button);
|
---|
155 |
|
---|
156 | edit_pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(2,0,0,0), BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder(Dictionary.get("Mirroring.Download_Controls")), BorderFactory.createEmptyBorder(2,2,2,2))));
|
---|
157 | edit_pane.setLayout(new BorderLayout());
|
---|
158 | edit_pane.add(details_pane, BorderLayout.CENTER);
|
---|
159 | edit_pane.add(button_pane, BorderLayout.SOUTH);
|
---|
160 |
|
---|
161 | setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
|
---|
162 | setLayout(new BorderLayout());
|
---|
163 | add(edit_pane, BorderLayout.NORTH);
|
---|
164 | add(list_scroll, BorderLayout.CENTER);
|
---|
165 | }
|
---|
166 |
|
---|
167 | public void collectionChanged(boolean ready) {
|
---|
168 | }
|
---|
169 |
|
---|
170 | public void setURL(String url) {
|
---|
171 | url_textfield.setText(url);
|
---|
172 | }
|
---|
173 |
|
---|
174 |
|
---|
175 | static public FileNode getWebCacheMapping()
|
---|
176 | {
|
---|
177 | if (Gatherer.config.get("workflow.mirror", false) && Gatherer.c_man.ready()) {
|
---|
178 | /* @todo - add to dictionary */
|
---|
179 | return new FileNode(Utility.getCacheDir(), "Mirror Cache");
|
---|
180 | }
|
---|
181 | return null;
|
---|
182 | }
|
---|
183 |
|
---|
184 | /** A DepthEntry contains a depth value, as an int, and a representitive text string. This allows for a more meaningful appearance than '0' for instance. */
|
---|
185 | private class DepthEntry
|
---|
186 | implements Comparable {
|
---|
187 | private int value;
|
---|
188 | private String text;
|
---|
189 | /** Default constructor.
|
---|
190 | * @param value the depth value as an int
|
---|
191 | * @param text how this entry show represent itself as a String
|
---|
192 | */
|
---|
193 | public DepthEntry(int value, String text) {
|
---|
194 | this.text = text;
|
---|
195 | this.value = value;
|
---|
196 | }
|
---|
197 | /** Determines the natural ordering of this DepthEntry and some other object
|
---|
198 | * @param object the Object to test for ordering
|
---|
199 | * @return >0 if the object is before this one, 0 if they are equal, or <0 if the object is after this one
|
---|
200 | */
|
---|
201 | public int compareTo(Object object) {
|
---|
202 | // If the object is a DepthEntry then this is easy pesy.
|
---|
203 | if(object instanceof DepthEntry) {
|
---|
204 | int target_value = ((DepthEntry) object).getValue();
|
---|
205 | return value - target_value;
|
---|
206 | }
|
---|
207 | // If the object is a String, then we should try parsing an int from it
|
---|
208 | if(object instanceof String) {
|
---|
209 | try {
|
---|
210 | int target_value = Integer.parseInt((String)object);
|
---|
211 | return value - target_value;
|
---|
212 | }
|
---|
213 | catch(Exception exception) {
|
---|
214 | }
|
---|
215 | }
|
---|
216 | // Otherwise we'll try a string comparison between our text and the toString of the object
|
---|
217 | return text.compareTo(object.toString());
|
---|
218 | }
|
---|
219 |
|
---|
220 | /** Determine if this DepthEntry is equal to some other object. Given that there is significant processing involved we push the resposiblility for this onto compareTo, so we only have the complex code once.
|
---|
221 | * @param object the Object to test for equality
|
---|
222 | * @return true if the object is equal to this depth entry, false otherwise
|
---|
223 | */
|
---|
224 | public boolean equals(Object object) {
|
---|
225 | return (compareTo(object) == 0);
|
---|
226 | }
|
---|
227 |
|
---|
228 | public int getValue() {
|
---|
229 | return value;
|
---|
230 | }
|
---|
231 |
|
---|
232 | public String toString() {
|
---|
233 | return text;
|
---|
234 | }
|
---|
235 | }
|
---|
236 |
|
---|
237 | private class DownloadButtonListener
|
---|
238 | implements ActionListener {
|
---|
239 |
|
---|
240 | public void actionPerformed(ActionEvent event) {
|
---|
241 | // Retrieve the current url and confirm it is valid
|
---|
242 | String url_str = url_textfield.getText();
|
---|
243 | URL url = null;
|
---|
244 | try {
|
---|
245 | url = new URL(url_str);
|
---|
246 | }
|
---|
247 | catch(MalformedURLException error) {
|
---|
248 | JOptionPane.showMessageDialog(Gatherer.g_man, Dictionary.get("Mirroring.Invalid_URL"), Dictionary.get("Mirroring.Invalid_URL_Title"), JOptionPane.ERROR_MESSAGE);
|
---|
249 | }
|
---|
250 |
|
---|
251 | // Otherwise construct a new download job
|
---|
252 | Object depth_object = depth_combobox.getSelectedItem();
|
---|
253 | int depth_value = 0;
|
---|
254 | if(depth_object instanceof DepthEntry) {
|
---|
255 | depth_value = ((DepthEntry)depth_object).getValue();
|
---|
256 | }
|
---|
257 | else if(depth_object instanceof String) {
|
---|
258 | String depth_string = (String) depth_object;
|
---|
259 | try {
|
---|
260 | depth_value = Integer.parseInt(depth_string);
|
---|
261 | // Create a new entry for the purposes of comparison, and if needs be, addition
|
---|
262 | DepthEntry new_entry = new DepthEntry(depth_value, depth_string);
|
---|
263 | // Try to select the correct item from the combobox
|
---|
264 | depth_combobox.setSelectedItem(null);
|
---|
265 | depth_combobox.setSelectedItem(new_entry);
|
---|
266 | // We can see if that worked, and if it didn't add the entry
|
---|
267 | if(depth_combobox.getSelectedItem() == null) {
|
---|
268 | depth_combobox.addItem(new_entry);
|
---|
269 | depth_combobox.setSelectedItem(new_entry);
|
---|
270 | }
|
---|
271 | new_entry = null;
|
---|
272 | }
|
---|
273 | catch(Exception exception) {
|
---|
274 | /* @todo - add to dictionary */
|
---|
275 | JOptionPane.showMessageDialog(Gatherer.g_man, "The depth value you have entered is not valid.\nPlease choose an item from the list, or type in\na number.", "Invalid Depth", JOptionPane.ERROR_MESSAGE);
|
---|
276 | return;
|
---|
277 | }
|
---|
278 | depth_string = null;
|
---|
279 | }
|
---|
280 | depth_object = null;
|
---|
281 |
|
---|
282 | File destination_file = Utility.getCacheDir();
|
---|
283 | destination_file.mkdirs(); // If they aren't already
|
---|
284 | String destination_filename = destination_file.getAbsolutePath();
|
---|
285 | if(!destination_filename.endsWith(File.separator)) {
|
---|
286 | destination_filename = destination_filename + File.separator;
|
---|
287 | }
|
---|
288 |
|
---|
289 | if(url != null) {
|
---|
290 | getter.newJob(!higher_checkbox.isSelected(), !same_host_checkbox.isSelected(), requisite_checkbox.isSelected(), url, depth_value, destination_filename);
|
---|
291 | }
|
---|
292 | }
|
---|
293 | }
|
---|
294 | }
|
---|