[jboss-svn-commits] JBoss Common SVN: r3874 - in shrinkwrap/trunk: impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter and 2 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Dec 22 11:53:11 EST 2009


Author: ALRubinger
Date: 2009-12-22 11:53:10 -0500 (Tue, 22 Dec 2009)
New Revision: 3874

Added:
   shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/exporter/FileExistsException.java
Modified:
   shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/exporter/ZipExporter.java
   shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/ZipExporterImpl.java
   shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/io/IOUtil.java
   shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/exporter/ExportTestBase.java
   shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/exporter/ZipExporterTestCase.java
Log:
[SHRINKWRAP-87] Add support to export to ZIP File

Added: shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/exporter/FileExistsException.java
===================================================================
--- shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/exporter/FileExistsException.java	                        (rev 0)
+++ shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/exporter/FileExistsException.java	2009-12-22 16:53:10 UTC (rev 3874)
@@ -0,0 +1,52 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jboss.shrinkwrap.api.exporter;
+
+import java.io.File;
+
+/**
+ * Thrown to denote that an export request to a particular
+ * {@link File} has failed because the file specified already exists
+ * and should not be overwritten. 
+ * 
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class FileExistsException extends IllegalArgumentException
+{
+
+   //-------------------------------------------------------------------------------------||
+   // Class Members ----------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * serialVersionUID
+    */
+   private static final long serialVersionUID = 1L;
+
+   //-------------------------------------------------------------------------------------||
+   // Constructor ------------------------------------------------------------------------||
+   //-------------------------------------------------------------------------------------||
+
+   /**
+    * @param s
+    */
+   public FileExistsException(final String s)
+   {
+      super(s);
+   }
+}

Modified: shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/exporter/ZipExporter.java
===================================================================
--- shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/exporter/ZipExporter.java	2009-12-22 15:41:57 UTC (rev 3873)
+++ shrinkwrap/trunk/api/src/main/java/org/jboss/shrinkwrap/api/exporter/ZipExporter.java	2009-12-22 16:53:10 UTC (rev 3874)
@@ -16,17 +16,18 @@
  */
 package org.jboss.shrinkwrap.api.exporter;
 
+import java.io.File;
 import java.io.InputStream;
 
 import org.jboss.shrinkwrap.api.Assignable;
 
 /**
- * ZipExporter
+ * Exporter used to represent an Archive as a ZIP format. 
  * 
- * Exporter used to export an Archive as a Zip format. 
- * 
+ * @see http://www.pkware.com/documents/casestudies/APPNOTE.TXT
  * @author <a href="mailto:baileyje at gmail.com">John Bailey</a>
  * @author <a href="mailto:aslak at conduct.no">Aslak Knutsen</a>
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
  * @version $Revision: $
  */
 public interface ZipExporter extends Assignable
@@ -39,9 +40,36 @@
     * Exports provided archive as a Zip archive.
     * 
     * @param archive
-    * @return InputStram for exported Zip
-    * @throws IllegalArgumentException if the archive is not valid
+    * @return {@link InputStream} for exported Zip
     * @throws ArchiveExportException if the export process fails
     */
-   InputStream exportZip();
+   InputStream exportZip() throws ArchiveExportException;
+
+   /**
+    * Exports provided archive as a ZIP archive, written to the 
+    * specified {@link File} target.  If the target exists this call will
+    * fail with {@link IllegalArgumentException}
+    * 
+    * @param archive
+    * @return {@link InputStream} for exported Zip
+    * @throws IllegalArgumentException If the target is not specified
+    * @throws FileExistsException If the target already exists 
+    * @throws ArchiveExportException if the export process fails
+    */
+   void exportZip(File target) throws ArchiveExportException, FileExistsException, IllegalArgumentException;
+
+   /**
+    * Exports provided archive as a ZIP archive, written to the 
+    * specified {@link File} target.  If the target both exists and the "overwrite"
+    * flag is true, this call will allow the existing file to be overwritten, else
+    * the invocation will fail with {@link IllegalArgumentException}
+    * 
+    * @param archive
+    * @return {@link InputStream} for exported Zip
+    * @throws IllegalArgumentException If the target is not specified 
+    * @throws FileExistsException If the target both already exists and the overwrite flag is false
+    * @throws ArchiveExportException if the export process fails
+    */
+   void exportZip(File target, boolean overwrite) throws ArchiveExportException, FileExistsException,
+         IllegalArgumentException;
 }

