Statistics
| Revision:

svn-gvsig-desktop / tags / v1_0_2_Build_907 / libraries / libRemoteServices / src / org / gvsig / remoteClient / utils / Utilities.java @ 11015

History | View | Annotate | Download (15.6 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

    
494
                    if (canceled)
495
                            return null;
496
                    downloader = null;
497
                    monitor = null;
498
                    if (Utilities.downloadException!=null) {
499
                            Exception e = Utilities.downloadException;
500
                            if (e instanceof FileNotFoundException)
501
                                    throw (IOException) e;
502
                            else if (e instanceof IOException)
503
                                    throw (IOException) e;
504
                            else if (e instanceof ConnectException)
505
                                    throw (ConnectException) e;
506
                            else if (e instanceof UnknownHostException)
507
                                    throw (UnknownHostException) e;
508
                    }
509
            } else {
510
                    System.out.println(url.toString()+" cached at '"+f.getAbsolutePath()+"'");
511
            }
512

    
513
            return f;
514
        }
515

    
516
    /**
517
     * Cleans every temporal file previously downloaded.
518
     */
519
    public static void cleanUpTempFiles() {
520
            try{
521
                    File tempDirectory = new File(tempDirectoryPath);
522

    
523
                    File[] files = tempDirectory.listFiles();
524
                    if (files!=null) {
525
                            for (int i = 0; i < files.length; i++) {
526
                                     // s?lo por si en un futuro se necesitan crear directorios temporales
527
                                    if (files[i].isDirectory())        deleteDirectory(files[i]);
528
                                    files[i].delete();
529
                            }
530
                    }
531
                    tempDirectory.delete();
532
            } catch (Exception e) {        }
533

    
534
    }
535
    /**
536
     * Recursive directory delete.
537
     * @param f
538
     */
539
        private static void deleteDirectory(File f) {
540
                File[] files = f.listFiles();
541
                for (int i = 0; i < files.length; i++) {
542
                        if (files[i].isDirectory()) deleteDirectory(files[i]);
543
                        files[i].delete();
544
                }
545

    
546
        }
547

    
548

    
549
    /**
550
     * Remove an URL from the system cache. The file will remain in the file
551
     * system for further eventual uses.
552
     * @param request
553
     */
554
        public static void removeURL(URL url) {
555
                if (downloadedFiles != null && downloadedFiles.containsKey(url))
556
                        downloadedFiles.remove(url);
557
        }
558

    
559

    
560
}
561

    
562
final class Monitor implements Runnable {
563
        ICancellable c;
564
        public Monitor(ICancellable cancel) {
565
                Utilities.canceled = false;
566
                this.c = cancel;
567
        }
568
        public void run() {
569
                while (!c.isCanceled()) {
570
                        try {
571
                                Thread.sleep(Utilities.latency);
572
                        } catch (InterruptedException e) {
573
                                e.printStackTrace();
574
                        }
575
                }
576

    
577
                /*  WARNING!! This works because only one download is being processed at once.
578
                 *  You could prefer to start several transfers simultaneously. If so, you
579
                 *  should consideer using a non-static variable such is Utilities.canceled to
580
                 *  control when and which transfer in particular has been canceled.
581
                 *
582
                 *  The feature of transfer several files is at the moment under study. We are
583
                 *  planning to add an intelligent system that will give you a lot of services
584
                 *  and ease-of-use. So, we encourage you to wait for it instead of write your
585
                 *  own code.
586
                 */
587

    
588
                Utilities.canceled = true;
589
        }
590
}
591

    
592
final class Downloader implements Runnable {
593
        private URL url;
594
        private File dstFile;
595

    
596
        public Downloader(URL url, File dstFile) {
597
                this.url = url;
598
                this.dstFile = dstFile;
599
                Utilities.downloadException = null;
600
        }
601

    
602
        public void run() {
603
                System.out.println("downloading '"+url.toString()+"' to: "+dstFile.getAbsolutePath());
604

    
605
                DataOutputStream dos;
606
                try {
607
                        dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(dstFile)));
608
                        byte[] buffer = new byte[1024*4];
609
                        DataInputStream is = new DataInputStream(url.openStream());
610
                        long readed = 0;
611
                        for (int i = is.read(buffer); !Utilities.canceled && i>0; i = is.read(buffer)){
612
                                dos.write(buffer, 0, i);
613
                                readed += i;
614

    
615
                        }
616
                        dos.close();
617
                        is.close();
618
                        is = null;
619
                        dos = null;
620
                        if (Utilities.canceled) {
621
                                System.err.println("[RemoteClients] '"+url+"' CANCELED.");
622
                                dstFile.delete();
623
                                dstFile= null;
624
                        } else {
625
                                Utilities.addDownloadedURL(url, dstFile.getAbsolutePath());
626
                        }
627
                } catch (Exception e) {
628
                        Utilities.downloadException = e;
629
                }
630

    
631
        }
632
}