Ant (1.6.5) - Как установить два свойства в одном <условие> или <if>

Я пытаюсь назначить две разные строки двум различным переменным, зависящим от двух булевых в Ant.

Псевдокод (ish):

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

Что я пробовал:

<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>

Но я получаю исключение нулевого указателя для строки, содержащей "<if>". Я могу заставить его работать с тегами <condition property=...>, но может устанавливать только одно свойство за раз. Я пробовал использовать <propertyset>, но это тоже было запрещено.

Я новичок в ant, как вы, вероятно, догадались:).

Гав

Ответы

Ответ 1

Есть несколько способов сделать это. Самое простое - просто использовать два оператора condition и воспользоваться неизменностью свойств:

<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"/>

Это немного громоздко и плохо масштабируется, но для двух свойств я бы, вероятно, использовал этот подход.

Несколько лучший способ - использовать условную цель:

<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>

Мы снова используем здесь неизменность свойств. Если вы не хотите этого делать, вы можете использовать атрибут unless и дополнительный уровень косвенности:

<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>

Важно отметить, что атрибуты if и unless target проверяют только свойство, а не значение свойства.

Ответ 2

Вы можете использовать Ant -Contrib библиотеку, чтобы иметь доступ к аккуратным синтаксическим <if><then><else> однако для этого потребуется несколько шагов загрузки/установки.

Смотрите этот другой вопрос SO: Ant -contrib - если /then/else task