add read-only support for uncompressed arj archives

git-svn-id: https://svn.apache.org/repos/asf/ant/antlibs/compress/trunk@1517183 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/changes.xml b/changes.xml
index f0da13a..3478e96 100644
--- a/changes.xml
+++ b/changes.xml
@@ -41,6 +41,9 @@
       <action type="add">
         Encoding support for dump and cpio archives and filesets.
       </action>
+      <action type="add">
+        Read-only upport for uncompress arj archives has been added.
+      </action>
     </release>
 
     <release version="1.2" date="2012-04-20">
diff --git a/docs/expand.html b/docs/expand.html
index 2f52dc9..c4cb450 100644
--- a/docs/expand.html
+++ b/docs/expand.html
@@ -110,6 +110,34 @@
   in different ways, the GNU/SRV4 and the BSD variant; both of which
   are transparently supported since Commons Compress 1.3.</p>
 
+<h3><a name="unarj">UnArj</a></h3>
+
+<p><em>Since Apache Compress Antlib 1.3</em>.</p>
+
+<p>An <a href="#expand">unarchiving task</a> for arj archives.</p>
+
+<p>In addition to the parameters above, the unarj tasks supports the
+  following attributes:</p>
+
+<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">encoding</td>
+    <td valign="top">
+    The character encoding that has been used for filenames
+    inside the arj file.  For a list of possible values see <a
+    href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html</a>.<br>
+    Defaults <code>native-encoding</code> which is the magic value for
+    the platform's default character encoding.<br/>
+    <em>since Compress Antlib 1.3</em></td>
+    <td align="center" valign="top">No</td>
+  </tr>
+</table>
+
 <h3><a name="uncpio">UnCpio</a></h3>
 
 <p>An <a href="#expand">unarchiving task</a> for CPIO archives.</p>
diff --git a/docs/fileset.html b/docs/fileset.html
index b36cc05..4e9da2e 100644
--- a/docs/fileset.html
+++ b/docs/fileset.html
@@ -178,6 +178,51 @@
   target directory, no files get overwritten unless they are
   out-of-date.</p>
 
+<h2><a name="arjfileset">ArjFileSet</a></h2>
+
+<p><em>Since Apache Compress Antlib 1.3</em>.</p>
+
+<p>A <code>&lt;arjfileset&gt;</code> is
+  an <a href="#archivefileset">archive fileset</a>.</p>
+
+<h3>Parameters</h3>
+<table border="1" cellpadding="2" cellspacing="0">
+  <tbody>
+    <tr>
+      <td valign="top"><b>Attribute</b></td>
+      <td valign="top"><b>Description</b></td>
+      <td valign="top" align="center"><b>Required</b></td>
+    </tr>
+    <tr>
+      <td valign="top">encoding</td>
+      <td valign="top">
+        The character encoding that has been used for filenames
+        inside the arj file.  For a list of possible values see <a
+                                                                   href="http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html">http://java.sun.com/j2se/1.5.0/docs/guide/intl/encoding.doc.html</a>.<br>
+        Defaults <code>native-encoding</code> which is the magic value for
+        the platform's default character encoding.<br/>
+        <em>since Compress Antlib 1.3</em></td>
+      <td align="center" valign="top">No</td>
+    </tr>
+  </tbody>
+</table>
+
+<h4>Examples</h4>
+<blockquote>
+<pre>
+  &lt;copy todir="some-dir"&gt;
+    &lt;cmp:arjfileset xmlns:cmp="antlib:org.apache.ant.compress"&gt;
+      &lt;file file="some-archive.arj"/&gt;
+    &lt;/cmp:arjfileset&gt;
+  &lt;/copy&gt;
+</pre></blockquote>
+
+<p>extracts some-archive.arj
+  and copies the contents of it into some-dir.  File timestamps will
+  be compared between the archive's entries and files inside the
+  target directory, no files get overwritten unless they are
+  out-of-date.</p>
+
 <h2><a name="cpiofileset">CpioFileSet</a></h2>
 
 <p>A <code>&lt;cpiofileset&gt;</code> is
diff --git a/src/main/org/apache/ant/compress/antlib.xml b/src/main/org/apache/ant/compress/antlib.xml
index baf6e45..9f94839 100644
--- a/src/main/org/apache/ant/compress/antlib.xml
+++ b/src/main/org/apache/ant/compress/antlib.xml
@@ -21,6 +21,10 @@
      classname="org.apache.ant.compress.taskdefs.Unar"
      />
   <taskdef
