1 package com.atlassian.plugin.util.zip;
2
3 import org.apache.commons.io.IOUtils;
4 import org.apache.commons.io.FileUtils;
5 import org.apache.commons.logging.Log;
6 import org.apache.commons.logging.LogFactory;
7
8 import java.io.*;
9 import java.util.zip.ZipEntry;
10 import java.util.zip.ZipInputStream;
11 import java.util.List;
12 import java.util.ArrayList;
13 import java.util.Collections;
14
15 public abstract class AbstractUnzipper implements Unzipper
16 {
17 protected static Log log = LogFactory.getLog(FileUnzipper.class);
18 protected File destDir;
19
20 protected File saveEntry(InputStream is, ZipEntry entry) throws IOException
21 {
22 File file = new File(destDir, entry.getName());
23
24 if (entry.isDirectory())
25 {
26 file.mkdirs();
27 }
28 else
29 {
30 File dir = new File(file.getParent());
31 dir.mkdirs();
32
33 FileOutputStream fos = null;
34 try
35 {
36 fos = new FileOutputStream(file);
37 IOUtils.copy(is, fos);
38 fos.flush();
39 }
40 catch (FileNotFoundException fnfe)
41 {
42 log.error("Error extracting a file to '" + destDir + File.separator + entry.getName() + "'. This destination is invalid for writing an extracted file stream to. ");
43 return null;
44 }
45 finally
46 {
47 IOUtils.closeQuietly(fos);
48 }
49 }
50
51 return file;
52 }
53
54 protected ZipEntry[] entries(ZipInputStream zis) throws IOException
55 {
56 List entries = new ArrayList();
57 try
58 {
59 ZipEntry zipEntry = zis.getNextEntry();
60 while (zipEntry != null)
61 {
62 entries.add(zipEntry);
63 zis.closeEntry();
64 zipEntry = zis.getNextEntry();
65 }
66 }
67 finally
68 {
69 IOUtils.closeQuietly(zis);
70 }
71
72 return (ZipEntry[]) entries.toArray(new ZipEntry[entries.size()]);
73 }
74
75 public void conditionalUnzip() throws IOException
76 {
77 List zipContents = new ArrayList();
78
79 ZipEntry[] zipEntries = entries();
80 for (int i = 0; i < zipEntries.length; i++)
81 {
82 zipContents.add(zipEntries[i].getName());
83 }
84
85
86
87 List targetDirContents = getContentsOfTargetDir(destDir);
88 if (!targetDirContents.equals(zipContents))
89 {
90 FileUtils.deleteDirectory(destDir);
91 unzip();
92 }
93 else
94 {
95 if (log.isDebugEnabled())
96 log.debug("Target directory contents match zip contents. Do nothing.");
97 }
98 }
99
100 protected List getContentsOfTargetDir(File dir)
101 {
102
103 FilenameFilter filter = new FilenameFilter()
104 {
105 public boolean accept(File dir, String name)
106 {
107 return name.endsWith(".jar");
108 }
109 };
110
111 String[] children = dir.list(filter);
112
113 if (children == null)
114 {
115
116 return Collections.emptyList();
117 }
118
119 ArrayList targetDirContents = new ArrayList();
120
121 if (log.isDebugEnabled() && children.length > 0)
122 log.debug("Listing JAR files in " + dir.getAbsolutePath());
123
124 for (int i = 0; i < children.length; i++)
125 {
126 if (log.isDebugEnabled())
127 log.debug(children[i]);
128 targetDirContents.add(children[i]);
129
130 }
131 return targetDirContents;
132 }
133 }