Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / extensions / org.gvsig.installer / org.gvsig.installer.lib / org.gvsig.installer.lib.impl / src / main / java / org / gvsig / installer / lib / impl / utils / Download.java @ 37599

History | View | Annotate | Download (5.43 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
package org.gvsig.installer.lib.impl.utils;
23

    
24
import java.io.BufferedInputStream;
25
import java.io.BufferedOutputStream;
26
import java.io.File;
27
import java.io.FileOutputStream;
28
import java.io.IOException;
29
import java.net.URL;
30
import java.net.URLConnection;
31
import java.util.Date;
32
import java.util.StringTokenizer;
33

    
34
import org.slf4j.Logger;
35
import org.slf4j.LoggerFactory;
36

    
37
import org.gvsig.tools.task.AbstractMonitorableTask;
38
import org.gvsig.tools.task.SimpleTaskStatus;
39

    
40
/**
41
 * @author gvSIG Team
42
 * @version $Id$
43
 * 
44
 */
45
public class Download extends AbstractMonitorableTask {
46

    
47
        private static final Logger LOG = LoggerFactory.getLogger(Download.class);
48
        private boolean isMyTaskStatus;
49

    
50
        /**
51
         * @param taskName
52
         */
53
        public Download(SimpleTaskStatus taskStatus) {
54
                this();
55
                this.taskStatus = taskStatus;
56
                isMyTaskStatus = false;
57
        }
58

    
59
        public Download() {
60
                super("Downloading...");
61
                isMyTaskStatus = true;
62
        }
63

    
64
        public File downloadFile(URL url, String defaultFileName)
65
                        throws IOException {
66

    
67
                URL downloadURL = url;
68

    
69
                // check if the URL ends with '/' and append the file name
70
                if (defaultFileName != null) {
71
                        String urlStr = url.toString();
72
                        if (urlStr.endsWith("/")) {
73
                                urlStr = urlStr.concat(defaultFileName);
74
                                downloadURL = new URL(urlStr);
75
                        }
76
                }
77

    
78
                URLConnection connection = downloadURL.openConnection();
79
                String fileName = getFileName(connection);
80

    
81
                if (LOG.isDebugEnabled()) {
82
                        Date date = new Date(connection.getLastModified());
83
                        LOG
84
                                        .debug(
85
                                                        "Downloading file {} from URL {}, with last modified date: {}",
86
                                                        new Object[] { fileName, downloadURL, date });
87
                }
88

    
89
                String fileNamePrefix = fileName;
90
                String fileNameSuffix = "zip";
91
                int dotPosition = fileName.lastIndexOf('.');
92
                if ((dotPosition > -1) && (dotPosition < fileName.length() - 1)) {
93
                        fileNamePrefix = fileName.substring(0, dotPosition);
94
                        fileNameSuffix = fileName.substring(dotPosition);
95
                }
96

    
97
                BufferedInputStream bis = new BufferedInputStream(downloadURL
98
                                .openStream());
99

    
100
                File localFile = File.createTempFile(fileNamePrefix, fileNameSuffix);
101

    
102
                BufferedOutputStream bos = new BufferedOutputStream(
103
                                new FileOutputStream(localFile));
104

    
105
                this.taskStatus.setRangeOfValues(0, connection.getContentLength());
106
                try {
107
                        byte[] data = new byte[1024];
108
                        int count = 0;
109
                        long totalCount = 0; // total bytes readed
110
                        while ((count = bis.read(data, 0, 1024)) >= 0) {
111
                                bos.write(data, 0, count);
112
                                totalCount += count;
113

    
114
                                this.taskStatus.setCurValue(totalCount);
115

    
116
                                if (this.taskStatus.isCancellationRequested()) {
117
                                        return null;
118
                                }
119
                        }
120
                        if (isMyTaskStatus) {
121
                                this.taskStatus.terminate();
122
                                this.taskStatus.remove();
123
                        }
124
                        return localFile;
125
                } finally {
126
                        bis.close();
127
                        bos.flush();
128
                        bos.close();
129
                }
130

    
131
        }
132

    
133
        /**
134
         * Returns the file name associated to an url connection.<br />
135
         * The result is not a path but just a file name.
136
         * 
137
         * @param urlConnection
138
         *            - the url connection
139
         * @return the file name
140
         * 
141
         * @throws IOException
142
         *             Signals that an I/O exception has occurred.
143
         */
144
        private String getFileName(URLConnection urlConnection) throws IOException {
145
                String fileName = null;
146

    
147
                String contentDisposition = urlConnection
148
                                .getHeaderField("content-disposition");
149

    
150
                if (contentDisposition != null) {
151
                        fileName = extractFileNameFromContentDisposition(contentDisposition);
152
                }
153

    
154
                // if the file name cannot be extracted from the content-disposition
155
                // header, using the url.getFilename() method
156
                if (fileName == null) {
157
                        StringTokenizer st = new StringTokenizer(urlConnection.getURL()
158
                                        .getFile(), "/");
159
                        while (st.hasMoreTokens()) {
160
                                fileName = st.nextToken();
161
                        }
162
                }
163

    
164
                return fileName;
165
        }
166

    
167
        /**
168
         * Extract the file name from the content disposition header.
169
         * <p>
170
         * See <a
171
         * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html">http:
172
         * //www.w3.org/Protocols/rfc2616/rfc2616-sec19.html</a> for detailled
173
         * information regarding the headers in HTML.
174
         * 
175
         * @param contentDisposition
176
         *            - the content-disposition header. Cannot be <code>null>/code>.
177
         * @return the file name, or <code>null</code> if the content-disposition
178
         *         header does not contain the filename attribute.
179
         */
180
        private String extractFileNameFromContentDisposition(
181
                        String contentDisposition) {
182
                String[] attributes = contentDisposition.split(";");
183

    
184
                for (String a : attributes) {
185
                        if (a.toLowerCase().contains("filename")) {
186
                                // The attribute is the file name. The filename is between
187
                                // quotes.
188
                                return a.substring(a.indexOf('\"') + 1, a.lastIndexOf('\"'));
189
                        }
190
                }
191

    
192
                // not found
193
                return null;
194

    
195
        }
196
}