compression support when writing 7z

git-svn-id: https://svn.apache.org/repos/asf/ant/antlibs/compress/trunk@1531317 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/changes.xml b/changes.xml
index 56731ac..d27bbc1 100644
--- a/changes.xml
+++ b/changes.xml
@@ -42,9 +42,9 @@
         The Apache Compress Antlib now requires Apache Commons
         Compress 1.6 if you want to work with arj or 7z archives.
 
-        In addition XZ for Java 1.4 is required if you want to read 7z
-        archives using LZMA (not LZMA2) compression or stand-alone
-        LZMA files.
+        In addition XZ for Java 1.4 is required if you want to
+        read/write 7z archives using LZMA(2) compression or
+        stand-alone LZMA files.
       </action>
       <action type="add">
         Encoding support for dump and cpio archives and filesets.
@@ -57,9 +57,7 @@
         added.
       </action>
       <action type="add">
-        Support for file based 7z archives has been added - most
-        compression algorithms used in 7z archives can be read but
-        only uncompressed archives can be written.
+        Support for file based 7z archives has been added.
       </action>
     </release>
 
diff --git a/docs/archive.html b/docs/archive.html
index e14e69c..ffcf32e 100644
--- a/docs/archive.html
+++ b/docs/archive.html
@@ -279,7 +279,25 @@
 
   <p>An <a href="#archive">archiving task</a> creating archives of the
     7z format.  As of Commons Compress 1.6 this task only supports
-    writing uncompressed archives.</p>
+    writing unencrypted archives.</p>
+
+  <h3>Parameters</h3>
+  <table border="1" cellpadding="2" cellspacing="0">
+    <tr>
+      <td valign="top"><b>Attribute</b></td>
+      <td valign="top"><b>Description</b></td>
+      <td align="center" valign="top"><b>Required</b></td>
+    </tr>
+    <tr>
+      <td valign="top">contentCompression</td>
+      <td valign="top">compression algorithm to use for entry
+        contents.</td>
+      <td valign="top">As of Commons Compress 1.6 this can be "LZMA2",
+        "BZIP2", "DEFLATE" or "COPY" where "COPY" means no compression
+        at all.</td>
+      <td valign="top" align="center">No, default is LZMA2.</td>
+    </tr>
+  </table>
 
   <h3><a name="tar">Tar</a></h3>
 
diff --git a/src/main/org/apache/ant/compress/taskdefs/SevenZ.java b/src/main/org/apache/ant/compress/taskdefs/SevenZ.java
index 1324b72..f0b9435 100644
--- a/src/main/org/apache/ant/compress/taskdefs/SevenZ.java
+++ b/src/main/org/apache/ant/compress/taskdefs/SevenZ.java
@@ -18,12 +18,18 @@
 
 package org.apache.ant.compress.taskdefs;
 
+import java.io.IOException;
+import java.io.File;
 import java.util.Date;
+import java.util.Locale;
 
 import org.apache.ant.compress.resources.SevenZFileSet;
 import org.apache.ant.compress.util.SevenZStreamFactory;
+import org.apache.ant.compress.util.SevenZStreamFactory.SevenZArchiveOutputStream;
 import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.ArchiveOutputStream;
 import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
+import org.apache.commons.compress.archivers.sevenz.SevenZMethod;
 import org.apache.tools.ant.types.ArchiveFileSet;
 import org.apache.tools.ant.types.Resource;
 