Modified: shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/ZipExporterImpl.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/ZipExporterImpl.java	2009-12-22 15:41:57 UTC (rev 3873)
+++ shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/exporter/ZipExporterImpl.java	2009-12-22 16:53:10 UTC (rev 3874)
@@ -16,21 +16,28 @@
  */
 package org.jboss.shrinkwrap.impl.base.exporter;
 
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.logging.Logger;
 
 import org.jboss.shrinkwrap.api.Archive;
+import org.jboss.shrinkwrap.api.exporter.ArchiveExportException;
+import org.jboss.shrinkwrap.api.exporter.FileExistsException;
 import org.jboss.shrinkwrap.api.exporter.ZipExporter;
 import org.jboss.shrinkwrap.impl.base.AssignableBase;
 import org.jboss.shrinkwrap.impl.base.Validate;
+import org.jboss.shrinkwrap.impl.base.io.IOUtil;
 
 /**
- * ZipExporterImpl
- * 
  * Implementation of ZipExporter used to export an Archive as a Zip format. 
  * 
  * @author <a href="mailto:baileyje at gmail.com">John Bailey</a>
  * @author <a href="mailto:aslak at conduct.no">Aslak Knutsen</a>
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
  * @version $Revision: $
  */
 public class ZipExporterImpl extends AssignableBase implements ZipExporter
@@ -48,13 +55,13 @@
    /**
     * Archive to import into. 
     */
-   private Archive<?> archive; 
-   
+   private Archive<?> archive;
+
    //-------------------------------------------------------------------------------------||
    // Constructor ------------------------------------------------------------------------||
    //-------------------------------------------------------------------------------------||
 
-   public ZipExporterImpl(Archive<?> archive) 
+   public ZipExporterImpl(final Archive<?> archive)
    {
       Validate.notNull(archive, "Archive must be specified");
       this.archive = archive;
@@ -77,7 +84,8 @@
    // Required Implementations - ZipExporter ---------------------------------------------||
    //-------------------------------------------------------------------------------------||
 
-   /* (non-Javadoc)
+   /**
+    * {@inheritDoc}
     * @see org.jboss.shrinkwrap.api.exporter.ZipExporter#exportZip()
     */
    @Override
@@ -89,10 +97,65 @@
       // Execute export
       exportDelegate.export();
       // Get results
-      InputStream inputStream = exportDelegate.getResult(); 
+      InputStream inputStream = exportDelegate.getResult();
 
       // Return input stream
       return inputStream;
    }
 
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.shrinkwrap.api.exporter.ZipExporter#exportZip(java.io.File, boolean)
+    */
+   @Override
+   public void exportZip(final File target, final boolean overwrite) throws ArchiveExportException,
+         FileExistsException, IllegalArgumentException
+   {
+      // Precondition checks
+      if (target == null)
+      {
+         throw new IllegalArgumentException("Target file must be specified");
+      }
+      // If target exists and we're not allowed to overwrite it
+      if (target.exists() && !overwrite)
+      {
+         throw new FileExistsException("Target exists and we haven't been flagged to overwrite it: "
+               + target.getAbsolutePath());
+      }
+
+      // Get Streams
+      final InputStream in = this.exportZip();
+      final OutputStream out;
+      try
+      {
+         out = new FileOutputStream(target);
+      }
+      catch (final FileNotFoundException e)
+      {
+         throw new ArchiveExportException("File could not be created: " + target);
+      }
+
+      // Write out
+      try
+      {
+         IOUtil.copyWithClose(in, out);
+      }
+      catch (final IOException e)
+      {
+         throw new ArchiveExportException("Error encountered in exporting archive to " + target.getAbsolutePath(), e);
+      }
+
+   }
+
+   /**
+    * {@inheritDoc}
+    * @see org.jboss.shrinkwrap.api.exporter.ZipExporter#exportZip(java.io.File)
+    */
+   @Override
+   public void exportZip(final File target) throws ArchiveExportException, FileExistsException,
+         IllegalArgumentException
+   {
+      this.exportZip(target, false);
+   }
+
 }

