Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.compat / org.gvsig.compat.se / src / main / java / org / gvsig / compat / se / net / downloader / se / SEDownloader.java @ 41528

History | View | Annotate | Download (14.3 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.compat.se.net.downloader.se;
24

    
25
import java.io.File;
26
import java.io.FileNotFoundException;
27
import java.io.IOException;
28
import java.net.ConnectException;
29
import java.net.URI;
30
import java.net.URL;
31
import java.net.UnknownHostException;
32
import java.util.Hashtable;
33

    
34
import org.slf4j.Logger;
35
import org.slf4j.LoggerFactory;
36

    
37
import org.gvsig.compat.net.ICancellable;
38
import org.gvsig.compat.se.net.downloader.Downloader;
39

    
40
/**
41
 * Clase con m?todos de utilidad en el protocolo WMS
42
 *
43
 * @authors Laura D?az, jaume dominguez faus
44
 */
45
public class SEDownloader implements Downloader {
46

    
47
//    String characters;
48
    private boolean canceled;
49
    private final long latency = 500;
50
    private static int count = 0;
51
    private static Logger LOG = LoggerFactory.getLogger(SEDownloader.class);
52

    
53
    /**
54
     * Used to cancel a group of files
55
     * <b>key</b>: Group id, <b>value</b>: Boolean (true if the group has to be
56
     * canceled. Otherwise it is false)
57
     */
58
    private Hashtable canceledGroup = new Hashtable();
59
    /**
60
     * <b>key</b>: URL, <b>value</b>: path to the downloaded file.
61
     */
62
    private Hashtable cachedURItoFile;
63
    private Exception downloadException;
64
    final String tempDirectoryPath = System.getProperty("java.io.tmpdir") + "/tmp-andami";
65

    
66
    public SEDownloader() {
67
        super();
68
//        characters = "";
69
//        for (int j = 32; j <= 127; j++) {
70
//            characters += (char) j;
71
//        }
72
//        characters += "?????????????????????????????????????????????????\n\r\f\t??";
73
    }
74

    
75
    /**
76
     * Return the content of a file that has been created from a URL using the
77
     * HTTP GET protocol
78
     *
79
     * @param url The URL
80
     * @return File containing this URL's content or null if no file was found.
81
     */
82
    private File getPreviousDownloadedURL(URL url) {
83
        return getPreviousDownloaded(url);
84
    }
85

    
86
    /**
87
     * Return the content of a file that has been created from a URL using the
88
     * HTTP POST protocol
89
     *
90
     * @param url The URL
91
     * @param data The data to send on the query
92
     * @return File containing this URL's content or null if no file was found.
93
     */
94
    private File getPreviousDownloadedURL(URL url, String data) {
95
        if (data == null) {
96
            return getPreviousDownloaded(url);
97
        }
98
        return getPreviousDownloaded(url.toString() + data);
99
    }
100

    
101
    /**
102
     * Returns the content of a URL as a file from the file system.<br>
103
     * <p>
104
     * If the URL has been already downloaded in this session and notified to
105
     * the system using the static <b>Utilities.addDownloadedURL(URL)</b>
106
     * method, it can be restored faster from the file system avoiding to
107
     * download it again.
108
     * </p>
109
     *
110
     * @param url
111
     * @return File containing this URL's content or null if no file was found.
112
     */
113
    private File getPreviousDownloaded(Object theurl) {
114

    
115
        File f = null;
116
        Object thekey = null;
117
        try {
118
            if (theurl instanceof URL) {
119
                thekey = ((URL) theurl).toURI();
120
            } else {
121
                thekey = theurl;
122
            }
123
        } catch (Exception e) {
124
            LOG.info("Warning: did not check url: " + theurl, e);
125
            return null;
126
        }
127

    
128
        if (cachedURItoFile != null && cachedURItoFile.containsKey(thekey)) {
129
            String filePath = (String) cachedURItoFile.get(thekey);
130
            f = new File(filePath);
131
            if (!f.exists()) {
132
                return null;
133
            }
134
        }
135
        return f;
136
    }
137

    
138
    /**
139
     * Adds an URL to the table of downloaded files for further uses. If the URL
140
     * already exists in the table its filePath value is updated to the new one
141
     * and the old file itself is removed from the file system.
142
     *
143
     * @param url
144
     * @param filePath
145
     */
146
    public void addDownloadedURL(URL url, String filePath) {
147
        if (cachedURItoFile == null) {
148
            cachedURItoFile = new Hashtable();
149
        }
150

    
151
        URI theuri = null;
152
        try {
153
            theuri = url.toURI();
154
        } catch (Exception e) {
155
            LOG.info("Warning: did not cache bad url: " + url, e);
156
            return;
157
        }
158

    
159
        String fileName = (String) cachedURItoFile.put(theuri, filePath);
160
        //JMV: No se puede eliminar el anterior porque puede que alguien lo
161
        // este usando
162
                /*
163
         if (fileName!=null){
164
         File f = new File(fileName);
165
         if (f.exists())
166
         f.delete();
167
         }
168
         */
169
    }
170

    
171
    /**
172
     * Downloads an URL into a temporary file that is removed the next time the
173
     * tempFileManager class is called, which means the next time gvSIG is
174
     * launched.
175
     *
176
     * @param url
177
     * @param name
178
     * @return
179
     * @throws IOException
180
     * @throws ServerErrorResponseException
181
     * @throws ConnectException
182
     * @throws UnknownHostException
183
     */
184
    public synchronized File downloadFile(URL url, String name, ICancellable cancel) throws IOException, ConnectException, UnknownHostException {
185
        File f = null;
186

    
187
        if ((f = getPreviousDownloadedURL(url)) == null) {
188
            File tempDirectory = new File(tempDirectoryPath);
189
            if (!tempDirectory.exists()) {
190
                tempDirectory.mkdir();
191
            }
192

    
193
            f = new File(calculateFileName(name));
194

    
195
            if (cancel == null) {
196
                cancel = new ICancellable() {
197
                    public boolean isCanceled() {
198
                        return false;
199
                    }
200

    
201
                    public Object getID() {
202
                        return SEDownloader.class.getName();
203
                    }
204
                };
205
            }
206

    
207
            SEMonitor monitorObj = new SEMonitor(this, cancel);
208
            Thread downloader = new Thread(createDownloaderTask(this, url, null, f, cancel.getID()));
209
            Thread monitor = new Thread(monitorObj);
210

    
211
            monitor.start();
212
            downloader.start();
213
            while (!getCanceled(cancel.getID()) && downloader.isAlive()) {
214
                try {
215
                    Thread.sleep(latency);
216
                } catch (InterruptedException e) {
217
                    LOG.error("Error", e);
218
                }
219
            }
220

    
221
            try {
222
                monitorObj.setFinish(true);
223
                monitor.join();
224
                downloader.join();
225
            } catch (InterruptedException e1) {
226
                LOG.warn(e1.getMessage());
227
            }
228
            downloader = null;
229
            monitor = null;
230

    
231
            if (getCanceled(cancel.getID())) {
232
                return null;
233
            }
234
            downloader = null;
235
            monitor = null;
236
            if (this.downloadException != null) {
237
                Exception e = this.downloadException;
238
                if (e instanceof FileNotFoundException) {
239
                    throw (IOException) e;
240
                } else if (e instanceof IOException) {
241
                    throw (IOException) e;
242
                } else if (e instanceof ConnectException) {
243
                    throw (ConnectException) e;
244
                } else if (e instanceof UnknownHostException) {
245
                    throw (UnknownHostException) e;
246
                }
247
            }
248
        } else {
249
            LOG.info(url.toString() + " cached at '" + f.getAbsolutePath() + "'");
250
        }
251

    
252
        return f;
253
    }
254

    
255
    private String calculateFileName(String name) {
256
        count++;
257
        int index = name.lastIndexOf(".");
258
        if (index > 0) {
259
            return tempDirectoryPath + "/" + name.substring(0, index) + System.currentTimeMillis() + count
260
                    + name.substring(index, name.length());
261
        }
262
        return tempDirectoryPath + "/" + name + System.currentTimeMillis() + count;
263
    }
264

    
265
    /**
266
     * Downloads a URL using the HTTP Post protocol
267
     *
268
     * @param url The server URL
269
     * @param data The data to send in the request
270
     * @param name A common name for all the retrieved files
271
     * @param cancel Used to cancel the downloads
272
     * @return The retrieved file
273
     * @throws IOException
274
     * @throws ConnectException
275
     * @throws UnknownHostException
276
     */
277
    public synchronized File downloadFile(URL url, String data, String name, ICancellable cancel) throws IOException, ConnectException, UnknownHostException {
278
        File f = null;
279

    
280
        if ((f = getPreviousDownloadedURL(url, data)) == null) {
281
            File tempDirectory = new File(tempDirectoryPath);
282
            if (!tempDirectory.exists()) {
283
                tempDirectory.mkdir();
284
            }
285

    
286
            f = new File(calculateFileName(name));
287

    
288
            if (cancel == null) {
289
                cancel = new ICancellable() {
290
                    public boolean isCanceled() {
291
                        return false;
292
                    }
293

    
294
                    public Object getID() {
295
                        return SEDownloader.class.getName();
296
                    }
297
                };
298
            }
299
            SEMonitor monitorObj = new SEMonitor(this, cancel);
300
            Thread downloader = new Thread(createDownloaderTask(this, url, data, f, cancel.getID()));
301
            Thread monitor = new Thread(monitorObj);
302
            monitor.start();
303
            downloader.start();
304
            while (!getCanceled(cancel.getID()) && downloader.isAlive()) {
305
                try {
306
                    Thread.sleep(latency);
307
                } catch (InterruptedException e) {
308
                    LOG.error("Error", e);
309
                }
310
            }
311

    
312
            try {
313
                monitorObj.setFinish(true);
314
                monitor.join();
315
                downloader.join();
316
            } catch (InterruptedException e1) {
317
                LOG.warn(e1.getMessage());
318
            }
319
            downloader = null;
320
            monitor = null;
321

    
322
            if (getCanceled(cancel.getID())) {
323
                return null;
324
            }
325
            if (this.downloadException != null) {
326
                Exception e = this.downloadException;
327
                if (e instanceof FileNotFoundException) {
328
                    throw (IOException) e;
329
                } else if (e instanceof IOException) {
330
                    throw (IOException) e;
331
                } else if (e instanceof ConnectException) {
332
                    throw (ConnectException) e;
333
                } else if (e instanceof UnknownHostException) {
334
                    throw (UnknownHostException) e;
335
                }
336
            }
337
        } else {
338
            LOG.info(url.toString() + " cached at '" + f.getAbsolutePath() + "'");
339
        }
340

    
341
        return f;
342
    }
343

    
344
    /**
345
     * Try if a group of downloads has been canceled
346
     *
347
     * @param groupId Group id
348
     * @return If the group has been canceled
349
     */
350
    public boolean getCanceled(Object groupId) {
351
        Object obj = canceledGroup.get(groupId);
352
        if (obj != null) {
353
            return ((Boolean) obj).booleanValue();
354
        }
355
        return false;
356
    }
357

    
358
    /**
359
     * Cancel a group of downloads
360
     *
361
     * @param groupId Group id
362
     * @param isCanceled if the group has to be canceled
363
     */
364
    public void setCanceled(Object groupId, boolean isCanceled) {
365
        if (groupId == null) {
366
            groupId = SEDownloader.class.getName();
367
        }
368
        canceledGroup.put(groupId, new Boolean(isCanceled));
369
    }
370

    
371
    /**
372
     * Cleans every temporal file previously downloaded.
373
     */
374
    public void cleanUpTempFiles() {
375
        try {
376
            File tempDirectory = new File(tempDirectoryPath);
377

    
378
            File[] files = tempDirectory.listFiles();
379
            if (files != null) {
380
                for (int i = 0; i < files.length; i++) {
381
                    // s?lo por si en un futuro se necesitan crear directorios temporales
382
                    if (files[i].isDirectory()) {
383
                        deleteDirectory(files[i]);
384
                    }
385
                    files[i].delete();
386
                }
387
            }
388
            tempDirectory.delete();
389
        } catch (Exception e) {
390
        }
391

    
392
    }
393

    
394
    /**
395
     * Recursive directory delete.
396
     *
397
     * @param f
398
     */
399
    private void deleteDirectory(File f) {
400
        File[] files = f.listFiles();
401
        for (int i = 0; i < files.length; i++) {
402
            if (files[i].isDirectory()) {
403
                deleteDirectory(files[i]);
404
            }
405
            files[i].delete();
406
        }
407

    
408
    }
409

    
410
    /**
411
     * Remove an URL from the system cache. The file will remain in the file
412
     * system for further eventual uses.
413
     *
414
     * @param request
415
     */
416
    public void removeURL(URL url) {
417

    
418
        URI theuri = null;
419

    
420
        try {
421
            theuri = url.toURI();
422
        } catch (Exception e) {
423
            LOG.info("Warning: did not remove bad url: " + url, e);
424
            return;
425
        }
426

    
427
        if (cachedURItoFile != null && cachedURItoFile.containsKey(theuri)) {
428
            cachedURItoFile.remove(theuri);
429
        }
430
    }
431

    
432
    /**
433
     * Remove an URL from the system cache. The file will remain in the file
434
     * system for further eventual uses.
435
     *
436
     * @param request
437
     */
438
    public void removeURL(Object url) {
439
        if (cachedURItoFile != null && cachedURItoFile.containsKey(url)) {
440
            cachedURItoFile.remove(url);
441
        }
442
    }
443

    
444
    public void setDownloadException(Exception exception) {
445
        this.downloadException = exception;
446
    }
447

    
448
    public long getLatency() {
449
        return this.latency;
450
    }
451

    
452
    protected Runnable createDownloaderTask(Downloader downloader, URL url, String data, File target, Object groupID){
453
        return new SEDownloaderTask(downloader, url, data, target, groupID);
454
    }
455
}