@@ -32,8 +38,25 @@
  */
 public class SevenZ extends ArchiveBase {
 
+    private String contentCompression;
+
     public SevenZ() {
-        setFactory(new SevenZStreamFactory());
+        setFactory(new SevenZStreamFactory() {
+                public ArchiveOutputStream getArchiveOutputStream(File f,
+                                                                  String encoding)
+                    throws IOException {
+                    SevenZArchiveOutputStream o = (SevenZArchiveOutputStream)
+                        super.getArchiveOutputStream(f, encoding);
+                    if (contentCompression != null) {
+                        SevenZMethod m = (SevenZMethod)
+                            Enum.valueOf(SevenZMethod.class,
+                                         contentCompression.toUpperCase(Locale
+                                                                        .US));
+                        o.setContentCompression(m);
+                    }
+                    return o;
+                }
+            });
         setEntryBuilder(
               new ArchiveBase.EntryBuilder() {
                 public ArchiveEntry buildEntry(ArchiveBase.ResourceWithFlags r) {
@@ -55,4 +78,14 @@
             });
     }
 
+    /**
+     * Sets the compression method to use for entry contents - the
+     * default is LZMA2.
+     *
+     * <p>As of Commons Compress 1.6 only COPY (which means no
+     * compression), LZMA2, BZIP2 and DEFLATE are supported.</p>
+     */
+    public void setContentCompression(String method) {
+        this.contentCompression = method;
+    }
 }
diff --git a/src/main/org/apache/ant/compress/util/SevenZStreamFactory.java b/src/main/org/apache/ant/compress/util/SevenZStreamFactory.java
index 327f92c..a9d1269 100644
--- a/src/main/org/apache/ant/compress/util/SevenZStreamFactory.java
+++ b/src/main/org/apache/ant/compress/util/SevenZStreamFactory.java
@@ -26,6 +26,7 @@
 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.sevenz.SevenZMethod;
 import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile;
 import org.apache.commons.compress.archivers.sevenz.SevenZFile;
 
@@ -103,7 +104,7 @@
      * Not really a stream but provides an ArchiveOutputStream
      * compatible interface over SevenZOutputFile.
      */
-    private static class SevenZArchiveOutputStream extends ArchiveOutputStream {
+    public static class SevenZArchiveOutputStream extends ArchiveOutputStream {
 
         private final SevenZOutputFile zipFile;
 
@@ -136,6 +137,10 @@
             zipFile.write(b, off, len);
         }
                 
+        public void setContentCompression(SevenZMethod method) {
+            zipFile.setContentCompression(method);
+        }
+
     }
 
 }
diff --git a/src/tests/antunit/un7z-test.xml b/src/tests/antunit/un7z-test.xml
index 2ea0dea..5e02799 100644
--- a/src/tests/antunit/un7z-test.xml
+++ b/src/tests/antunit/un7z-test.xml
@@ -38,6 +38,54 @@
        />
   </target>
 
+  <target name="testAgainstAntlib7zTaskLZMA2" depends="setUp">
+    <cmp:sevenz destfile="${input}/test.7z" contentCompression="lzma2">
+      <fileset dir="." includes="un7z-test.xml"/>
+    </cmp:sevenz>
+    <cmp:un7z src="${input}/test.7z" dest="${output}"/>
+    <au:assertFileExists file="${output}/un7z-test.xml"/>
+    <au:assertFilesMatch
+       actual="${output}/un7z-test.xml"
+       expected="un7z-test.xml"
+       />
+  </target>
+
+  <target name="testAgainstAntlib7zTaskBZIP2" depends="setUp">
+    <cmp:sevenz destfile="${input}/test.7z" contentCompression="bzip2">
+      <fileset dir="." includes="un7z-test.xml"/>
+    </cmp:sevenz>
+    <cmp:un7z src="${input}/test.7z" dest="${output}"/>
+    <au:assertFileExists file="${output}/un7z-test.xml"/>
+    <au:assertFilesMatch
+       actual="${output}/un7z-test.xml"
+       expected="un7z-test.xml"
+       />
+  </target>
+
+  <target name="testAgainstAntlib7zTaskDeflate" depends="setUp">
+    <cmp:sevenz destfile="${input}/test.7z" contentCompression="deflate">
+      <fileset dir="." includes="un7z-test.xml"/>
+    </cmp:sevenz>
+    <cmp:un7z src="${input}/test.7z" dest="${output}"/>
+    <au:assertFileExists file="${output}/un7z-test.xml"/>
+    <au:assertFilesMatch
+       actual="${output}/un7z-test.xml"
+       expected="un7z-test.xml"
+       />
+  </target>
+
+  <target name="testAgainstAntlib7zTaskCopy" depends="setUp">
+    <cmp:sevenz destfile="${input}/test.7z" contentCompression="copy">
+      <fileset dir="." includes="un7z-test.xml"/>
+    </cmp:sevenz>
+    <cmp:un7z src="${input}/test.7z" dest="${output}"/>
+    <au:assertFileExists file="${output}/un7z-test.xml"/>
+    <au:assertFilesMatch
+       actual="${output}/un7z-test.xml"
+       expected="un7z-test.xml"
+       />
+  </target>
+
   <target name="testAgainstNative7z" depends="setUp">
     <cmp:un7z src="../resources/asf-logo.gif.7z" dest="${output}" />
     <au:assertFileExists file="${output}/asf-logo.gif"/>