Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.installer / org.gvsig.installer.lib / org.gvsig.installer.lib.impl / src / main / java / org / gvsig / installer / lib / impl / utils / Decompress.java @ 40560

History | View | Annotate | Download (12.3 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
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 3
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
/*
25
 * AUTHORS (In addition to CIT):
26
 * 2010 {Prodevelop}   {Task}
27
 */
28

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

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

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

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

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

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

    
67
        private int option = 0;
68

    
69
        private int BUFFER = 2048;
70

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

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

    
80
        public Decompress() {
81

    
82
        }
83

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

    
89
                decompressFolderOfPlugins(is);
90
        }
91

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

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

    
112
        public class InstallerPluginReadException extends
113
                        InstallPackageServiceException {
114

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

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

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

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

    
125
        }
126

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

    
138
        public class InstallerPluginReadErrorException extends
139
                        InstallPackageServiceException {
140

    
141
                private static final long serialVersionUID = 4505298394252120334L;
142

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

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

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

    
152
        }
153

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

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

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

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

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

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

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

    
199
                String name = "";
200

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

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

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

    
218
                                        for (int i = 0; i < lineas.length; i++) {
219
                                            
220
                                            String trim_lineas = lineas[i].trim();
221
                                            if (! ((trim_lineas.startsWith("#") || trim_lineas.startsWith(";")))) {
222
                                                // not a comment
223
                                                defaultPackagesList.add(lineas[i]);
224
                                            }
225
                                                
226
                                        }
227

    
228
                                        defaultSelectedPackets = defaultPackagesList;
229
                                        out.flush();
230
                                } else {
231
                                        logger.debug("Extracting all Plugins, plugin: " + entry);
232
                                        if (option == OPTION_INSTALL) {
233

    
234
                                        } else {
235
                                                if (option == OPTION_DECOMPRESS) {
236
                                                        decompressPlugin(zipInputStream);
237
                                                } else if (option == OPTION_READ_INSTALLINFO) {
238
                                                        readPlugin(zipInputStream, entry.getName());
239
                                                }
240
                                        }
241
                                }
242
                                zipInputStream.closeEntry();
243
                        }
244
                        zipInputStream.close();
245

    
246
                } catch (Exception e) {
247
                        throw new InstallerPluginReadErrorException(e, name);
248
                }
249
        }
250

    
251
        private void decompressFolderOfPluginFromPackage(InputStream is, String name)
252
                        throws InstallPackageServiceException {
253

    
254
                try {
255
                        if (option == OPTION_INSTALL) {
256

    
257
                        } else {
258
                                if (option == OPTION_DECOMPRESS) {
259
                                        decompressPlugin(is);
260
                                } else {
261
                                        if (option == OPTION_READ_INSTALLINFO) {
262
                                                readPlugin(is, name);
263
                                        }
264
                                }
265
                        }
266

    
267
                } catch (Exception e) {
268
                        throw new InstallerPluginReadErrorException(e, name);
269
                }
270
        }
271

    
272
        private void readPlugin(InputStream is, String zipEntryName)
