Statistics
| Revision:

root / trunk / libraries / libArcIMS_old / src / org / gvsig / remoteClient / arcims / utils / ArcImsDownloadUtils.java @ 11865

History | View | Annotate | Download (16.7 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2006 Prodevelop and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *   +34 963862235
28
 *   gvsig@gva.es
29
 *   www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   Prodevelop Integraci?n de Tecnolog?as SL
34
 *   Conde Salvatierra de ?lava , 34-10
35
 *   46004 Valencia
36
 *   Spain
37
 *
38
 *   +34 963 510 612
39
 *   +34 963 510 968
40
 *   gis@prodevelop.es
41
 *   http://www.prodevelop.es
42
 */
43

    
44
package org.gvsig.remoteClient.arcims.utils;
45

    
46
import org.apache.log4j.Logger;
47

    
48
import org.gvsig.remoteClient.arcims.ArcImsStatus;
49
import org.gvsig.remoteClient.arcims.exceptions.ArcImsException;
50

    
51
import java.io.BufferedOutputStream;
52
import java.io.DataOutputStream;
53
import java.io.File;
54
import java.io.FileNotFoundException;
55
import java.io.FileOutputStream;
56
import java.io.IOException;
57
import java.io.InputStream;
58
import java.io.OutputStreamWriter;
59

    
60
import java.net.ConnectException;
61
import java.net.HttpURLConnection;
62
import java.net.MalformedURLException;
63
import java.net.ProtocolException;
64
import java.net.URL;
65
import java.net.UnknownHostException;
66

    
67
import java.util.Hashtable;
68

    
69

    
70
/**
71
 * These download methods derive from those in
72
 * <tt>org.gvsig.remoteClient.arcims.utils.Utilities<tt>
73
 * and have been modified to prevent multiple downloads of the same image when
74
 * using an ArcIMS server, because the remote image's URL is not the
75
 * same when requesting the same map twice.
76
 *
77
 * @author jldominguez
78
 *
79
 */
80

    
81
/**
82
 * @author jsanz
83
 *
84
 */
85
public class ArcImsDownloadUtils {
86
    private static Logger logger = Logger.getLogger(ArcImsDownloadUtils.class.getName());
87
    private static Hashtable downloadedFiles;
88
    private static final String tempDirectoryPath = System.getProperty(
89
            "java.io.tmpdir") + "/tmp-andami";
90

    
91
    /**
92
     * Returns the content of this URL as a file from the file system.<br>
93
     * <p>
94
     * If the URL has been already downloaded in this session and notified to
95
     * the system using the static <b>Utilities.addDownloadedURL(URL)</b>
96
     * method, it can be restored faster from the file system avoiding to
97
     * download it again.
98
     * </p>
99
     *
100
     * @param virtualUrl
101
     * @param override If false, the file won't be downloaded
102
     * @return File containing this URL's content or null if no file was found.
103
     */
104
    private static File getPreviousDownloadedURL(URL virtualUrl,
105
        boolean override) {
106
        File f = null;
107

    
108
        if ((downloadedFiles != null) &&
109
                downloadedFiles.containsKey(virtualUrl) && !override) {
110
            String filePath = (String) downloadedFiles.get(virtualUrl);
111
            f = new File(filePath);
112
        }
113

    
114
        return f;
115
    }
116

    
117
    /**
118
     * Returns the content of this URL as a file from the file system.<br>
119
     * <p>
120
     * If the URL has been already downloaded in this session and notified to
121
     * the system using the static <b>Utilities.addDownloadedURL(URL)</b>
122
     * method, it can be restored faster from the file system avoiding to
123
     * download it again.
124
     * </p>
125
     * This overrided method doesn't require the boolean parameter
126
     * @see #getPreviousDownloadedURL(URL, boolean)
127
     * @param virtualUrl
128
     * @return File containing this URL's content or null if no file was found.
129
     */
130
    private static File getPreviousDownloadedURL(URL virtualUrl) {
131
        return getPreviousDownloadedURL(virtualUrl, false);
132
    }
133

    
134
    /**
135
     * Downloads an URL into a temporary file that is removed the next time the
136
     * tempFileManager class is called, which means the next time gvSIG is
137
     * launched.
138
     *
139
     * @param url
140
     * @param  virtualURL The virtual URL that identifies the file in the internal cache
141
     * @param filePath Where the file will be downloaded
142
     * @return File object of the downloaded file
143
     * @throws IOException
144
     * @throws ServerErrorResponseException
145
     * @throws ConnectException
146
     * @throws UnknownHostException
147
     */
148
    public static File downloadFile(URL url, URL virtualURL, String filePath)
149
        throws IOException, ConnectException, UnknownHostException {
150
        File f = null;
151
        long t1 = System.currentTimeMillis();
152

    
153
        try {
154
            if ((f = getPreviousDownloadedURL(virtualURL)) == null) {
155
                long t3 = System.currentTimeMillis();
156
                File tempDirectory = new File(tempDirectoryPath);
157

    
158
                if (!tempDirectory.exists()) {
159
                    tempDirectory.mkdir();
160
                }
161

    
162
                //f = new File(tempDirectoryPath + "/" + filePath);
163
                String fName = normalizeFileName(filePath);
164
                f = new File(tempDirectoryPath + "/" + fName);
165

    
166
                logger.info("downloading '" + url.toString() + "' to: " +
167
                    f.getAbsolutePath());
168

    
169
                f.deleteOnExit();
170

    
171
                DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(
172
                            new FileOutputStream(f)));
173
                byte[] buffer = new byte[1024 * 256];
174
                InputStream is = url.openStream();
175
                long readed = 0;
176

    
177
                for (int i = is.read(buffer); i > 0; i = is.read(buffer)) {
178
                    dos.write(buffer, 0, i);
179
                    readed += i;
180
                }
181

    
182
                dos.close();
183
                addDownloadedURL(virtualURL, f.getAbsolutePath());
184

    
185
                long t4 = System.currentTimeMillis();
186
                System.err.println("Download time: " + (t4 - t3));
187
            }
188
        } catch (IOException io) {
189
            io.printStackTrace();
190
        }
191

    
192
        // Avoid possible conflits caused by multiple application instances.
193
        if (!f.exists()) {
194
            downloadedFiles.remove(virtualURL);
195
            f = downloadFile(url, virtualURL, filePath);
196
        }
197

    
198
        long t2 = System.currentTimeMillis();
199
        System.err.println("Total download method time: " + (t2 - t1));
200

    
201
        return f;
202
    }
203

    
204
    /**
205
     * Downloads an URL into a temporary file that is removed the next time the
206
     * tempFileManager class is called, which means the next time gvSIG is
207
     * launched.
208
     *
209
     * @param url
210
     * @param filePath Where the file will be downloaded
211
     * @return File object of the downloaded file
212
     * @throws IOException
213
     * @throws ServerErrorResponseException
214
     * @throws ConnectException
215
     * @throws UnknownHostException
216
     */
217
    public static File downloadFile(URL url, String filePath)
218
        throws IOException, ConnectException, UnknownHostException {
219
        File f = null;
220
        long t1 = System.currentTimeMillis();
221

    
222
        try {
223
            long t3 = System.currentTimeMillis();
224
            File tempDirectory = new File(tempDirectoryPath);
225

    
226
            if (!tempDirectory.exists()) {
227
                tempDirectory.mkdir();
228
            }
229

    
230
            //f = new File(tempDirectoryPath + "/" + filePath);
231
            String fName = normalizeFileName(filePath);
232
            f = new File(tempDirectoryPath + "/" + fName);
233

    
234
            logger.info("downloading '" + url.toString() + "' to: " +
235
                f.getAbsolutePath());
236

    
237
            f.deleteOnExit();
238

    
239
            DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(
240
                        new FileOutputStream(f)));
241
            byte[] buffer = new byte[1024 * 256];
242
            InputStream is = url.openStream();
243
            long readed = 0;
244

    
245
            for (int i = is.read(buffer); i > 0; i = is.read(buffer)) {
246
                dos.write(buffer, 0, i);
247
                readed += i;
248
            }
249

    
250
            dos.close();
251

    
252
            long t4 = System.currentTimeMillis();
253
            System.err.println("Download time: " + (t4 - t3));
254
        } catch (IOException io) {
255
            io.printStackTrace();
256
        }
257

    
258
        long t2 = System.currentTimeMillis();
259
        System.err.println("Total download method time: " + (t2 - t1));
260

    
261
        return f;
262
    }
