Search code examples
javaxmlxsltantant-contrib

Macrodef attribute doesnt change its value


In my previous post I was trying to implement macrodef in order to substitute repetitive code block with "function like" task. Then I faced some problems. After that I reduced the script, so I can experiment with the tasks I am not used with. Here is what I made up:

<project basedir="../../../" name="do-report" default="extract-common-paths">
    <xmlproperty keeproot="false" file="implementation/xml/ant/properties.xml"/>
    <!--    -->
    <taskdef resource="net/sf/antcontrib/antlib.xml">
        <classpath>
            <pathelement location="${infrastructure-base-dir}/apache-ant-1.9.6/lib/antcontrib.jar"/>
        </classpath>
    </taskdef>
    <!--    -->
    <macrodef name="get-common-path">
        <attribute name="common-path-property"/>
        <attribute name="file"/>
        <attribute name="file-base-dir"/>
        <sequential>
            <local name="file-dir-absolute-path"/>
            <dirname property="file-dir-absolute-path" file="@{file}"/>
            <property name="file-base-dir-absolute-path" location="@{file-base-dir}"/>
            <echo>MACRODEF FILE: ${file-dir-absolute-path}</echo>
            <echo>MACRODEF FILE-BASE-DIR: ${file-base-dir-absolute-path}</echo>
            <pathconvert property="@{common-path-property}" dirsep="/">
                <path location="${file-dir-absolute-path}"/>
                <map from="${file-base-dir-absolute-path}/" to=""/>
            </pathconvert>
        </sequential>
    </macrodef>
    <!--    -->
    <target name="clean">
        <delete dir="${dita-odt.path.odt-unzipped-base-dir}" includeemptydirs="true" failonerror="no"/>
        <delete dir="examples/intermediate/odt-files" includeemptydirs="true" failonerror="no"/>
    </target>
    <!--    -->
    <target name="unzip-writing-odt-file" depends="clean">
        <unzip src="${dita-odt.path.writing-odt}" dest="${dita-odt.path.writing-odt-unzipped}"/>
    </target>
    <!--    -->
    <target name="extract-common-paths" depends="unzip-writing-odt-file">
        <for param="file">
            <path>
                <fileset dir="${dita-odt.path.text-xml-base-dir}">
                    <include name="**/content.xml"/>
                </fileset>
            </path>
            <sequential>
                <get-common-path common-path-property="common-path" file="@{file}" file-base-dir="${dita-odt.path.text-xml-base-dir}"/>
                <echo>THIS IS THE PATH: ${common-path}</echo>
            </sequential>
        </for>
    </target>
</project>

The FOR task iterates over two files in different directories. Actually FOR works as expected. It passes ${file} as it should. macrodef attribute common-path-property is first set to the converted path of the first file (it is OK). But when the second file is passed to the get-common-path/@file, the attribute common-path-property doesn't change its value and again I receive this:

[echo] MACRODEF FILE: C:\Users\rmrd001\git\xslt-framework\examples\text\t1\t1.1

[echo] MACRODEF FILE-BASE-DIR: C:\Users\rmrd001\git\xslt-framework\examples\text

[echo] THIS IS THE PATH: t1/t1.1

[echo] MACRODEF FILE: C:\Users\rmrd001\git\xslt-framework\examples\text\t2\t2.1

[echo] MACRODEF FILE-BASE-DIR: C:\Users\rmrd001\git\xslt-framework\examples\text

[echo] THIS IS THE PATH: t1/t1.1

Instead I hope to receive this:

[echo] MACRODEF FILE: C:\Users\rmrd001\git\xslt-framework\examples\text\t1\t1.1

[echo] MACRODEF FILE-BASE-DIR: C:\Users\rmrd001\git\xslt-framework\examples\text

[echo] THIS IS THE PATH: t1/t1.1

[echo] MACRODEF FILE: C:\Users\rmrd001\git\xslt-framework\examples\text\t2\t2.1

[echo] MACRODEF FILE-BASE-DIR: C:\Users\rmrd001\git\xslt-framework\examples\text

[echo] THIS IS THE PATH: \t2\t2.1

I hope you understand what I am trying to do. Thank you in advance!


Solution

  • Try printing the macrodef attribute values instead of the property values.

    • @{attribute} - can change with every execution of a macrodef
    • ${property} - are always set and fixed once and once only in Ant, even within a macrodef
      • unless preceded by a <local> task, in which case the locally set property value is used within the scope of that block.

    Probably what you want is provided by the Ant Local task.

    Adds a local property to the current scope. Property scopes exist at Apache Ant's various "block" levels.