Reduce duplication in filesets.

Yes, this could be further reduced by reflection or generics.  I'm a
bit afraid of the runtime cost of reflection and wouldn't want to
introduce reflection before version 2.0 of the antlib (which I expect
to start if CC 2.0 is ever started).


git-svn-id: https://svn.apache.org/repos/asf/ant/antlibs/compress/trunk@1514870 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/org/apache/ant/compress/resources/ArFileSet.java b/src/main/org/apache/ant/compress/resources/ArFileSet.java
index 840e7ba..ce9f3d3 100644
--- a/src/main/org/apache/ant/compress/resources/ArFileSet.java
+++ b/src/main/org/apache/ant/compress/resources/ArFileSet.java
@@ -21,13 +21,8 @@
 
 import org.apache.commons.compress.archivers.ArchiveEntry;
 import org.apache.commons.compress.archivers.ar.ArArchiveEntry;
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.types.AbstractFileSet;
-import org.apache.tools.ant.types.ArchiveFileSet;
 import org.apache.tools.ant.types.ArchiveScanner;
 import org.apache.tools.ant.types.FileSet;
-import org.apache.tools.ant.types.Reference;
 import org.apache.tools.ant.types.Resource;
 
 /**
@@ -39,15 +34,7 @@
  * a prefix attribute which is prepended to each entry in the output Ar file.
  *
  */
