Hi Peter,

this looks really cool, but I'd suggest adding an attribute like scope="local|global" to the <property> task instead of adding a completely new task.

-chris

peter reilly wrote:
I have written the code to support local properties.
While I was doing this, I realized that the attributes
of a macrodef could/should be local properties as well,
removing some of the issues seen last week (use of
attribute in a bsf script and support of parallel/recursive).

The following shows it in using a new task called local.

<project name="local">
  <property name="prop1" value="a global value"/>
  <target name="test1">
    <local name="prop1" value="a local value"/>
    <echo>prop1 is "${prop1}"</echo>
  </target>
  <target name="test2" depends="test1">
    <echo>prop1 is "${prop1}"</echo>
  </target>
</project>

This ant test2 generates the following:

test1:
prop1 is "a local value"

test2:
prop1 is "a global value"

Each taskcontainer sets up a new local scope:

  <target name="sequential">
    <local name="prop2" value="in target"/>
    <sequential>
      <local name="prop2" value="in sequential"/>
      <echo>prop2 is "${prop2}"</echo>
    </sequential>
    <echo>prop2 is "${prop2}"</echo>
  </target>

will generate the following:
sequential:
prop2 is "in sequential"
prop2 is "in target"

The value part of <local> is optional, and  the local
property may be set by a subsequent <property>, <property>
will only set it if the value is not set.

  <target name="notset">
    <local name="prop3"/>
    <echo>prop3 is "${prop3}"</echo>
    <property name="prop3" value="is set"/>
    <property name="prop3" value="is set again"/>
    <echo>prop3 is "${prop3}"</echo>
  </target>

will generate the following:
notset:
prop3 is "${prop3}"
prop3 is "is set"

prop3 is still a local variable and will not be seen outside the target.

The local properties are thread local so the following works as expected:
  <target name="parallel">
    <local name="prop4"/>
    <parallel>
      <sequential>
        <property name="prop4" value="thread1"/>
        <echo>t1: prop4 is "${prop4}"</echo>
      </sequential>
      <sequential>
        <property name="prop4" value="thread2"/>
        <echo>t2: prop4 is "${prop4}"</echo>
      </sequential>
      <sequential>
        <property name="prop4" value="thread3"/>
        <echo>t3: prop4 is "${prop4}"</echo>
      </sequential>
    </parallel>
  </target>

parallel:
t2: prop4 is "thread2"
t1: prop4 is "thread1"
t3: prop4 is "thread3"

Use with macrodef.
-----------------

Attributes may now be implemented as local properties, which means that
they will be seen as normal properties by ant tasks - including script.

  <target name="macro">
    <macrodef name="callscript">
      <attribute name="x"/>
      <sequential>
        <script language="beanshell">
          System.out.println("x is '" + project.getProperty("x") + "'");
        </script>
      </sequential>
    </macrodef>

    <callscript x="this is x"/>
  </target>

will generate:
macro:
x is 'this is x'

Macrodef does not do the attribute substitutions so the following
  <target name="macro2">
    <macrodef name="callscript">
      <attribute name="x"/>
      <sequential>
        <script language="beanshell">
          System.out.println("x is '${x}'");
        </script>
      </sequential>
    </macrodef>

    <callscript x="this is x"/>
  </target>
will generate:
macro2:
x is '${x}'
as <script/> does not do property expansion.

A variation of the recurive macrodef last week may be done by:
<target name="recur">
<macrodef name="recur">
<attribute name="thread"/>
<attribute name="current"/>
<sequential>
<antcontrib:if>
<equals arg1="0" arg2="${current}"/>
<then>
<echo message="Thread: ${thread} done"/>
</then>
<else>
<antcontrib:math
datatype = "int"
operand1 = "${current}"
operation = "-"
operand2 = "1"
result = "current"
/>
<echo message = "T: ${thread}, C: ${current}" />
<sleep seconds="1"/>
<recur current = "${current}" thread = "${thread}" />
</else>
</antcontrib:if>
</sequential>
</macrodef>
<parallel>
<recur thread="1" current="5"/>
<recur thread="2" current="6"/>
<recur thread="3" current="2"/>
</parallel>
</target>


The output is:
recur:
T: 3, C: 1
T: 1, C: 4
T: 2, C: 5
T: 3, C: 0
T: 1, C: 3
T: 2, C: 4
Thread: 3 done
T: 1, C: 2
T: 2, C: 3
T: 1, C: 1
T: 2, C: 2
T: 1, C: 0
T: 2, C: 1
Thread: 1 done
T: 2, C: 0
Thread: 2 done



I realize that it is late in the day to get this
into ant1.6, but I think that it will make macrodef
much more usefull and easy to port current antcalls.

The changes are quite small (mostly to PropertyHelper).

Peter



--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to