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 @ 43126
History | View | Annotate | Download (14.7 KB)
1 | 40560 | jjdelcerro | /**
|
---|---|---|---|
2 | * gvSIG. Desktop Geographic Information System.
|
||
3 | 40435 | jjdelcerro | *
|
4 | 40560 | jjdelcerro | * Copyright (C) 2007-2013 gvSIG Association.
|
5 | *
|
||
6 | 40435 | jjdelcerro | * This program is free software; you can redistribute it and/or
|
7 | * modify it under the terms of the GNU General Public License
|
||
8 | 40560 | jjdelcerro | * as published by the Free Software Foundation; either version 3
|
9 | 40435 | jjdelcerro | * of the License, or (at your option) any later version.
|
10 | 40560 | jjdelcerro | *
|
11 | 40435 | jjdelcerro | * 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 | 40560 | jjdelcerro | *
|
16 | 40435 | jjdelcerro | * 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 | 40560 | jjdelcerro | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
19 | 40435 | jjdelcerro | * MA 02110-1301, USA.
|
20 | 40560 | jjdelcerro | *
|
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 | 40435 | jjdelcerro | */
|
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 | 43126 | jjdelcerro | import java.util.Properties; |
41 | 40435 | jjdelcerro | import java.util.zip.ZipEntry; |
42 | import java.util.zip.ZipException; |
||
43 | import java.util.zip.ZipInputStream; |
||
44 | |||
45 | import org.slf4j.Logger; |
||
46 | import org.slf4j.LoggerFactory; |
||
47 | 40969 | jjdelcerro | import org.apache.commons.io.FileUtils; |
48 | 40991 | jjdelcerro | import org.apache.commons.io.FilenameUtils; |
49 | 43126 | jjdelcerro | import org.apache.commons.io.IOUtils; |
50 | 40435 | jjdelcerro | import org.gvsig.installer.lib.api.PackageInfo; |
51 | import org.gvsig.installer.lib.api.execution.InstallPackageServiceException; |
||
52 | import org.gvsig.installer.lib.impl.DefaultPackageInfo; |
||
53 | import org.gvsig.installer.lib.impl.info.InstallerInfoFileReader; |
||
54 | import org.gvsig.installer.lib.spi.InstallerInfoFileException; |
||
55 | import org.gvsig.installer.lib.spi.InstallerProviderLocator; |
||
56 | import org.gvsig.tools.service.ServiceException; |
||
57 | import org.gvsig.tools.task.SimpleTaskStatus; |
||
58 | |||
59 | /**
|
||
60 | * @author <a href="mailto:jpiera@gvsig.org">Jorge Piera Llodrá</a>
|
||
61 | */
|
||
62 | public class Decompress { |
||
63 | |||
64 | private static final int OPTION_DECOMPRESS = 1; |
||
65 | private static final int OPTION_READ_INSTALLINFO = 2; |
||
66 | private static final int OPTION_INSTALL = 3; |
||
67 | |||
68 | private int option = 0; |
||
69 | |||
70 | private int BUFFER = 2048; |
||
71 | |||
72 | private static final Logger logger = LoggerFactory |
||
73 | .getLogger(Decompress.class); |
||
74 | |||
75 | private List<PackageInfo> readedIinstallerInfos = null; |
||
76 | private File outputDirectory = null; |
||
77 | private List<PackageInfo> selectedInstallerInfos = null; |
||
78 | private Map<PackageInfo, String> zipEntriesMap = null; |
||
79 | private List<String> defaultSelectedPackets = null; |
||
80 | 43126 | jjdelcerro | private Properties properties; |
81 | private SimpleTaskStatus taskStatus = null; |
||
82 | |||
83 | 40435 | jjdelcerro | public Decompress() {
|
84 | 43126 | jjdelcerro | this.properties = new Properties(); |
85 | 40435 | jjdelcerro | } |
86 | 43126 | jjdelcerro | |
87 | public Decompress(SimpleTaskStatus taskStatus) {
|
||
88 | this();
|
||
89 | this.taskStatus = taskStatus;
|
||
90 | } |
||
91 | |||
92 | 40435 | jjdelcerro | public void decompressPlugins(InputStream is, File outputDirectory) |
93 | throws InstallPackageServiceException {
|
||
94 | option = OPTION_DECOMPRESS; |
||
95 | this.outputDirectory = outputDirectory;
|
||
96 | |||
97 | decompressFolderOfPlugins(is); |
||
98 | } |
||
99 | |||
100 | public void readPackageSetInstallInfos(InputStream is, |
||
101 | List<PackageInfo> installerInfos,
|
||
102 | Map<PackageInfo, String> zipEntriesMap) |
||
103 | throws InstallPackageServiceException {
|
||
104 | option = OPTION_READ_INSTALLINFO; |
||
105 | this.readedIinstallerInfos = installerInfos;
|
||
106 | this.zipEntriesMap = zipEntriesMap;
|
||
107 | decompressFolderOfPlugins(is); |
||
108 | } |
||
109 | |||
110 | public void readPackageInstallInfo(InputStream is, |
||
111 | List<PackageInfo> installerInfos,
|
||
112 | Map<PackageInfo, String> zipEntriesMap, String name) |
||
113 | throws InstallPackageServiceException {
|
||
114 | option = OPTION_READ_INSTALLINFO; |
||
115 | this.readedIinstallerInfos = installerInfos;
|
||
116 | this.zipEntriesMap = zipEntriesMap;
|
||
117 | decompressFolderOfPluginFromPackage(is, name); |
||
118 | } |
||
119 | |||
120 | public class InstallerPluginReadException extends |
||
121 | InstallPackageServiceException { |
||
122 | |||
123 | private static final long serialVersionUID = -6065359474790792680L; |
||
124 | |||
125 | private static final String message = "Error reading the plugin"; |
||
126 | |||
127 | private static final String KEY = "_Error_reading_the_plugin"; |
||
128 | |||
129 | public InstallerPluginReadException(ServiceException e) {
|
||
130 | super(message, e, KEY, serialVersionUID);
|
||
131 | } |
||
132 | |||
133 | } |
||
134 | |||
135 | public void decompressPlugin(InputStream is, File outputDirectory) |
||
136 | throws InstallPackageServiceException {
|
||
137 | try {
|
||
138 | option = OPTION_DECOMPRESS; |
||
139 | this.outputDirectory = outputDirectory;
|
||
140 | 40969 | jjdelcerro | FileUtils.forceMkdir(outputDirectory); |
141 | 40991 | jjdelcerro | logger.debug("decompress plugin to '"+outputDirectory.getAbsolutePath()+"'."); |
142 | 40435 | jjdelcerro | decompressPlugin(is); |
143 | } catch (Exception e) { |
||
144 | 40936 | jjdelcerro | logger.warn("Can't decompress plugin in '"+outputDirectory+"'.", e); |
145 | 40435 | jjdelcerro | throw new InstallPackageServiceException(e); |
146 | } |
||
147 | } |
||
148 | |||
149 | public class InstallerPluginReadErrorException extends |
||
150 | InstallPackageServiceException { |
||
151 | |||
152 | private static final long serialVersionUID = 4505298394252120334L; |
||
153 | |||
154 | private static final String message = "Error reading the plugin '%(name)s'"; |
||
155 | |||
156 | private static final String KEY = "_Error_reading_the_plugin"; |
||
157 | |||
158 | public InstallerPluginReadErrorException(Exception e, String packageName) { |
||
159 | super(message, e, KEY, serialVersionUID);
|
||
160 | setValue("name", packageName);
|
||
161 | } |
||
162 | |||
163 | } |
||
164 | |||
165 | public InputStream searchPlugin(InputStream is, String zipEntry) |
||
166 | throws InstallPackageServiceException {
|
||
167 | ZipEntry entry = null; |
||
168 | String name = ""; |
||
169 | |||
170 | try {
|
||
171 | ZipInputStream zipInputStream = new ZipInputStream(is); |
||
172 | |||
173 | while ((entry = zipInputStream.getNextEntry()) != null) { |
||
174 | name = entry.getName(); |
||
175 | if (entry.getName().equals(zipEntry)) {
|
||
176 | return zipInputStream;
|
||
177 | } |
||
178 | zipInputStream.closeEntry(); |
||
179 | } |
||
180 | zipInputStream.closeEntry(); |
||
181 | |||
182 | zipInputStream.close(); |
||
183 | } catch (Exception e) { |
||
184 | throw new InstallerPluginReadErrorException(e, name); |
||
185 | } |
||
186 | return null; |
||
187 | } |
||
188 | |||
189 | public void installFromStream(InputStream is, PackageInfo installerInfo) |
||
190 | throws InstallPackageServiceException {
|
||
191 | option = OPTION_INSTALL; |
||
192 | this.selectedInstallerInfos = new ArrayList<PackageInfo>(); |
||
193 | this.selectedInstallerInfos.add(installerInfo);
|
||
194 | decompressFolderOfPlugins(is); |
||
195 | } |
||
196 | |||
197 | public void installFromStream(InputStream is, |
||
198 | List<PackageInfo> installerInfos)
|
||
199 | throws InstallPackageServiceException {
|
||
200 | option = OPTION_INSTALL; |
||
201 | this.selectedInstallerInfos = installerInfos;
|
||
202 | decompressFolderOfPlugins(is); |
||
203 | } |
||
204 | |||
205 | private void decompressFolderOfPlugins(InputStream is) |
||
206 | throws InstallPackageServiceException {
|
||
207 | ZipInputStream zipInputStream = new ZipInputStream(is); |
||
208 | ZipEntry entry = null; |
||
209 | |||
210 | String name = ""; |
||
211 | |||
212 | try {
|
||
213 | while ((entry = zipInputStream.getNextEntry()) != null) { |
||
214 | name = entry.getName(); |
||
215 | if (entry.getName().equals("defaultPackages") |
||
216 | || entry.getName().equals("defaultSelection")) {
|
||
217 | int count;
|
||
218 | byte data[] = new byte[BUFFER]; |
||
219 | ByteArrayOutputStream out = new ByteArrayOutputStream(); |
||
220 | |||
221 | while ((count = zipInputStream.read(data, 0, BUFFER)) != -1) { |
||
222 | out.write(data, 0, count);
|
||
223 | } |
||
224 | |||
225 | String str = out.toString().replace("\r", ""); |
||
226 | String lineas[] = str.split("\\n"); |
||
227 | List<String> defaultPackagesList = new ArrayList<String>(); |
||
228 | |||
229 | for (int i = 0; i < lineas.length; i++) { |
||
230 | |||
231 | String trim_lineas = lineas[i].trim();
|
||
232 | if (! ((trim_lineas.startsWith("#") || trim_lineas.startsWith(";")))) { |
||
233 | // not a comment
|
||
234 | defaultPackagesList.add(lineas[i]); |
||
235 | } |
||
236 | |||
237 | } |
||
238 | |||
239 | defaultSelectedPackets = defaultPackagesList; |
||
240 | out.flush(); |
||
241 | 43126 | jjdelcerro | } else if (entry.getName().equals("packages.properties") ) { |
242 | int count;
|
||
243 | byte data[] = new byte[BUFFER]; |
||
244 | ByteArrayOutputStream out = new ByteArrayOutputStream(); |
||
245 | |||
246 | while ((count = zipInputStream.read(data, 0, BUFFER)) != -1) { |
||
247 | out.write(data, 0, count);
|
||
248 | } |
||
249 | InputStream in = new ByteArrayInputStream(out.toByteArray()); |
||
250 | properties.load(in); |
||
251 | IOUtils.closeQuietly(in); |
||
252 | IOUtils.closeQuietly(out); |
||
253 | } else {
|
||
254 | 40969 | jjdelcerro | // logger.debug("Extracting all Plugins, plugin: " + name);
|
255 | 40435 | jjdelcerro | if (option == OPTION_INSTALL) {
|
256 | |||
257 | } else {
|
||
258 | if (option == OPTION_DECOMPRESS) {
|
||
259 | 40969 | jjdelcerro | logger.info("decompress plugin " + name);
|
260 | 40435 | jjdelcerro | decompressPlugin(zipInputStream); |
261 | } else if (option == OPTION_READ_INSTALLINFO) { |
||
262 | readPlugin(zipInputStream, entry.getName()); |
||
263 | } |
||
264 | } |
||
265 | } |
||
266 | zipInputStream.closeEntry(); |
||
267 | } |
||
268 | zipInputStream.close(); |
||
269 | |||
270 | } catch (Exception e) { |
||
271 | throw new InstallerPluginReadErrorException(e, name); |
||
272 | } |
||
273 | } |
||
274 | |||
275 | private void decompressFolderOfPluginFromPackage(InputStream is, String name) |
||
276 | throws InstallPackageServiceException {
|
||
277 | |||
278 | try {
|
||
279 | if (option == OPTION_INSTALL) {
|
||
280 | |||
281 | } else {
|
||
282 | if (option == OPTION_DECOMPRESS) {
|
||
283 | decompressPlugin(is); |
||
284 | } else {
|
||
285 | if (option == OPTION_READ_INSTALLINFO) {
|
||
286 | readPlugin(is, name); |
||
287 | } |
||
288 | } |
||
289 | } |
||
290 | |||
291 | } catch (Exception e) { |
||
292 | throw new InstallerPluginReadErrorException(e, name); |
||
293 | } |
||
294 | } |
||
295 | |||
296 | private void readPlugin(InputStream is, String zipEntryName) |
||
297 | throws ZipException, IOException, InstallerInfoFileException { |
||
298 | ZipEntry entry = null; |
||
299 | int installerInfoNumber = zipEntriesMap.size();
|
||
300 | String packageInfoName = getPackageInfoFileName();
|
||
301 | String unixPackageInfoPath = "/".concat(packageInfoName); |
||
302 | String windowsPackageInfoPath = "\\".concat(packageInfoName); |
||
303 | ZipInputStream zis = new ZipInputStream(is); |
||
304 | while ((entry = zis.getNextEntry()) != null) { |
||
305 | logger.debug("Extracting: " + entry.getName());
|
||
306 | |||
307 | String name = entry.getName();
|
||
308 | // Just in case, but we are going to create them always using
|
||
309 | // the unix file separator
|
||
310 | if (name.endsWith(unixPackageInfoPath)
|
||
311 | || name.endsWith(windowsPackageInfoPath)) { |
||
312 | PackageInfo installerInfo = readInstallInfo(zis); |
||
313 | zipEntriesMap.put(installerInfo, zipEntryName); |
||
314 | readedIinstallerInfos.add(installerInfo); |
||
315 | } |
||
316 | zis.closeEntry(); |
||
317 | } |
||
318 | // Don't close the stream as if it is a zip file contained
|
||
319 | // into another zip file, closing of the child Zip?nputStream
|
||
320 | // will close also the parent's.
|
||
321 | // zis.close();
|
||
322 | |||
323 | if (installerInfoNumber == zipEntriesMap.size()) {
|
||
324 | PackageInfo installerInfo = new DefaultPackageInfo();
|
||
325 | installerInfo.setCode(zipEntryName); |
||
326 | installerInfo.setName(zipEntryName); |
||
327 | zipEntriesMap.put(installerInfo, zipEntryName); |
||
328 | readedIinstallerInfos.add(installerInfo); |
||
329 | } |
||
330 | } |
||
331 | |||
332 | private void decompressPlugin(InputStream inputStream) throws ZipException, |
||
333 | IOException, InstallerInfoFileException {
|
||
334 | |||
335 | ZipInputStream zis = null; |
||
336 | ZipEntry entry = null; |
||
337 | byte data[] = new byte[BUFFER]; |
||
338 | int count = 0; |
||
339 | |||
340 | 40969 | jjdelcerro | int countRootFolders = 0; |
341 | String entryName = "(header)"; |
||
342 | 40435 | jjdelcerro | try {
|
343 | 40969 | jjdelcerro | long readed = 0; |
344 | 43126 | jjdelcerro | if( taskStatus!=null ) { |
345 | taskStatus.push(); |
||
346 | } |
||
347 | 40969 | jjdelcerro | zis = new ZipInputStream(inputStream); |
348 | while ((entry = zis.getNextEntry()) != null) { |
||
349 | 40991 | jjdelcerro | entryName = FilenameUtils.separatorsToSystem(entry.getName()); |
350 | 43126 | jjdelcerro | if( taskStatus!=null ) { |
351 | taskStatus.message(entryName); |
||
352 | } |
||
353 | 40969 | jjdelcerro | |
354 | File file = new File(outputDirectory, entryName); |
||
355 | if (file.exists()) {
|
||
356 | logger.info("delete " + file.getAbsolutePath());
|
||
357 | 40991 | jjdelcerro | FileUtils.forceDelete(file); |
358 | 40969 | jjdelcerro | } |
359 | if (entry.isDirectory()) {
|
||
360 | 40991 | jjdelcerro | String s = FilenameUtils.getPathNoEndSeparator(entryName);
|
361 | if( !s.contains(File.separator) ) { |
||
362 | 40969 | jjdelcerro | if( ++countRootFolders > 1 ) { |
363 | 40991 | jjdelcerro | logger.warn("More than one root folder ("+entryName+") in the package; it may be an error."); |
364 | 40969 | jjdelcerro | } |
365 | } |
||
366 | logger.debug("makedirs " + file.getAbsolutePath());
|
||
367 | 41902 | jjdelcerro | if( !file.mkdirs() ) {
|
368 | throw new IOException("Can't create folder '"+file.getAbsolutePath()+"'."); |
||
369 | } |
||
370 | 40969 | jjdelcerro | } else {
|
371 | createParentFolder(file); |
||
372 | logger.debug("extracting " + file.getAbsolutePath());
|
||
373 | FileOutputStream fos = new FileOutputStream(file); |
||
374 | while ((count = zis.read(data, 0, BUFFER)) != -1) { |
||
375 | fos.write(data, 0, count);
|
||
376 | readed += count; |
||
377 | 43126 | jjdelcerro | if( taskStatus!=null ) { |
378 | taskStatus.setCurValue(readed); |
||
379 | } |
||
380 | 40969 | jjdelcerro | } |
381 | fos.flush(); |
||
382 | fos.close(); |
||
383 | } |
||
384 | 40435 | jjdelcerro | } |
385 | 40969 | jjdelcerro | zis.close(); |
386 | } catch(IOException ex) { |
||
387 | logger.warn("Problems uncompresing plugin (last entry '"+entryName+"'.",ex); |
||
388 | throw ex;
|
||
389 | |||
390 | } catch(RuntimeException ex) { |
||
391 | logger.warn("Problems uncompresing plugin (last entry '"+entryName+"'.",ex); |
||
392 | throw ex;
|
||
393 | 43126 | jjdelcerro | } finally {
|
394 | if( taskStatus!=null ) { |
||
395 | taskStatus.pop(); |
||
396 | } |
||
397 | } |
||
398 | 40435 | jjdelcerro | } |
399 | |||
400 | private void createParentFolder(File file) { |
||
401 | File parentFile = file.getParentFile();
|
||
402 | if (!parentFile.exists()) {
|
||
403 | parentFile.mkdirs(); |
||
404 | } |
||
405 | } |
||
406 | |||
407 | public boolean delete(File dir) { |
||
408 | if (dir.isDirectory()) {
|
||
409 | String[] children = dir.list(); |
||
410 | for (int i = 0; i < children.length; i++) { |
||
411 | boolean success = delete(new File(dir, children[i])); |
||
412 | if (!success) {
|
||
413 | return false; |
||
414 | } |
||
415 | } |
||
416 | } |
||
417 | return dir.delete();
|
||
418 | } |
||
419 | |||
420 | public PackageInfo readInstallerInfo(InputStream is) |
||
421 | throws InstallerInfoFileException {
|
||
422 | try {
|
||
423 | return readInstallInfo(new ZipInputStream(is)); |
||
424 | } catch (IOException e) { |
||
425 | throw new InstallerInfoFileException("error_reading_installerinfo", |
||
426 | e); |
||
427 | } |
||
428 | } |
||
429 | |||
430 | private PackageInfo readInstallInfo(ZipInputStream zipInputStream) |
||
431 | throws IOException, InstallerInfoFileException { |
||
432 | int count;
|
||
433 | byte data[] = new byte[BUFFER]; |
||
434 | |||
435 | ByteArrayOutputStream out = new ByteArrayOutputStream(); |
||
436 | |||
437 | while ((count = zipInputStream.read(data, 0, BUFFER)) != -1) { |
||
438 | out.write(data, 0, count);
|
||
439 | } |
||
440 | out.flush(); |
||
441 | |||
442 | DefaultPackageInfo installerInfo = new DefaultPackageInfo();
|
||
443 | InstallerInfoFileReader installerInfoFileReader = new InstallerInfoFileReader();
|
||
444 | installerInfoFileReader.read(installerInfo, new ByteArrayInputStream( |
||
445 | out.toByteArray())); |
||
446 | 43126 | jjdelcerro | if( taskStatus!=null ) { |
447 | taskStatus.message(installerInfo.getName()); |
||
448 | } |
||
449 | 40435 | jjdelcerro | return installerInfo;
|
450 | } |
||
451 | |||
452 | private String getPackageInfoFileName() { |
||
453 | return InstallerProviderLocator.getProviderManager()
|
||
454 | .getPackageInfoFileName(); |
||
455 | } |
||
456 | |||
457 | public List<String> getDefaultSelectedPackages() { |
||
458 | return defaultSelectedPackets;
|
||
459 | } |
||
460 | 43126 | jjdelcerro | |
461 | public Properties getProperties() { |
||
462 | return properties;
|
||
463 | } |
||
464 | 40435 | jjdelcerro | } |