Statistics
| Revision:

root / trunk / libraries / libRemoteServices / src / org / gvsig / remoteClient / utils / Utilities.java @ 18333

History | View | Annotate | Download (21.5 KB)

1 3323 ldiaz
package org.gvsig.remoteClient.utils;
2
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
3 5180 jaume
 *
4
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 *
20
 * For more information, contact:
21
 *
22
 *  Generalitat Valenciana
23
 *   Conselleria d'Infraestructures i Transport
24
 *   Av. Blasco Ib??ez, 50
25
 *   46010 VALENCIA
26
 *   SPAIN
27
 *
28
 *      +34 963862235
29
 *   gvsig@gva.es
30
 *      www.gvsig.gva.es
31
 *
32
 *    or
33
 *
34
 *   IVER T.I. S.A
35
 *   Salamanca 50
36
 *   46005 Valencia
37
 *   Spain
38
 *
39
 *   +34 963163400
40
 *   dac@iver.es
41
 */
42 3323 ldiaz
43 5180 jaume
import java.io.BufferedOutputStream;
44 5409 jaume
import java.io.DataInputStream;
45 5180 jaume
import java.io.DataOutputStream;
46 3516 jaume
import java.io.File;
47
import java.io.FileNotFoundException;
48 5180 jaume
import java.io.FileOutputStream;
49 3516 jaume
import java.io.FileReader;
50 3323 ldiaz
import java.io.IOException;
51
import java.io.InputStream;
52
import java.io.OutputStream;
53 18333 jpiera
import java.io.OutputStreamWriter;
54 5409 jaume
import java.net.ConnectException;
55 18333 jpiera
import java.net.HttpURLConnection;
56 5180 jaume
import java.net.URL;
57 18333 jpiera
import java.net.URLConnection;
58 5409 jaume
import java.net.UnknownHostException;
59 3323 ldiaz
import java.rmi.NoSuchObjectException;
60 15505 jpiera
import java.security.KeyManagementException;
61
import java.security.NoSuchAlgorithmException;
62 5180 jaume
import java.util.Hashtable;
63 3377 ldiaz
import java.util.StringTokenizer;
64 3345 ldiaz
import java.util.Vector;
65 3323 ldiaz
66 15505 jpiera
import javax.net.ssl.HttpsURLConnection;
67
import javax.net.ssl.SSLContext;
68
import javax.net.ssl.TrustManager;
69
import javax.net.ssl.X509TrustManager;
70
71 5409 jaume
import org.gvsig.remoteClient.wms.ICancellable;
72 3323 ldiaz
73 5409 jaume
74 15505 jpiera
75
76 3323 ldiaz
/**
77 5180 jaume
 * Clase con m?todos de utilidad en el protocolo WMS
78
 *
79
 * @authors Laura D?az, jaume dominguez faus
80
 */
