Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRemoteServices / src / org / gvsig / remoteClient / utils / Utilities.java @ 5536

History | View | Annotate | Download (15 KB)

1
package org.gvsig.remoteClient.utils;
2
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
3
 *
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

    
43
import java.io.BufferedOutputStream;
44
import java.io.DataInputStream;
45
import java.io.DataOutputStream;
46
import java.io.File;
47
import java.io.FileNotFoundException;
48
import java.io.FileOutputStream;
49
import java.io.FileReader;
50
import java.io.IOException;
51
import java.io.InputStream;
52
import java.io.OutputStream;
53
import java.net.ConnectException;
54
import java.net.URL;
55
import java.net.UnknownHostException;
56
import java.rmi.NoSuchObjectException;
57
import java.util.Hashtable;
58
import java.util.StringTokenizer;
59
import java.util.Vector;
60

    
61
import org.gvsig.remoteClient.wms.ICancellable;
62

    
63

    
64
/**
65
 * Clase con m?todos de utilidad en el protocolo WMS
66
 *
67
 * @authors Laura D?az, jaume dominguez faus
68
 */
69
public class Utilities {
70
        private static String characters;
71
        static boolean canceled;
72
        static final long latency = 500;
73
        /**
74
     * <b>key</b>: URL, <b>value</b>: path to the downloaded file.
75
     */
76
    private static Hashtable downloadedFiles;
77
        static Exception downloadException;
78
    private static final String tempDirectoryPath = System.getProperty("java.io.tmpdir")+"/tmp-andami";
79
        
80
        
81
        static {
82
                characters = "";
83
                for (int j = 32; j<=127; j++){
84
                        characters += (char) j;
85
                }
86
                characters += "?????????????????????????????????????????????????\n\r\f\t??";
87
        }
88
        
89
        
90
        /**
91
         * Checks a File and tries to figure if the file is a text or a binary file.<br>
92
         * Keep in mind that binary files are those that contains at least one
93
         * non-printable character.
94
         * 
95
         * @param file
96
         * @return <b>true</b> when the file is <b>pretty problably</b> text, 
97
         * <b>false</b> if the file <b>is</b> binary.
98
         */
99
        public static boolean isTextFile(File file){
100
                return isTextFile(file, 1024);
101
        }
102
        
103
        /**
104
         * Checks a File and tries to figure if the file is a text or a binary file.<br>
105
         * Keep in mind that binary files are those that contains at least one
106
         * non-printable character. 
107
         * 
108
         * @param file
109
         * @param byteAmount, number of bytes to check.
110
         * @return <b>true</b> when the file is <b>pretty problably</b> text, 
111
         * <b>false</b> if the file <b>is</b> binary.
112
         */
113
        public static boolean isTextFile(File file, int byteAmount){
114
                int umbral = byteAmount; 
115
                try {
116
                        FileReader fr = new FileReader(file);
117
                        for (int i = 0; i < umbral; i++) {
118
                                int c = fr.read();
119
                                if (c==-1){
120
                                        // End of file. If we reach this
121
                                        // everything before is printable data.
122
                                        return true;
123
                                }
124
                                char ch = (char) c;
125
                                if (characters.indexOf(ch)==-1){
126
                                        // We've found a non-printable character.
127
                                        // Then we'll assume that this file is binary.
128
                                        return false;
129
                                }
130
                        }
131
                } catch (FileNotFoundException e) {
132
                        e.printStackTrace();
133
                } catch (IOException e) {
134
                        e.printStackTrace();
135
                }
136
                return true;
137
        }
138
        
139
        /**
140
         * Checks a byte array and tells if it contains only text or contains
141
         * any binary data.
142
         * 
143
         * @param file
144
         * @return <b>true</b> when the data is <b>only</b> text, <b>false</b> otherwise.
145
         * @deprecated
146
         */
147
        public static boolean isTextData(byte[] data){
148
                char[] charData = new char[data.length];
149
                for (int i = 0; i<data.length; i++){
150
                        charData[i] = (char) data[i];
151
                }
152
                
153
                for (int i = 0; i < data.length; i++) {
154
                        int c = charData[i];
155
                        
156
                        
157
                        if (c==-1){
158
                                // End of file. If we reach this
159
                                // everything before is printable data.
160
                                return true;
161
                        }
162
                        char ch = (char) c;
163
                        if (characters.indexOf(ch)==-1){
164
                                // We've found a non-printable character.
165
                                // Then we'll assume that this file is binary.
166
                                
167
                                //System.out.println(ch+" at "+i);
168
                                return false;
169
                        }
170
                }
171
                return true;
172
        }
173
        
174
        
175
        
176
        
177
        /**
178
         * Copia el contenido de un InputStream en un OutputStream
179
         *
180
         * @param in InputStream
181
         * @param out OutputStream
182
         */
183
        public static void serializar(InputStream in, OutputStream out) {
184
                byte[] buffer = new byte[102400];
185
                
186
                int n;
187
                
188
                try {
189
                        while ((n = in.read(buffer)) != -1) {
190
                                out.write(buffer, 0, n);
191
                        }
192
                } catch (IOException e) {
193
                        e.printStackTrace();
194
                }
195
        }
196
        
197
        /**
198
         * Elimina del xml la declaraci?n del DTD
199
         *
200
         * @param bytes bytes del fichero XML de respuesta a getCapabilities
201
         * @param startTag Tag raiz del xml respuesta a getCapabilities
202
         *
203
         * @return bytes del fichero XML sin la declaraci?n del DTD
204
         */
205
        public static byte[] eliminarDTD(byte[] bytes, String startTag) {
206
                String text = new String(bytes);
207
                int index1 = text.indexOf("?>") + 2;
208
                int index2;
209
                
210
                try {
211
                        index2 = findBeginIndex(bytes, startTag);
212
                } catch (NoSuchObjectException e) {
213
                        return bytes;
214
                }
215
                
216
                byte[] buffer = new byte[bytes.length - (index2 - index1)];
217
                System.arraycopy(bytes, 0, buffer, 0, index1);
218
                System.arraycopy(bytes, index2, buffer, index1, bytes.length - index2);
219
                
220
                return buffer;
221
        }
222
        
223
        /**
224
         * Obtiene el ?ndice del comienzo del xml
225
         *
226
         * @param bytes bytes del fichero XML en el que se busca
227
         * @param tagRaiz Tag raiz del xml respuesta a getCapabilities
228
         *
229
         * @return ?ndice donde empieza el tag raiz
230
         *
231
         * @throws NoSuchObjectException Si no se encuentra el tag
232
         */
233
        private static int findBeginIndex(byte[] bytes, String tagRaiz)
234
        throws NoSuchObjectException {
235
                try {
236
                        int nodo = 0;
237
                        int ret = -1;
238
                        
239
                        int i = 0;
240
                        
241
                        while (true) {
242
                                switch (nodo) {
243
                                case 0:
244
                                        
245
                                        if (bytes[i] == '<') {
246
                                                ret = i;
247
                                                nodo = 1;
248
                                        }
249
                                        
250
                                        break;
251
                                        
252
                                case 1:
253
                                        
254
                                        if (bytes[i] == ' ') {
255
                                        } else if (bytes[i] == tagRaiz.charAt(0)) {
256
                                                nodo = 2;
257
                                        } else {
258
                                                nodo = 0;
259
                                        }
260
                                        
261
                                        break;
262
                                        
263
                                case 2:
264
                                        
265
                                        String aux = new String(bytes, i, 18);
266
                                        
267
                                        if (aux.equalsIgnoreCase(tagRaiz.substring(1))) {
268
                                                return ret;
269
                                        }
270
                                        
271
                                        nodo = 0;
272
                                        
273
                                        break;
274
                                }
275
                                
276
                                i++;
277
                        }
278
                } catch (Exception e) {
279
                        throw new NoSuchObjectException("No se pudo parsear el xml");
280
                }
281
        }
282
        
283
        /**
284
         * Converts the contents of a Vector to a comma separated list
285
         * 
286
         * */
287
        public static String Vector2CS(Vector v)
288
        {
289
                String str = new String();        
290
                if (v != null)
291
                {
292
                        int i;
293
                        for (i=0; i<v.size() ;i++)
294
                        {
295
                                str = str + v.elementAt(i);
296
                                if (i<v.size()-1)
297
                                        str = str + ",";
298
                        }
299
                }
300
                return str;
301
        }
302
        
303
        public static boolean isValidVersion(String version)
304
        {
305
                if(version.trim().length() == 5)
306
                {
307
                        if ( (version.charAt(1)=='.') && (version.charAt(3)=='.'))
308
                        {
309
                                char x = version.charAt(0);
310
                                char y = version.charAt(2);
311
                                char z = version.charAt(4);
312
                                
313
                                if ((Character.isDigit(x)) && (Character.isDigit(y)) && (Character.isDigit(z)))
314
                                {
315
                                        return true;
316
                                }
317
                                else
318
                                {
319
                                        return false;
320
                                }
321
                        }
322
                        else
323
                        {
324
                                return false;
325
                        }
326
                }
327
                else
328
                {
329
                        return false;
330
                }
331
        }
332
        
333
        /**
334
         * Crea un fichero temporal con un nombre concreto y unos datos pasados por
335
         * par?metro.
336
         * @param fileName Nombre de fichero
337
         * @param data datos a guardar en el fichero
338
         */
339
        public static void createTemp(String fileName, String data)throws IOException{
340
                File f = new File(fileName);
341
                DataOutputStream dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(f)) );