263

    
264
    /**
265
     * Adds an URL to the table of downloaded files for further uses. If the URL
266
     * already exists in the table its filePath value is updated to the new one
267
     * and the old file itself is removed from the file system.
268
     *
269
     * @param virtualURL
270
     * @param filePath
271
     */
272
    private static void addDownloadedURL(URL virtualURL, String filePath) {
273
        if (downloadedFiles == null) {
274
            downloadedFiles = new Hashtable();
275
        }
276

    
277
        String fileName = (String) downloadedFiles.put(virtualURL, filePath);
278

    
279
        if (fileName != null) {
280
            File f = new File(fileName);
281

    
282
            if (f.exists()) {
283
                f.delete();
284
            }
285
        }
286
    }
287

    
288
    /**
289
     * Sends a XML request to the server as a String and returns the server's
290
     * response as a File object
291
     *
292
     * @param url
293
     *            server's URL
294
     * @param req
295
     *            XML request as a String
296
     * @param fName
297
     *            the name of the local file which will keep the server's
298
     *            response
299
     * @param override
300
     *                            this boolean sets if the download will be done (true)
301
     * @return File object associated to the server's response (and it's
302
     *         local name is fName)
303
     * @throws ArcImsException
304
     */
305
    public static File doRequestPost(URL url, String req, String fName,
306
        boolean override) throws ArcImsException {
307
        File f = null;
308
        URL virtualUrl = getVirtualRequestUrlFromUrlAndRequest(url, req);
309

    
310
        if ((f = getPreviousDownloadedURL(virtualUrl, override)) == null) {
311
            File tempDirectory = new File(tempDirectoryPath);
312

    
313
            if (!tempDirectory.exists()) {
314
                tempDirectory.mkdir();
315
            }
316

    
317
            String nfName = normalizeFileName(fName);
318

    
319
            f = new File(tempDirectoryPath + "/" + nfName);
320

    
321
            //                        f = new File(tempDirectoryPath + "/" + fName + "."
322
            //                                        + System.currentTimeMillis());
323
            f.deleteOnExit();
324

    
325
            logger.info("downloading '" + url.toString() + "' to: " +
326
                f.getAbsolutePath());
327

    
328
            try {
329
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
330
                conn.setDoOutput(true);
331
                conn.setRequestMethod("POST");
332
                conn.setRequestProperty("Content-type",
333
                    "application/x-www-form-urlencoded");
334
                conn.setRequestProperty("Content-length", "" + req.length());
335

    
336
                OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
337
                wr.write(req);
338
                wr.flush();
339

    
340
                // Get the response
341
                DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(
342
                            new FileOutputStream(f)));
343
                byte[] buffer = new byte[1024 * 256];
344

    
345
                InputStream is = conn.getInputStream();
346

    
347
                long readed = 0;
348

    
349
                for (int i = is.read(buffer); i > 0; i = is.read(buffer)) {
350
                    dos.write(buffer, 0, i);
351
                    readed += i;
352
                }
353

    
354
                dos.close();
355
                is.close();
356
                wr.close();
357
                addDownloadedURL(virtualUrl, f.getAbsolutePath());
358
            } catch (ConnectException ce) {
359
                logger.error("Timed out error", ce);
360
                throw new ArcImsException("arcims_server_timeout");
361
            } catch (FileNotFoundException fe) {
362
                logger.error("FileNotFound Error", fe);
363
                throw new ArcImsException("arcims_server_error");
364
            } catch (IOException e) {
365
                logger.error("IO Error", e);
366
                throw new ArcImsException("arcims_server_error");
367
            }
368
        }