+     name="unarj"
+     classname="org.apache.ant.compress.taskdefs.Unarj"
+     />
+  <taskdef
      name="uncpio"
      classname="org.apache.ant.compress.taskdefs.Uncpio"
      />
@@ -94,6 +98,10 @@
      classname="org.apache.ant.compress.resources.ArResource"
      />
   <typedef
+     name="arjentry"
+     classname="org.apache.ant.compress.resources.ArjResource"
+     />
+  <typedef
      name="cpioentry"
      classname="org.apache.ant.compress.resources.CpioResource"
      />
@@ -115,6 +123,10 @@
      classname="org.apache.ant.compress.resources.ArFileSet"
      />
   <typedef
+     name="arjfileset"
+     classname="org.apache.ant.compress.resources.ArjFileSet"
+     />
+  <typedef
      name="cpiofileset"
      classname="org.apache.ant.compress.resources.CpioFileSet"
      />
diff --git a/src/main/org/apache/ant/compress/resources/ArjFileSet.java b/src/main/org/apache/ant/compress/resources/ArjFileSet.java
new file mode 100644
index 0000000..86027f6
--- /dev/null
+++ b/src/main/org/apache/ant/compress/resources/ArjFileSet.java
@@ -0,0 +1,96 @@
+/*
+ *  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.ant.compress.util.ArjStreamFactory;
+
+import org.apache.commons.compress.archivers.ArchiveEntry;
+import org.apache.commons.compress.archivers.arj.ArjArchiveEntry;
+import org.apache.tools.ant.types.ArchiveScanner;
+import org.apache.tools.ant.types.FileSet;
+import org.apache.tools.ant.types.Resource;
+
+/**
+ * A ArjFileSet is a FileSet with extra attributes useful in the context of
+ * Arj tasks.
+ *
+ * A ArjFileSet extends FileSets with the ability to extract a subset of the
+ * entries of a Arj file for inclusion in another Arj file.  It also includes
+ * a prefix attribute which is prepended to each entry in the output Arj file.
+ *
+ * @since Apache Compress Antlib 1.3
+ */
+public class ArjFileSet extends CommonsCompressFileSet {
+
+    /** Constructor for ArjFileSet */
+    public ArjFileSet() {
+        super();
+    }
+
+    /**
+     * Constructor using a fileset argument.
+     * @param fileset the fileset to use
+     */
+    protected ArjFileSet(FileSet fileset) {
+        super(fileset);
+    }
+
+    /**
+     * Constructor using a arjfileset argument.
+     * @param fileset the arjfileset to use
+     */
+    protected ArjFileSet(ArjFileSet fileset) {
+        super(fileset);
+    }
+
+    /**
+     * Constructor using a CommonsCompressFileSet argument.
+     * @param fileset the fileset to use
+     */
+    protected ArjFileSet(CommonsCompressFileSet fileset) {
+        super(fileset);
+    }
+
+    /**
+     * Create a new scanner.
+     * @return the created scanner.
+     */
+    protected ArchiveScanner newArchiveScanner() {
+        CommonsCompressArchiveScanner cs =
+            new CommonsCompressArchiveScanner(new ArjStreamFactory(),
+                                              new CommonsCompressArchiveScanner.ResourceBuilder() {
+                public Resource buildResource(Resource archive, String encoding,
+                                              ArchiveEntry entry) {
+                    return new ArjResource(archive, encoding, (ArjArchiveEntry) entry);
+                }
+            }, getSkipUnreadableEntries(), getProject());
+        cs.setEncoding(getEncoding());
+        return cs;
+    }
+
+    protected CommonsCompressFileSet newFileSet(FileSet fs) {
+        if (fs instanceof ArjFileSet) {
+            return new ArjFileSet((ArjFileSet) fs);
+        }
+        if (fs instanceof CommonsCompressFileSet) {
+            return new ArjFileSet((CommonsCompressFileSet) fs);
+        }
+        return new ArjFileSet(fs);
+    }
+
+}
diff --git a/src/main/org/apache/ant/compress/resources/ArjResource.java b/src/main/org/apache/ant/compress/resources/ArjResource.java
new file mode 100644
index 0000000..73f6fe1
--- /dev/null
+++ b/src/main/org/apache/ant/compress/resources/ArjResource.java
@@ -0,0 +1,85 @@
+/*
+ *  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 java.io.File;
+
+import org.apache.tools.ant.types.Resource;
+import org.apache.ant.compress.util.ArjStreamFactory;
+import org.apache.commons.compress.archivers.arj.ArjArchiveEntry;
+
+/**
+ * A Resource representation of an entry in a arj archive.
+ * @since Apache Compress Antlib 1.3
+ */
+public final class ArjResource extends CommonsCompressArchiveResource {
+
+    /**
+     * Default constructor.
+     */
+    public ArjResource() {
+        super(new ArjStreamFactory(), "arj");
+    }
+
+    /**
+     * Construct a ArjResource representing the specified
+     * entry in the specified archive.
+     * @param a the archive as File.
+     * @param e the ArjEntry.
+     */
+    public ArjResource(File a, ArjArchiveEntry e) {
+        this(a, null, e);
+    }
+
+    /**
+     * Construct a ArjResource representing the specified
+     * entry in the specified archive.
+     * @param a the archive as Resource.
+     * @param e the ArjEntry.
+     */
+    public ArjResource(Resource a, ArjArchiveEntry e) {
+        this(a, null, e);
+    }
+
+    /**
+     * Construct a ArjResource representing the specified
+     * entry in the specified archive.
+     * @param a the archive as File.
+     * @param enc the encoding used for filenames.
+     * @param e the ArjEntry.
+     */
+    public ArjResource(File a, String enc, ArjArchiveEntry e) {
+        super(new ArjStreamFactory(), "arj", a, e);
+        setEncoding(enc);
+        setEntry(e);
+    }
+
+    /**
+     * Construct a ArjResource representing the specified
+     * entry in the specified archive.
+     * @param a the archive as Resource.
+     * @param enc the encoding used for filenames.
+     * @param e the ArjEntry.
+     */
+    public ArjResource(Resource a, String enc, ArjArchiveEntry e) {
+        super(new ArjStreamFactory(), "arj", a, e);
+        setEncoding(enc);
+        setEntry(e);
+    }
+
+}
diff --git a/src/main/org/apache/ant/compress/taskdefs/Unarj.java b/src/main/org/apache/ant/compress/taskdefs/Unarj.java
new file mode 100644
index 0000000..4f6b69e
--- /dev/null
+++ b/src/main/org/apache/ant/compress/taskdefs/Unarj.java
@@ -0,0 +1,40 @@
+/*
+ *  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.taskdefs;
+
+import org.apache.ant.compress.util.ArjStreamFactory;
+
+/**
+ * Unarj a file.
+ * @since Apache Compress Antlib 1.3
+ */
+public class Unarj extends ExpandBase {
+    public Unarj() {
+        super(new ArjStreamFactory());
+    }
+
+    /**
+     * Set the file-name encoding for this archive, defaults to the
+     * native encoding.
+     */
+    public void setEncoding(String encoding) {
+        internalSetEncoding(encoding);
+    }
+
+}
diff --git a/src/main/org/apache/ant/compress/util/ArchiveStreamFactory.java b/src/main/org/apache/ant/compress/util/ArchiveStreamFactory.java
index 9d75287..0097dec 100644
--- a/src/main/org/apache/ant/compress/util/ArchiveStreamFactory.java
+++ b/src/main/org/apache/ant/compress/util/ArchiveStreamFactory.java
@@ -33,7 +33,7 @@
     /**
      * @param stream the stream to read from, should be buffered
      * @param encoding the encoding of the entry names, ignored by all
-     * formats except cpio, dump, tar and zip
+     * formats except arj, cpio, dump, tar and zip
      */
     public ArchiveInputStream getArchiveStream(InputStream stream,
                                                String encoding)
