Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / org.gvsig.arcims / src / org / gvsig / remoteclient / arcims / utils / ArcImsDownloadUtils.java @ 32367

History | View | Annotate | Download (14.3 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2010 Prodevelop S.L. main development
26
 * http://www.prodevelop.es
27
 */
28

    
29
package org.gvsig.remoteclient.arcims.utils;
30

    
31
import java.io.BufferedOutputStream;
32
import java.io.DataOutputStream;
33
import java.io.File;
34
import java.io.FileNotFoundException;
35
import java.io.FileOutputStream;
36
import java.io.IOException;
37
import java.io.InputStream;
38
import java.io.OutputStreamWriter;
39
import java.net.ConnectException;
40
import java.net.HttpURLConnection;
41
import java.net.MalformedURLException;
42
import java.net.ProtocolException;
43
import java.net.URL;
44
import java.net.UnknownHostException;
45
import java.util.Hashtable;
46

    
47
import org.slf4j.Logger;
48
import org.slf4j.LoggerFactory;
49
import org.gvsig.remoteclient.arcims.ArcImsStatus;
50
import org.gvsig.remoteclient.arcims.exceptions.ArcImsException;
51

    
52
/**
53
 * These download methods derive from those in
54
 * <tt>org.gvsig.remoteClient.arcims.utils.Utilities<tt>
55
 * and have been modified to prevent multiple downloads of the same image when
56
 * using an ArcIMS server, because the remote image's URL is not the
57
 * same when requesting the same map twice.
58
 *
59
 * @author jldominguez
60
 *
61
 */
62

    
63
/**
64
 * @author jsanz
65
 * @author vsanjaime version 2.0
66
 */
67
public class ArcImsDownloadUtils {
68
        private static Logger logger = LoggerFactory.getLogger(ArcImsDownloadUtils.class
69
                        .getName());
70
        private static Hashtable<URL, String> downloadedFiles;
71
        private static final String tempDirectoryPath = System
72
                        .getProperty("java.io.tmpdir")
73
                        + "/tmp-andami";
74

    
75
        /**
76
         * Returns the content of this URL as a file from the file system.<br>
77
         * <p>
78
         * If the URL has been already downloaded in this session and notified to
79
         * the system using the static <b>Utilities.addDownloadedURL(URL)</b>
80
         * method, it can be restored faster from the file system avoiding to
81
         * download it again.
82
         * </p>
83
         * 
84
         * @param virtualUrl
85
         * @param override
86
         *            If false, the file won't be downloaded
87
         * @return File containing this URL's content or null if no file was found.
88
         */
89
        private static File getPreviousDownloadedURL(URL virtualUrl,
90
                        boolean override) {
91
                File f = null;
92

    
93
                if ((downloadedFiles != null)
94
                                && downloadedFiles.containsKey(virtualUrl) && !override) {
95
                        String filePath = (String) downloadedFiles.get(virtualUrl);
96
                        f = new File(filePath);
97
                }
98

    
99
                return f;
100
        }
101

    
102
        /**
103
         * Returns the content of this URL as a file from the file system.<br>
104
         * <p>
105
         * If the URL has been already downloaded in this session and notified to
106
         * the system using the static <b>Utilities.addDownloadedURL(URL)</b>
107
         * method, it can be restored faster from the file system avoiding to
108
         * download it again.
109
         * </p>
110
         * This overrided method doesn't require the boolean parameter
111
         * 
112
         * @see #getPreviousDownloadedURL(URL, boolean)
113
         * @param virtualUrl
114
         * @return File containing this URL's content or null if no file was found.
115
         */
116
        private static File getPreviousDownloadedURL(URL virtualUrl) {
117
                return getPreviousDownloadedURL(virtualUrl, false);
118
        }
119

    
120
        /**
121
         * Downloads an URL into a temporary file that is removed the next time the
122
         * tempFileManager class is called, which means the next time gvSIG is
123
         * launched.
124
         * 
125
         * @param url
126
         * @param virtualURL
127
         *            The virtual URL that identifies the file in the internal cache
128
         * @param filePath
129
         *            Where the file will be downloaded
130
         * @return File object of the downloaded file
131
         * @throws IOException
132
         * @throws ServerErrorResponseException
133
         * @throws ConnectException
134
         * @throws UnknownHostException
135
         */
136
        public static File downloadFile(URL url, URL virtualURL, String filePath)
137
                        throws IOException, ConnectException, UnknownHostException {
138
                File f = null;
139
                long t1 = System.currentTimeMillis();
140

    
141
                try {
142
                        if ((f = getPreviousDownloadedURL(virtualURL)) == null) {
143
                                long t3 = System.currentTimeMillis();
144
                                File tempDirectory = new File(tempDirectoryPath);
145

    
146
                                if (!tempDirectory.exists()) {
147
                                        tempDirectory.mkdir();
148
                                }
149

    
150
                                // f = new File(tempDirectoryPath + "/" + filePath);
151
                                String fName = normalizeFileName(filePath);
152
                                f = new File(tempDirectoryPath + "/" + fName);
153

    
154
                                logger.info("downloading '" + url.toString() + "' to: "
155
                                                + f.getAbsolutePath());
156

    
157
                                f.deleteOnExit();
158

    
159
                                DataOutputStream dos = new DataOutputStream(
160
                                                new BufferedOutputStream(new FileOutputStream(f)));
161
                                byte[] buffer = new byte[1024 * 256];
162
                                InputStream is = url.openStream();
163
                                long readed = 0;
164

    
165
                                for (int i = is.read(buffer); i > 0; i = is.read(buffer)) {
166
                                        dos.write(buffer, 0, i);
167
                                        readed += i;
168
                                }
169

    
170
                                dos.close();
171
                                addDownloadedURL(virtualURL, f.getAbsolutePath());
172

    
173
                                long t4 = System.currentTimeMillis();
174
                                System.err.println("Download time: " + (t4 - t3));
175
                        }
176
                } catch (IOException io) {
177
                        io.printStackTrace();
178
                }
179

    
180
                // Avoid possible conflits caused by multiple application instances.
181
                if (!f.exists()) {
182
                        downloadedFiles.remove(virtualURL);
183
                        f = downloadFile(url, virtualURL, filePath);
184
                }
185

    
186
                long t2 = System.currentTimeMillis();
187
                System.err.println("Total download method time: " + (t2 - t1));
188

    
189
                return f;
190
        }
191

    
192
        /**
193
         * Downloads an URL into a temporary file that is removed the next time the
194
         * tempFileManager class is called, which means the next time gvSIG is
195
         * launched.
196
         * 
197
         * @param url
198
         * @param filePath
199
         *            Where the file will be downloaded
200
         * @return File object of the downloaded file
201
         * @throws IOException
202
         * @throws ServerErrorResponseException
203
         * @throws ConnectException
204
         * @throws UnknownHostException
205
         */
206
        public static File downloadFile(URL url, String filePath)
207
                        throws IOException, ConnectException, UnknownHostException {
208
                File f = null;
209
                long t1 = System.currentTimeMillis();
210

    
211
                try {
212
                        long t3 = System.currentTimeMillis();
213
                        File tempDirectory = new File(tempDirectoryPath);
214

    
215
                        if (!tempDirectory.exists()) {
216
                                tempDirectory.mkdir();
217
                        }
218

    
219
                        // f = new File(tempDirectoryPath + "/" + filePath);
220
                        String fName = normalizeFileName(filePath);
221
                        f = new File(tempDirectoryPath + "/" + fName);
222

    
223
                        logger.info("downloading '" + url.toString() + "' to: "
224
                                        + f.getAbsolutePath());
225

    
226
                        f.deleteOnExit();
227

    
228
                        DataOutputStream dos = new DataOutputStream(
229
                                        new BufferedOutputStream(new FileOutputStream(f)));
230
                        byte[] buffer = new byte[1024 * 256];
231
                        InputStream is = url.openStream();
232
                        long readed = 0;
233

    
234
                        for (int i = is.read(buffer); i > 0; i = is.read(buffer)) {
235
                                dos.write(buffer, 0, i);
236
                                readed += i;
237
                        }
238

    
239
                        dos.close();
240

    
241
                        long t4 = System.currentTimeMillis();
242
                        System.err.println("Download time: " + (t4 - t3));
243
                } catch (IOException io) {
244
                        io.printStackTrace();
245
                }
246

    
247
                long t2 = System.currentTimeMillis();
248
                System.err.println("Total download method time: " + (t2 - t1));
249

    
250
                return f;
251
        }
252

    
253
        /**
254
         * Adds an URL to the table of downloaded files for further uses. If the URL
255
         * already exists in the table its filePath value is updated to the new one
256
         * and the old file itself is removed from the file system.
257
         * 
258
         * @param virtualURL
259
         * @param filePath
260
         */
261
        private static void addDownloadedURL(URL virtualURL, String filePath) {
262
                if (downloadedFiles == null) {
263
                        downloadedFiles = new Hashtable<URL, String>();
264
                }
265

    
266
                String fileName = (String) downloadedFiles.put(virtualURL, filePath);
267

    
268
                if (fileName != null) {
269
                        File f = new File(fileName);
270

    
271
                        if (f.exists()) {
272
                                f.delete();
273
                        }
274
                }
275
        }
276

    
277
        /**
278
         * Sends a XML request to the server as a String and returns the server's
279
         * response as a File object
280
         * 
281
         * @param url
282
         *            server's URL
283
         * @param req
284
         *            XML request as a String
285
         * @param fName
286
         *            the name of the local file which will keep the server's
287
         *            response
288
         * @param override
289
         *            this boolean sets if the download will be done (true)
290
         * @return File object associated to the server's response (and it's local
291
         *         name is fName)
292
         * @throws ArcImsException
293
         */
294
        public static File doRequestPost(URL url, String req, String fName,
295
                        boolean override) throws ArcImsException {
296
                File f = null;
297
                URL virtualUrl = getVirtualRequestUrlFromUrlAndRequest(url, req);
298

    
299
                if ((f = getPreviousDownloadedURL(virtualUrl, override)) == null) {
300
                        File tempDirectory = new File(tempDirectoryPath);
301

    
302
                        if (!tempDirectory.exists()) {
303
                                tempDirectory.mkdir();
304
                        }
305

    
306
                        String nfName = normalizeFileName(fName);
307

    
308
                        f = new File(tempDirectoryPath + "/" + nfName);
309

    
310
                        // f = new File(tempDirectoryPath + "/" + fName + "."
311
                        // + System.currentTimeMillis());
312
                        f.deleteOnExit();
313

    
314
                        logger.info("downloading '" + url.toString() + "' to: "
315
                                        + f.getAbsolutePath());
316

    
317
                        try {
318
                                HttpURLConnection conn = (HttpURLConnection) url
319
                                                .openConnection();
320
                                conn.setDoOutput(true);
321
                                conn.setRequestMethod("POST");
322
                                conn.setRequestProperty("Content-type",
323
                                                "application/x-www-form-urlencoded");
324
                                conn.setRequestProperty("Content-length", "" + req.length());
325

    
326
                                OutputStreamWriter wr = new OutputStreamWriter(conn
327
                                                .getOutputStream());
328
                                wr.write(req);
329
                                wr.flush();
330

    
331
                                // Get the response
332
                                DataOutputStream dos = new DataOutputStream(
333
                                                new BufferedOutputStream(new FileOutputStream(f)));
334
                                byte[] buffer = new byte[1024 * 256];
335

    
336
                                InputStream is = conn.getInputStream();
337

    
338
                                long readed = 0;
339

    
340
                                for (int i = is.read(buffer); i > 0; i = is.read(buffer)) {
341
                                        dos.write(buffer, 0, i);
342
                                        readed += i;
343
                                }
344

    
345
                                dos.close();
346
                                is.close();
347
                                wr.close();
348
                                addDownloadedURL(virtualUrl, f.getAbsolutePath());
349
                        } catch (ConnectException ce) {
350
                                logger.error("Timed out error", ce);
351
                                throw new ArcImsException("arcims_server_timeout");
352
                        } catch (FileNotFoundException fe) {
353
                                logger.error("FileNotFound Error", fe);
354
                                throw new ArcImsException("arcims_server_error");
355
                        } catch (IOException e) {
356
                                logger.error("IO Error", e);
357
                                throw new ArcImsException("arcims_server_error");
358
                        }
359
                }
360

    
361
                // Avoid possible conflits caused by multiple application instances.
362
                if (!f.exists()) {
363
                        downloadedFiles.remove(virtualUrl);
364
                        f = doRequestPost(url, req, fName, override);
365
                }
366

    
367
                return f;
368
        }
369

    
370
        private static String normalizeFileName(String name) {
371
                String ret = new String();
372
                int indPoint = name.lastIndexOf(".");
373
                ret = name.substring(0, indPoint);
374
                ret += ("-" + System.currentTimeMillis());
375
                ret += ("." + name.substring(indPoint + 1));
376

    
377
                return ret;
378
        }
379

    
380
        /**
381
         * Sends a XML request to the server as a String and returns the server's
382
         * response as a File object
383
         * 
384
         * @param url
385
         *            server's URL
386
         * @param req
387
         *            XML request as a String
388
         * @param fName
389
         *            the name of the local file which will keep the server's
390
         *            response
391
         * @return File object associated to the server's response (and it's local
392
         *         name is fName)
393
         * @throws ArcImsException
394
         */
395
        public static File doRequestPost(URL url, String req, String fName)
396
                        throws ArcImsException {
397
                return doRequestPost(url, req, fName, false);
398
        }
399

    
400
        /**
401
         * Sends a POST request to a specified URL and gets a BufferedReader of the
402
         * contents
403
         * 
404
         * @param url
405
         * @param post
406
         * @return BufferedReaded
407
         * @throws ArcImsException
408
         */
409
        public static InputStream getRemoteIS(URL url, String post)
410
                        throws ArcImsException {
411
                InputStream lector = null;
412

    
413
                try {
414
                        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
415
                        conn.setDoOutput(true);
416
                        conn.setRequestMethod("POST");
417
                        conn.setRequestProperty("Content-type",
418
                                        "application/x-www-form-urlencoded");
419
                        conn.setRequestProperty("Content-length", "" + post.length());
420

    
421
                        OutputStreamWriter wr = new OutputStreamWriter(conn
422
                                        .getOutputStream());
423

    
424
                        // Do the POST request
425
                        wr.write(post);
426
                        wr.flush();
427

    
428
                        // Get the response
429
                        logger.info("downloading '" + url.toString());
430
                        lector = conn.getInputStream();
431
                } catch (ConnectException e) {
432
                        logger.error("Timed out error", e);
433
                        throw new ArcImsException("arcims_server_timeout");
434
                } catch (ProtocolException e) {
435
                        logger.error(e.getMessage(), e);
436
                        throw new ArcImsException("arcims_server_error");
437
                } catch (IOException e) {
438
                        logger.error(e.getMessage(), e);
439
                        throw new ArcImsException("arcims_server_error");
440
                }
441

    
442
                return lector;
443
        }
444

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

    
467
                try {
468
                        u = new URL(r);
469
                } catch (MalformedURLException e) {
470
                        System.err.println("Error in method getVirtualUrlFromStatus: "
471
                                        + e.getMessage());
472
                }
473

    
474
                return u;
475
        }
476

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

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

    
500
                return u;
501
        }
502
}