问题
I am trying to "function"alize few lines of ant-code using macrodef
. But its resulting in error like :
copy doesn't support the nested "my-macro" element.
If I "inline" definition of my-macro of adding filterchian within copy-task it works.
My test target looks like this -
<target name="copy-files">
<sequential>
<copy todir="abc" >
<fileset dir="xyz">
<!--needy includes/excludes -->
</fileset>
<my-macro/>
</copy>
</sequential>
</target>
And my-macro looks like this:
<macrodef name="my-macro">
<sequential>
<filterchain>
<fixcrlf includes="**" eol="lf"/>
</filterchain>
</sequential>
</macrodef>
Code which works (inlined-one ) looks like :
<target name="copy-files">
<sequential>
<copy todir="abc" >
<fileset dir="xyz">
<!--needy includes/excludes -->
</fileset>
<filterchain>
<fixcrlf includes="**" eol="lf"/>
</filterchain>
</copy>
</sequential></target>
回答1:
The copy task doesn't accept a nested macro element, thats what the errormessage says.
Put the whole copy stuff into your macrodef, f.e. :
<macrodef name="my-macro">
<attribute name="dest"/>
<attribute name="fsdir"/>
<attribute name="fsincludes"/>
<attribute name="fsexcludes"/>
<attribute name="fixincl"/>
<sequential>
<copy todir="@dest}">
<fileset dir="@{fsdir}">
<include name="@{fsincludes}"/>
<exclude name="@{fsexcludes}"/>
</fileset>
<filterchain>
<fixcrlf includes="@{fixincl}" eol="lf"/>
</filterchain>
</copy>
</sequential>
</macrodef>
-- EDIT --
If number of filesets varies, remove the fsincludes and fsexcludes attribute if not valid for all filesets and use element like that :
<macrodef name="my-macro">
<attribute name="dest"/>
<element name="fs" description="nested filesets"/>
<attribute name="fixincl"/>
<sequential>
<copy todir="@dest}">
<!-- 1-n nested filesets) -->
<fs/>
<filterchain>
<fixcrlf includes="@{fixincl}" eol="lf"/>
</filterchain>
</copy>
</sequential>
</macrodef>
<my-macro dest="C:/whatever" fixincl="**">
<fs>
<fileset dir="." includes="**/*.foo"/>
<fileset dir="../foo" includes="**/*.xml"/>
<!-- ... -->
</fs>
</my-macro>
-- EDIT --
To copy a single file with nested fileset use :
<fileset file="C:/somepath/some.file"/>
-- EDIT --
If you need other copysteps with file tofile, you may use another element if that is sufficient:
<macrodef name="my-macro">
<attribute name="dest"/>
<element name="copyfiles" description="nested copy"/>
<element name="fs" description="nested filesets"/>
<attribute name="fixincl"/>
<sequential>
<copy todir="@dest}">
<!-- 1-n nested filesets) -->
<fs/>
<filterchain>
<fixcrlf includes="@{fixincl}" eol="lf"/>
</filterchain>
</copy>
<copyfiles/>
</sequential>
</macrodef>
<my-macro dest="C:/whatever" fixincl="**">
<fs>
<fileset dir="." includes="**/*.foo"/>
<fileset dir="../foo" includes="**/*.xml"/>
<!-- ... -->
</fs>
<copyfiles>
<copy file="..." tofile="..."/>
<!-- ... -->
</copyfiles>
</my-macro>
Normally for bulk renaming of files a mapper is used.
After all if it gets more complicated you should consider scripting with Groovy or write your own Ant Task.
回答2:
Rebse's answer already shows what you should go with <macrodef>
, and here's some explanation.
Copy Task
<copy>
, <macrodef>
, <sequential>
are Ant tasks. Each Ant task is backed with Java code. Most of Java classes of built-in Ant tasks are under org.apache.tools.ant.taskdefs
, e.g. Copy.java is the backend of <copy>
task.
The nested elements of a task is handled by the task's Java code. For <copy>
task, it's code in Copy.java (or other classes it depends on) handling the nested elements.
You will see in Copy.java methods named with createFilterChain
, addFileset
, createMapper
and others. That's why <copy>
supports fileset, filterchain, mapper and other nested elements stated in Copy's manual page.
Macrodef
This defines a new task using a nested task as a template.
Macrodef is a way to define an Ant task without coding in Java. It turns its nested Ant xml lines into a new task, which works the same way as other Ant tasks.
Obviously, you should not just put a <filterchain>
in <macrodef>
, as <filterchain>
is not an Ant task, but an Ant type.
来源:https://stackoverflow.com/questions/23514789/functionalizing-few-lines-of-code-with-ant-macrodef