Modified: shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/io/IOUtil.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/io/IOUtil.java	2009-12-22 15:41:57 UTC (rev 3873)
+++ shrinkwrap/trunk/impl-base/src/main/java/org/jboss/shrinkwrap/impl/base/io/IOUtil.java	2009-12-22 16:53:10 UTC (rev 3874)
@@ -27,8 +27,6 @@
 import org.jboss.shrinkwrap.impl.base.Validate;
 
 /**
- * IOUtil
- * 
  * Generic input/output utilities
  *
  * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
@@ -112,7 +110,10 @@
          }
          catch (final IOException ignore)
          {
-
+            if (log.isLoggable(Level.FINER))
+            {
+               log.finer("Could not close stream due to: " + ignore.getMessage() + "; ignoring");
+            }
          }
          // We don't need to close the outstream, it's a byte array out
       }
@@ -125,28 +126,24 @@
    }
 
    /**
-    * Copies the contents from an InputStream to an OutputStream
+    * Copies the contents from an InputStream to an OutputStream.  It is the
+    * responsibility of the caller to close the streams passed in when done, 
+    * though the {@link OutputStream} will be fully flushed.
     * 
     * @param input
     * @param output
+    * @throws IOException If a problem occurred during any I/O operations
     */
-   public static void copy(InputStream input, OutputStream output)
+   public static void copy(InputStream input, OutputStream output) throws IOException
    {
       final byte[] buffer = new byte[4096];
       int read = 0;
-      try
+      while ((read = input.read(buffer)) != -1)
       {
-         while ((read = input.read(buffer)) != -1)
-         {
-            output.write(buffer, 0, read);
-         }
+         output.write(buffer, 0, read);
+      }
 
-         output.flush();
-      }
-      catch (final IOException ioe)
-      {
-         throw new RuntimeException("Error copying contents from " + input + " to " + output, ioe);
-      }
+      output.flush();
    }
 
    /**
@@ -154,8 +151,10 @@
     * 
     * @param input
     * @param output
+    * @throws IOException If a problem occurred during any I/O operations during the copy, but
+    * on closing the streams these will be ignored and logged at {@link Level#FINER}
     */
-   public static void copyWithClose(InputStream input, OutputStream output)
+   public static void copyWithClose(InputStream input, OutputStream output) throws IOException
    {
       try
       {
@@ -219,16 +218,20 @@
       }
       finally
       {
-         try
+         if (stream != null)
          {
-            if (stream != null)
+            try
             {
                stream.close();
             }
+            catch (final IOException ignore)
+            {
+               if (log.isLoggable(Level.FINER))
+               {
+                  log.finer("Could not close stream due to: " + ignore.getMessage() + "; ignoring");
+               }
+            }
          }
-         catch (Exception ex)
-         {
-         }
       }
    }
 }

Modified: shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/exporter/ExportTestBase.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/exporter/ExportTestBase.java	2009-12-22 15:41:57 UTC (rev 3873)
+++ shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/exporter/ExportTestBase.java	2009-12-22 16:53:10 UTC (rev 3874)
@@ -17,6 +17,7 @@
 package org.jboss.shrinkwrap.impl.base.exporter;
 
 import java.io.File;
+import java.io.IOException;
 import java.net.URISyntaxException;
 import java.util.logging.Logger;
 
@@ -120,7 +121,7 @@
    /** 
     * Returns a temp directory for a test.  Needs the test
     */
-   protected File createTempDirectory(String testName) throws Exception
+   protected File createTempDirectory(String testName) throws IOException
    {
       // Qualify the temp directory by test case
       File tempDirectoryParent = new File(this.getTarget(), this.getClass().getSimpleName());

Modified: shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/exporter/ZipExporterTestCase.java
===================================================================
--- shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/exporter/ZipExporterTestCase.java	2009-12-22 15:41:57 UTC (rev 3873)
+++ shrinkwrap/trunk/impl-base/src/test/java/org/jboss/shrinkwrap/impl/base/exporter/ZipExporterTestCase.java	2009-12-22 16:53:10 UTC (rev 3874)
@@ -25,10 +25,13 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
+import junit.framework.TestCase;
+
 import org.jboss.shrinkwrap.api.Archive;
 import org.jboss.shrinkwrap.api.Asset;
 import org.jboss.shrinkwrap.api.Path;
 import org.jboss.shrinkwrap.api.exporter.ArchiveExportException;
+import org.jboss.shrinkwrap.api.exporter.FileExistsException;
 import org.jboss.shrinkwrap.api.exporter.ZipExporter;
 import org.jboss.shrinkwrap.impl.base.io.IOUtil;
 import org.jboss.shrinkwrap.impl.base.path.BasicPath;
@@ -37,12 +40,11 @@
 import org.junit.Test;
 
 /**
- * ZipExporterTestCase
- * 
  * TestCase to ensure that the {@link ZipExporter} correctly exports archives to Zip format.
  *
  * @author <a href="mailto:baileyje at gmail.com">John Bailey</a>
  * @author <a href="mailto:aslak at conduct.no">Aslak Knutsen</a>
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
  * @version $Revision: $
  */
 public class ZipExporterTestCase extends ExportTestBase
@@ -81,21 +83,67 @@
       // Write zip content to temporary file 
       ZipFile expectedZip = getExportedZipFile(NAME_ARCHIVE, zipStream, tempDirectory);
 
-      // Validate entries were written out
-      assertAssetInZip(expectedZip, PATH_ONE, ASSET_ONE);
-      assertAssetInZip(expectedZip, PATH_TWO, ASSET_TWO);
+      // Validate
+      ensureZipFileInExpectedForm(expectedZip);
+   }
 