81 3323 ldiaz
public class Utilities {
82 5180 jaume
        private static String characters;
83 5536 jaume
        static boolean canceled;
84
        static final long latency = 500;
85 5409 jaume
        /**
86 14548 jmvivo
         * Used to cancel a group of files
87 15505 jpiera
         * <b>key</b>: Group id, <b>value</b>: Boolean (true if
88
         * the group has to be canceled. Otherwise it is
89
         * false)
90
         */
91 14548 jmvivo
        static Hashtable canceledGroup = new Hashtable();
92
        /**
93 15505 jpiera
         * <b>key</b>: URL, <b>value</b>: path to the downloaded file.
94
         */
95
        private static Hashtable downloadedFiles;
96 5536 jaume
        static Exception downloadException;
97 15505 jpiera
        private static final String tempDirectoryPath = System.getProperty("java.io.tmpdir")+"/tmp-andami";
98 6042 jaume
99
100 5180 jaume
        static {
101
                characters = "";
102
                for (int j = 32; j<=127; j++){
103
                        characters += (char) j;
104
                }
105
                characters += "?????????????????????????????????????????????????\n\r\f\t??";
106
        }
107 6042 jaume
108
109 5180 jaume
        /**
110
         * Checks a File and tries to figure if the file is a text or a binary file.<br>
111
         * Keep in mind that binary files are those that contains at least one
112
         * non-printable character.
113 6042 jaume
         *
114 5180 jaume
         * @param file
115 6042 jaume
         * @return <b>true</b> when the file is <b>pretty problably</b> text,
116 5180 jaume
         * <b>false</b> if the file <b>is</b> binary.
117
         */
118
        public static boolean isTextFile(File file){
119
                return isTextFile(file, 1024);
120
        }
121 6042 jaume
122 5180 jaume
        /**
123
         * Checks a File and tries to figure if the file is a text or a binary file.<br>
124
         * Keep in mind that binary files are those that contains at least one
125 6042 jaume
         * non-printable character.
126
         *
127 5180 jaume
         * @param file
128
         * @param byteAmount, number of bytes to check.
129 6042 jaume
         * @return <b>true</b> when the file is <b>pretty problably</b> text,
130 5180 jaume
         * <b>false</b> if the file <b>is</b> binary.
131
         */
132
        public static boolean isTextFile(File file, int byteAmount){
133 6042 jaume
                int umbral = byteAmount;
134 5180 jaume
                try {
135
                        FileReader fr = new FileReader(file);
136
                        for (int i = 0; i < umbral; i++) {
137
                                int c = fr.read();
138
                                if (c==-1){
139
                                        // End of file. If we reach this
140
                                        // everything before is printable data.
141
                                        return true;
142
                                }
143
                                char ch = (char) c;
144
                                if (characters.indexOf(ch)==-1){
145
                                        // We've found a non-printable character.
146
                                        // Then we'll assume that this file is binary.
147
                                        return false;
148
                                }
149
                        }
150
                } catch (FileNotFoundException e) {
151
                        e.printStackTrace();
152
                } catch (IOException e) {
153
                        e.printStackTrace();
154
                }
155
                return true;
156
        }
157 6042 jaume
158 5180 jaume
        /**
159
         * Checks a byte array and tells if it contains only text or contains
160
         * any binary data.
161 6042 jaume
         *
162 5180 jaume
         * @param file
163
         * @return <b>true</b> when the data is <b>only</b> text, <b>false</b> otherwise.
164
         * @deprecated
165
         */
166
        public static boolean isTextData(byte[] data){
167
                char[] charData = new char[data.length];
168
                for (int i = 0; i<data.length; i++){
169
                        charData[i] = (char) data[i];
170
                }
171 6042 jaume
172 5180 jaume
                for (int i = 0; i < data.length; i++) {
173
                        int c = charData[i];
174 6042 jaume
175
176 5180 jaume
                        if (c==-1){
177
                                // End of file. If we reach this
178
                                // everything before is printable data.
179
                                return true;
180
                        }
181
                        char ch = (char) c;
182
                        if (characters.indexOf(ch)==-1){
183
                                // We've found a non-printable character.
184
                                // Then we'll assume that this file is binary.
185 6042 jaume
186 5180 jaume
                                //System.out.println(ch+" at "+i);
187
                                return false;
188
                        }
189
                }
190
                return true;
191
        }
192 6042 jaume
193
194
195
196 5180 jaume
        /**
197
         * Copia el contenido de un InputStream en un OutputStream
198
         *
199
         * @param in InputStream
200
         * @param out OutputStream
201
         */
202
        public static void serializar(InputStream in, OutputStream out) {
203
                byte[] buffer = new byte[102400];
204 6042 jaume
205 5180 jaume
                int n;
206 6042 jaume
207 5180 jaume
                try {
208
                        while ((n = in.read(buffer)) != -1) {
209
                                out.write(buffer, 0, n);
210
                        }
211
                } catch (IOException e) {
212
                        e.printStackTrace();
213
                }
214
        }
215 6042 jaume
216 5180 jaume
        /**
217
         * Elimina del xml la declaraci?n del DTD
218
         *
219
         * @param bytes bytes del fichero XML de respuesta a getCapabilities
220
         * @param startTag Tag raiz del xml respuesta a getCapabilities
221
         *
222
         * @return bytes del fichero XML sin la declaraci?n del DTD
223
         */
224
        public static byte[] eliminarDTD(byte[] bytes, String startTag) {
225
                String text = new String(bytes);
226
                int index1 = text.indexOf("?>") + 2;
227
                int index2;
228 6042 jaume
229 5180 jaume
                try {
230
                        index2 = findBeginIndex(bytes, startTag);
231
                } catch (NoSuchObjectException e) {
232
                        return bytes;
233
                }
234 6042 jaume
235 5180 jaume
                byte[] buffer = new byte[bytes.length - (index2 - index1)];
236
                System.arraycopy(bytes, 0, buffer, 0, index1);
237
                System.arraycopy(bytes, index2, buffer, index1, bytes.length - index2);
238 6042 jaume
239 5180 jaume
                return buffer;
240
        }
241 6042 jaume
242 5180 jaume
        /**
243
         * Obtiene el ?ndice del comienzo del xml
244
         *
245
         * @param bytes bytes del fichero XML en el que se busca
246
         * @param tagRaiz Tag raiz del xml respuesta a getCapabilities
247
         *
248
         * @return ?ndice donde empieza el tag raiz
249
         *
250
         * @throws NoSuchObjectException Si no se encuentra el tag
251
         */
252
        private static int findBeginIndex(byte[] bytes, String tagRaiz)
253
        throws NoSuchObjectException {
254
                try {
255
                        int nodo = 0;
256
                        int ret = -1;
257 6042 jaume
258 5180 jaume
                        int i = 0;
259 6042 jaume
260 5180 jaume
                        while (true) {
261
                                switch (nodo) {
262
                                case 0:
263 6042 jaume
264 5180 jaume
                                        if (bytes[i] == '<') {
265
                                                ret = i;
266
                                                nodo = 1;
267
                                        }
268 6042 jaume
269 5180 jaume
                                        break;
270 6042 jaume
271 5180 jaume
                                case 1:
272 6042 jaume
273 5180 jaume
                                        if (bytes[i] == ' ') {
274
                                        } else if (bytes[i] == tagRaiz.charAt(0)) {
275
                                                nodo = 2;
276
                                        } else {
277
                                                nodo = 0;
278
                                        }
279 6042 jaume
280 5180 jaume
                                        break;
281 6042 jaume
282 5180 jaume
                                case 2:
283 6042 jaume
284 5180 jaume
                                        String aux = new String(bytes, i, 18);
285 6042 jaume
286 5180 jaume
                                        if (aux.equalsIgnoreCase(tagRaiz.substring(1))) {
287
                                                return ret;
288
                                        }
289 6042 jaume
290 5180 jaume
                                        nodo = 0;
291 6042 jaume
292 5180 jaume
                                        break;
293
                                }
294 6042 jaume
295 5180 jaume
                                i++;
296
                        }
297
                } catch (Exception e) {
298
                        throw new NoSuchObjectException("No se pudo parsear el xml");
299
                }
300
        }
301 6042 jaume
302 5180 jaume
        /**
303
         * Converts the contents of a Vector to a comma separated list
304 6042 jaume
         *
305 5180 jaume
         * */
306
        public static String Vector2CS(Vector v)
307
        {
308 6042 jaume
                String str = new String();
309 5180 jaume
                if (v != null)
310
                {
311
                        int i;
312
                        for (i=0; i<v.size() ;i++)
313
                        {
314
                                str = str + v.elementAt(i);
315
                                if (i<v.size()-1)
316
                                        str = str + ",";
317
                        }
318
                }
319
                return str;
320
        }
321 6042 jaume
322 3345 ldiaz
        public static boolean isValidVersion(String version)
323
        {
324 5180 jaume
                if(version.trim().length() == 5)
325 3345 ldiaz
                {
326 5180 jaume
                        if ( (version.charAt(1)=='.') && (version.charAt(3)=='.'))
327
                        {
328
                                char x = version.charAt(0);
329
                                char y = version.charAt(2);
330
                                char z = version.charAt(4);
331 6042 jaume
332 5180 jaume
                                if ((Character.isDigit(x)) && (Character.isDigit(y)) && (Character.isDigit(z)))
333
                                {
334
                                        return true;
335
                                }
336
                                else
337
                                {
338
                                        return false;
339
                                }
340
                        }
341
                        else
342
                        {
343
                                return false;
344
                        }
345 3345 ldiaz
                }
346
                else
347
                {
348 5180 jaume
                        return false;
349 3345 ldiaz
                }
350
        }
351 6042 jaume
352 3377 ldiaz
        /**
353 5180 jaume
         * Crea un fichero temporal con un nombre concreto y unos datos pasados por
354
         * par?metro.
355
         * @param fileName Nombre de fichero
356
         * @param data datos a guardar en el fichero
357
         */
358
        public static void createTemp(String fileName, String data)throws IOException{
359
                File f = new File(fileName);
360
                DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(f)) );
