开发者

concat as resource collection in zip not working?

I'm trying to use <concat> as a resource collection in a <zip> task and, according to the documentation, this should work. I'd like to do this because some of the files I want to inc开发者_JAVA技巧lude in the zip need to have some properties expanded, so I will also add a <filterchain> to the <concat> to do this. I'd prefer to do it directly rather than copying to a temp location (with property substitution) and including the copy in the zip file.

However, I can't seem to get <zip> to correctly use the <concat> element.

A simplified example of what I have so far:

<zip destfile="target/dist.zip">
   <concat>
      <fileset file="CHANGES.txt" />
   </concat>
</zip>

This creates a zip file containing several directories all named concat (C: (obviously this is on a Windows machine).

What am I missing?


A colleague and I came up with the answer by looking through the <zip> and <concat> source. There are really two answers:

  1. <concat>'s implementation of the ResourceCollection interface is odd, but we understand why.
  2. There's a way around that.

For #1, while <concat> is a ResourceCollection (like FileSet), under the hood it returns as the name of single Resource it contains a hard-coded value:

"concat (" + String.valueOf(c) + ")";

Look familiar?

The name of resources is normally ignored--except by <zip> and its related tasks, which uses the resource name as the ZipEntry name. Since <concat> returns the odd-looking name, that's what we get in the zip file.

I haven't quite figured out why I get multiple entries, but it doesn't matter: the observation leads to a convoluted solution.

Since I know the name of the ZipEntry I want to create, I can use a <mapper> to give the <concat> resource a name. Here's what I came up with in all its glory:

<zip destfile="target/distribution.zip">
    <fileset dir=".">
        <exclude name="target/**" />
        <exclude name="CHANGES.txt" />
    </fileset>
    <mappedresources>
        <concat>
            <fileset file="CHANGES.txt" />
            <filterchain>
                <expandproperties />
            </filterchain>
        </concat>
        <mergemapper to="CHANGES.txt" />
    </mappedresources>
</zip>

As my colleague says "In Ant every problem can be solved using a mapper."

This only works for Ant 1.8+ because <mappedresources> was added in that release.

I'm going to post some comments to the Ant mailing list and suggest a couple of enhancements:

  1. Allow a resource name to be specified as an attribute on <concat> when it's being used as a ResourceCollection.
  2. Throw an exception (and don't create a synthetic value) if getName() is called without having a value specified.
  3. Finally, though not directly related, I do wish <expandproperties> could take a <propertyset> so I can control which properties get substituted.


Do you want the final zip to contain a single file or multiple files? As far as I can see, using concat (when done successfully, which isn't done above) would produce a single file, the result of concatenation of all files in the resource collection.

If you want multiple files rather than concatenation, I think intermediate copy is what you'll need.

From Ant manual for the concat task:

Since Apache Ant 1.7.1, this task can be used as a Resource Collection that will return exactly one resource.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