Getting file name inside Ant copy task filter

2019-02-19 07:54发布

Is it possible to get the current file name being copied inside an Ant copy task? I am trying to run a beanshell script and would like access to the current file name:

<target>
    <mkdir dir="${project.build.directory}/generated-sources"/>
    <copy todir="${project.build.directory}/generated-sources"
          includeemptydirs="true" failonerror="true" verbose="true">
        <fileset dir="${project.build.sourceDirectory}"/>
        <filterchain>
            <tokenfilter>
                <filetokenizer/>
                <scriptfilter language="beanshell" byline="true"><![CDATA[
                    import java.io.BufferedReader;
                    import java.io.StringReader;
                    int count = 1;
                    BufferedReader br = new BufferedReader(new StringReader(self.getToken()));
                    StringBuilder builder = new StringBuilder();
                    String line;
                    while ((line = br.readLine()) != null) {
                        builder.append(line.replace("\"__LINE__\"", Integer.toString(count))).append('\n');
                        count++;
                    }
                    self.setToken(builder.toString());
                ]]></scriptfilter>
            </tokenfilter>
        </filterchain>
    </copy>
</target>

1条回答
做自己的国王
2楼-- · 2019-02-19 08:47

This has been bugging me for a while - I hoped there would be a nice way to do this, but I've not found it yet.

I've had a look at the Ant source code for the 'copy' task. The actual copy is done in the ResourceUtils class, but the names of the source and destination files are not exposed in a way that would make them accessible from the filterchain. Similarly, the iteration over the fileset takes place in the copy taskdef where the 'current' file names are not held in public variables.

The least-bad option I've come up with is to use an ant-contrib 'for' task to iterate over the fileset and copy each file one by one. As you iterate, the names of the files are then available in the property specified in the 'param' attribute:

<for param="file.name">
  <path>
    <fileset dir="${project.build.sourceDirectory}"/>
  </path>
  <sequential>
    <local name="file.name"/>
    <property name="file.name" value="@{file.name}"/>
    <copy file="${file.name}" ... >
      ...
      <filterchain>
        <scriptfilter ...>
          ...
          current_file = project.getProperty( "file.name" );
          ...
        </scriptfilter>
      </filterchain>
      ...
    </copy>
  </sequential>
</for>
查看更多
登录 后发表回答