361
                dos.writeBytes(data);
362
                dos.close();
363
                f.deleteOnExit();
364
        }
365 6042 jaume
366 5180 jaume
        /**
367
         * Checks if a String is a number or not
368 6042 jaume
         *
369 5180 jaume
         * @param String, s
370
         * @return boolean, true if s is a number
371
         */
372 6042 jaume
        public static boolean isNumber(String s)
373 5180 jaume
        {
374
                try
375
                {
376
                        //double d = Double.parseDouble(s);
377
                        return true;
378
                }
379
                catch(NumberFormatException e)
380
                {
381
                        return false;
382
                }
383 6042 jaume
384
        }
385
386 5180 jaume
        /**
387 3377 ldiaz
         * Parses the String containing different items [character] separated and
388
         * creates a vector with them.
389
         * @param str String contains item1[c]item2[c]item3...
390
         * @param c is the string value for separating the items
391
         * @return Vector containing all the items
392
         */
393
        public static Vector createVector(String str, String c)
394
        {
395
                StringTokenizer tokens = new StringTokenizer(str, c);
396
                Vector v = new Vector();
397
                try
398
                {
399
                        while (tokens.hasMoreTokens())
400
                        {
401
                                v.addElement(tokens.nextToken());
402
                        }
403
                        return v;
404
                }
405
                catch (Exception e)
406
                {
407
                        return new Vector();
408
                }
409
        }