diff --git a/src/main/org/apache/ant/compress/util/ArjStreamFactory.java b/src/main/org/apache/ant/compress/util/ArjStreamFactory.java
new file mode 100644
index 0000000..265f6a2
--- /dev/null
+++ b/src/main/org/apache/ant/compress/util/ArjStreamFactory.java
@@ -0,0 +1,58 @@
+/*
+ *  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.util;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.commons.compress.archivers.ArchiveException;
+import org.apache.commons.compress.archivers.ArchiveInputStream;
+import org.apache.commons.compress.archivers.ArchiveOutputStream;
+import org.apache.commons.compress.archivers.arj.ArjArchiveInputStream;
+import org.apache.tools.ant.BuildException;
+
+/**
+ * @since Apache Compress Antlib 1.3
+ */
+public class ArjStreamFactory implements ArchiveStreamFactory {
+
+    /**
+     * @param stream the stream to read from, should be buffered
+     * @param encoding the encoding of the entry names
+     */
+    public ArchiveInputStream getArchiveStream(InputStream stream,
+                                               String encoding)
+        throws IOException {
+        try {
+            return new ArjArchiveInputStream(stream, encoding);
+        } catch (ArchiveException ex) {
+            throw new BuildException(ex);
+        }
+    }
+
+    /**
+     * Not implemented.
+     */
+    public ArchiveOutputStream getArchiveStream(OutputStream stream,
+                                                String encoding)
+        throws IOException {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/src/main/org/apache/ant/compress/util/EntryHelper.java b/src/main/org/apache/ant/compress/util/EntryHelper.java
index d6382c6..e56e85c 100644
--- a/src/main/org/apache/ant/compress/util/EntryHelper.java
+++ b/src/main/org/apache/ant/compress/util/EntryHelper.java
@@ -24,6 +24,7 @@
 
 import org.apache.commons.compress.archivers.ArchiveEntry;
 import org.apache.commons.compress.archivers.ar.ArArchiveEntry;
+import org.apache.commons.compress.archivers.arj.ArjArchiveEntry;
 import org.apache.commons.compress.archivers.cpio.CpioArchiveEntry;
 import org.apache.commons.compress.archivers.dump.DumpArchiveEntry;
 import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
@@ -48,6 +49,9 @@
         if (entry instanceof ArArchiveEntry) {
             return ((ArArchiveEntry) entry).getMode();
         }
+        if (entry instanceof ArjArchiveEntry) {
+            return ((ArjArchiveEntry) entry).getUnixMode();
+        }
         if (entry instanceof CpioArchiveEntry) {
             return (int) ((CpioArchiveEntry) entry).getMode();
         }
@@ -77,6 +81,9 @@
         if (entry instanceof ArArchiveEntry) {
             return ((ArArchiveEntry) entry).getUserId();
         }
+        if (entry instanceof ArjArchiveEntry) {
+            return UNKNOWN_ID;
+        }
         if (entry instanceof CpioArchiveEntry) {
             return (int) ((CpioArchiveEntry) entry).getUID();
         }
@@ -104,6 +111,9 @@
         if (entry instanceof ArArchiveEntry) {
             return ((ArArchiveEntry) entry).getGroupId();
         }
+        if (entry instanceof ArjArchiveEntry) {
+            return UNKNOWN_ID;
+        }
         if (entry instanceof CpioArchiveEntry) {
             return (int) ((CpioArchiveEntry) entry).getGID();
         }
@@ -119,4 +129,4 @@
         throw new BuildException("archive entry " + entry.getClass()
                                  + " is not supported.");
     }
-}
\ No newline at end of file
+}
diff --git a/src/tests/antunit/arjentry-test.xml b/src/tests/antunit/arjentry-test.xml
new file mode 100644
index 0000000..089d752
--- /dev/null
+++ b/src/tests/antunit/arjentry-test.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<project default="antunit"
+         xmlns:au="antlib:org.apache.ant.antunit"
+         xmlns:cond="antlib:org.apache.tools.ant.types.conditions"
+         xmlns:cmp="antlib:org.apache.ant.compress">
+
+  <import file="antunit-base.xml" />
+
+  <target name="setUp">
+    <mkdir dir="${output}"/>
+  </target>
+
+  <target name="testArjSource" depends="setUp">
+    <copy todir="${output}">
+      <cmp:arjentry name="asf-logo.gif">
+        <file file="../resources/asf-logo.gif.arj"/>
+      </cmp:arjentry>
+    </copy>
+    <au:assertFilesMatch
+       actual="${output}/asf-logo.gif"
+       expected="../resources/asf-logo.gif"
+       />
+  </target>
+
+  <!-- reading of either seems to be wrong right now, or my archive is
+       broken-->
+  <target name="NotestResourceProperties">
+    <au:assertTrue>
+      <cond:islastmodified datetime="2001-11-19-15:34:20 +0100"
+                           pattern="yyyy-MM-dd-HH:mm:ss Z">
+        <cmp:arjentry name="asf-logo.gif">
+          <file file="../resources/asf-logo.gif.arj"/>
+        </cmp:arjentry>
+      </cond:islastmodified>
+    </au:assertTrue>
+    <au:assertTrue>
+      <cmp:hasmode mode="644">
+        <cmp:arjentry name="asf-logo.gif">
+          <file file="../resources/asf-logo.gif.arj"/>
+        </cmp:arjentry>
+      </cmp:hasmode>
+    </au:assertTrue>
+  </target>
+</project>
diff --git a/src/tests/antunit/arjfileset-test.xml b/src/tests/antunit/arjfileset-test.xml
new file mode 100644
index 0000000..678ffc4
--- /dev/null
+++ b/src/tests/antunit/arjfileset-test.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<project default="antunit"
+         xmlns:au="antlib:org.apache.ant.antunit"
+         xmlns:cmp="antlib:org.apache.ant.compress">
+  <import file="antunit-base.xml"/>
+
+  <target name="setUp">
+    <mkdir dir="${output}"/>
+    <mkdir dir="${input}"/>
+  </target>
+
+  <target name="testMissingArchive">
+    <mkdir dir="${output}"/>
+    <au:expectfailure expectedMessage="The archive foo.arj doesn't exist">
+      <copy todir="${output}">
+        <cmp:arjfileset src="foo.arj"/>
+      </copy>
+    </au:expectfailure>
+  </target>
+
+  <target name="testMissingArchiveDoesntMatter">
+    <mkdir dir="${output}"/>
+    <copy todir="${output}">
+      <cmp:arjfileset src="foo.arj" errorOnMissingArchive="false"/>
+    </copy>
+  </target>
+
+  <target name="testArjSource" depends="setUp">
+    <copy todir="${output}">
+      <cmp:arjfileset src="../resources/asf-logo.gif.arj"
+                      includes="*.gif"/>
+    </copy>
+    <au:assertFilesMatch
+       actual="${output}/asf-logo.gif"
+       expected="../resources/asf-logo.gif"
+       />
+  </target>
+
+  <target name="testUncompressSource" depends="setUp">
+    <gzip destfile="${input}/asf-logo.gif.arj.gz"
+          src="../resources/asf-logo.gif.arj"/>
+    <copy todir="${output}">
+      <cmp:arjfileset includes="*.gif">
+        <gzipresource>
+          <file file="${input}/asf-logo.gif.arj.gz"/>
+        </gzipresource>
+      </cmp:arjfileset>
+    </copy>
+    <au:assertFilesMatch
+       actual="${output}/asf-logo.gif"
+       expected="../resources/asf-logo.gif"
+       />
+  </target>
+
+  <target name="test-refid-check-encoding">
+    <cmp:arjfileset id="test-refid2"
+                encoding="utf-8"
+                dir="${basedir}"/>
+    <au:expectfailure>
+      <cmp:arjfileset id="ref4"
+                  encoding="utf-8"
+                  refid="test-refid2"/>
+    </au:expectfailure>
+  </target>
+
+</project>
diff --git a/src/tests/antunit/unarj-test.xml b/src/tests/antunit/unarj-test.xml
new file mode 100644
index 0000000..b06af1d
--- /dev/null
+++ b/src/tests/antunit/unarj-test.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<!--
+  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.
+-->
+<project default="antunit"
+         xmlns:au="antlib:org.apache.ant.antunit"
+         xmlns:cmp="antlib:org.apache.ant.compress">
+
+  <import file="antunit-base.xml" />
+
+  <target name="setUp">
+    <mkdir dir="${output}"/>
+    <mkdir dir="${input}"/>
+  </target>
+
+  <target name="testAgainstNativeArj" depends="setUp">
+    <cmp:unarj src="../resources/asf-logo.gif.arj" dest="${output}"/>
+    <au:assertFileExists file="${output}/asf-logo.gif"/>
+    <au:assertFilesMatch
+       actual="${output}/asf-logo.gif"
+       expected="../resources/asf-logo.gif"
+       />
+  </target>
+
+  <target name="testResourceCollection" depends="setUp">
+    <zip destfile="${input}/test.zip">
+      <fileset dir="../resources" includes="*.arj"/>
+    </zip>
+    <cmp:unarj dest="${output}">
+      <zipfileset src="${input}/test.zip">
+        <include name="*.arj"/>
+      </zipfileset>
+    </cmp:unarj>
+    <au:assertFileExists file="${output}/asf-logo.gif"/>
+    <au:assertFilesMatch
+       actual="${output}/asf-logo.gif"
+       expected="../resources/asf-logo.gif"
+       />
+  </target>
+</project>
diff --git a/src/tests/resources/asf-logo.gif.arj b/src/tests/resources/asf-logo.gif.arj
new file mode 100644
index 0000000..a42d0ac
--- /dev/null
+++ b/src/tests/resources/asf-logo.gif.arj
Binary files differ