342
                dos.writeBytes(data);
343
                dos.close();
344
                f.deleteOnExit();
345
        }
346
        
347
        /**
348
         * Checks if a String is a number or not
349
         * 
350
         * @param String, s
351
         * @return boolean, true if s is a number
352
         */
353
        public static boolean isNumber(String s) 
354
        {
355
                try
356
                {
357
                        //double d = Double.parseDouble(s);
358
                        return true;
359
                }
360
                catch(NumberFormatException e)
361
                {
362
                        return false;
363
                }
364
                
365
        }  
366
        
367
        /**
368
         * Parses the String containing different items [character] separated and
369
         * creates a vector with them.
370
         * @param str String contains item1[c]item2[c]item3...
371
         * @param c is the string value for separating the items
372
         * @return Vector containing all the items
373
         */
374
        public static Vector createVector(String str, String c)
375
        {
376
                StringTokenizer tokens = new StringTokenizer(str, c);
377
                Vector v = new Vector();
378
                try
379
                {
380
                        while (tokens.hasMoreTokens())
381
                        {
382
                                v.addElement(tokens.nextToken());
383
                        }
384
                        return v;
385
                }
386
                catch (Exception e)
387
                {
388
                        return new Vector();
389
                }
390
        }
391
        
392
        /**
393
         * @param dimensions
394
         * @return
395
         */