410 6042 jaume
411 5180 jaume
        /**
412
         * @param dimensions
413
         * @return
414
         */
415
        public static String Vector2URLParamString(Vector v) {
416
                if (v==null) return "";
417
                String s = "";
418
                for (int i = 0; i < v.size(); i++) {
419
                        s += v.get(i);
420
                        if (i<v.size()-1)
421
                                s += "&";
422
                }
423
                return s;
424
        }
425 6042 jaume
426 5409 jaume
        /**
427 18333 jpiera
         * Return the content of a file that has been created
428
         * from a URL using the HTTP GET protocol
429
         * @param url
430
         * The URL
431
         * @return
432
         * File containing this URL's content or null if no file was found.
433
         */
434
        private static File getPreviousDownloadedURL(URL url){
435
                return getPreviousDownloaded(url);
436
        }
437
438
        /**
439
         * Return the content of a file that has been created
440
         * from a URL using the HTTP POST protocol
441
         * @param url
442
         * The URL
443
         * @param data
444
         * The data to send on the query
445
         * @return
446
         * File containing this URL's content or null if no file was found.
447
         */
448
        private static File getPreviousDownloadedURL(URL url, String data){
449
                return getPreviousDownloaded(url+data);
450
        }
451
452
        /**
453
         * Returns the content of a URL as a file from the file system.<br>
454 15505 jpiera
         * <p>
455
         * If the URL has been already downloaded in this session and notified
456
         * to the system using the static <b>Utilities.addDownloadedURL(URL)</b>
457
         * method, it can be restored faster from the file system avoiding to
458
         * download it again.
459
         * </p>
460
         * @param url
461
         * @return File containing this URL's content or null if no file was found.
462
         */
