View Javadoc

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          // If the jar contents of the directory does not match the contents of the zip
86          // The we will nuke the bundled plugins directory and re-extract.
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         // Create filter that lists only jars
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             // No files, return empty array
116             return Collections.EMPTY_LIST;
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 }