-public class ArFileSet extends ArchiveFileSet {
-
-    private boolean userIdSet;
-    private boolean groupIdSet;
-
-    private int    uid;
-    private int    gid;
-
-    private boolean skipUnreadable = false;
+public class ArFileSet extends CommonsCompressFileSet {
 
     /** Constructor for ArFileSet */
     public ArFileSet() {
@@ -55,7 +42,7 @@
     }
 
     /**
-     * Constructor using a fileset arguement.
+     * Constructor using a fileset argument.
      * @param fileset the fileset to use
      */
     protected ArFileSet(FileSet fileset) {
@@ -63,7 +50,7 @@
     }
 
     /**
-     * Constructor using a arfileset arguement.
+     * Constructor using a arfileset argument.
      * @param fileset the arfileset to use
      */
     protected ArFileSet(ArFileSet fileset) {
@@ -71,68 +58,11 @@
     }
 
     /**
-     * The uid for the ar entry
-     * This is not the same as the User name.
-     * @param uid the id of the user for the ar entry.
+     * Constructor using a CommonsCompressFileSet argument.
+     * @param fileset the fileset to use
      */
-    public void setUid(int uid) {
-        checkArFileSetAttributesAllowed();
-        userIdSet = true;
-        this.uid = uid;
-    }
-
-    /**
-     * @return the uid for the ar entry
-     */
-    public int getUid() {
-        if (isReference()) {
-            return ((ArFileSet) getCheckedRef()).getUid();
-        }
-        return uid;
-    }
-
-    /**
-     * @return whether the user id has been explicitly set.
-     */
-    public boolean hasUserIdBeenSet() {
-        return userIdSet;
-    }
-
-    /**
-     * The GID for the ar entry; optional, default="0"
-     * This is not the same as the group name.
-     * @param gid the group id.
-     */
-    public void setGid(int gid) {
-        checkArFileSetAttributesAllowed();
-        groupIdSet = true;
-        this.gid = gid;
-    }
-
-    /**
-     * @return the group identifier.
-     */
-    public int getGid() {
-        if (isReference()) {
-            return ((ArFileSet) getCheckedRef()).getGid();
-        }
-        return gid;
-    }
-
-    /**
-     * @return whether the group id has been explicitly set.
-     */
-    public boolean hasGroupIdBeenSet() {
-        return groupIdSet;
-    }
-
-    /**
-     * Whether to skip entries that Commons Compress signals it cannot read.
-     *
-     * @since Compress Antlib 1.1
-     */
-    public void setSkipUnreadableEntries(boolean b) {
-        skipUnreadable = b;
+    protected ArFileSet(CommonsCompressFileSet fileset) {
+        super(fileset);
     }
 
     /**
@@ -146,87 +76,17 @@
                                               ArchiveEntry entry) {
                     return new ArResource(archive, (ArArchiveEntry) entry);
                 }
-            }, skipUnreadable, getProject());
+            }, getSkipUnreadableEntries(), getProject());
     }
 
-    /**
-     * Makes this instance in effect a reference to another instance.
-     *
-     * <p>You must not set another attribute or nest elements inside
-     * this element if you make it a reference.</p>
-     * @param r the <code>Reference</code> to use.
-     * @throws BuildException on error
-     */
-    public void setRefid(Reference r) throws BuildException {
-        if (userIdSet || groupIdSet) {
-            throw tooManyAttributes();
+    protected CommonsCompressFileSet newFileSet(FileSet fs) {
+        if (fs instanceof ArFileSet) {
+            return new ArFileSet((ArFileSet) fs);
         }
-        super.setRefid(r);
-    }
-
-    /**
-     * A ArFileset accepts another ArFileSet or a FileSet as reference
-     * FileSets are often used by the war task for the lib attribute
-     * @param p the project to use
-     * @return the abstract fileset instance
-     */
-    protected AbstractFileSet getRef(Project p) {
-        dieOnCircularReference(p);
-        Object o = getRefid().getReferencedObject(p);
-        if (o instanceof ArFileSet) {
-            return (AbstractFileSet) o;
-        } else if (o instanceof FileSet) {
-            ArFileSet zfs = new ArFileSet((FileSet) o);
-            configureFileSet(zfs);
-            return zfs;
-        } else {
-            String msg = getRefid().getRefId() + " doesn\'t denote a arfileset or a fileset";
-            throw new BuildException(msg);
+        if (fs instanceof CommonsCompressFileSet) {
+            return new ArFileSet((CommonsCompressFileSet) fs);
         }
-    }
-
-    /**
-     * Configure a fileset based on this fileset.
-     * If the fileset is a ArFileSet copy in the arfileset
-     * specific attributes.
-     * @param zfs the archive fileset to configure.
-     */
-    protected void configureFileSet(ArchiveFileSet zfs) {
-        super.configureFileSet(zfs);
-        if (zfs instanceof ArFileSet) {
-            ArFileSet tfs = (ArFileSet) zfs;
-            tfs.setUid(uid);
-            tfs.setGid(gid);
-        }
-    }
-
-    /**
-     * Return a ArFileSet that has the same properties
-     * as this one.
-     * @return the cloned arFileSet
-     */
-    public Object clone() {
-        if (isReference()) {
-            return ((ArFileSet) getRef(getProject())).clone();
-        } else {
-            return super.clone();
-        }
-    }
-
-    /**
-     * A check attributes for ArFileSet.
-     * If there is a reference, and
-     * it is a ArFileSet, the ar fileset attributes
-     * cannot be used.
-     */
-    private void checkArFileSetAttributesAllowed() {
-        if (getProject() == null
-            || (isReference()
-                && (getRefid().getReferencedObject(
-                        getProject())
-                    instanceof ArFileSet))) {
-            checkAttributesAllowed();
-        }
+        return new ArFileSet(fs);
     }
 
 }
diff --git a/src/main/org/apache/ant/compress/resources/CommonsCompressFileSet.java b/src/main/org/apache/ant/compress/resources/CommonsCompressFileSet.java
new file mode 100644
index 0000000..7a51bf5
--- /dev/null
+++ b/src/main/org/apache/ant/compress/resources/CommonsCompressFileSet.java
@@ -0,0 +1,255 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+package org.apache.ant.compress.resources;
+
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.AbstractFileSet;
+import org.apache.tools.ant.types.ArchiveFileSet;
+import org.apache.tools.ant.types.ArchiveScanner;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Reference;
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * A fileset based on the contents of a commons compress archive.
+ *
+ * A CommonsCompressFileSet extends FileSets with the ability to
+ * extract a subset of the entries of an archive for inclusion in
+ * another archive.  It also includes a prefix attribute which is
+ * prepended to each entry in the output archive.
+ *
+ * @since Compress Antlib 1.3
+ */
+public abstract class CommonsCompressFileSet extends ArchiveFileSet {
+
+    private boolean userIdSet;
+    private boolean groupIdSet;
+
+    // not supported for zip
+    private int    uid;
+    private int    gid;
+
+    private boolean skipUnreadable = false;
+
+    // not supported for ar
+    private String encoding = null;
+
+    /** Constructor for CommonsCompressFileSet */
+    public CommonsCompressFileSet() {
+        super();
+    }
+
+    /**
+     * Constructor using a fileset argument.
+     * @param fileset the fileset to use
+     */
+    protected CommonsCompressFileSet(FileSet fileset) {
+        super(fileset);
+    }
+
+    /**
+     * Constructor using a CommonsCompressFileSet argument.
+     * @param fileset the fileset to use
+     */
+    protected CommonsCompressFileSet(CommonsCompressFileSet fileset) {
+        super(fileset);
+        encoding = fileset.encoding;
+    }
+
+    /**
+     * Set the encoding used for this CommonsCompressFileSet.
+     * @param enc encoding as String.
+     */
+    public void setEncoding(String enc) {
+        checkCommonsCompressFileSetAttributesAllowed();
+        this.encoding = enc;
+    }
+
+    /**
+     * Get the encoding used for this TarFileSet.
+     * @return String encoding.
+     */
+    public String getEncoding() {
+        if (isReference()) {
+            AbstractFileSet ref = getRef(getProject());
+            if (ref instanceof CommonsCompressFileSet) {
+                return ((CommonsCompressFileSet) ref).getEncoding();
+            } else {
+                return null;
+            }
+        }
+        return encoding;
+    }
+
+    /**
+     * The uid for the entry
+     * This is not the same as the User name.
+     * @param uid the id of the user for the entry.
+     */
+    public void setUid(int uid) {
+        checkCommonsCompressFileSetAttributesAllowed();
+        userIdSet = true;
+        this.uid = uid;
+    }
+
+    /**
+     * @return the uid for the entry
+     */
+    public int getUid() {
+        if (isReference()) {
+            return ((CommonsCompressFileSet) getCheckedRef()).getUid();
+        }
+        return uid;
+    }
+
+    /**
+     * @return whether the user id has been explicitly set.
+     */
+    public boolean hasUserIdBeenSet() {
+        return userIdSet;
+    }
+
+    /**
+     * The GID for the entry; optional, default="0"
+     * This is not the same as the group name.
+     * @param gid the group id.
+     */
+    public void setGid(int gid) {
+        checkCommonsCompressFileSetAttributesAllowed();
+        groupIdSet = true;
+        this.gid = gid;
+    }
+
+    /**
+     * @return the group identifier.
+     */
+    public int getGid() {
+        if (isReference()) {
+            return ((CommonsCompressFileSet) getCheckedRef()).getGid();
+        }
+        return gid;
+    }
+
+    /**
+     * @return whether the group id has been explicitly set.
+     */
+    public boolean hasGroupIdBeenSet() {
+        return groupIdSet;
+    }
+
+    /**
+     * Whether to skip entries that Commons Compress signals it cannot read.
+     */
+    public void setSkipUnreadableEntries(boolean b) {
+        skipUnreadable = b;
+    }
+
+    /**
+     * Whether to skip entries that Commons Compress signals it cannot read.
+     */
+    public boolean getSkipUnreadableEntries() {
+        return skipUnreadable;
+    }
+
+    /**
+     * Makes this instance in effect a reference to another instance.
+     *
+     * <p>You must not set another attribute or nest elements inside
+     * this element if you make it a reference.</p>
+     * @param r the <code>Reference</code> to use.
+     * @throws BuildException on error
+     */
+    public void setRefid(Reference r) throws BuildException {
+        if (userIdSet || groupIdSet) {
+            throw tooManyAttributes();
+        }
+        super.setRefid(r);
+    }
+
+    /**
+     * A CommonsCompressFileSet accepts another FileSet as reference
+     * @param p the project to use
+     * @return the abstract fileset instance
+     */
+    protected AbstractFileSet getRef(Project p) {
+        dieOnCircularReference(p);
+        Object o = getRefid().getReferencedObject(p);
+        if (o.getClass().equals(getClass())) {
+            return (AbstractFileSet) o;
+        } else if (o instanceof FileSet) {
+            CommonsCompressFileSet zfs = newFileSet((FileSet) o);
+            configureFileSet(zfs);
+            return zfs;
+        } else {
+            String msg = getRefid().getRefId() + " doesn\'t denote a fileset";
+            throw new BuildException(msg);
+        }
+    }
+
+    /**
+     * Configure a fileset based on this fileset.
+     * If the fileset is a CommonsCompressFileSet copy in the
+     * specific attributes.
+     * @param zfs the archive fileset to configure.
+     */
+    protected void configureFileSet(ArchiveFileSet zfs) {
+        super.configureFileSet(zfs);
+        if (zfs instanceof CommonsCompressFileSet) {
+            CommonsCompressFileSet ccfs = (CommonsCompressFileSet) zfs;
+            ccfs.setUid(uid);
+            ccfs.setGid(gid);
+        }
+    }
+
+    /**
+     * Return a CommonsCompressFileSet that has the same properties
+     * as this one.
+     * @return the cloned tarFileSet
+     */
+    public Object clone() {
+        if (isReference()) {
+            return ((CommonsCompressFileSet) getRef(getProject())).clone();
+        } else {
+            return super.clone();
+        }
+    }
+
+    /**
+     * Creates a new CommonsCompressFileSet based on the given fileset.
+     */
+    protected abstract CommonsCompressFileSet newFileSet(FileSet fs);
+
+    /**
+     * A check attributes for CommonsCompressFileSet.
+     * If there is a reference, and
+     * it is a CommonsCompressFileSet, the specific attributes
+     * cannot be used.
+     */
+    protected final void checkCommonsCompressFileSetAttributesAllowed() {
+        if (getProject() == null
+            || (isReference()
+                && (getRefid().getReferencedObject(
+                        getProject())
+                    instanceof CommonsCompressFileSet))) {
+            checkAttributesAllowed();
+        }
+    }
+
+}
diff --git a/src/main/org/apache/ant/compress/resources/CpioFileSet.java b/src/main/org/apache/ant/compress/resources/CpioFileSet.java
index 9489df1..901baa1 100644
--- a/src/main/org/apache/ant/compress/resources/CpioFileSet.java
+++ b/src/main/org/apache/ant/compress/resources/CpioFileSet.java
@@ -21,13 +21,8 @@
 
 import org.apache.commons.compress.archivers.ArchiveEntry;
 import org.apache.commons.compress.archivers.cpio.CpioArchiveEntry;
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.types.AbstractFileSet;
-import org.apache.tools.ant.types.ArchiveFileSet;
 import org.apache.tools.ant.types.ArchiveScanner;
 import org.apache.tools.ant.types.FileSet;
-import org.apache.tools.ant.types.Reference;
 import org.apache.tools.ant.types.Resource;
 
 /**
@@ -39,16 +34,7 @@
  * a prefix attribute which is prepended to each entry in the output Cpio file.
  *
  */
-public class CpioFileSet extends ArchiveFileSet {
-
-    private boolean userIdSet;
-    private boolean groupIdSet;
-
-    private int    uid;
-    private int    gid;
-
-    private boolean skipUnreadable = false;
-    private String encoding = null;
+public class CpioFileSet extends CommonsCompressFileSet {
 
     /** Constructor for CpioFileSet */
     public CpioFileSet() {
@@ -56,7 +42,7 @@
     }
 
     /**
-     * Constructor using a fileset arguement.
+     * Constructor using a fileset argument.
      * @param fileset the fileset to use
      */
     protected CpioFileSet(FileSet fileset) {
@@ -64,87 +50,19 @@
     }
 
     /**
-     * Constructor using a cpiofileset arguement.
+     * Constructor using a cpiofileset argument.
      * @param fileset the cpiofileset to use
      */
     protected CpioFileSet(CpioFileSet fileset) {
         super(fileset);
-        encoding = fileset.encoding;
     }
 
     /**
-     * The uid for the cpio entry
-     * This is not the same as the User name.
-     * @param uid the id of the user for the cpio entry.
+     * Constructor using a CommonsCompressFileSet argument.
+     * @param fileset the fileset to use
      */
-    public void setUid(int uid) {
-        checkCpioFileSetAttributesAllowed();
-        userIdSet = true;
-        this.uid = uid;
-    }
-
-    /**
-     * @return the uid for the cpio entry
-     */
-    public int getUid() {
-        if (isReference()) {
-            return ((CpioFileSet) getCheckedRef()).getUid();
-        }
-        return uid;
-    }
-
-    /**
-     * @return whether the user id has been explicitly set.
-     */
-    public boolean hasUserIdBeenSet() {
-        return userIdSet;
-    }
-
-    /**
-     * The GID for the cpio entry; optional, default="0"
-     * This is not the same as the group name.
-     * @param gid the group id.
-     */
-    public void setGid(int gid) {
-        checkCpioFileSetAttributesAllowed();
-        groupIdSet = true;
-        this.gid = gid;
-    }
-
-    /**
-     * @return the group identifier.
-     */
-    public int getGid() {
-        if (isReference()) {
-            return ((CpioFileSet) getCheckedRef()).getGid();
-        }
-        return gid;
-    }
-
-    /**
-     * @return whether the group id has been explicitly set.
-     */
-    public boolean hasGroupIdBeenSet() {
-        return groupIdSet;
-    }
-
-    /**
-     * Whether to skip entries that Commons Compress signals it cannot read.
-     *
-     * @since Compress Antlib 1.1
-     */
-    public void setSkipUnreadableEntries(boolean b) {
-        skipUnreadable = b;
-    }
-
-    /**
-     * Set the encoding used for this CpioFileSet.
-     * @param enc encoding as String.
-     * @since Compress Antlib 1.3
-     */
-    public void setEncoding(String enc) {
-        checkCpioFileSetAttributesAllowed();
-        this.encoding = enc;
+    protected CpioFileSet(CommonsCompressFileSet fileset) {
+        super(fileset);
     }
 
     /**
@@ -159,89 +77,19 @@
                                               ArchiveEntry entry) {
                     return new CpioResource(archive, encoding, (CpioArchiveEntry) entry);
                 }
-            }, skipUnreadable, getProject());
-        cs.setEncoding(encoding);
+            }, getSkipUnreadableEntries(), getProject());
+        cs.setEncoding(getEncoding());
         return cs;
     }
 
-    /**
-     * Makes this instance in effect a reference to another instance.
-     *
-     * <p>You must not set another attribute or nest elements inside
-     * this element if you make it a reference.</p>
-     * @param r the <code>Reference</code> to use.
-     * @throws BuildException on error
-     */
-    public void setRefid(Reference r) throws BuildException {
-        if (userIdSet || groupIdSet) {
-            throw tooManyAttributes();
+    protected CommonsCompressFileSet newFileSet(FileSet fs) {
+        if (fs instanceof CpioFileSet) {
+            return new CpioFileSet((CpioFileSet) fs);
         }
-        super.setRefid(r);
-    }
-
-    /**
-     * A CpioFileset accepts another CpioFileSet or a FileSet as reference
-     * FileSets are often used by the war task for the lib attribute
-     * @param p the project to use
-     * @return the abstract fileset instance
-     */
-    protected AbstractFileSet getRef(Project p) {
-        dieOnCircularReference(p);
-        Object o = getRefid().getReferencedObject(p);
-        if (o instanceof CpioFileSet) {
-            return (AbstractFileSet) o;
-        } else if (o instanceof FileSet) {
-            CpioFileSet zfs = new CpioFileSet((FileSet) o);
-            configureFileSet(zfs);
-            return zfs;
-        } else {
-            String msg = getRefid().getRefId() + " doesn\'t denote a cpiofileset or a fileset";
-            throw new BuildException(msg);
+        if (fs instanceof CommonsCompressFileSet) {
+            return new CpioFileSet((CommonsCompressFileSet) fs);
         }
-    }
-
-    /**
-     * Configure a fileset based on this fileset.
-     * If the fileset is a CpioFileSet copy in the cpiofileset
-     * specific attributes.
-     * @param zfs the archive fileset to configure.
-     */
-    protected void configureFileSet(ArchiveFileSet zfs) {
-        super.configureFileSet(zfs);
-        if (zfs instanceof CpioFileSet) {
-            CpioFileSet tfs = (CpioFileSet) zfs;
-            tfs.setUid(uid);
-            tfs.setGid(gid);
-        }
-    }
-
-    /**
-     * Return a CpioFileSet that has the same properties
-     * as this one.
-     * @return the cloned cpioFileSet
-     */
-    public Object clone() {
-        if (isReference()) {
-            return ((CpioFileSet) getRef(getProject())).clone();
-        } else {
-            return super.clone();
-        }
-    }
-
-    /**
-     * A check attributes for CpioFileSet.
-     * If there is a reference, and
-     * it is a CpioFileSet, the cpio fileset attributes
-     * cannot be used.
-     */
-    private void checkCpioFileSetAttributesAllowed() {
-        if (getProject() == null
-            || (isReference()
-                && (getRefid().getReferencedObject(
-                        getProject())
-                    instanceof CpioFileSet))) {
-            checkAttributesAllowed();
-        }
+        return new CpioFileSet(fs);
     }
 
 }
diff --git a/src/main/org/apache/ant/compress/resources/DumpFileSet.java b/src/main/org/apache/ant/compress/resources/DumpFileSet.java
index 37f008a..a5bc520 100644
--- a/src/main/org/apache/ant/compress/resources/DumpFileSet.java
+++ b/src/main/org/apache/ant/compress/resources/DumpFileSet.java
@@ -21,13 +21,8 @@
 
 import org.apache.commons.compress.archivers.ArchiveEntry;
 import org.apache.commons.compress.archivers.dump.DumpArchiveEntry;
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.types.AbstractFileSet;
-import org.apache.tools.ant.types.ArchiveFileSet;
 import org.apache.tools.ant.types.ArchiveScanner;
 import org.apache.tools.ant.types.FileSet;
-import org.apache.tools.ant.types.Reference;
 import org.apache.tools.ant.types.Resource;
 
 /**
@@ -40,16 +35,7 @@
  *
  * @since Apache Compress Antlib 1.1
  */
-public class DumpFileSet extends ArchiveFileSet {
-
-    private boolean userIdSet;
-    private boolean groupIdSet;
-
-    private int    uid;
-    private int    gid;
-
-    private boolean skipUnreadable = false;
-    private String encoding = null;
+public class DumpFileSet extends CommonsCompressFileSet {
 
     /** Constructor for DumpFileSet */
     public DumpFileSet() {
@@ -57,7 +43,7 @@
     }
 
     /**
-     * Constructor using a fileset arguement.
+     * Constructor using a fileset argument.
      * @param fileset the fileset to use
      */
     protected DumpFileSet(FileSet fileset) {
@@ -65,85 +51,19 @@
     }
 
     /**
-     * Constructor using a dumpfileset arguement.
+     * Constructor using a dumpfileset argument.
      * @param fileset the dumpfileset to use
      */
     protected DumpFileSet(DumpFileSet fileset) {
         super(fileset);
-        encoding = fileset.encoding;
     }
 
     /**
-     * The uid for the dump entry
-     * This is not the same as the User name.
-     * @param uid the id of the user for the dump entry.
+     * Constructor using a CommonsCompressFileSet argument.
+     * @param fileset the fileset to use
      */
-    public void setUid(int uid) {
-        checkDumpFileSetAttributesAllowed();
-        userIdSet = true;
-        this.uid = uid;
-    }
-
-    /**
-     * @return the uid for the dump entry
-     */
-    public int getUid() {
-        if (isReference()) {
-            return ((DumpFileSet) getCheckedRef()).getUid();
-        }
-        return uid;
-    }
-
-    /**
-     * @return whether the user id has been explicitly set.
-     */
-    public boolean hasUserIdBeenSet() {
-        return userIdSet;
-    }
-
-    /**
-     * The GID for the dump entry; optional, default="0"
-     * This is not the same as the group name.
-     * @param gid the group id.
-     */
-    public void setGid(int gid) {
-        checkDumpFileSetAttributesAllowed();
-        groupIdSet = true;
-        this.gid = gid;
-    }
-
-    /**
-     * @return the group identifier.
-     */
-    public int getGid() {
-        if (isReference()) {
-            return ((DumpFileSet) getCheckedRef()).getGid();
-        }
-        return gid;
-    }
-
-    /**
-     * @return whether the group id has been explicitly set.
-     */
-    public boolean hasGroupIdBeenSet() {
-        return groupIdSet;
-    }
-
-    /**
-     * Whether to skip entries that Commons Compress signals it cannot read.
-     */
-    public void setSkipUnreadableEntries(boolean b) {
-        skipUnreadable = b;
-    }
-
-    /**
-     * Set the encoding used for this CpioFileSet.
-     * @param enc encoding as String.
-     * @since Compress Antlib 1.3
-     */
-    public void setEncoding(String enc) {
-        checkDumpFileSetAttributesAllowed();
-        this.encoding = enc;
+    protected DumpFileSet(CommonsCompressFileSet fileset) {
+        super(fileset);
     }
 
     /**
@@ -158,89 +78,19 @@
                                               ArchiveEntry entry) {
                     return new DumpResource(archive, encoding, (DumpArchiveEntry) entry);
                 }
-            }, skipUnreadable, getProject());
-        cs.setEncoding(encoding);
+            }, getSkipUnreadableEntries(), getProject());
+        cs.setEncoding(getEncoding());
         return cs;
     }
 
-    /**
-     * Makes this instance in effect a reference to another instance.
-     *
-     * <p>You must not set another attribute or nest elements inside
-     * this element if you make it a reference.</p>
-     * @param r the <code>Reference</code> to use.
-     * @throws BuildException on error
-     */
-    public void setRefid(Reference r) throws BuildException {
-        if (userIdSet || groupIdSet) {
-            throw tooManyAttributes();
+    protected CommonsCompressFileSet newFileSet(FileSet fs) {
+        if (fs instanceof DumpFileSet) {
+            return new DumpFileSet((DumpFileSet) fs);
         }
-        super.setRefid(r);
-    }
-
-    /**
-     * A DumpFileset accepts another DumpFileSet or a FileSet as reference
-     * FileSets are often used by the war task for the lib attribute
-     * @param p the project to use
-     * @return the abstract fileset instance
-     */
-    protected AbstractFileSet getRef(Project p) {
-        dieOnCircularReference(p);
-        Object o = getRefid().getReferencedObject(p);
-        if (o instanceof DumpFileSet) {
-            return (AbstractFileSet) o;
-        } else if (o instanceof FileSet) {
-            DumpFileSet zfs = new DumpFileSet((FileSet) o);
-            configureFileSet(zfs);
-            return zfs;
-        } else {
-            String msg = getRefid().getRefId() + " doesn\'t denote a dumpfileset or a fileset";
-            throw new BuildException(msg);
+        if (fs instanceof CommonsCompressFileSet) {
+            return new DumpFileSet((CommonsCompressFileSet) fs);
         }
-    }
-
-    /**
-     * Configure a fileset based on this fileset.
-     * If the fileset is a DumpFileSet copy in the dumpfileset
-     * specific attributes.
-     * @param zfs the archive fileset to configure.
-     */
-    protected void configureFileSet(ArchiveFileSet zfs) {
-        super.configureFileSet(zfs);
-        if (zfs instanceof DumpFileSet) {
-            DumpFileSet tfs = (DumpFileSet) zfs;
-            tfs.setUid(uid);
-            tfs.setGid(gid);
-        }
-    }
-
-    /**
-     * Return a DumpFileSet that has the same properties
-     * as this one.
-     * @return the cloned dumpFileSet
-     */
-    public Object clone() {
-        if (isReference()) {
-            return ((DumpFileSet) getRef(getProject())).clone();
-        } else {
-            return super.clone();
-        }
-    }
-
-    /**
-     * A check attributes for DumpFileSet.
-     * If there is a reference, and
-     * it is a DumpFileSet, the dump fileset attributes
-     * cannot be used.
-     */
-    private void checkDumpFileSetAttributesAllowed() {
-        if (getProject() == null
-            || (isReference()
-                && (getRefid().getReferencedObject(
-                        getProject())
-                    instanceof DumpFileSet))) {
-            checkAttributesAllowed();
-        }
+        return new DumpFileSet(fs);
     }
 
 }
diff --git a/src/main/org/apache/ant/compress/resources/TarFileSet.java b/src/main/org/apache/ant/compress/resources/TarFileSet.java
index 3597244..0c3dae7 100644
--- a/src/main/org/apache/ant/compress/resources/TarFileSet.java
+++ b/src/main/org/apache/ant/compress/resources/TarFileSet.java
@@ -22,8 +22,6 @@
 import org.apache.commons.compress.archivers.ArchiveEntry;
 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
 import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.types.AbstractFileSet;
 import org.apache.tools.ant.types.ArchiveFileSet;
 import org.apache.tools.ant.types.ArchiveScanner;
 import org.apache.tools.ant.types.FileSet;
@@ -39,20 +37,13 @@
  * a prefix attribute which is prepended to each entry in the output Tar file.
  *
  */
-public class TarFileSet extends ArchiveFileSet {
+public class TarFileSet extends CommonsCompressFileSet {
 
     private boolean userNameSet;
     private boolean groupNameSet;
-    private boolean userIdSet;
-    private boolean groupIdSet;
 
     private String userName = "";
     private String groupName = "";
-    private int    uid;
-    private int    gid;
-
-    private boolean skipUnreadable = false;
-    private String encoding = null;
 
     /** Constructor for TarFileSet */
     public TarFileSet() {
@@ -60,7 +51,7 @@
     }
 
     /**
-     * Constructor using a fileset arguement.
+     * Constructor using a fileset argument.
      * @param fileset the fileset to use
      */
     protected TarFileSet(FileSet fileset) {
@@ -68,39 +59,19 @@
     }
 
     /**
-     * Constructor using a tarfileset arguement.
+     * Constructor using a tarfileset argument.
      * @param fileset the tarfileset to use
      */
     protected TarFileSet(TarFileSet fileset) {
         super(fileset);
-        encoding = fileset.encoding;
     }
 
     /**
-     * Set the encoding used for this TarFileSet.
-     * @param enc encoding as String.
-     * @since Compress Antlib 1.2
+     * Constructor using a CommonsCompressFileSet argument.
+     * @param fileset the fileset to use
      */
-    public void setEncoding(String enc) {
-        checkTarFileSetAttributesAllowed();
-        this.encoding = enc;
-    }
-
-    /**
-     * Get the encoding used for this TarFileSet.
-     * @return String encoding.
-     * @since Compress Antlib 1.2
-     */
-    public String getEncoding() {
-        if (isReference()) {
-            AbstractFileSet ref = getRef(getProject());
-            if (ref instanceof TarFileSet) {
-                return ((TarFileSet) ref).getEncoding();
-            } else {
-                return null;
-            }
-        }
-        return encoding;
+    protected TarFileSet(CommonsCompressFileSet fileset) {
+        super(fileset);
     }
 
     /**
@@ -109,7 +80,7 @@
      * @param userName the user name for the tar entry.
      */
     public void setUserName(String userName) {
-        checkTarFileSetAttributesAllowed();
+        checkCommonsCompressFileSetAttributesAllowed();
         userNameSet = true;
         this.userName = userName;
     }
@@ -132,40 +103,12 @@
     }
 
     /**
-     * The uid for the tar entry
-     * This is not the same as the User name.
-     * @param uid the id of the user for the tar entry.
-     */
-    public void setUid(int uid) {
-        checkTarFileSetAttributesAllowed();
-        userIdSet = true;
-        this.uid = uid;
-    }
-
-    /**
-     * @return the uid for the tar entry
-     */
-    public int getUid() {
-        if (isReference()) {
-            return ((TarFileSet) getCheckedRef()).getUid();
-        }
-        return uid;
-    }
-
-    /**
-     * @return whether the user id has been explicitly set.
-     */
-    public boolean hasUserIdBeenSet() {
-        return userIdSet;
-    }
-
-    /**
      * The groupname for the tar entry; optional, default=""
      * This is not the same as the GID.
      * @param groupName the group name string.
      */
     public void setGroup(String groupName) {
-        checkTarFileSetAttributesAllowed();
+        checkCommonsCompressFileSetAttributesAllowed();
         groupNameSet = true;
         this.groupName = groupName;
     }
@@ -188,43 +131,6 @@
     }
 
     /**
-     * The GID for the tar entry; optional, default="0"
-     * This is not the same as the group name.
-     * @param gid the group id.
-     */
-    public void setGid(int gid) {
-        checkTarFileSetAttributesAllowed();
-        groupIdSet = true;
-        this.gid = gid;
-    }
-
-    /**
-     * @return the group identifier.
-     */
-    public int getGid() {
-        if (isReference()) {
-            return ((TarFileSet) getCheckedRef()).getGid();
-        }
-        return gid;
-    }
-
-    /**
-     * @return whether the group id has been explicitly set.
-     */
-    public boolean hasGroupIdBeenSet() {
-        return groupIdSet;
-    }
-
-    /**
-     * Whether to skip entries that Commons Compress signals it cannot read.
-     *
-     * @since Compress Antlib 1.1
-     */
-    public void setSkipUnreadableEntries(boolean b) {
-        skipUnreadable = b;
-    }
-
-    /**
      * Create a new scanner.
      * @return the created scanner.
      */
@@ -237,8 +143,8 @@
                     return new TarResource(archive, encoding,
                                            (TarArchiveEntry) entry);
                 }
-            }, skipUnreadable, getProject());
-        cs.setEncoding(encoding);
+            }, getSkipUnreadableEntries(), getProject());
+        cs.setEncoding(getEncoding());
         return cs;
     }
 
@@ -251,34 +157,13 @@
      * @throws BuildException on error
      */
     public void setRefid(Reference r) throws BuildException {
-        if (userNameSet || userIdSet || groupNameSet || groupIdSet) {
+        if (userNameSet || groupNameSet) {
             throw tooManyAttributes();
         }
         super.setRefid(r);
     }
 
     /**
-     * A TarFileset accepts another TarFileSet or a FileSet as reference
-     * FileSets are often used by the war task for the lib attribute
-     * @param p the project to use
-     * @return the abstract fileset instance
-     */
-    protected AbstractFileSet getRef(Project p) {
-        dieOnCircularReference(p);
-        Object o = getRefid().getReferencedObject(p);
-        if (o instanceof TarFileSet) {
-            return (AbstractFileSet) o;
-        } else if (o instanceof FileSet) {
-            TarFileSet zfs = new TarFileSet((FileSet) o);
-            configureFileSet(zfs);
-            return zfs;
-        } else {
-            String msg = getRefid().getRefId() + " doesn\'t denote a tarfileset or a fileset";
-            throw new BuildException(msg);
-        }
-    }
-
-    /**
      * Configure a fileset based on this fileset.
      * If the fileset is a TarFileSet copy in the tarfileset
      * specific attributes.
@@ -290,38 +175,16 @@
             TarFileSet tfs = (TarFileSet) zfs;
             tfs.setUserName(userName);
             tfs.setGroup(groupName);
-            tfs.setUid(uid);
-            tfs.setGid(gid);
         }
     }
 
-    /**
-     * Return a TarFileSet that has the same properties
-     * as this one.
-     * @return the cloned tarFileSet
-     */
-    public Object clone() {
-        if (isReference()) {
-            return ((TarFileSet) getRef(getProject())).clone();
-        } else {
-            return super.clone();
+    protected CommonsCompressFileSet newFileSet(FileSet fs) {
+        if (fs instanceof TarFileSet) {
+            return new TarFileSet((TarFileSet) fs);
         }
-    }
-
-    /**
-     * A check attributes for TarFileSet.
-     * If there is a reference, and
-     * it is a TarFileSet, the tar fileset attributes
-     * cannot be used.
-     */
-    private void checkTarFileSetAttributesAllowed() {
-        if (getProject() == null
-            || (isReference()
-                && (getRefid().getReferencedObject(
-                        getProject())
-                    instanceof TarFileSet))) {
-            checkAttributesAllowed();
+        if (fs instanceof CommonsCompressFileSet) {
+            return new TarFileSet((CommonsCompressFileSet) fs);
         }
+        return new TarFileSet(fs);
     }
-
 }
diff --git a/src/main/org/apache/ant/compress/resources/ZipFileSet.java b/src/main/org/apache/ant/compress/resources/ZipFileSet.java
index 4856572..3f0df20 100644
--- a/src/main/org/apache/ant/compress/resources/ZipFileSet.java
+++ b/src/main/org/apache/ant/compress/resources/ZipFileSet.java
@@ -17,13 +17,8 @@
  */
 package org.apache.ant.compress.resources;
 
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.types.AbstractFileSet;
-import org.apache.tools.ant.types.ArchiveFileSet;
 import org.apache.tools.ant.types.ArchiveScanner;
 import org.apache.tools.ant.types.FileSet;
-import org.apache.tools.ant.types.Reference;
 
 /**
  * A ZipFileSet is a FileSet with extra attributes useful in the context of
@@ -34,10 +29,7 @@
  * a prefix attribute which is prepended to each entry in the output Zip file.
  *
  */
-public class ZipFileSet extends ArchiveFileSet {
-
-    private String encoding = null;
-    private boolean skipUnreadable = false;
+public class ZipFileSet extends CommonsCompressFileSet {
 
     /** Constructor for ZipFileSet */
     public ZipFileSet() {
@@ -45,7 +37,7 @@
     }
 
     /**
-     * Constructor using a fileset arguement.
+     * Constructor using a fileset argument.
      * @param fileset the fileset to use
      */
     protected ZipFileSet(FileSet fileset) {
@@ -53,46 +45,19 @@
     }
 
     /**
-     * Constructor using a zipfileset arguement.
+     * Constructor using a zipfileset argument.
      * @param fileset the zipfileset to use
      */
     protected ZipFileSet(ZipFileSet fileset) {
         super(fileset);
-        encoding = fileset.encoding;
     }
 
     /**
-     * Set the encoding used for this ZipFileSet.
-     * @param enc encoding as String.
+     * Constructor using a CommonsCompressFileSet argument.
+     * @param fileset the fileset to use
      */
-    public void setEncoding(String enc) {
-        checkZipFileSetAttributesAllowed();
-        this.encoding = enc;
-    }
-
-    /**
-     * Get the encoding used for this ZipFileSet.
-     * @return String encoding.
-     */
-    public String getEncoding() {
-        if (isReference()) {
-            AbstractFileSet ref = getRef(getProject());
-            if (ref instanceof ZipFileSet) {
-                return ((ZipFileSet) ref).getEncoding();
-            } else {
-                return null;
-            }
-        }
-        return encoding;
-    }
-
-    /**
-     * Whether to skip entries that Commons Compress signals it cannot read.
-     *
-     * @since Compress Antlib 1.1
-     */
-    public void setSkipUnreadableEntries(boolean b) {
-        skipUnreadable = b;
+    protected ZipFileSet(CommonsCompressFileSet fileset) {
+        super(fileset);
     }
 
     /**
@@ -100,59 +65,19 @@
      * @return a new ZipScanner with the same encoding as this one.
      */
     protected ArchiveScanner newArchiveScanner() {
-        ZipScanner zs = new ZipScanner(skipUnreadable, getProject());
-        zs.setEncoding(encoding);
+        ZipScanner zs = new ZipScanner(getSkipUnreadableEntries(), getProject());
+        zs.setEncoding(getEncoding());
         return zs;
     }
 
-    /**
-     * A ZipFileset accepts another ZipFileSet or a FileSet as reference
-     * FileSets are often used by the war task for the lib attribute
-     * @param p the project to use
-     * @return the abstract fileset instance
-     */
-    protected AbstractFileSet getRef(Project p) {
-        dieOnCircularReference(p);
-        Object o = getRefid().getReferencedObject(p);
-        if (o instanceof ZipFileSet) {
-            return (AbstractFileSet) o;
-        } else if (o instanceof FileSet) {
-            ZipFileSet zfs = new ZipFileSet((FileSet) o);
-            configureFileSet(zfs);
-            return zfs;
-        } else {
-            String msg = getRefid().getRefId() + " doesn\'t denote a zipfileset or a fileset";
-            throw new BuildException(msg);
+    protected CommonsCompressFileSet newFileSet(FileSet fs) {
+        if (fs instanceof ZipFileSet) {
+            return new ZipFileSet((ZipFileSet) fs);
         }
-    }
-
-    /**
-     * Return a ZipFileSet that has the same properties
-     * as this one.
-     * @return the cloned zipFileSet
-     */
-    public Object clone() {
-        if (isReference()) {
-            return ((ZipFileSet) getRef(getProject())).clone();
-        } else {
-            return super.clone();
+        if (fs instanceof CommonsCompressFileSet) {
+            return new ZipFileSet((CommonsCompressFileSet) fs);
         }
-    }
-
-    /**
-     * A check attributes for zipFileSet.
-     * If there is a reference, and
-     * it is a ZipFileSet, the zip fileset attributes
-     * cannot be used.
-     */
-    private void checkZipFileSetAttributesAllowed() {
-        if (getProject() == null
-            || (isReference()
-                && (getRefid().getReferencedObject(
-                        getProject())
-                    instanceof ZipFileSet))) {
-            checkAttributesAllowed();
-        }
+        return new ZipFileSet(fs);
     }
 
 }