463 18333 jpiera
        private static File getPreviousDownloaded(Object object){
464 15505 jpiera
                File f = null;
465 18333 jpiera
                if (downloadedFiles!=null && downloadedFiles.containsKey(object)){
466
                        String filePath = (String) downloadedFiles.get(object);
467 15505 jpiera
                        f = new File(filePath);
468
                        if (!f.exists())
469
                                return null;
470
                }
471
                return f;
472
        }
473 6042 jaume
474 15505 jpiera
        /**
475
         * Adds an URL to the table of downloaded files for further uses. If the URL
476
         * already exists in the table its filePath value is updated to the new one and
477
         * the old file itself is removed from the file system.
478
         *
479
         * @param url
480
         * @param filePath
481
         */
482
        static void addDownloadedURL(URL url, String filePath){
483
                if (downloadedFiles==null)
484
                        downloadedFiles = new Hashtable();
485
                String fileName = (String) downloadedFiles.put(url, filePath);
486
                //JMV: No se puede eliminar el anterior porque puede que alguien lo
487
                // este usando
488
                /*
489 5409 jaume
        if (fileName!=null){
490
            File f = new File(fileName);
491
            if (f.exists())
492
                f.delete();
493
        }
494 15505 jpiera
                 */
495
        }
496 6042 jaume
497 15505 jpiera
        /**
498
         * Downloads an URL into a temporary file that is removed the next time the
499
         * tempFileManager class is called, which means the next time gvSIG is launched.
500
         *
501
         * @param url
502
         * @param name
503
         * @return
504
         * @throws IOException
505
         * @throws ServerErrorResponseException
506
         * @throws ConnectException
507
         * @throws UnknownHostException
508
         */
509
        public static synchronized File downloadFile(URL url, String name, ICancellable cancel) throws IOException,ConnectException, UnknownHostException{
510
                File f = null;
511 6042 jaume
512 15505 jpiera
                if ((f=getPreviousDownloadedURL(url))==null){
513
                        File tempDirectory = new File(tempDirectoryPath);
514
                        if (!tempDirectory.exists())
515
                                tempDirectory.mkdir();
516 6042 jaume
517 15505 jpiera
                        f = new File(tempDirectoryPath+"/"+name+System.currentTimeMillis());
518 6042 jaume
519 15505 jpiera
                        if (cancel == null) {
520
                                cancel = new ICancellable() {
521 5536 jaume
                                        public boolean isCanceled() {
522
                                                return false;
523
                                        }
524 14548 jmvivo
                                        public Object getID(){
525
                                                return Utilities.class.getName();
526
                                        }
527 15505 jpiera
                                };
528
                        }
529
                        Thread downloader = new Thread(new Downloader(url, f, cancel.getID()));
530
                        Thread monitor = new Thread(new Monitor(cancel));
531
                        monitor.start();
532
                        downloader.start();
533
                        while(!getCanceled(cancel.getID()) && downloader.isAlive()) {
534
                                try {
535 5536 jaume
                                        Thread.sleep(latency);
536
                                } catch (InterruptedException e) {
537
                                        // TODO Auto-generated catch block
538
                                        e.printStackTrace();
539
                                }
540 15505 jpiera
                        }
541 6042 jaume
542 15505 jpiera
                        if (getCanceled(cancel.getID()))
543
                                return null;
544
                        downloader = null;
545
                        monitor = null;
546
                        if (Utilities.downloadException!=null) {
547
                                Exception e = Utilities.downloadException;
548
                                if (e instanceof FileNotFoundException)
549
                                        throw (IOException) e;
550
                                else if (e instanceof IOException)
551
                                        throw (IOException) e;
552
                                else if (e instanceof ConnectException)
553
                                        throw (ConnectException) e;
554
                                else if (e instanceof UnknownHostException)
555
                                        throw (UnknownHostException) e;
556
                        }
557
                } else {
558
                        System.out.println(url.toString()+" cached at '"+f.getAbsolutePath()+"'");
559
                }
560 6042 jaume
561 15505 jpiera
                return f;
562 5409 jaume
        }
