Statistics
| Revision:

root / tags / v2_0_0_Build_2051 / extensions / org.gvsig.installer / org.gvsig.installer.lib / org.gvsig.installer.lib.impl / src / main / java / org / gvsig / installer / lib / impl / utils / Decompress.java @ 38753

History | View | Annotate | Download (12.2 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
                                            
219
                                            String trim_lineas = lineas[i].trim();
220
                                            if (! ((trim_lineas.startsWith("#") || trim_lineas.startsWith(";")))) {
221
                                                // not a comment
222
                                                defaultPackagesList.add(lineas[i]);
223
                                            }
224
                                                
225
                                        }
226

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

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

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

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

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

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

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

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

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

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

    
307
        private void decompressPlugin(InputStream inputStream) throws ZipException,
308
                        IOException, InstallerInfoFileException {
309
                ZipInputStream zis = null;
310
                ZipEntry entry = null;
311
                byte data[] = new byte[BUFFER];
312
                int count = 0;
313

    
314
                TaskStatusManager manager = ToolsLocator.getTaskStatusManager();
315
                SimpleTaskStatus taskStatus = manager
316
                                .creteDefaultSimpleTaskStatus("Uncompressing...");
317
                manager.add(taskStatus);
318
                long readed = 0;
319

    
320
                // // First read all the contents size
321
                // zis = new ZipInputStream(inputStream);
322
                // while ((entry = zis.getNextEntry()) != null) {
323
                // count += entry.getSize();
324
                // }
325
                // // zis.close();
326
                // taskStatus.setRangeOfValues(0, count);
327

    
328
                // Return the stream to the initial position
329
                zis = new ZipInputStream(inputStream);
330
                while ((entry = zis.getNextEntry()) != null) {
331
                        String entryName = entry.getName();
332
                        taskStatus.message(entryName);
333

    
334
                        if (File.separatorChar != '/') {
335
                                entryName = entryName.replace('/', File.separatorChar);
336
                        }
337
                        logger.debug("Extracting: " + entryName);
338

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

    
362
        private void createParentFolder(File file) {
363
                File parentFile = file.getParentFile();
364
                if (!parentFile.exists()) {
365
                        parentFile.mkdirs();
366
                }
367
        }
368

    
369
        public boolean delete(File dir) {
370
                if (dir.isDirectory()) {
371
                        String[] children = dir.list();
372
                        for (int i = 0; i < children.length; i++) {
373
                                boolean success = delete(new File(dir, children[i]));
374
                                if (!success) {
375
                                        return false;
376
                                }
377
                        }
378
                }
379
                return dir.delete();
380
        }
381

    
382
        public PackageInfo readInstallerInfo(InputStream is)
383
                        throws InstallerInfoFileException {
384
                try {
385
                        return readInstallInfo(new ZipInputStream(is));
386
                } catch (IOException e) {
387
                        throw new InstallerInfoFileException("error_reading_installerinfo",
388
                                        e);
389
                }
390
        }
391

    
392
        private PackageInfo readInstallInfo(ZipInputStream zipInputStream)
393
                        throws IOException, InstallerInfoFileException {
394
                int count;
395
                byte data[] = new byte[BUFFER];
396

    
397
                ByteArrayOutputStream out = new ByteArrayOutputStream();
398

    
399
                while ((count = zipInputStream.read(data, 0, BUFFER)) != -1) {
400
                        out.write(data, 0, count);
401
                }
402
                out.flush();
403

    
404
                DefaultPackageInfo installerInfo = new DefaultPackageInfo();
405
                InstallerInfoFileReader installerInfoFileReader = new InstallerInfoFileReader();
406
                installerInfoFileReader.read(installerInfo, new ByteArrayInputStream(
407
                                out.toByteArray()));
408

    
409
                return installerInfo;
410
        }
411

    
412
        private String getPackageInfoFileName() {
413
                return InstallerProviderLocator.getProviderManager()
414
                                .getPackageInfoFileName();
415
        }
416

    
417
        public List<String> getDefaultSelectedPackages() {
418
                return defaultSelectedPackets;
419
        }
420
}