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 / Decompress.java @ 38218

History | View | Annotate | Download (12 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 * 
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 * 
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
 * MA  02110-1301, USA.
20
 * 
21
 */
22

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2010 {Prodevelop}   {Task}
26
 */
27

    
28
package org.gvsig.installer.lib.impl.utils;
29

    
30
import java.io.ByteArrayInputStream;
31
import java.io.ByteArrayOutputStream;
32
import java.io.File;
33
import java.io.FileOutputStream;
34
import java.io.IOException;
35
import java.io.InputStream;
36
import java.util.ArrayList;
37
import java.util.List;
38
import java.util.Map;
39
import java.util.zip.ZipEntry;
40
import java.util.zip.ZipException;
41
import java.util.zip.ZipInputStream;
42

    
43
import org.slf4j.Logger;
44
import org.slf4j.LoggerFactory;
45

    
46
import org.gvsig.installer.lib.api.PackageInfo;
47
import org.gvsig.installer.lib.api.execution.InstallPackageServiceException;
48
import org.gvsig.installer.lib.impl.DefaultPackageInfo;
49
import org.gvsig.installer.lib.impl.info.InstallerInfoFileReader;
50
import org.gvsig.installer.lib.spi.InstallerInfoFileException;
51
import org.gvsig.installer.lib.spi.InstallerProviderLocator;
52
import org.gvsig.tools.ToolsLocator;
53
import org.gvsig.tools.service.ServiceException;
54
import org.gvsig.tools.task.SimpleTaskStatus;
55
import org.gvsig.tools.task.TaskStatusManager;
56

    
57
/**
58
 * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera Llodr&aacute;</a>
59
 */
60
public class Decompress {
61

    
62
        private static final int OPTION_DECOMPRESS = 1;
63
        private static final int OPTION_READ_INSTALLINFO = 2;
64
        private static final int OPTION_INSTALL = 3;
65

    
66
        private int option = 0;
67

    
68
        private int BUFFER = 2048;
69

    
70
        private static final Logger logger = LoggerFactory
71
                        .getLogger(Decompress.class);
72

    
73
        private List<PackageInfo> readedIinstallerInfos = null;
74
        private File outputDirectory = null;
75
        private List<PackageInfo> selectedInstallerInfos = null;
76
        private Map<PackageInfo, String> zipEntriesMap = null;
77
        private List<String> defaultSelectedPackets = null;
78

    
79
        public Decompress() {
80

    
81
        }
82

    
83
        public void decompressPlugins(InputStream is, File outputDirectory)
84
                        throws InstallPackageServiceException {
85
                option = OPTION_DECOMPRESS;
86
                this.outputDirectory = outputDirectory;
87

    
88
                decompressFolderOfPlugins(is);
89
        }
90

    
91
        public void readPackageSetInstallInfos(InputStream is,
92
                        List<PackageInfo> installerInfos,
93
                        Map<PackageInfo, String> zipEntriesMap)
94
                        throws InstallPackageServiceException {
95
                option = OPTION_READ_INSTALLINFO;
96
                this.readedIinstallerInfos = installerInfos;
97
                this.zipEntriesMap = zipEntriesMap;
98
                decompressFolderOfPlugins(is);
99
        }
100

    
101
        public void readPackageInstallInfo(InputStream is,
102
                        List<PackageInfo> installerInfos,
103
                        Map<PackageInfo, String> zipEntriesMap, String name)
104
                        throws InstallPackageServiceException {
105
                option = OPTION_READ_INSTALLINFO;
106
                this.readedIinstallerInfos = installerInfos;
107
                this.zipEntriesMap = zipEntriesMap;
108
                decompressFolderOfPluginFromPackage(is, name);
109
        }
110

    
111
        public class InstallerPluginReadException extends
112
                        InstallPackageServiceException {
113

    
114
                private static final long serialVersionUID = -6065359474790792680L;
115

    
116
                private static final String message = "Error reading the plugin";
117

    
118
                private static final String KEY = "_Error_reading_the_plugin";
119

    
120
                public InstallerPluginReadException(ServiceException e) {
121
                        super(message, e, KEY, serialVersionUID);
122
                }
123

    
124
        }
125

    
126
        public void decompressPlugin(InputStream is, File outputDirectory)
127
                        throws InstallPackageServiceException {
128
                try {
129
                        option = OPTION_DECOMPRESS;
130
                        this.outputDirectory = outputDirectory;
131
                        decompressPlugin(is);
132
                } catch (Exception e) {
133
                        throw new InstallPackageServiceException(e);
134
                }
135
        }
136

    
137
        public class InstallerPluginReadErrorException extends
138
                        InstallPackageServiceException {
139

    
140
                private static final long serialVersionUID = 4505298394252120334L;
141

    
142
                private static final String message = "Error reading the plugin '%(name)s'";
143

    
144
                private static final String KEY = "_Error_reading_the_plugin";
145

    
146
                public InstallerPluginReadErrorException(Exception e, String packageName) {
147
                        super(message, e, KEY, serialVersionUID);
148
                        setValue("name", packageName);
149
                }
150

    
151
        }
152

    
153
        public InputStream searchPlugin(InputStream is, String zipEntry)
154
                        throws InstallPackageServiceException {
155
                ZipEntry entry = null;
156
                String name = "";
157

    
158
                try {
159
                        ZipInputStream zipInputStream = new ZipInputStream(is);
160

    
161
                        while ((entry = zipInputStream.getNextEntry()) != null) {
162
                                name = entry.getName();
163
                                if (entry.getName().equals(zipEntry)) {
164
                                        return zipInputStream;
165
                                }
166
                                zipInputStream.closeEntry();
167
                        }
168
                        zipInputStream.closeEntry();
169

    
170
                        zipInputStream.close();
171
                } catch (Exception e) {
172
                        throw new InstallerPluginReadErrorException(e, name);
173
                }
174
                return null;
175
        }
176

    
177
        public void installFromStream(InputStream is, PackageInfo installerInfo)
178
                        throws InstallPackageServiceException {
179
                option = OPTION_INSTALL;
180
                this.selectedInstallerInfos = new ArrayList<PackageInfo>();
181
                this.selectedInstallerInfos.add(installerInfo);
182
                decompressFolderOfPlugins(is);
183
        }
184

    
185
        public void installFromStream(InputStream is,
186
                        List<PackageInfo> installerInfos)
187
                        throws InstallPackageServiceException {
188
                option = OPTION_INSTALL;
189
                this.selectedInstallerInfos = installerInfos;
190
                decompressFolderOfPlugins(is);
191
        }
192

    
193
        private void decompressFolderOfPlugins(InputStream is)
194
                        throws InstallPackageServiceException {
195
                ZipInputStream zipInputStream = new ZipInputStream(is);
196
                ZipEntry entry = null;
197

    
198
                String name = "";
199

    
200
                try {
201
                        while ((entry = zipInputStream.getNextEntry()) != null) {
202
                                name = entry.getName();
203
                                if (entry.getName().equals("defaultPackages")
204
                                                || entry.getName().equals("defaultSelection")) {
205
                                        int count;
206
                                        byte data[] = new byte[BUFFER];
207
                                        ByteArrayOutputStream out = new ByteArrayOutputStream();
208

    
209
                                        while ((count = zipInputStream.read(data, 0, BUFFER)) != -1) {
210
                                                out.write(data, 0, count);
211
                                        }
212

    
213
                                        String str = out.toString().replace("\r", "");
214
                                        String lineas[] = str.split("\\n");
215
                                        List<String> defaultPackagesList = new ArrayList<String>();
216

    
217
                                        for (int i = 0; i < lineas.length; i++) {
218
                                                defaultPackagesList.add(lineas[i]);
219
                                        }
220

    
221
                                        defaultSelectedPackets = defaultPackagesList;
222
                                        out.flush();
223
                                } else {
224
                                        logger.debug("Extracting all Plugins, plugin: " + entry);
225
                                        if (option == OPTION_INSTALL) {
226

    
227
                                        } else {
228
                                                if (option == OPTION_DECOMPRESS) {
229
                                                        decompressPlugin(zipInputStream);
230
                                                } else if (option == OPTION_READ_INSTALLINFO) {
231
                                                        readPlugin(zipInputStream, entry.getName());
232
                                                }
233
                                        }
234
                                }
235
                                zipInputStream.closeEntry();
236
                        }
237
                        zipInputStream.close();
238

    
239
                } catch (Exception e) {
240
                        throw new InstallerPluginReadErrorException(e, name);
241
                }
242
        }
243

    
244
        private void decompressFolderOfPluginFromPackage(InputStream is, String name)
245
                        throws InstallPackageServiceException {
246

    
247
                try {
248
                        if (option == OPTION_INSTALL) {
249

    
250
                        } else {
251
                                if (option == OPTION_DECOMPRESS) {
252
                                        decompressPlugin(is);
253
                                } else {
254
                                        if (option == OPTION_READ_INSTALLINFO) {
255
                                                readPlugin(is, name);
256
                                        }
257
                                }
258
                        }
259

    
260
                } catch (Exception e) {
261
                        throw new InstallerPluginReadErrorException(e, name);
262
                }
263
        }
264

    
265
        private void readPlugin(InputStream is, String zipEntryName)
266
                        throws ZipException, IOException, InstallerInfoFileException {
267
                ZipEntry entry = null;
268
                int installerInfoNumber = zipEntriesMap.size();
269
                String packageInfoName = getPackageInfoFileName();
270
                String unixPackageInfoPath = "/".concat(packageInfoName);
271
                String windowsPackageInfoPath = "\\".concat(packageInfoName);
272
                ZipInputStream zis = new ZipInputStream(is);
273
                while ((entry = zis.getNextEntry()) != null) {
274
                        logger.debug("Extracting: " + entry.getName());
275

    
276
                        String name = entry.getName();
277
                        // Just in case, but we are going to create them always using
278
                        // the unix file separator
279
                        if (name.endsWith(unixPackageInfoPath)
280
                                        || name.endsWith(windowsPackageInfoPath)) {
281
                                PackageInfo installerInfo = readInstallInfo(zis);
282
                                zipEntriesMap.put(installerInfo, zipEntryName);
283
                                readedIinstallerInfos.add(installerInfo);
284
                        }
285
                        zis.closeEntry();
286
                }
287
                // Don't close the stream as if it is a zip file contained
288
                // into another zip file, closing of the child Zip?nputStream
289
                // will close also the parent's.
290
                // zis.close();
291

    
292
                if (installerInfoNumber == zipEntriesMap.size()) {
293
                        PackageInfo installerInfo = new DefaultPackageInfo();
294
                        installerInfo.setCode(zipEntryName);
295
                        installerInfo.setName(zipEntryName);
296
                        zipEntriesMap.put(installerInfo, zipEntryName);
297
                        readedIinstallerInfos.add(installerInfo);
298
                }
299
        }
300

    
301
        private void decompressPlugin(InputStream inputStream) throws ZipException,
302
                        IOException, InstallerInfoFileException {
303
                ZipInputStream zis = null;
304
                ZipEntry entry = null;
305
                byte data[] = new byte[BUFFER];
306
                int count = 0;
307

    
308
                TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
309
                SimpleTaskStatus taskStatus = manager
310
                                .creteDefaultSimpleTaskStatus("Uncompressing...");
311
                manager.add(taskStatus);
312
                long readed = 0;
313

    
314
                // // First read all the contents size
315
                // zis = new ZipInputStream(inputStream);
316
                // while ((entry = zis.getNextEntry()) != null) {
317
                // count += entry.getSize();
318
                // }
319
                // // zis.close();
320
                // taskStatus.setRangeOfValues(0, count);
321

    
322
                // Return the stream to the initial position
323
                zis = new ZipInputStream(inputStream);
324
                while ((entry = zis.getNextEntry()) != null) {
325
                        String entryName = entry.getName();
326
                        taskStatus.message(entryName);
327

    
328
                        if (File.separatorChar != '/') {
329
                                entryName = entryName.replace('/', File.separatorChar);
330
                        }
331
                        logger.debug("Extracting: " + entryName);
332

    
333
                        File file = new File(outputDirectory.getAbsolutePath()
334
                                        + File.separator + entryName);
335
                        if (file.exists()) {
336
                                delete(file);
337
                        }
338
                        if (entry.isDirectory()) {
339
                                file.mkdirs();
340
                        } else {
341
                                createParentFolder(file);
342
                                FileOutputStream fos = new FileOutputStream(file);
343
                                while ((count = zis.read(data, 0, BUFFER)) != -1) {
344
                                        fos.write(data, 0, count);
345
                                        readed += count;
346
                                        taskStatus.setCurValue(readed);
347
                                }
348
                                fos.flush();
349
                                fos.close();
350
                        }
351
                }
352
                zis.close();
353
                taskStatus.remove();
354
        }
355

    
356
        private void createParentFolder(File file) {
357
                File parentFile = file.getParentFile();
358
                if (!parentFile.exists()) {
359
                        parentFile.mkdirs();
360
                }
361
        }
362

    
363
        public boolean delete(File dir) {
364
                if (dir.isDirectory()) {
365
                        String[] children = dir.list();
366
                        for (int i = 0; i < children.length; i++) {
367
                                boolean success = delete(new File(dir, children[i]));
368
                                if (!success) {
369
                                        return false;
370
                                }
371
                        }
372
                }
373
                return dir.delete();
374
        }
375

    
376
        public PackageInfo readInstallerInfo(InputStream is)
377
                        throws InstallerInfoFileException {
378
                try {
379
                        return readInstallInfo(new ZipInputStream(is));
380
                } catch (IOException e) {
381
                        throw new InstallerInfoFileException("error_reading_installerinfo",
382
                                        e);
383
                }
384
        }
385

    
386
        private PackageInfo readInstallInfo(ZipInputStream zipInputStream)
387
                        throws IOException, InstallerInfoFileException {
388
                int count;
389
                byte data[] = new byte[BUFFER];
390

    
391
                ByteArrayOutputStream out = new ByteArrayOutputStream();
392

    
393
                while ((count = zipInputStream.read(data, 0, BUFFER)) != -1) {
394
                        out.write(data, 0, count);
395
                }
396
                out.flush();
397

    
398
                DefaultPackageInfo installerInfo = new DefaultPackageInfo();
399
                InstallerInfoFileReader installerInfoFileReader = new InstallerInfoFileReader();
400
                installerInfoFileReader.read(installerInfo, new ByteArrayInputStream(
401
                                out.toByteArray()));
402

    
403
                return installerInfo;
404
        }
405

    
406
        private String getPackageInfoFileName() {
407
                return InstallerProviderLocator.getProviderManager()
408
                                .getPackageInfoFileName();
409
        }
410

    
411
        public List<String> getDefaultSelectedPackages() {
412
                return defaultSelectedPackets;
413
        }
414
}