369

    
370
        // Avoid possible conflits caused by multiple application instances.
371
        if (!f.exists()) {
372
            downloadedFiles.remove(virtualUrl);
373
            f = doRequestPost(url, req, fName, override);
374
        }
375

    
376
        return f;
377
    }
378

    
379
    private static String normalizeFileName(String name) {
380
        String ret = new String();
381
        int indPoint = name.lastIndexOf(".");
382
        ret = name.substring(0, indPoint);
383
        ret += ("-" + System.currentTimeMillis());
384
        ret += ("." + name.substring(indPoint + 1));
385

    
386
        return ret;
387
    }
388

    
389
    /**
390
     * Sends a XML request to the server as a String and returns the server's
391
     * response as a File object
392
     *
393
     * @param url
394
     *            server's URL
395
     * @param req
396
     *            XML request as a String
397
     * @param fName
398
     *            the name of the local file which will keep the server's
399
     *            response
400
     * @return File object associated to the server's response (and it's
401
     *         local name is fName)
402
     * @throws ArcImsException
403
     */
404
    public static File doRequestPost(URL url, String req, String fName)
405
        throws ArcImsException {
406
        return doRequestPost(url, req, fName, false);
407
    }
408

    
409
    /**
410
     * Sends a POST request to a specified URL and gets a BufferedReader of the contents
411
     * @param url
412
     * @param post
413
     * @return BufferedReaded
414
     * @throws ArcImsException
415
     */
