catch up with POSIX/PAX support in Commons Compress' tar package

git-svn-id: https://svn.apache.org/repos/asf/ant/antlibs/compress/trunk@1213185 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/changes.xml b/changes.xml
index 5da246c..c868017 100644
--- a/changes.xml
+++ b/changes.xml
@@ -42,6 +42,9 @@
         The Apache Compress Antlib now requires Apache Commons
         Compress 1.4 and the public domain XZ for Java library if you
         want to use the XZ format.
+
+        Commons Compress 1.4 is also required for the GNU, STAR and
+        PAX formats of the tar task.
       </action>
       <action type="add">
         Support for xz compression has been added.
@@ -53,6 +56,20 @@
         behavior has to be enabled explicitly via the
         decompressConcatenated attribute.
       </action>
+      <action type="add">
+        The tar task now supports the POSIX 1003.1/PAX way of storing
+        long file names used by most modern tar implementations.
+      </action>
+      <action type="add">
+        The tar resources and the untar task read entries bigger than
+        8 GByte transparently now, if you use Commons Compress 1.4.
+      </action>
+      <action type="add">
+        The tar task writes entries bigger than 8 GByte using POSIX
+        1003.1/PAX headers or the star extension if you set the format
+        attribute to "star", "gnu" or "pax".  See the tar task's
+        documentation of details.
+      </action>
     </release>
 
     <release version="1.1" date="2011-11-05">
diff --git a/docs/archive.html b/docs/archive.html
index 3ae13c9..d52c563 100644
--- a/docs/archive.html
+++ b/docs/archive.html
@@ -293,14 +293,76 @@
     </tr>
     <tr>
       <td valign="top">format</td>
-      <td valign="top">Tar format for entries with names longer than
-        100 characters.  Supported values are "ustar" which doesn't
-        support entries of that length and results in a build failure
-        and "oldgnu".</td>
+      <td valign="top">Tar format to use.
+        See <a href="#tarformat">the section below.  Supported values
+        are "ustar", "oldgnu", "gnu", "star" and "pax".</td>
       <td valign="top" align="center">No, default is "ustar"</td>
     </tr>
   </table>
 
+  <h4><a name="tarformat"></a>Tar format</h4>
+
+  <p>Over time the original tar format has seen various extensions and
+    revisions.  The Apache Commons Compress library supports the
+    original format (called "ustar") and some extensions added later,
+    but not all of them.  It supports a subset of features offered by
+    the POSIX 1003.1 standard (often referred to as PAX), but this
+    support is not complete.</p>
+
+  <p>The Compress Antlib follows Commons Compress' support.  Currently
+    the format affects two areas, files bigger than 8 GiB and entries
+    with names longer than 100 characters.  For Commons Compress these
+    areas can be configured separately while the Antlib chooses them
+    based on a single format attribute.</p>
+
+  <table border="1" cellpadding="2" cellspacing="0">
+    <tr>
+      <td valign="top"><b>Format Attribute</b></td>
+      <td valign="top"><b>Files bigger 8GiB</b></td>
+      <td valign="top"><b>Entry Names longer 100 characters</b></td>
+      <td valign="top"><b>Notes</b></td>
+    </tr>
+    <tr>
+      <td valign="top">ustar</td>
+      <td valign="top">Not supported, throws an exception.</td>
+      <td valign="top">Not supported, throws an exception.</td>
+      <td valign="top">Default.</td>
+    </tr>
+    <tr>
+      <td valign="top">oldgnu</td>
+      <td valign="top">Not supported, throws an exception.</td>
+      <td valign="top">Uses a GNU tar specific extension.</td>
+      <td valign="top">Created archives may be unreadable on MacOS X,
+        Solaris or with other non-GNU implementations of tar.</td>
+    </tr>
+    <tr>
+      <td valign="top">star</td>
+      <td valign="top" rowspan="2">Uses an extension first introduced by J&#xf6;rg
+          Schilling's <a href="http://developer.berlios.de/projects/star">star</a>
+          and later adopted by GNU tar and BSD tar.</td>
+      <td valign="top">Uses a
+          PAX <a href="http://pubs.opengroup.org/onlinepubs/009695399/utilities/pax.html#tag_04_100_13_03">extended
+          header</a> as defined by POSIX 1003.1.</td>
+      <td valign="top">Created archives will be readable by star and
+        modern versions of GNU tar and BSD tar.</td>
+    </tr>
+    <tr>
+      <td valign="top">gnu</td>
+      <td valign="top">Uses a GNU tar specific extension.</td>
+      <td valign="top">Created archives may be unreadable on MacOS X,
+        Solaris or with other non-GNU implementations of tar.  The
+        archives are similar to what GNU tar would create by
+        default.</td>
+    </tr>
+    <tr>
+      <td valign="top">pax</td>
+      <td valign="top" colspan="2">Uses use a PAX extended header as
+          defined by POSIX 1003.1.</td>
+      <td valign="top">Created archives will be readable by all modern
+        implementations of tar.</td>
+    </tr>
+  </table>
+
   <h4>Examples</h4>
 
 <pre>