563
564 15505 jpiera
        /**
565 18333 jpiera
         * Downloads a URL using the HTTP Post protocol
566
         * @param url
567
         * The server URL
568
         * @param data
569
         * The data to send in the request
570
         * @param name
571
         * A common name for all the retrieved files
572
         * @param cancel
573
         * Used to cancel the downloads
574
         * @return
575
         * The retrieved file
576
         * @throws IOException
577
         * @throws ConnectException
578
         * @throws UnknownHostException
579
         */
580
        public static synchronized File downloadFile(URL url, String data, String name, ICancellable cancel) throws IOException,ConnectException, UnknownHostException{
581
                File f = null;
582
583
                if ((f=getPreviousDownloadedURL(url,data))==null){
584
                        File tempDirectory = new File(tempDirectoryPath);
585
                        if (!tempDirectory.exists())
586
                                tempDirectory.mkdir();
587
588
                        f = new File(tempDirectoryPath+"/"+name+System.currentTimeMillis());
589
590
                        if (cancel == null) {
591
                                cancel = new ICancellable() {
592
                                        public boolean isCanceled() {
593
                                                return false;
594
                                        }
595
                                        public Object getID(){
596
                                                return Utilities.class.getName();
597
                                        }
598
                                };
599
                        }
600
                        Thread downloader = new Thread(new Downloader(url, data, f, cancel.getID()));
601
                        Thread monitor = new Thread(new Monitor(cancel));
602
                        monitor.start();
603
                        downloader.start();
604
                        while(!getCanceled(cancel.getID()) && downloader.isAlive()) {
605
                                try {
606
                                        Thread.sleep(latency);
607
                                } catch (InterruptedException e) {
608
                                        // TODO Auto-generated catch block
609
                                        e.printStackTrace();
610
                                }
611
                        }
612
613
                        if (getCanceled(cancel.getID()))
614
                                return null;
615
                        downloader = null;
616
                        monitor = null;
617
                        if (Utilities.downloadException!=null) {
618
                                Exception e = Utilities.downloadException;
619
                                if (e instanceof FileNotFoundException)
620
                                        throw (IOException) e;
621
                                else if (e instanceof IOException)
622
                                        throw (IOException) e;
623
                                else if (e instanceof ConnectException)
624
                                        throw (ConnectException) e;
625
                                else if (e instanceof UnknownHostException)
626
                                        throw (UnknownHostException) e;
627
                        }
628
                } else {
629
                        System.out.println(url.toString()+" cached at '"+f.getAbsolutePath()+"'");
630
                }
631
632
                return f;
633
        }
634
635
        /**
636 15505 jpiera
         * Try if a group of downloads has been canceled
637
         * @param groupId
638
         * Group id
639
         * @return
640
         * If the group has been canceled
641
         */
642
        protected static boolean getCanceled(Object groupId){
643
                Object obj = canceledGroup.get(groupId);
644
                if (obj != null){
645
                        return ((Boolean)obj).booleanValue();
646
                }
647
                return false;
648
        }
649 14548 jmvivo
650 15505 jpiera
        /**
651
         * Cancel a group of downloads
652
         * @param groupId
653
         * Group id
654
         * @param isCanceled
655
         * if the group has to be canceled
656
         */
