You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by bo...@apache.org on 2013/01/01 19:33:33 UTC

svn commit: r1427509 - in /commons/proper/compress/trunk/src: changes/changes.xml main/java/org/apache/commons/compress/changes/ChangeSetPerformer.java test/java/org/apache/commons/compress/changes/ChangeSetTestCase.java

Author: bodewig
Date: Tue Jan  1 18:33:33 2013
New Revision: 1427509

URL: http://svn.apache.org/viewvc?rev=1427509&view=rev
Log:
COMPRESS-159 make ChangeSetPerformer work on ZipFiles as well

Modified:
    commons/proper/compress/trunk/src/changes/changes.xml
    commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/changes/ChangeSetPerformer.java
    commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/changes/ChangeSetTestCase.java

Modified: commons/proper/compress/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/changes/changes.xml?rev=1427509&r1=1427508&r2=1427509&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/changes/changes.xml (original)
+++ commons/proper/compress/trunk/src/changes/changes.xml Tue Jan  1 18:33:33 2013
@@ -99,6 +99,10 @@ The <action> type attribute can be add,u
         TarArchiveEntry has a new constructor that allows setting
         linkFlag and preserveLeadingSlashes at the same time.
       </action>
+      <action type="update" date="2013-01-01" issue="COMPRESS-159">
+        ChangeSetPerformer has a new perform overload that uses a
+        ZipFile instance as input.
+      </action>
     </release>
     <release version="1.4.1" date="2012-05-23"
              description="Release 1.4.1">

Modified: commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/changes/ChangeSetPerformer.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/changes/ChangeSetPerformer.java?rev=1427509&r1=1427508&r2=1427509&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/changes/ChangeSetPerformer.java (original)
+++ commons/proper/compress/trunk/src/main/java/org/apache/commons/compress/changes/ChangeSetPerformer.java Tue Jan  1 18:33:33 2013
@@ -20,6 +20,7 @@ package org.apache.commons.compress.chan
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.Set;
@@ -27,6 +28,8 @@ import java.util.Set;
 import org.apache.commons.compress.archivers.ArchiveEntry;
 import org.apache.commons.compress.archivers.ArchiveInputStream;
 import org.apache.commons.compress.archivers.ArchiveOutputStream;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipFile;
 import org.apache.commons.compress.utils.IOUtils;
 
 /**
@@ -66,6 +69,47 @@ public class ChangeSetPerformer {
      */
     public ChangeSetResults perform(ArchiveInputStream in, ArchiveOutputStream out)
             throws IOException {
+        return perform(new ArchiveInputStreamIterator(in), out);
+    }
+
+    /**
+     * Performs all changes collected in this ChangeSet on the ZipFile and
+     * streams the result to the output stream. Perform may be called more than once.
+     * 
+     * This method finishes the stream, no other entries should be added
+     * after that.
+     * 
+     * @param in
+     *            the ZipFile to perform the changes on
+     * @param out
+     *            the resulting OutputStream with all modifications
+     * @throws IOException
+     *             if an read/write error occurs
+     * @return the results of this operation
+     */
+    public ChangeSetResults perform(ZipFile in, ArchiveOutputStream out)
+            throws IOException {
+        return perform(new ZipFileIterator(in), out);
+    }
+
+    /**
+     * Performs all changes collected in this ChangeSet on the input entries and
+     * streams the result to the output stream.
+     * 
+     * This method finishes the stream, no other entries should be added
+     * after that.
+     * 
+     * @param entryIterator
+     *            the entries to perform the changes on
+     * @param out
+     *            the resulting OutputStream with all modifications
+     * @throws IOException
+     *             if an read/write error occurs
+     * @return the results of this operation
+     */
+    private ChangeSetResults perform(ArchiveEntryIterator entryIterator,
+                                     ArchiveOutputStream out)
+            throws IOException {
         ChangeSetResults results = new ChangeSetResults();
 
         Set<Change> workingSet = new LinkedHashSet<Change>(changes);
@@ -80,8 +124,8 @@ public class ChangeSetPerformer {
             }
         }
 