diff --git a/src/main/org/apache/ant/compress/taskdefs/Tar.java b/src/main/org/apache/ant/compress/taskdefs/Tar.java
index f8d9584..adc331e 100644
--- a/src/main/org/apache/ant/compress/taskdefs/Tar.java
+++ b/src/main/org/apache/ant/compress/taskdefs/Tar.java
@@ -48,6 +48,18 @@
                     if (format.equals(Format.OLDGNU)) {
                         o.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
                     }
+                    else if (format.equals(Format.GNU)) {
+                        o.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
+                        o.setBigFileMode(TarArchiveOutputStream.BIGFILE_STAR);
+                    }
+                    else if (format.equals(Format.STAR)) {
+                        o.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
+                        o.setBigFileMode(TarArchiveOutputStream.BIGFILE_STAR);
+                    }
+                    else if (format.equals(Format.PAX)) {
+                        o.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
+                        o.setBigFileMode(TarArchiveOutputStream.BIGFILE_POSIX);
+                    }
                     return o;
                 }
             });
@@ -117,8 +129,7 @@
     }
 
     /**
-     * The format for entries with filenames longer than 100
-     * characters - any other entry will always use "ustar".
+     * The format to use.
      */
     public void setFormat(Format f) {
         format = f;
@@ -130,9 +141,15 @@
     public final static class Format extends EnumeratedAttribute {
         private static final String USTAR_NAME = "ustar";
         private static final String OLDGNU_NAME = "oldgnu";
+        private static final String GNU_NAME = "gnu";
+        private static final String STAR_NAME = "star";
+        private static final String PAX_NAME = "pax";
 
         public static final Format USTAR = new Format(USTAR_NAME);
         public static final Format OLDGNU = new Format(OLDGNU_NAME);
+        public static final Format GNU = new Format(GNU_NAME);
+        public static final Format STAR = new Format(STAR_NAME);
+        public static final Format PAX = new Format(PAX_NAME);
 
         public Format(String v) {
             setValue(v);
@@ -143,7 +160,10 @@
         }
 
         public String[] getValues() {
-            return new String[] {USTAR_NAME, OLDGNU_NAME};
+            return new String[] {
+                USTAR_NAME, OLDGNU_NAME, GNU_NAME,
+                STAR_NAME, PAX_NAME
+            };
         }
 
         public boolean equals(Object other) {
diff --git a/src/tests/antunit/tar-test.xml b/src/tests/antunit/tar-test.xml
index bbe1904..c8f5e06 100644
--- a/src/tests/antunit/tar-test.xml
+++ b/src/tests/antunit/tar-test.xml
@@ -620,4 +620,15 @@
       </cmp:tarentry>
     </assertResourceExists>
   </target>
+
+  <target name="testPaxLongFile" depends="-longFileSetUp">
+    <cmp:tar destfile="${dest}" format="pax">
+      <fileset dir="${input}"/>
+    </cmp:tar>
+    <assertResourceExists>
+      <cmp:tarentry name="${long}">
+        <file file="${dest}"/>
+      </cmp:tarentry>
+    </assertResourceExists>
+  </target>
 </project>