root / 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 |
/* 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.getLayersIdsSelected().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 |
} |