source: josm/trunk/src/org/openstreetmap/josm/gui/io/DownloadFileTask.java@ 6248

Last change on this file since 6248 was 6248, checked in by Don-vip, 11 years ago

Rework console output:

  • new log level "error"
  • Replace nearly all calls to system.out and system.err to Main.(error|warn|info|debug)
  • Remove some unnecessary debug output
  • Some messages are modified (removal of "Info", "Warning", "Error" from the message itself -> notable i18n impact but limited to console error messages not seen by the majority of users, so that's ok)
File size: 6.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Component;
7import java.io.BufferedOutputStream;
8import java.io.File;
9import java.io.FileOutputStream;
10import java.io.IOException;
11import java.io.InputStream;
12import java.io.OutputStream;
13import java.net.HttpURLConnection;
14import java.net.MalformedURLException;
15import java.net.URL;
16import java.util.Enumeration;
17import java.util.zip.ZipEntry;
18import java.util.zip.ZipFile;
19
20import org.openstreetmap.josm.Main;
21import org.openstreetmap.josm.gui.PleaseWaitDialog;
22import org.openstreetmap.josm.gui.PleaseWaitRunnable;
23import org.openstreetmap.josm.tools.Utils;
24import org.xml.sax.SAXException;
25
26/**
27 * Asynchronous task for downloading and unpacking arbitrary file lists
28 * Shows progress bar when downloading
29 */
30public class DownloadFileTask extends PleaseWaitRunnable{
31 private final String address;
32 private final File file;
33 private final boolean mkdir;
34 private final boolean unpack;
35
36 /**
37 * Creates the download task
38 *
39 * @param parent the parent component relative to which the {@link PleaseWaitDialog} is displayed
40 * @param address the URL to download
41 * @param file The destination file
42 * @param mkdir {@code true} if the destination directory must be created, {@code false} otherwise
43 * @param unpack {@code true} if zip archives must be unpacked recursively, {@code false} otherwise
44 * @throws IllegalArgumentException if {@code parent} is null
45 */
46 public DownloadFileTask(Component parent, String address, File file, boolean mkdir, boolean unpack) {
47 super(parent, tr("Downloading file"), false);
48 this.address = address;
49 this.file = file;
50 this.mkdir = mkdir;
51 this.unpack = unpack;
52 }
53
54 private static class DownloadException extends Exception {
55 public DownloadException(String msg) {
56 super(msg);
57 }
58 }
59
60 private boolean canceled;
61 private HttpURLConnection downloadConnection;
62
63 private synchronized void closeConnectionIfNeeded() {
64 if (downloadConnection != null) {
65 downloadConnection.disconnect();
66 }
67 downloadConnection = null;
68 }
69
70
71 @Override
72 protected void cancel() {
73 this.canceled = true;
74 closeConnectionIfNeeded();
75 }
76
77 @Override
78 protected void finish() {}
79
80 /**
81 * Performs download.
82 * @throws DownloadException if the URL is invalid or if any I/O error occurs.
83 */
84 public void download() throws DownloadException {
85 OutputStream out = null;
86 InputStream in = null;
87 try {
88 if (mkdir) {
89 File newDir = file.getParentFile();
90 if (!newDir.exists()) {
91 newDir.mkdirs();
92 }
93 }
94
95 URL url = new URL(address);
96 int size;
97 synchronized(this) {
98 downloadConnection = Utils.openHttpConnection(url);
99 downloadConnection.setRequestProperty("Cache-Control", "no-cache");
100 downloadConnection.connect();
101 size = downloadConnection.getContentLength();
102 }
103
104 progressMonitor.setTicksCount(100);
105 progressMonitor.subTask(tr("Downloading File {0}: {1} bytes...", file.getName(),size));
106
107 in = downloadConnection.getInputStream();
108 out = new FileOutputStream(file);
109 byte[] buffer = new byte[32768];
110 int count=0;
111 int p1=0, p2=0;
112 for (int read = in.read(buffer); read != -1; read = in.read(buffer)) {
113 out.write(buffer, 0, read);
114 count+=read;
115 if (canceled) break;
116 p2 = 100 * count / size;
117 if (p2!=p1) {
118 progressMonitor.setTicks(p2);
119 p1=p2;
120 }
121 }
122 Utils.close(out);
123 if (!canceled) {
124 Main.info(tr("Download finished"));
125 if (unpack) {
126 Main.info(tr("Unpacking {0} into {1}", file.getAbsolutePath(), file.getParent()));
127 unzipFileRecursively(file, file.getParent());
128 file.delete();
129 }
130 }
131 } catch(MalformedURLException e) {
132 String msg = tr("Cannot download file ''{0}''. Its download link ''{1}'' is not a valid URL. Skipping download.", file.getName(), address);
133 Main.warn(msg);
134 throw new DownloadException(msg);
135 } catch (IOException e) {
136 if (canceled)
137 return;
138 throw new DownloadException(e.getMessage());
139 } finally {
140 closeConnectionIfNeeded();
141 Utils.close(out);
142 }
143 }
144
145 @Override
146 protected void realRun() throws SAXException, IOException {
147 if (canceled) return;
148 try {
149 download();
150 } catch(DownloadException e) {
151 e.printStackTrace();
152 }
153 }
154
155 /**
156 * Replies true if the task was canceled by the user
157 *
158 * @return {@code true} if the task was canceled by the user, {@code false} otherwise
159 */
160 public boolean isCanceled() {
161 return canceled;
162 }
163
164 /**
165 * Recursive unzipping function
166 * TODO: May be placed somewhere else - Tools.Utils?
167 * @param file
168 * @param dir
169 * @throws IOException
170 */
171 public static void unzipFileRecursively(File file, String dir) throws IOException {
172 OutputStream os = null;
173 InputStream is = null;
174 ZipFile zf = null;
175 try {
176 zf = new ZipFile(file);
177 Enumeration<?> es = zf.entries();
178 ZipEntry ze;
179 while (es.hasMoreElements()) {
180 ze = (ZipEntry) es.nextElement();
181 File newFile = new File(dir, ze.getName());
182 if (ze.isDirectory()) {
183 newFile.mkdirs();
184 } else {
185 is = zf.getInputStream(ze);
186 os = new BufferedOutputStream(new FileOutputStream(newFile));
187 byte[] buffer = new byte[8192];
188 int read;
189 while ((read = is.read(buffer)) != -1) {
190 os.write(buffer, 0, read);
191 }
192 Utils.close(os);
193 Utils.close(is);
194 }
195 }
196 } finally {
197 Utils.close(zf);
198 }
199 }
200}
201
Note: See TracBrowser for help on using the repository browser.