svn-gvsig-desktop / branches / v2_0_0_prep / libraries / org.gvsig.arcims / src / org / gvsig / remoteclient / arcims / utils / ArcImsDownloadUtils.java @ 32538
History | View | Annotate | Download (14.3 KB)
1 | 32319 | vsanjaime | /* 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 | 32367 | vsanjaime | r = r + status.getServerURL(); |
458 | 32319 | vsanjaime | r = r + "&Service=";
|
459 | 32367 | vsanjaime | r = r + status.getServiceName(); |
460 | 32319 | vsanjaime | r = r + "&LayerIds=";
|
461 | 32538 | vsanjaime | r = r + status.getLayersIdsSelected().toString(); |
462 | 32319 | vsanjaime | 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 | } |