You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by mn...@apache.org on 2010/08/17 15:02:18 UTC

svn commit: r986298 - in /incubator/aries/trunk/application/application-utils/src: main/java/org/apache/aries/application/utils/filesystem/IOUtils.java test/java/org/apache/aries/application/utils/filesystem/IOUtilsTest.java

Author: mnuttall
Date: Tue Aug 17 13:02:17 2010
New Revision: 986298

URL: http://svn.apache.org/viewvc?rev=986298&view=rev
Log:
ARIES-380: IOUtils.getOutputStream bug; add unpackZip method

Modified:
    incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/filesystem/IOUtils.java
    incubator/aries/trunk/application/application-utils/src/test/java/org/apache/aries/application/utils/filesystem/IOUtilsTest.java

Modified: incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/filesystem/IOUtils.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/filesystem/IOUtils.java?rev=986298&r1=986297&r2=986298&view=diff
==============================================================================
--- incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/filesystem/IOUtils.java (original)
+++ incubator/aries/trunk/application/application-utils/src/main/java/org/apache/aries/application/utils/filesystem/IOUtils.java Tue Aug 17 13:02:17 2010
@@ -33,8 +33,11 @@ import java.util.Set;
 import java.util.jar.JarOutputStream;
 import java.util.jar.Manifest;
 import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipInputStream;
 import java.util.zip.ZipOutputStream;
 
+import org.apache.aries.application.filesystem.IFile;
 import org.apache.aries.application.utils.internal.MessageUtil;
 
 public class IOUtils
@@ -78,18 +81,18 @@ public class IOUtils
     {
       dirName = relativePath.substring(0, lastSeparatorIndex);
       fileName = relativePath.substring(lastSeparatorIndex + 1);
-
       outputDirectory = new File(outputDir, dirName);
       
-      if (!!!outputDirectory.exists() && !!!outputDirectory.mkdirs())
-        throw new IOException(MessageUtil.getMessage("APPUTILS0012E", relativePath));
     }
     else
     {
       outputDirectory = outputDir;
       fileName = relativePath;
     }
-    
+    if (!!!outputDirectory.exists() && !!!outputDirectory.mkdirs()) {
+        throw new IOException(MessageUtil.getMessage("APPUTILS0012E", relativePath));
+    }
+
     File outputFile = new File(outputDirectory, fileName);
     return new FileOutputStream(outputFile);
   }
@@ -201,5 +204,77 @@ public class IOUtils
       return root.delete() && result;
     }
   }
+  
+  /**
+   * Unpack the zip file into the outputDir
+   * @param zip
+   * @param outputDir
+   * @return true if the zip was expanded, false if the zip was found not to be a zip
+   * @throws IOException when there are unexpected issues handling the zip files.
+   */
+  public static boolean unpackZip(IFile zip, File outputDir) throws IOException{
+    boolean success=true;
+    //unpack from fileOnDisk into bundleDir.
+    ZipInputStream zis = null;
+    try{
+      boolean isZip = false;
+      ZipEntry zipEntry = null;
+      try {
+        zis = new ZipInputStream (zip.open());
+        zipEntry = zis.getNextEntry();
+        isZip = zipEntry != null; 
+      } catch (ZipException e) { // It's not a zip - that's ok, we'll return that below. 
+        isZip = false;
+      } catch (UnsupportedOperationException e) {  // This isn't declared, but is thrown in practice
+        isZip = false;                             // It's not a zip - that's ok, we'll return that below. 
+      }
+      if(isZip){
+        do { 
+          if (!zipEntry.isDirectory()) { 
+            writeOutAndDontCloseInputStream(outputDir, zipEntry.getName(), zis);
+          } else { 
+            File f = new File (outputDir, zipEntry.getName());
+            if (!f.exists()) { 
+              success &= f.mkdirs();
+            }
+          }
+          zis.closeEntry();
+          zipEntry = zis.getNextEntry();
+        } while (zipEntry != null);
+      }else{
+        success=false;
+      }
+    }finally{
+      IOUtils.close(zis);
+    }
+    return success;
+  }
+  
+  /**
+   * Write the given InputStream to a file given by a root directory (outputDir) and a relative directory.
+   * Necessary subdirectories will be created. This method will not close the supplied InputStream.
+   */
+  public static void writeOutAndDontCloseInputStream(File outputDir, String relativePath, InputStream content) throws IOException
+  {
+    OutputStream out = null;
+    try {
+      out = getOutputStream(outputDir, relativePath);
+      IOUtils.copyAndDoNotCloseInputStream(content, out);
+    }
+    finally {
+      close(out);
+    }
+  }
+  
+  /**
+   * Copy an InputStream to an OutputStream and do not close the InputStream afterwards.
+   */
+  public static void copyAndDoNotCloseInputStream(InputStream in, OutputStream out) throws IOException
+  {
+    int len;
+    byte[] b = new byte[1024];
+    while ((len = in.read(b)) != -1)
+      out.write(b,0,len);
+  }
 }
 