657
        protected static void setCanceled(Object groupId, boolean isCanceled){
658
                if (groupId == null){
659
                        groupId = Utilities.class.getName();
660
                }
661
                canceledGroup.put(groupId,new Boolean(isCanceled));
662
        }
663 14548 jmvivo
664 15505 jpiera
        /**
665
         * Cleans every temporal file previously downloaded.
666
         */
667
        public static void cleanUpTempFiles() {
668
                try{
669
                        File tempDirectory = new File(tempDirectoryPath);
670 6042 jaume
671 15505 jpiera
                        File[] files = tempDirectory.listFiles();
672
                        if (files!=null) {
673
                                for (int i = 0; i < files.length; i++) {
674
                                        // s?lo por si en un futuro se necesitan crear directorios temporales
675
                                        if (files[i].isDirectory())        deleteDirectory(files[i]);
676
                                        files[i].delete();
677
                                }
678
                        }
679
                        tempDirectory.delete();
680
                } catch (Exception e) {        }
681 6042 jaume
682 15505 jpiera
        }
683
        /**
684
         * Recursive directory delete.
685
         * @param f
686
         */
687 5409 jaume
        private static void deleteDirectory(File f) {
688
                File[] files = f.listFiles();
689
                for (int i = 0; i < files.length; i++) {
690
                        if (files[i].isDirectory()) deleteDirectory(files[i]);
691
                        files[i].delete();
692
                }
693 6042 jaume
694 5409 jaume
        }
695 6042 jaume
696
697 15505 jpiera
        /**
698
         * Remove an URL from the system cache. The file will remain in the file
699
         * system for further eventual uses.
700
         * @param request
701
         */
702 5409 jaume
        public static void removeURL(URL url) {
703
                if (downloadedFiles != null && downloadedFiles.containsKey(url))
704
                        downloadedFiles.remove(url);
705
        }
706 5536 jaume
707 18333 jpiera
        /**
708
         * Remove an URL from the system cache. The file will remain in the file
709
         * system for further eventual uses.
710
         * @param request
711
         */
712
        public static void removeURL(Object url) {
713
                if (downloadedFiles != null && downloadedFiles.containsKey(url))
714
                        downloadedFiles.remove(url);
715
        }