-        ArchiveEntry entry = null;
-        while ((entry = in.getNextEntry()) != null) {
+        while (entryIterator.hasNext()) {
+            ArchiveEntry entry = entryIterator.next();
             boolean copy = true;
 
             for (Iterator<Change> it = workingSet.iterator(); it.hasNext();) {
@@ -109,7 +153,7 @@ public class ChangeSetPerformer {
             if (copy
                 && !isDeletedLater(workingSet, entry)
                 && !results.hasBeenAdded(entry.getName())) {
-                copyStream(in, out, entry);
+                copyStream(entryIterator.getInputStream(), out, entry);
                 results.addedFromStream(entry.getName());
             }
         }
@@ -176,4 +220,57 @@ public class ChangeSetPerformer {
         IOUtils.copy(in, out);
         out.closeArchiveEntry();
     }
+
+    /**
+     * Used in perform to abstract out getting entries and streams for
+     * those entries.
+     *
+     * <p>Iterator#hasNext is not allowed to throw exceptions that's
+     * why we can't use Iterator&lt;ArchiveEntry&gt; directly -
+     * otherwise we'd need to convert exceptions thrown in
+     * ArchiveInputStream#getNextEntry.</p>
+     */
+    interface ArchiveEntryIterator {
+        boolean hasNext() throws IOException;
+        ArchiveEntry next();
+        InputStream getInputStream() throws IOException;
+    }
+
+    private static class ArchiveInputStreamIterator
+        implements ArchiveEntryIterator {
+        private final ArchiveInputStream in;
+        private ArchiveEntry next;
+        ArchiveInputStreamIterator(ArchiveInputStream in) {
+            this.in = in;
+        }
+        public boolean hasNext() throws IOException {
+            return (next = in.getNextEntry()) != null;
+        }
+        public ArchiveEntry next() {
+            return next;
+        }
+        public InputStream getInputStream() {
+            return in;
+        }
+    }
+
+    private static class ZipFileIterator
+        implements ArchiveEntryIterator {
+        private final ZipFile in;
+        private final Enumeration<ZipArchiveEntry> nestedEnum;
+        private ZipArchiveEntry current;
+        ZipFileIterator(ZipFile in) throws IOException {
+            this.in = in;
+            nestedEnum = in.getEntriesInPhysicalOrder();
+        }
+        public boolean hasNext() {
+            return nestedEnum.hasMoreElements();
+        }
+        public ArchiveEntry next() {
+            return (current = nestedEnum.nextElement());
+        }
+        public InputStream getInputStream() throws IOException {
+            return in.getInputStream(current);
+        }
+    }
 }

Modified: commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/changes/ChangeSetTestCase.java
URL: http://svn.apache.org/viewvc/commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/changes/ChangeSetTestCase.java?rev=1427509&r1=1427508&r2=1427509&view=diff
==============================================================================
--- commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/changes/ChangeSetTestCase.java (original)
+++ commons/proper/compress/trunk/src/test/java/org/apache/commons/compress/changes/ChangeSetTestCase.java Tue Jan  1 18:33:33 2013
@@ -38,6 +38,7 @@ import org.apache.commons.compress.archi
 import org.apache.commons.compress.archivers.jar.JarArchiveEntry;
 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipFile;
 
 /**
  * Checks several ChangeSet business logics.
@@ -572,6 +573,50 @@ public final class ChangeSetTestCase ext
     }
 
     /**
+     * Adds a file to a zip archive. Deletes an other file.
+     * 
+     * @throws Exception
+     */
+    public void testDeleteFromAndAddToZipUsingZipFilePerform() throws Exception {
+        final String archivename = "zip";
+        File input = this.createArchive(archivename);
+
+        ArchiveOutputStream out = null;
+        ZipFile ais = null;
+        File result = File.createTempFile("test", "."+archivename);
+        result.deleteOnExit();
+        try {
+
+            ais = new ZipFile(input);
+            out = factory.createArchiveOutputStream(archivename,
+                    new FileOutputStream(result));
+
+            ChangeSet changes = new ChangeSet();
+
+            final File file1 = getFile("test.txt");
+            ArchiveEntry entry = new ZipArchiveEntry("blub/test.txt");
+            changes.add(entry, new FileInputStream(file1));
+            archiveList.add("blub/test.txt");
+
+            changes.delete("testdata/test1.xml");
+            archiveListDelete("testdata/test1.xml");
+
+            ChangeSetPerformer performer = new ChangeSetPerformer(changes);
+            performer.perform(ais, out);
+
+        } finally {
+            if (out != null) {
+                out.close();
+            }
+            if (ais != null) {
+                ais.close();
+            }
+        }
+
+        this.checkArchiveContent(result, archiveList);
+    }
+
+    /**
      * add blub/test.txt + delete blub Should add blub/test.txt and delete it
      * afterwards. In this example, the archive should stay untouched.
      *