ant-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Steven Dodd" <>
Subject IterateHash Task - HashMap
Date Tue, 04 Nov 2003 08:30:00 GMT

I have created a new task based on a task submitted to this list by Alan

If you think of Alan's task as a foreach loop or an array of property
values you can think of mine as a hashmap iterator - hence the name

I have used this task to combine document root's, for application
servers with multiple applications, to deploy to web servers for serving
static content...  

In this example I create a comma separated list of 'keys' or what will
be contextRoots - and then define the src directories containing the
content, by mapping the key to a value.

<taskdef name="iterateHash"

<property name="keys" value="app1,app2,app3"/>
<property name="appn1" value="applications/app1/web-app"/>
<property name="appn2" value="applications/app2/web-app"/>
<property name="appn3" value="applications/niceApp/web-app"/>

I then can call a target '-combineDocRoot' repeatedly each time setting
the 'key' to a context root and the 'value' to the src directory.

<iterateHash key="key" value="value" itemList="keys"

      key      = the name of the ant property to set as the key
      value    = the name of the ant property to set as the value
      itemList = the list of keys (perhaps might be better named
      target   = the name of the ant target to call foreach key/value

<target name="-combineDocRoot" description="Incrementally combines
  <mkdir dir="${docRoot}/${key}"/>
  <copy todir="${docRoot}/${key}">
    <fileset dir="${value}"/>

Source code below - enjoy :)


import java.util.Map;
import java.util.Iterator;
import java.util.StringTokenizer;

/** This class is a Jakarta Ant custom task that repeatedly calls a
 * passing different key/value pair from a delimited string.
 * <p>For example:
 * <pre>
 * &lt;project name="Ant_Extensions" default="main" basedir="."&gt;
 *   &lt;taskdef name="iterate"
 *   &lt;target name="main"&gt;
 *     &lt;iterate target="hello" itemList="one,two,three" key="i"
 *     &lt;/iterate&gt;
 *     &lt;property name="one" value="1"/&gt;
 *     &lt;property name="two" value="2"/&gt;
 *     &lt;property name="three" value="3"/&gt;
 *   &lt;/target&gt;
 *   &lt;target name="hello"&gt;
 *     &lt;echo message="${i}" = "${j}" /&gt;
 *   &lt;/target&gt;
 * &lt;/project&gt;
 * </pre>
 * <p>The above example will call the hello target three times, each
 * passing a key/value pair. In this case the hello target will
 * echo one = 1, then two = 2 and then three = 3.
 * <p>List of attributes:
 * <table border>
 * <tr><th>Attribute</th><th>Description</th><th>Required</th></tr>
 * <tr><td>target</td><td>This is the name of the target to
 * <tr><td>key</td><td>The name of the key in which each value from
item list will be 
 * stored for each iteration.</td><td>Yes</td></tr>
 * <tr><td>value</td><td>The name of the value in which each value
the item list will 
 * be stored for each iteration.</td><td>Yes</td></tr>
 * <tr><td>itemList</td><td>A delimited list of items
 * <tr><td>iheritAll</td><td>Boolean to enable/disable the called
from inheriting all 
 * the properties from the environment.</td><td>No</td></tr>
 * <tr><td>delimiter</td><td>The delimiter that is used to delimited
strings in the 
 * item list.</td><td>No</td></tr>
 * </table>
 * @author Steven Dodd,
public class IterateHash extends Task {

  /** Default constructor.
  public IterateHash() {}

  /** Set the item list string. The item list can contain one or more
   *  delimited strings. The specified target will be called once for
   *  string in the item list.
   *  <p>The delimiter can be changed by specifying the
   *  delimiter attribute.
   * @param pItemList Delimited string of items.
  public void setItemList(String pItemList) {
    mItemList = pItemList;

  /** Set the Ant target name that will be called repeatedly, once for
   *  item in the item list.
   * @param pTargetName The name of the target to call repeatedly.
  public void setTarget(String pTargetName) {
    mTargetName = pTargetName;

  /** Sets the inherit all flag. If the value is true, then the target
   *  is called will inherit all the properties. Default is true.
   * @param pInheritAll Inherit flag.
  public void setInheritAll(boolean pInheritAll) {
    mInheritAll = pInheritAll;

  /** Set the Key. The key attribute is the name of the property
   *  that will contain each key in the item hash.
   * @param pKey Key Name
  public void setKey(String pKey) {
    mKey = pKey;

  /** Set the Value. The value attribute is the name of the property
   *  that will contain each value in the item hash.
   * @param pValue Value Name
  public void setValue(String pValue) {
    mValue = pValue;

  /** Set the delimiter that will be used to delimit the strings in the
   *  list, the default is comma ",".
   * @param pDelimiter Delimiter charater.
  public void setDelimiter(String pDelimiter) {
    mDelimiter = pDelimiter;

  /** Ant execute service method, called when the task is executed.
   * @exception BuildException When required attributes are not set
  public void execute() throws BuildException {

    if (mTargetName == null || mTargetName.equals("")) {
      throw new BuildException("Attribute target is required.",

    if (mKey == null || mKey.equals("")) {
      throw new BuildException("Attribute key is required.", location);

    if (mValue == null || mValue.equals("")) {
      throw new BuildException("Attribute value is required.",

    if (mItemList == null || mItemList.equals("")) {
      throw new BuildException("Attribute itemList is required.",

    // initialise the target

    // set key/value and then call the target for each item in the item
    mItemList = project.getProperty(mItemList);
    StringTokenizer st = new StringTokenizer(mItemList, mDelimiter);
    while (st.hasMoreTokens()) {
      String p = st.nextToken().trim();

      // Set the key value
      project.setProperty(mKey, p);
      log("Set key:" + mKey + " to " + p);

      // Get the value property or set to null if not defined
      p = project.getProperty(p);

      // If the key/value pair is aviable set the value property
      // and then execute the target
      if (p != null) {
        project.setProperty(mValue, p);
        log("Set value:" + mValue + " to " + p);

      } else {
        log("Could not find value - will not execute target");

  /** Ant init service method, to initialise the task.
   * @exception BuildException Build exception.
  public void init() throws BuildException {

    // initialise the called target
    mTarget = (Ant) project.createTask("ant");

  /** Ant create param service method, which is called for each 
   * embedded param element.
   * @return Property object.
  public Property createParam() {
    return mTarget.createProperty();

  private void dumpProperties() {

    Map values = project.getProperties();
    Iterator i = values.entrySet().iterator();

    while(i.hasNext()) {

  private String mItemList;
  private String mTargetName;
  private boolean mInheritAll = true;
  private Ant mTarget;
  private String mKey;
  private String mValue;
  private String mDelimiter = ",";



This e-mail (and any attachments) may contain privileged and/or confidential
information. If you are not the intended recipient please do not disclose, 
copy, distribute, disseminate or take any action in reliance on it. 

If you have received this message in error please reply and tell us and then
delete it. Should you wish to communicate with us by e-mail we cannot 
guarantee the security of any data outside our own computer systems. 

For the protection of Practiv's systems and staff, incoming and outgoing 
emails are automatically scanned.

View raw message