The subject of performing iteration or applying a task to a certain group of
targets has appear regularly over and over again. I for one, think it is a
justified requirement but it needs to be designed carefully.

Now, careful design is not because we want to protect users against
themselves, but because, at least I, would like to have a clean and clear
set of basic features that can be easily used to compose more complex ones,
as oppose of having feature after feature without any sense of the result of
the interaction between them, or what limitations their definition may put
on future developments.

I will refer to the issue as "set application" as oppose to "iteration"
beacuse I would like to leave open the posibility of parallelizable
execution in future versions of the ANT engine. Iteration implies secuential
execution, which usually implies a fix execution order of the sequence. I
would like to keep away of requiring such execution order. So the aim is to:
given a set of values apply XYZ to them.

Question 1) What should XYZ be?

There has been various proposals on this:

a) a <target> which is what the contributed <foreach> task does.

b) a group of <task>s, with a construct that allows the embedding of tasks
as elements.

c) a <task>, by adding some predefined support to the abstract Task.

d) a <antcall>, which will allow something simillar to application to
<target> but within its own execution context.

Given my views on property mutability, it is not surprising that I would
prefer to stay away of any approach that requires changing the values of
properties within the same execution context. Why? because I think that
would make any paralellizable execution approach very difficult to achieve.
It will also bring into place the need to define what would be the values of
such properties at the end of the set application.

So, even though I am not sure at all on the current implementation of
<foreach>, I think I would discard (a) and (b) on the grounds that they
probably would require having properties in the current environment needing
to take different values for every element of the set.

That leaves (c) and (d). (d) is almost the same as the so called <anton>.
(c) on the other hand can be seen as a generalization and it can be use to
obtain <anton> by applying it to <ant*>. So I will pick (c) as my target
candidate, for the moment.

Question 2) how to describe the set of values?

<fileset> is the most natural one. But it may not be the only interesting
one. With the addition of cullers we may have the ability to apply to
subsets (defined dynamically: newer, outofdate, etc.). The <foreach> task
introduced the idea of defining "sets of values": {"a", "b", "c"}, which are
not necessarily files.

It looks to me like we may need to have some "Set" interface implemented by
<fileset> and others on which the application occurs, is that part of ANT2
already?

Question 3) What should be the syntax?
I have tried several syntax before, I will try one more time with the
following examples:

(1)
        <task  att1="..." attr2="..." ... >
          <applyto attribute="attr3">
                <fileset .... />
          </applyto>

          <element1 .....>
          <element2 .....>
        </task>

Here the elements of the set are applied as the value for "attr3" by calling
setAttr3() on the task, this is done without any specific intervention of
the <task> code itself.
No way to apply all arguments at once since it seem to make little sense.
Although one could argue to use toString() on this case.

(2)
        <task  att1="..." attr2="..." ... >
          <applyto element="element3" attribute="elemAttr" fixpart="...."
all="false" >
                <fileset .... />
          </applyto>
          <element1 .....>
          <element2 .....>
        </task>

Here the elements of the set are applied as the value of an inner element of
the task by calling createElement3() and then calling el3.setElemAttr(). The
attribute "all" indicates whether to set all the values at once, or one per
execution. What should be the position of the application with respect to
other elements? At the end? At the begining? Should it maintain its relative
position? (if <applyto> occurs between <element1> and <element2> the
expansion will occur also between them).

Now, two interesting aspects here is that in some cases the inner element
has more than one attribute that needs to be set, like the case of <param>
in <ant*>. On those cases one needs a way to pass the fixed part of the
element definition. That is what I am doing with  "fixpart". I am open to
better solutions.

Here is a couple of real examples on how they could be used with the above
syntax:

        <echo message="files to be processed:" />
        <echo >
         <applyto attribute="message">
          <fileset ..../>
         </applyto>
        </echo>


        <antcall target="build" >
         <applyto element="param" attribute="value" fixpart="name='srcfile'" >
          <fileset ... />
         <applyto>
        </antcall>


What do you think about the usability of such notation, and the concept in
general. I certainlty could use something like this in some of my tasks
today. Does anyone has a better idea on how to deal with "fixpart"?

Does it make sense to allow for more than one "applyto" element? (cartesian
product)
Or would that just make the semantics too complicated for confort.

Jose Alberto

Reply via email to