396
        public static String Vector2URLParamString(Vector v) {
397
                if (v==null) return "";
398
                String s = "";
399
                for (int i = 0; i < v.size(); i++) {
400
                        s += v.get(i);
401
                        if (i<v.size()-1)
402
                                s += "&";
403
                }
404
                return s;
405
        }
406
        
407
        /**
408
     * Returns the content of this URL as a file from the file system.<br>
409
     * <p>
410
     * If the URL has been already downloaded in this session and notified 
411
     * to the system using the static <b>Utilities.addDownloadedURL(URL)</b>
412
     * method, it can be restored faster from the file system avoiding to
413
     * download it again.
414
     * </p>
415
     * @param url
416
     * @return File containing this URL's content or null if no file was found.
417
     */
418
    private static File getPreviousDownloadedURL(URL url){
419
        File f = null;
420
        if (downloadedFiles!=null && downloadedFiles.containsKey(url)){
421
            String filePath = (String) downloadedFiles.get(url);
422
            f = new File(filePath);
423
            if (!f.exists())
424
                    return null;
425
        }
426
        return f;
427
    }
428
    
429
    /**
430
     * Adds an URL to the table of downloaded files for further uses. If the URL
431
     * already exists in the table its filePath value is updated to the new one and
432
     * the old file itself is removed from the file system.
433
     * 
434
     * @param url
435
     * @param filePath
436
     */
437
    static void addDownloadedURL(URL url, String filePath){
438
        if (downloadedFiles==null)
439
            downloadedFiles = new Hashtable();
440
        String fileName = (String) downloadedFiles.put(url, filePath);
441
        //JMV: No se puede eliminar el anterior porque puede que alguien lo
442
        // este usando
443
        /*
444
        if (fileName!=null){
445
            File f = new File(fileName);
446
            if (f.exists())
447
                f.delete();
448
        }
449
        */
450
    }
451
       
452
    /**
453
     * Downloads an URL into a temporary file that is removed the next time the 
454
     * tempFileManager class is called, which means the next time gvSIG is launched.
455
     * 
456
     * @param url
457
     * @param name
458
     * @return
459
     * @throws IOException
460
     * @throws ServerErrorResponseException
461
     * @throws ConnectException
462
     * @throws UnknownHostException
463
     */
