Hi! me again
Sorry for sending the email again but I would like to write the code at home this weekend. I'm not waiting your complete approval but, at least, I'm waiting my proposal not to be plainly rejected to begin writing it (I don't want to have my own ant branch :( ).
Thank you in advance, Carlos
----- Original Message -----
From: Carlos Pita
To: ant-dev@jakarta.apache.org
Sent: Wednesday, July 12, 2000 5:23 PM
Subject: Nesting Tasks

    I would like to add some foreach-like functionality to Tasks. I was thinking about this and concluded that a more general solution would be better than, for example, a Task for cycles. This more general solution would make it possible to write "nesting Tasks" with different semantics based on a few general principles:
1) nesting Tasks are Tasks (actually subclasses of Task)
2) nesting Tasks can be nested by other nesting Tasks
3) nesting Tasks have a special (xml) property which lists a number of (ant) properties which wouldn't be expanded the normal way in the enclosed tags but instead will be expanded when execute'ing the nesting Task with a special subclass method (see below).
4) a nesting Task has a list with every enclosed (top-level) Task. (it could, for example, cycle over this list).
NOTE: nested (read carefully: nested, not nesting) Tasks are NOT NestedProperty'es.
    Some comments about this points:
1) nesting Tasks are Tasks because they do everything tasks do. They are subclasses of Task because they have more functionality and a special execute method. I will need to add a enclosingTask property to the Task class. I think this doesn't break any existing code.
3,4) because the properties on the currently written Tasks are simple getter/setter for class properties I couldn't implement this with some kind of scope (associated with the enclosing Task) in which properties are resolved every time a getter is invoked. Instead of this, nesting Tasks will have a list of (Task-setters) pairs (this is not about implementation) with every pair corresponding to the properties to set for a nested Task. This list is created using the following algorithm (this will imply some changes to replaceProperties in the ProjectHelper):
    . if we found a property which is being assigned something matching ${.*} (see (*) below for more on this) then
    .   if not findProp(Task, property)
    .     proceed as usual
    .   fi
    . fi
    . function findProp(Task, property)
    .   if the Task has a parentTask
    .     if the property is in the special set of the parent Task
    .       add the (Task-setter) pair (or only the setter if we already added the Task)
            to the list of (Task-settermethods) in the parent Task
    .       return true
    .     else
    .       findProp(parentTask, property)
    .     fi
    .   else
    .     return false
    .   fi
    . endfunction
    This way an enclosed nesting Task special set would have preference against its outer Task's special set (I talk about sets but the special set would usually contain only one property name).
    There will be a method in the nesting Task subclass that will take a hash with prop->values mappings and will set every property in every nested Task in the list obtained according to the previous algorithm to the indicated values. An execute method in a foreach Task could be a Java for() or while() iterating over a list of strings; in each iteration, the Task will put one string in the hash indexed by the only value in its unitary special set and will invoke this special method which will, in turn, invoke the setters related to the property(in the special set) in each nested (not necessarily top-level) Task (obtained according..... see the algorithm). Then, the foreach-like Task could execute every top-level nested task in its list (point 4) in secuence (or perhaps not).
    (*) I think that setter methods could be constructed to allow more complex assignations. For example dir="${base_dir}/etc/${etc_dir}/*.hj" where base_dir and etc_dir are in the special sets of one or more enclosing Tasks (see the example below).
    An example:
<foreach iterProp="dirName,jarName" values="d1,d2,d3/j1,j2,j3">
    <jar jarfile="${dist}/lib/${jarName}" basedir="classes/$dirName" ....>
    where iterProp is the name of the special status property which contains the special set and "values" has two secuences of strings over which the elements of iterProp iterates. Note that iterProp is a fixed name, its content has a fixed syntaxis and the semantic is well defined while "values" and its contents are completly Task dependant.
    I really need to write the code but I would only do it if the changes could be commited (obviously if they work well). I also would write the doc if you want.
Thank you