416
    public static InputStream getRemoteIS(URL url, String post)
417
        throws ArcImsException {
418
        InputStream lector = null;
419

    
420
        try {
421
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
422
            conn.setDoOutput(true);
423
            conn.setRequestMethod("POST");
424
            conn.setRequestProperty("Content-type",
425
                "application/x-www-form-urlencoded");
426
            conn.setRequestProperty("Content-length", "" + post.length());
427

    
428
            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
429

    
430
            //Do the POST request
431
            wr.write(post);
432
            wr.flush();
433

    
434
            //Get the response
435
            logger.info("downloading '" + url.toString());
436
            lector = conn.getInputStream();
437
        } catch (ConnectException e) {
438
            logger.error("Timed out error", e);
439
            throw new ArcImsException("arcims_server_timeout");
440
        } catch (ProtocolException e) {
441
            logger.error(e.getMessage(), e);
442
            throw new ArcImsException("arcims_server_error");
443
        } catch (IOException e) {
444
            logger.error(e.getMessage(), e);
445
            throw new ArcImsException("arcims_server_error");
446
        }
447

    
448
        return lector;
449
    }
450

    
451
    /**
452
     * Returns a virtual URL from status to emulate WMS requests to make unique
453
     * requests for every image gvSIG downloads.
454
     * @param status @see org.gvsig.remoteClient.arcims.utils.ArcImsStatus
455
     * @return URL with the virtual link
456
     */
457
    public static URL getVirtualUrlFromStatus(ArcImsStatus status) {
458
        URL u = null;
459
        String r = "http://arcims.image.virtual.url/";
460
        r = r + "?Server=";
461
        r = r + status.getServer();
462
        r = r + "&Service=";
463
        r = r + status.getService();
464
        r = r + "&LayerIds=";
465
        r = r + status.getLayerIds().toString();
466
        r = r + "&Extent=";
467
        r = r + status.getExtent().toString();
468
        r = r + "&Format=";
469
        r = r + status.getFormat();
470

    
471
        try {
472
            u = new URL(r);
473
        } catch (MalformedURLException e) {
474
            System.err.println("Error in method getVirtualUrlFromStatus: " +
475
                e.getMessage());
476
        }
477

    
478
        return u;
479
    }
480

    
481
    /**
482
     * Returns a virtual URL from status to emulate WMS requests to make unique
483
     * requests for every image gvSIG downloads.
484
     * @param url
485
     * @param request
486
     * @return URL with the virtual link
487
     */
488
    public static URL getVirtualRequestUrlFromUrlAndRequest(URL url,
489
        String request) {
490
        URL u = null;
491
        String r = "http://arcims.request.virtual.url/";
492
        r = r + "Url=" + url.toString();
493
        r = r + "&Request=";
494
        r = r + request;
495

    
496
        try {
497
            u = new URL(r);
498
        } catch (MalformedURLException e) {
499
            System.err.println("Error in methos getVirtualUrlFromStatus: " +
500
                e.getMessage());
501
        }
502

    
503
        return u;
504
    }
505
}