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

Last change on this file since 608 was 605, checked in by alloc, 12 years ago

AEI2:

  • Added mod download prior to installation
  • Dependency checking (needs verification)
  • Conflicts checking basis (not implemented)
  • Run Oni through AEI
File size: 5.6 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 updateStatus(downloaded, size);
97 }
98 }
99
100 /**
101 * @param suspend
102 * Suspend or resume
103 */
104 public synchronized void suspend(boolean suspend) {
105 if ((state == EState.RUNNING) || (state == EState.PAUSED)) {
106 if (suspend)
107 state = EState.PAUSED;
108 else
109 state = EState.RUNNING;
110 updateStatus(downloaded, size);
111 }
112 }
113
114 /**
115 * Stop (abort) download
116 */
117 public synchronized void stop() {
118 if (state != EState.FINISHED) {
119 state = EState.INTERRUPTED;
120 if (t != null) {
121 try {
122 t.join();
123 } catch (InterruptedException e) {
124 // TODO Auto-generated catch block
125 e.printStackTrace();
126 }
127 t = null;
128 }
129 updateStatus(0, 1);
130 if (target.exists())
131 target.delete();
132 }
133 }
134
135 private synchronized void updateStatus(int current, int total) {
136 downloaded = current;
137 for (FileDownloadListener l : listeners) {
138 l.statusUpdate(this, state, current, total);
139 }
140 }
141
142 @Override
143 public void run() {
144 int downloaded = 0;
145 int fileLength = Integer.MAX_VALUE;
146 String strLastModified = null;
147 String strEtag = null;
148 RandomAccessFile outFile = null;
149 try {
150 outFile = new RandomAccessFile(target, "rw");
151 } catch (FileNotFoundException e1) {
152 // TODO Auto-generated catch block
153 e1.printStackTrace();
154 state = EState.ERROR;
155 updateStatus(downloaded, fileLength);
156 return;
157 }
158
159 try {
160 while (downloaded < fileLength) {
161 switch (state) {
162 case ERROR:
163 updateStatus(downloaded, fileLength);
164 return;
165 case PAUSED:
166 try {
167 Thread.sleep(100);
168 } catch (InterruptedException e) {
169 e.printStackTrace();
170 }
171 break;
172 case INTERRUPTED:
173 return;
174 case RUNNING:
175 BufferedInputStream input = null;
176 try {
177 URLConnection connection = url.openConnection();
178 if (downloaded == 0) {
179 connection.connect();
180 strLastModified = connection
181 .getHeaderField("Last-Modified");
182 strEtag = connection.getHeaderField("ETag");
183 fileLength = connection.getContentLength();
184 } else {
185 connection.setRequestProperty("Range", "bytes="
186 + downloaded + "-");
187 if (strEtag != null)
188 connection.setRequestProperty("If-Range",
189 strEtag);
190 else
191 connection.setRequestProperty("If-Range",
192 strLastModified);
193 connection.connect();
194 }
195
196 // Setup streams and buffers.
197 input = new BufferedInputStream(
198 connection.getInputStream(), 8192);
199 if (downloaded > 0)
200 outFile.seek(downloaded);
201 byte data[] = new byte[1024];
202
203 // Download file.
204 int dataRead = 0;
205 int i = 0;
206 while (((dataRead = input.read(data, 0, 1024)) != -1)
207 && (state == EState.RUNNING)) {
208 outFile.write(data, 0, dataRead);
209 downloaded += dataRead;
210 if (downloaded >= fileLength)
211 break;
212
213 i++;
214 if ((i % 50) == 0)
215 updateStatus(downloaded, fileLength);
216 }
217 input.close();
218 } catch (IOException e) {
219 // TODO Auto-generated catch block
220 e.printStackTrace();
221 try {
222 if (input != null)
223 input.close();
224 } catch (IOException e2) {
225 e2.printStackTrace();
226 }
227 }
228 break;
229 default:
230 break;
231 }
232 }
233 } finally {
234 try {
235 // Close streams.
236 outFile.close();
237 } catch (IOException e) {
238 e.printStackTrace();
239 }
240 }
241
242 state = EState.FINISHED;
243 updateStatus(downloaded, fileLength);
244 }
245
246 /**
247 * @return the target
248 */
249 public File getTarget() {
250 return target;
251 }
252
253 /**
254 * @return the size
255 */
256 public int getSize() {
257 return size;
258 }
259
260 /**
261 * @return the downloaded size
262 */
263 public int getDownloaded() {
264 return downloaded;
265 }
266
267}
Note: See TracBrowser for help on using the repository browser.