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

Last change on this file since 6070 was 6070, checked in by stoecker, 11 years ago

see #8853 remove tabs, trailing spaces, windows line ends, strange characters

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