464
    public static synchronized File downloadFile(URL url, String name, ICancellable cancel) throws IOException,ConnectException, UnknownHostException{
465
            File f = null;
466
            
467
            if ((f=getPreviousDownloadedURL(url))==null){
468
                    File tempDirectory = new File(tempDirectoryPath);
469
                    if (!tempDirectory.exists())
470
                            tempDirectory.mkdir();
471
                    
472
                    f = new File(tempDirectoryPath+"/"+name+System.currentTimeMillis());
473
                    
474
                    if (cancel == null) {
475
                            cancel = new ICancellable() {
476
                                        public boolean isCanceled() {
477
                                                return false;
478
                                        }
479
                            };
480
                    }
481
                    Thread downloader = new Thread(new Downloader(url, f));
482
                    Thread monitor = new Thread(new Monitor(cancel));
483
                    monitor.start();
484
                    downloader.start();
485
                    while(!canceled && downloader.isAlive()) {
486
                            try {
487
                                        Thread.sleep(latency);
488
                                } catch (InterruptedException e) {
489
                                        // TODO Auto-generated catch block
490
                                        e.printStackTrace();
491
                                }
492
                    }
493
                    downloader = null;
494
                    monitor = null;
495
                    if (Utilities.downloadException!=null) {
496
                            Exception e = Utilities.downloadException;
497
                            if (e instanceof IOException)
498
                                    throw (IOException) e;
499
                            else if (e instanceof ConnectException)
500
                                    throw (ConnectException) e;
501
                            else if (e instanceof UnknownHostException)
502
                                    throw (UnknownHostException) e;
503
                    }
504
            }
505
            
506
            return f;
507
        }
508

    
509
    /**
510
     * Cleans every temporal file previously downloaded.
511
     */
512
    public static void cleanUpTempFiles() {
513
            try{
514
                    File tempDirectory = new File(tempDirectoryPath);
515
                    
516
                    File[] files = tempDirectory.listFiles();
517
                    if (files!=null) {
518
                            for (int i = 0; i < files.length; i++) {
519
                                     // s?lo por si en un futuro se necesitan crear directorios temporales
520
                                    if (files[i].isDirectory())        deleteDirectory(files[i]);
521
                                    files[i].delete();
522
                            }
523
                    }
524
                    tempDirectory.delete();
525
            } catch (Exception e) {        }
526
            
527
    }
528
    /**
529
     * Recursive directory delete.
530
     * @param f
531
     */
532
        private static void deleteDirectory(File f) {
533
                File[] files = f.listFiles();
534
                for (int i = 0; i < files.length; i++) {
535
                        if (files[i].isDirectory()) deleteDirectory(files[i]);
536
                        files[i].delete();
537
                }
538
                
539
        }
540
        
541
        
542
    /**
543
     * Remove an URL from the system cache. The file will remain in the file
544
     * system for further eventual uses.
545
     * @param request
546
     */
547
        public static void removeURL(URL url) {
548
                if (downloadedFiles != null && downloadedFiles.containsKey(url))
549
                        downloadedFiles.remove(url);
550
        }
551

    
552
        
553
}
554

    
555
final class Monitor implements Runnable {
556
        ICancellable c;
557
        public Monitor(ICancellable cancel) {
558
                Utilities.canceled = false;
559
                this.c = cancel;
560
        }
561
        public void run() {
562
                while (!c.isCanceled()) {
563
                        try {
564
                                Thread.sleep(Utilities.latency);
565
                        } catch (InterruptedException e) {
566
                                // TODO Auto-generated catch block
567
                                e.printStackTrace();
568
                        }
569
                }
570
                Utilities.canceled = true;
571
        }
572
}
573

    
574
final class Downloader implements Runnable {
575
        private URL url;
576
        private File dstFile;
577

    
578
        public Downloader(URL url, File dstFile) {
579
                this.url = url;
580
                this.dstFile = dstFile;
581
                Utilities.downloadException = null;
582
        }
583

    
584
        public void run() {
585
                System.out.println("downloading '"+url.toString()+"' to: "+dstFile.getAbsolutePath());
586
                
587
                DataOutputStream dos;
588
                try {
589
                        dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(dstFile)));
590
                        byte[] buffer = new byte[1024*4]; 
591
                        DataInputStream is = new DataInputStream(url.openStream());
592
                        long readed = 0;
593
                        for (int i = is.read(buffer); !Utilities.canceled && i>0; i = is.read(buffer)){
594
                                dos.write(buffer, 0, i);
595
                                readed += i;
596
                                
597
                        }
598
                        dos.close();
599
                        is.close();
600
                        is = null;
601
                        dos = null;
602
                        if (Utilities.canceled) {
603
                                System.err.println("[RemoteClients] '"+url+"' CANCELED.");
604
                                dstFile.delete();
605
                                dstFile= null;
606
                        } else {
607
                                Utilities.addDownloadedURL(url, dstFile.getAbsolutePath());
608
                        }
609
                } catch (Exception e) {
610
                        Utilities.downloadException = e;
611
                }
612
                
613
        }
614
}