ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Cyril Sagan <cyril.sa...@gmail.com>
Subject "Cloning" macrodef
Date Fri, 27 Sep 2013 20:15:10 GMT
I had previously posted a question asking about macro scoping, I thought
the community might be interested in my solution, perhaps the Ant experts
can tell me how dangerous of a hack it may be?  (I'm on Ant 1.7.0, and
cannot up-rev)

First, restating my question:
    Subject: "scoping" for macro definitions?
    Is there a way to override a macro defined from a library I cannot
    control, my goal is to provide a local implementation, but not have to
    change all the callers.

I got close with <presetdef/> but I couldn't find the way to call "super"
on the macro, until I used org.apache.tools.ant.ComponentHelper to add a
new macro definition with a second name.  The complete working example
follows should anyone wish to comment:

<?xml version="1.0" encoding="utf-8"?>
<project name="solution" default="testcase">
    <!-- would be in separate file and imported:  <import
file="library.xml" /> -->
    <macrodef name="routine">
        <attribute name="arg" />
        <sequential>
            <echo>Arg is @{arg}</echo>
        </sequential>
    </macrodef>

    <!-- utility to duplicate macro definition -->
    <scriptdef name="duplicateMacroDefinition" language="groovy">
        <attribute name="existingName" />
        <attribute name="newName" /><![CDATA[
        import org.apache.tools.ant.ComponentHelper;
        import org.apache.tools.ant.AntTypeDefinition;

        String existing = attributes.get("existingname");
        String newName = attributes.get("newname");

        ComponentHelper helper =
ComponentHelper.getComponentHelper(project);
        AntTypeDefinition m = null;

        m = helper.getDefinition(existing);
        if ( m == null ) {
            log("Cannot get definition of ${existing}");
        }
        else {
            m.setName(newName);
            helper.addDataTypeDefinition(m);
        }
        ]]>
    </scriptdef>


    <macrodef name="local_routine">
        <attribute name="arg" default="" />

        <sequential>
            <echo>Run local logic first, maybe change param and call common
routine...</echo>
            <common_routine arg="OVERRIDE" />
        </sequential>
    </macrodef>


    <target name="setup">
        <!-- make second name of common routine to avoid infinite loop -->
        <duplicateMacroDefinition existingName="routine"
                                  newName="common_routine" />

        <!-- permits "override" of library routine so we can add logic -->
        <presetdef name="routine">
            <local_routine />
        </presetdef>
    </target>

    <target name="testcase" depends="setup">
        <!-- all existing calls are "fixed", make sample call -->
        <routine arg="old" />

        <!-- If we need original one... -->
        <common_routine arg="use this"/>
    </target>
</project>

--Cyril

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message