|
Hi!
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" ....>
</foreach>
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
Carlos |
