views:

2572

answers:

1

I am trying to assign two different strings to two different variables dependent on two booleans in Ant.

Pseudocode (ish):

if(condition)
   if(property1 == null)
      property2 = string1;
      property3 = string2;
   else
      property2 = string2;
      property3 = string1;

What I've tried is;

<if>
  <and>
    <not><isset property="property1"/></not>
    <istrue value="${condition}" />
  </and>
  <then>
    <property name="property2" value="string1" />
    <property name="property3" value="string2" />
  </then>
  <else>
    <property name="property2" value="string2" />
    <property name="property3" value="string1" />
  </else>
</if>

But i get a null pointer exception for the line containing "<if>". I can get it to work using <condition property=...> tags but can only set one property at a time. I tried using <propertyset> but that wasn't allowed either.

I'm new to ant as you will probably have guessed :).

Gav

+3  A: 

There are several ways to do this. The most straightforward is to just use two condition statements, and take advantage of property immutability:

<condition property="property2" value="string1">
    <isset property="property1"/>
</condition>
<condition property="property3" value="string2">
    <isset property="property1"/>
</condition>

<!-- Properties in ant are immutable, so the following assignments will only
     take place if property1 is *not* set. -->
<property name="property2" value="string2"/>
<property name="property3" value="string1"/>

This is a bit cumbersome and doesn't scale well, but for just two properties I would probably use this approach.

A somewhat better way is to use a conditional target:

<target name="setProps" if="property1">
    <property name="property2" value="string1"/>
    <property name="property3" value="string2"/>
</target>

<target name="init" depends="setProps">
    <!-- Properties in ant are immutable, so the following assignments will only
         take place if property1 is *not* set. -->
    <property name="property2" value="string2"/>
    <property name="property3" value="string1"/>

    <!-- Other init code -->
</target>

We are again taking advantage of property immutability here. If you don't want to do that, you can use the unless attribute, and an extra level of indirection:

<target name="-set-props-if-set" if="property1">
    <property name="property2" value="string1"/>
    <property name="property3" value="string2"/>
</target>

<target name="-set-props-if-not-set" unless="property1">
    <property name="property2" value="string2"/>
    <property name="property3" value="string1"/>
</target>

<target name="setProps" depends="-set-props-if-set, -set-props-if-not-set"/>

<target name="init" depends="setProps">
    <!-- Other init code -->
</target>

It is important to note that the if and unless attributes of target only check if the property is set, not the value of the property.

Jason Day
Thanks, comprehensive answer.
gav