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<ArchiveEntry> 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.
*