Modified: incubator/aries/trunk/application/application-utils/src/test/java/org/apache/aries/application/utils/filesystem/IOUtilsTest.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/application/application-utils/src/test/java/org/apache/aries/application/utils/filesystem/IOUtilsTest.java?rev=986298&r1=986297&r2=986298&view=diff
==============================================================================
--- incubator/aries/trunk/application/application-utils/src/test/java/org/apache/aries/application/utils/filesystem/IOUtilsTest.java (original)
+++ incubator/aries/trunk/application/application-utils/src/test/java/org/apache/aries/application/utils/filesystem/IOUtilsTest.java Tue Aug 17 13:02:17 2010
@@ -20,17 +20,22 @@
 package org.apache.aries.application.utils.filesystem;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.StringBufferInputStream;
 import java.util.zip.ZipFile;
 
+import org.apache.aries.application.filesystem.IFile;
+import org.apache.aries.application.utils.filesystem.impl.FileImpl;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -65,7 +70,8 @@ public class IOUtilsTest
   public void testWriteOut() throws IOException
   {
     File tmpDir = new File("ioUtilsTest/tmp");
-    tmpDir.mkdirs();
+    // Do not call mkdirs() on tmpDir. writeOut() should create it. 
+    // tmpDir.mkdirs(); 
     
     IOUtils.writeOut(tmpDir, "simple.txt", new StringBufferInputStream("abc"));
     IOUtils.writeOut(tmpDir, "some/relative/directory/complex.txt", new StringBufferInputStream("def"));
@@ -95,5 +101,79 @@ public class IOUtilsTest
     assertNull(r.readLine());
     r.close();
   }
+  
+  @Test 
+  public void testWriteOutAndDoNotCloseInputStream() throws IOException{
+    InputStream is = new InputStream(){
+      int idx=0;
+      int data[]=new int[]{1,2,3,4,5,-1};
+      @Override
+      public int read() throws IOException
+      {
+        if(idx<data.length)
+          return data[idx++];
+        else
+          return -1;
+      }
+      @Override
+      public void close() throws IOException
+      {
+        fail("Close was invoked");
+      }
+    };
+    File f = new File("unittest/outtest1");
+    f.mkdirs();
+    IOUtils.writeOutAndDontCloseInputStream(f, "/fred", is);
+    File fred = new File(f,"/fred");
+    assertTrue(fred.exists());
+    File outtest = fred.getParentFile();
+    fred.delete();
+    outtest.delete();
+    
+  }
+  
+  @Test
+  public void testEmptyDirectory() throws IOException {
+    /* Create a .zip with a single entry, an empty directory inside. 
+     * Confirm that the directory is recreated on unzip. 
+     */
+    File testDir = new File ("unittest/emptyDirTest/");
+    File parent = new File (testDir, "emptyTestRootDir/");
+    File emptyDir = new File (parent, "foo/");
+    emptyDir.mkdirs();
+    assertTrue (emptyDir.exists());
+    
+    File zipWithEmptyDir = new File (testDir, "empty.zip");
+    IOUtils.zipUp(parent, zipWithEmptyDir);
+    
+    emptyDir.delete();
+    assertFalse (emptyDir.exists());
+    
+    IFile zip = new FileImpl(zipWithEmptyDir, testDir);
+    IOUtils.unpackZip(zip, parent);
+    assertTrue (emptyDir.exists());
+  }
+  
+  @Test
+  public void testSingleRootLevelEntry() throws IOException { 
+    /* Create a .zip with a single entry, a root-level file. 
+     * Confirm that the file is recreated on unzip. 
+     */
+    File testDir = new File ("unittest/singleFileInZipTest/");
+    File parent = new File (testDir, "singleFileRootDir/");
+    File entry = new File (parent, "foo.txt");
+    entry.mkdirs();
+    assertTrue (entry.exists());
+    
+    File zipWithSingleFileInRootdir = new File (testDir, "singleFile.zip");
+    IOUtils.zipUp(parent, zipWithSingleFileInRootdir);
+    
+    entry.delete();
+    assertFalse (entry.exists());
+    
+    IFile zip = new FileImpl(zipWithSingleFileInRootdir, testDir);
+    IOUtils.unpackZip(zip, parent);
+    assertTrue (entry.exists());
+  }
 }