716 3323 ldiaz
}
717 5536 jaume
718
final class Monitor implements Runnable {
719
        ICancellable c;
720
        public Monitor(ICancellable cancel) {
721 14548 jmvivo
                Utilities.setCanceled(cancel.getID(),false);
722 5536 jaume
                this.c = cancel;
723
        }
724
        public void run() {
725
                while (!c.isCanceled()) {
726
                        try {
727
                                Thread.sleep(Utilities.latency);
728
                        } catch (InterruptedException e) {
729
                                e.printStackTrace();
730
                        }
731
                }
732 6421 jaume
733
                /*  WARNING!! This works because only one download is being processed at once.
734
                 *  You could prefer to start several transfers simultaneously. If so, you
735
                 *  should consideer using a non-static variable such is Utilities.canceled to
736
                 *  control when and which transfer in particular has been canceled.
737
                 *
738
                 *  The feature of transfer several files is at the moment under study. We are
739
                 *  planning to add an intelligent system that will give you a lot of services
740
                 *  and ease-of-use. So, we encourage you to wait for it instead of write your
741
                 *  own code.
742
                 */
743
744 14548 jmvivo
                Utilities.setCanceled(c.getID(),true);
745 5536 jaume
        }
746
}
747
748
final class Downloader implements Runnable {
749
        private URL url;
750
        private File dstFile;
751 14548 jmvivo
        private Object groupID = null;
752 18333 jpiera
        private String data = null;
753 5536 jaume
754 14548 jmvivo
        public Downloader(URL url, File dstFile, Object groupID) {
755 5536 jaume
                this.url = url;
756
                this.dstFile = dstFile;
757 14548 jmvivo
                this.groupID = groupID;
758 5536 jaume
                Utilities.downloadException = null;
759
        }
760
761 18333 jpiera
        public Downloader(URL url, String data, File dstFile, Object groupID) {
762
                this.url = url;
763
                this.data = data;
764
                this.dstFile = dstFile;
765
                this.groupID = groupID;
766
                Utilities.downloadException = null;
767
        }
768
769 5536 jaume
        public void run() {
770
                System.out.println("downloading '"+url.toString()+"' to: "+dstFile.getAbsolutePath());
771 6042 jaume
772 5536 jaume
                DataOutputStream dos;
773
                try {
774 15505 jpiera
                        DataInputStream is;
775 18333 jpiera
                        OutputStreamWriter os = null;
776
                        HttpURLConnection connection = null;
777
                        //If the used protocol is HTTPS
778 15505 jpiera
                        if (url.getProtocol().equals("https")){
779
                                disableHttsValidation();
780 18333 jpiera
                        }
781
                        connection = (HttpURLConnection)url.openConnection();
782
                        //If it uses a HTTP POST
783
                        if (data != null){
784
                                connection.setRequestProperty("SOAPAction","post");
785
                                connection.setRequestMethod("POST");
786
                                connection.setDoOutput(true);
787
                                connection.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");
788
                                os = new OutputStreamWriter(connection.getOutputStream());
789
                                os.write(data);
790
                                os.flush();
791 15505 jpiera
                                is = new DataInputStream(connection.getInputStream());
792
                        }else{
793
                                is = new DataInputStream(url.openStream());
794
                        }
795 18333 jpiera
796 5536 jaume
                        dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(dstFile)));
797 6042 jaume
                        byte[] buffer = new byte[1024*4];
798 15505 jpiera
799
800 5536 jaume
                        long readed = 0;
801 14548 jmvivo
                        for (int i = is.read(buffer); !Utilities.getCanceled(groupID) && i>0; i = is.read(buffer)){
802 5536 jaume
                                dos.write(buffer, 0, i);
803
                                readed += i;
804 6042 jaume
805 5536 jaume
                        }
806 18333 jpiera
                        if(os != null){
807
                                os.close();
808
                        }
809 5536 jaume
                        dos.close();
810
                        is.close();
811
                        is = null;
812
                        dos = null;
813 14548 jmvivo
                        if (Utilities.getCanceled(groupID)) {
814 12043 jaume
                                System.err.println("[RemoteServices] '"+url+"' CANCELED.");
815 5536 jaume
                                dstFile.delete();
816
                                dstFile= null;
817
                        } else {
818
                                Utilities.addDownloadedURL(url, dstFile.getAbsolutePath());
819
                        }
820
                } catch (Exception e) {
821 15505 jpiera
                        e.printStackTrace();
822 5536 jaume
                        Utilities.downloadException = e;
823 15505 jpiera
                }
824
        }
825 6042 jaume
826 15505 jpiera
        /**
827
         * This method disables the Https certificate validation.
828
         * @throws KeyManagementException
829
         * @throws NoSuchAlgorithmException
830
         */
831
        private void disableHttsValidation() throws KeyManagementException, NoSuchAlgorithmException{
832
                // Create a trust manager that does not validate certificate chains
833
                TrustManager[] trustAllCerts = new TrustManager[]{
834
                                new X509TrustManager() {
835
                                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
836
                                                return null;
837
                                        }
838
                                        public void checkClientTrusted(
839
                                                        java.security.cert.X509Certificate[] certs, String authType) {
840
                                        }
841
                                        public void checkServerTrusted(
842
                                                        java.security.cert.X509Certificate[] certs, String authType) {
843
                                        }
844
                                }
845
                };
846
847
                // Install the all-trusting trust manager
848
                SSLContext sc = SSLContext.getInstance("SSL");
849
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
850
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
851 5536 jaume
        }
852
}