273
                        throws ZipException, IOException, InstallerInfoFileException {
274
                ZipEntry entry = null;
275
                int installerInfoNumber = zipEntriesMap.size();
276
                String packageInfoName = getPackageInfoFileName();
277
                String unixPackageInfoPath = "/".concat(packageInfoName);
278
                String windowsPackageInfoPath = "\\".concat(packageInfoName);
279
                ZipInputStream zis = new ZipInputStream(is);
280
                while ((entry = zis.getNextEntry()) != null) {
281
                        logger.debug("Extracting: " + entry.getName());
282

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

    
299
                if (installerInfoNumber == zipEntriesMap.size()) {
300
                        PackageInfo installerInfo = new DefaultPackageInfo();
301
                        installerInfo.setCode(zipEntryName);
302
                        installerInfo.setName(zipEntryName);
303
                        zipEntriesMap.put(installerInfo, zipEntryName);
304
                        readedIinstallerInfos.add(installerInfo);
305
                }
306
        }
307

    
308
        private void decompressPlugin(InputStream inputStream) throws ZipException,
309
                        IOException, InstallerInfoFileException {
310

    
311
                ZipInputStream zis = null;
312
                ZipEntry entry = null;
313
                byte data[] = new byte[BUFFER];
314
                int count = 0;
315

    
316
                TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
317
                SimpleTaskStatus taskStatus = manager
318
                                .createDefaultSimpleTaskStatus("Uncompressing...");
319
                
320
                manager.add(taskStatus);
321
                
322
                try {
323
                long readed = 0;
324

    
325
                // // First read all the contents size
326
                // zis = new ZipInputStream(inputStream);
327
                // while ((entry = zis.getNextEntry()) != null) {
328
                // count += entry.getSize();
329
                // }
330
                // // zis.close();
331
                // taskStatus.setRangeOfValues(0, count);
332

    
333
                // Return the stream to the initial position
334
                zis = new ZipInputStream(inputStream);
335
                while ((entry = zis.getNextEntry()) != null) {
336
                        String entryName = entry.getName();
337
                        taskStatus.message(entryName);
338

    
339
                        if (File.separatorChar != '/') {
340
                                entryName = entryName.replace('/', File.separatorChar);
341
                        }
342
                        logger.debug("Extracting: " + entryName);
343

    
344
                        File file = new File(outputDirectory.getAbsolutePath()
345
                                        + File.separator + entryName);
346
                        if (file.exists()) {
347
                                delete(file);
348
                        }
349
                        if (entry.isDirectory()) {
350
                                file.mkdirs();
351
                        } else {
352
                                createParentFolder(file);
353
                                FileOutputStream fos = new FileOutputStream(file);
354
                                while ((count = zis.read(data, 0, BUFFER)) != -1) {
355
                                        fos.write(data, 0, count);
356
                                        readed += count;
357
                                        taskStatus.setCurValue(readed);
358
                                }
359
                                fos.flush();
360
                                fos.close();
361
                        }
362
                }
363
                zis.close();
364
                
365
                } finally {
366
                    
367
                    taskStatus.remove();
368
                    
369
                }
370
                
371
        
372
        }
373

    
374
        private void createParentFolder(File file) {
375
                File parentFile = file.getParentFile();
376
                if (!parentFile.exists()) {
377
                        parentFile.mkdirs();
378
                }
379
        }
380

    
381
        public boolean delete(File dir) {
382
                if (dir.isDirectory()) {
383
                        String[] children = dir.list();
384
                        for (int i = 0; i < children.length; i++) {
385
                                boolean success = delete(new File(dir, children[i]));
386
                                if (!success) {
387
                                        return false;
388
                                }
389
                        }
390
                }
391
                return dir.delete();
392
        }
393

    
394
        public PackageInfo readInstallerInfo(InputStream is)
395
                        throws InstallerInfoFileException {
396
                try {
397
                        return readInstallInfo(new ZipInputStream(is));
398
                } catch (IOException e) {
399
                        throw new InstallerInfoFileException("error_reading_installerinfo",
400
                                        e);
401
                }
402
        }
403

    
404
        private PackageInfo readInstallInfo(ZipInputStream zipInputStream)
405
                        throws IOException, InstallerInfoFileException {
406
                int count;
407
                byte data[] = new byte[BUFFER];
408

    
409
                ByteArrayOutputStream out = new ByteArrayOutputStream();
410

    
411
                while ((count = zipInputStream.read(data, 0, BUFFER)) != -1) {
412
                        out.write(data, 0, count);
413
                }
414
                out.flush();
415

    
416
                DefaultPackageInfo installerInfo = new DefaultPackageInfo();
417
                InstallerInfoFileReader installerInfoFileReader = new InstallerInfoFileReader();
418
                installerInfoFileReader.read(installerInfo, new ByteArrayInputStream(
419
                                out.toByteArray()));
420

    
421
                return installerInfo;
422
        }
423

    
424
        private String getPackageInfoFileName() {
425
                return InstallerProviderLocator.getProviderManager()
426
                                .getPackageInfoFileName();
427
        }
428

    
429
        public List<String> getDefaultSelectedPackages() {
430
                return defaultSelectedPackets;
431
        }
432
}