Optional attributes in a macro wrapping a Java Ant Task

804 Views Asked by At

Ant tasks implemented in Java, as opposed to XML Ant macros, have this peculiarity of offering a slightly different behavior for missing attributes.

In my case, I'm trying to wrap the <testng> Ant task, implemented in Java, with a macro. Specifically, I would like to expose most of the functionality offered by the TestNG ant task with some minor tweaks.

Among other similar attributes, timeOut seems a bit difficult to reproduce, since its omission behaves differently than specifying and empty string.

This is simplified version of my macro definition:

<macrodef name="my-wrapper">
  <attribute name="timeOut" default=""/>
  <element name="nested-elements" optional="true" implicit="true"/>
  <sequential>
    <testng timeOut="@{timeOut}">
      <nested-elements/>
    </testng>
  </sequential>
</macrodef>

Which fails because Ant tries to convert the value to an integer:

Can't assign value '' to attribute timeout, reason: class java.lang.NumberFormatException with message 'For input string: ""'

I've been suggested to use <augment>, which seems to be the solution to this problem. However, I fail to understand how it should be used:

<macrodef name="my-wrapper">
  <attribute name="timeOut" default=""/>
  <element name="nested-elements" optional="true" implicit="true"/>
  <sequential>
    <augment unless:blank="timeOut" id="invocation" timeOut="@{timeOut}"/>
    <testng id="invocation">
      <nested-elements/>
    </testng>
  </sequential>
</macrodef>

The above fails because of a forward reference:

java.lang.IllegalStateException: Unknown reference "invocation"

Invering the order of <testng> and <augment> doesn't really work because the <testng> task starts executing before being augmented.

What I would need is a way to conditionally add an XML attribute to a task call. Is this possible only using Ant XML syntax?

1

There are 1 best solutions below

3
CAustin On

In this situation, the simplest solution would just be to set the default for timeOut to a valid value. It expects a string that can be resolved as an integer, so try using -1 if you don't want there to be a max timeout.

<macrodef name="my-wrapper">
  <attribute name="timeOut" default="-1"/>
  <element name="nested-elements" optional="true" implicit="true"/>
  <sequential>
    <testng timeOut="@{timeOut}">
      <nested-elements/>
    </testng>
  </sequential>
</macrodef>