Author: jdonnerstag
Date: Fri Apr 24 20:46:44 2009
New Revision: 768412

URL: http://svn.apache.org/viewvc?rev=768412&view=rev
Log:
applied patch WICKET-2230 Nested directory support for ZipResourceStream
Issue: WICKET-2230

Modified:
    
wicket/trunk/wicket/src/main/java/org/apache/wicket/util/resource/ZipResourceStream.java

Modified: 
wicket/trunk/wicket/src/main/java/org/apache/wicket/util/resource/ZipResourceStream.java
URL: 
http://svn.apache.org/viewvc/wicket/trunk/wicket/src/main/java/org/apache/wicket/util/resource/ZipResourceStream.java?rev=768412&r1=768411&r2=768412&view=diff
==============================================================================
--- 
wicket/trunk/wicket/src/main/java/org/apache/wicket/util/resource/ZipResourceStream.java
 (original)
+++ 
wicket/trunk/wicket/src/main/java/org/apache/wicket/util/resource/ZipResourceStream.java
 Fri Apr 24 20:46:44 2009
@@ -20,7 +20,6 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.zip.ZipEntry;
@@ -37,19 +36,14 @@
  * An IResourceStream that ZIPs a directory's contents on the fly
  * 
  * <p>
- * <b>NOTE 1.</b> Nested directories are not supported yet, and a {...@link 
FileNotFoundException} will
- * be thrown in that case.
- * </p>
- * 
- * <p>
- * <b>NOTE 2.</b> As a future improvement, cache a map of generated ZIP files 
for every directory
+ * <b>NOTE 1.</b> As a future improvement, cache a map of generated ZIP files 
for every directory
  * and use a Watcher to detect modifications in this directory. Using ehcache 
would be good for
  * that, but it's not in Wicket dependencies yet. <b>No caching of the 
generated ZIP files is done
  * yet.</b>
  * </p>
  * 
  * <p>
- * <b>NOTE 3.</b> As a future improvement, implement getLastModified() and 
request
+ * <b>NOTE 2.</b> As a future improvement, implement getLastModified() and 
request
  * ResourceStreamRequestTarget to generate Last-Modified and Expires HTTP 
headers. <b>No HTTP cache
  * headers are provided yet</b>. See WICKET-385
  * </p>
@@ -58,14 +52,11 @@
  */
 public class ZipResourceStream extends AbstractResourceStream
 {
-       /**
-        * 
-        */
        private static final long serialVersionUID = 1L;
 
        private static final Logger log = 
LoggerFactory.getLogger(ZipResourceStream.class);
 
-       ByteArrayOutputStream bytearray;
+       private final ByteArrayOutputStream bytearray;
 
        /**
         * Construct.
@@ -73,31 +64,90 @@
         * @param dir
         *            The directory where to look for files. The directory 
itself will not be included
         *            in the ZIP.
+        * @param recursive
+        *            If true, all subdirs will be zipped as well
         */
-       public ZipResourceStream(File dir)
+       public ZipResourceStream(final File dir, final boolean recursive)
        {
+               if ((dir == null) || !dir.isDirectory())
+               {
+                       throw new IllegalArgumentException("Not a directory: " 
+ dir);
+               }
+
                bytearray = new ByteArrayOutputStream();
                try
                {
-                       int BUFFER = 2048;
-                       BufferedInputStream origin = null;
                        ZipOutputStream out = new ZipOutputStream(bytearray);
-                       byte data[] = new byte[BUFFER];
-                       // get a list of files from current directory
-                       String files[] = dir.list();
+                       zipDir(dir, out, "", recursive);
+               }
+               catch (Exception e)
+               {
+                       throw new WicketRuntimeException(e);
+               }
+       }
+
+       /**
+        * Construct. Until Wicket 1.4-RC3 recursive zip was not supported. In 
order not to change the
+        * behavior, using this constructor will default to recursive == false.
+        * 
+        * @param dir
+        *            The directory where to look for files. The directory 
itself will not be included
+        *            in the ZIP.
+        */
+       public ZipResourceStream(final File dir)
+       {
+               this(dir, false);
+       }
+
+       /**
+        * Recursive method for zipping the contents of a directory including 
nested directories.
+        * 
+        * @param dir
+        *            dir to be zipped
+        * @param out
+        *            ZipOutputStream to write to
+        * @param path
+        *            Path to nested dirs (used in resursive calls)
+        * @param recursive
+        *            If true, all subdirs will be zipped as well
+        * @throws IOException
+        */
+       private static void zipDir(final File dir, final ZipOutputStream out, 
final String path,
+               final boolean recursive) throws IOException
+       {
+               if (!dir.isDirectory())
+               {
+                       throw new IllegalArgumentException("Not a directory: " 
+ dir);
+               }
 
-                       if (files == null)
+               String[] files = dir.list();
+
+               int BUFFER = 2048;
+               BufferedInputStream origin = null;
+               byte data[] = new byte[BUFFER];
+
+               for (int i = 0; i < files.length; i++)
+               {
+                       if (log.isDebugEnabled())
                        {
-                               throw new IllegalArgumentException("Not a 
directory: " + dir);
+                               log.debug("Adding: " + files[i]);
                        }
 
-                       for (int i = 0; i < files.length; i++)
+                       File f = new File(dir, files[i]);
+                       if (f.isDirectory())
                        {
-                               log.debug("Adding: " + files[i]);
-                               FileInputStream fi = new FileInputStream(new 
File(dir, files[i]));
+                               if (recursive == true)
+                               {
+                                       zipDir(f, out, path + f.getName() + 
"/", recursive);
+                               }
+                       }
+                       else
+                       {
+                               out.putNextEntry(new ZipEntry(path.toString() + 
f.getName()));
+
+                               FileInputStream fi = new FileInputStream(f);
                                origin = new BufferedInputStream(fi, BUFFER);
-                               ZipEntry entry = new ZipEntry(files[i]);
-                               out.putNextEntry(entry);
+
                                int count;
                                while ((count = origin.read(data, 0, BUFFER)) 
!= -1)
                                {
@@ -105,14 +155,17 @@
                                }
                                origin.close();
                        }
-                       out.close();
                }
-               catch (Exception e)
+
+               if (path.equals(""))
                {
-                       throw new WicketRuntimeException(e);
+                       out.close();
                }
        }
 
+       /**
+        * @see org.apache.wicket.util.resource.IResourceStream#close()
+        */
        public void close() throws IOException
        {
        }
@@ -126,20 +179,29 @@
                return null;
        }
 
+       /**
+        * @see org.apache.wicket.util.resource.IResourceStream#getInputStream()
+        */
        public InputStream getInputStream() throws 
ResourceStreamNotFoundException
        {
                return new ByteArrayInputStream(bytearray.toByteArray());
        }
 
+       /**
+        * @see org.apache.wicket.util.resource.AbstractResourceStream#length()
+        */
        @Override
        public long length()
        {
                return bytearray.size();
        }
 
+       /**
+        * @see 
org.apache.wicket.util.resource.AbstractResourceStream#lastModifiedTime()
+        */
        @Override
        public Time lastModifiedTime()
        {
                return null;
        }
-}
+}
\ No newline at end of file


Reply via email to