source: AE/installer2/src/net/oni2/aeinstaller/backend/network/FileDownloader.java@ 603

Last change on this file since 603 was 591, checked in by alloc, 12 years ago

AEI2-import

File size: 5.3 KB
Line 
1package net.oni2.aeinstaller.backend.network;
2
3import java.io.BufferedInputStream;
4import java.io.File;
5import java.io.FileNotFoundException;
6import java.io.IOException;
7import java.io.RandomAccessFile;
8import java.net.URL;
9import java.net.URLConnection;
10import java.util.HashSet;
11
12/**
13 * @author Christian Illy
14 */
15public class FileDownloader implements Runnable {
16 /**
17 * @author Christian Illy
18 */
19 public enum EState {
20 /**
21 * Downloader initialized but not started
22 */
23 INIT,
24 /**
25 * Download running
26 */
27 RUNNING,
28 /**
29 * Download suspended
30 */
31 PAUSED,
32 /**
33 * Download interrupted
34 */
35 INTERRUPTED,
36 /**
37 * Download finished successfully
38 */
39 FINISHED,
40 /**
41 * Aborted because of an error
42 */
43 ERROR
44 };
45
46 private HashSet<FileDownloadListener> listeners = new HashSet<FileDownloadListener>();
47 private Thread t = null;
48 private URL url = null;
49 private File target = null;
50 private int size = -1;
51 private int downloaded = 0;
52
53 private EState state = EState.INIT;
54
55 /**
56 * @param url
57 * URL of file to download
58 * @param target
59 * Path of target file to save to
60 * @throws IOException
61 * If url could not be opened
62 */
63 public FileDownloader(String url, String target) throws IOException {
64 this.url = new URL(url);
65 this.target = new File(target);
66
67 URLConnection connection = this.url.openConnection();
68 connection.connect();
69 size = connection.getContentLength();
70 }
71
72 /**
73 * @param listener
74 * Listener to add
75 */
76 public void addListener(FileDownloadListener listener) {
77 listeners.add(listener);
78 }
79
80 /**
81 * @param listener
82 * Listener to remove
83 */
84 public void removeListener(FileDownloadListener listener) {
85 listeners.remove(listener);
86 }
87
88 /**
89 * Start the download process
90 */
91 public synchronized void start() {
92 if (t == null) {
93 t = new Thread(this);
94 t.start();
95 state = EState.RUNNING;
96 }
97 }
98
99 /**
100 * @param suspend
101 * Suspend or resume
102 */
103 public synchronized void suspend(boolean suspend) {
104 if ((state == EState.RUNNING) || (state == EState.PAUSED)) {
105 if (suspend)
106 state = EState.PAUSED;
107 else
108 state = EState.RUNNING;
109 }
110 }
111
112 /**
113 * Stop (abort) download
114 */
115 public synchronized void stop() {
116 state = EState.INTERRUPTED;
117 try {
118 t.join();
119 } catch (InterruptedException e) {
120 // TODO Auto-generated catch block
121 e.printStackTrace();
122 }
123 updateStatus(0, 1);
124 t = null;
125 if (target.exists())
126 target.delete();
127 }
128
129 private synchronized void updateStatus(int current, int total) {
130 downloaded = current;
131 for (FileDownloadListener l : listeners) {
132 l.statusUpdate(this, state, current, total);
133 }
134 }
135
136 @Override
137 public void run() {
138 int downloaded = 0;
139 int fileLength = Integer.MAX_VALUE;
140 String strLastModified = null;
141 String strEtag = null;
142 RandomAccessFile outFile = null;
143 try {
144 outFile = new RandomAccessFile(target, "rw");
145 } catch (FileNotFoundException e1) {
146 // TODO Auto-generated catch block
147 e1.printStackTrace();
148 state = EState.ERROR;
149 return;
150 }
151
152 while (downloaded < fileLength) {
153 switch (state) {
154 case ERROR:
155 updateStatus(downloaded, fileLength);
156 return;
157 case PAUSED:
158 try {
159 Thread.sleep(100);
160 } catch (InterruptedException e) {
161 e.printStackTrace();
162 }
163 break;
164 case INTERRUPTED:
165 return;
166 case RUNNING:
167 BufferedInputStream input = null;
168 try {
169 URLConnection connection = url.openConnection();
170 if (downloaded == 0) {
171 connection.connect();
172 strLastModified = connection
173 .getHeaderField("Last-Modified");
174 strEtag = connection.getHeaderField("ETag");
175 fileLength = connection.getContentLength();
176 } else {
177 connection.setRequestProperty("Range", "bytes="
178 + downloaded + "-");
179 if (strEtag != null)
180 connection.setRequestProperty("If-Range",
181 strEtag);
182 else
183 connection.setRequestProperty("If-Range",
184 strLastModified);
185 connection.connect();
186 }
187
188 // Setup streams and buffers.
189 input = new BufferedInputStream(
190 connection.getInputStream(), 8192);
191 if (downloaded > 0)
192 outFile.seek(downloaded);
193 byte data[] = new byte[1024];
194
195 // Download file.
196 int dataRead = 0;
197 int i = 0;
198 while (((dataRead = input.read(data, 0, 1024)) != -1)
199 && (state == EState.RUNNING)) {
200 outFile.write(data, 0, dataRead);
201 downloaded += dataRead;
202 if (downloaded >= fileLength)
203 break;
204
205 i++;
206 if ((i % 10) == 0)
207 updateStatus(downloaded, fileLength);
208 }
209 input.close();
210 } catch (IOException e) {
211 // TODO Auto-generated catch block
212 e.printStackTrace();
213 try {
214 if (input != null)
215 input.close();
216 } catch (IOException e2) {
217 e2.printStackTrace();
218 }
219 }
220 break;
221 default:
222 break;
223 }
224 }
225
226 try {
227 // Close streams.
228 outFile.close();
229 } catch (IOException e) {
230 e.printStackTrace();
231 }
232
233 state = EState.FINISHED;
234 updateStatus(downloaded, fileLength);
235 }
236
237 /**
238 * @return the target
239 */
240 public File getTarget() {
241 return target;
242 }
243
244 /**
245 * @return the size
246 */
247 public int getSize() {
248 return size;
249 }
250
251 /**
252 * @return the downloaded size
253 */
254 public int getDownloaded() {
255 return downloaded;
256 }
257
258}
Note: See TracBrowser for help on using the repository browser.