You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by jd...@apache.org on 2009/04/24 22:46:45 UTC

svn commit: r768412 - /wicket/trunk/wicket/src/main/java/org/apache/wicket/util/resource/ZipResourceStream.java

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