-      // Validate all paths were written
-      // SHRINKWRAP-94
-      getEntryFromZip(expectedZip, NESTED_PATH);
-      
-      // Ensure we don't write the root PAth
-      // SHRINKWRAP-96
-      ZipEntry rootEntry = expectedZip.getEntry("/");
-      Assert.assertNull("ZIP should not have explicit root path written (SHRINKWRAP-96)", rootEntry);
+   /**
+    * Test to make sure an archive can be exported to Zip (file) and all 
+    * contents are correctly located in the Zip.
+    * @throws Exception
+    */
+   @Test
+   public void testExportZipToFile() throws IOException
+   {
+      log.info("testExportZipToFile");
+
+      // Get a temp directory for the test
+      File tempDirectory = createTempDirectory("testExportZipToFile");
+
+      // Get an archive instance
+      Archive<?> archive = createArchiveWithAssets();
+
+      // Export as File
+      final File exported = new File(tempDirectory, archive.getName());
+      archive.as(ZipExporter.class).exportZip(exported, true);
+
+      // Get as ZipFile
+      final ZipFile expectedZip = new ZipFile(exported);
+
+      // Validate
+      ensureZipFileInExpectedForm(expectedZip);
    }
 
    /**
+    * Test to make sure an archive can be exported to Zip (file) and all 
+    * contents are correctly located in the Zip.
+    * @throws Exception
+    */
+   @Test(expected = FileExistsException.class)
+   public void testExportZipToExistingFileFails() throws IOException
+   {
+      log.info("testExportZipToExistingFileFails");
+
+      // Get a temp directory for the test
+      File tempDirectory = createTempDirectory("testExportZipToExistingFileFails");
+
+      // Get an archive instance
+      Archive<?> archive = createArchiveWithAssets();
+
+      // Export as File
+      final File alreadyExists = new File(tempDirectory, archive.getName());
+      final OutputStream alreadyExistsOutputStream = new FileOutputStream(alreadyExists);
+      alreadyExistsOutputStream.write(new byte[]
+      {});
+      alreadyExistsOutputStream.close();
+      TestCase.assertTrue("The test setup is incorrect; an empty file should exist before writing the archive",
+            alreadyExists.exists());
+
+      // Try to write to a file that already exists (should fail)
+      archive.as(ZipExporter.class).exportZip(alreadyExists);
+   }
+
+   /**
     * Test to make sue an archive can be exported to Zip and nested archives are also in exported as nested Zip.
     * @throws Exception
     */
@@ -244,4 +292,26 @@
       IOUtil.copyWithClose(inputStream, fileOutputStream);
    }
 
+   /**
+    * Ensures that the specified {@link ZipFile} contains entries
+    * in the expected form
+    * @param expectedZip
+    * @throws IOException
+    */
+   private void ensureZipFileInExpectedForm(final ZipFile expectedZip) throws IOException
+   {
+      // Validate entries were written out
+      assertAssetInZip(expectedZip, PATH_ONE, ASSET_ONE);
+      assertAssetInZip(expectedZip, PATH_TWO, ASSET_TWO);
+
+      // Validate all paths were written
+      // SHRINKWRAP-94
+      getEntryFromZip(expectedZip, NESTED_PATH);
+
+      // Ensure we don't write the root PAth
+      // SHRINKWRAP-96
+      ZipEntry rootEntry = expectedZip.getEntry("/");
+      Assert.assertNull("ZIP should not have explicit root path written (SHRINKWRAP-96)", rootEntry);
+   }
+
 }



More information about the jboss-svn-commits mailing list