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 | 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 | 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á</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 | } |