Any way to check if an optional element in macrodef is provided?

378 Views Asked by At

is there any way to check if a given element X is passed to the macrodef. I have a case to decide if the element X should be required or optional. To achieve this I made the element optional for all the cases, but I want to make validation in case the element is missing, if it’s allowed to be missing :-).

The macro is looking like this:

<macrodef name="test">
<attribute name="attribute1"/> 
......
<attribute name="attributeN/>

<element name="X" optional="true/> 
<element name="Y" optional="true/>

<sequential>
<local>
<!--here check if the element <X/> is passed -->  
</local>
</sequential>
</macrodef>



<test attribute1="1", attributeN="N">
<!--Here do not provide element X. Only provide Y-->
<Y>
<nestedY1>Some text1</nestedY1>
<nestedY2>Some text2</nestedY2>
</Y>
</test>

The element X is looking just like element Y. I mean, in case it is present, it will contain another nested elements.

Maybe I am wrong in the way I understand this concept. I will try to give another example. Currently the element X is mandatory and my task is to make it optional in some cases but mandatory in another cases. I want to be able to use the macro both ways, but I don’t know how to implement this task:

<macrodef name="test">
<attribute name="attribute1"/> 

<element name="X"/> 
<element name="MandatoryX" optional="true/>

<sequential>
<local>
<!--here check if the element <MandatoryX/> is passed and if Yes than make sure that element X is passed too-->  
</local>
</sequential>
</macrodef>

<test attribute1="1">
<!--Here MandatoryX is missing and X can be missing too-->
</test>

or

<test attribute1="1">
<MandatoryX>In case MandatoryX is present, than element X must be present too</MandatoryX>
<X>Here X is mandatory</X>
</test>
1

There are 1 best solutions below

0
Chris On

I figured out a way of doing this. A bit kludgey, but works for me. The key is to use the <echoxml> task to write the macro element to a file, then read the file and look for some pattern in it. I write <stuff> and </stuff> around the macro element. When the macro element is not provided, the stuff element gets written out as simply <stuff />, and this can be searched for.

Note, I am also using antcontrib, hence the <if> block.

<macrodef name="processFiles">
  <attribute name="workDir"/>
  <attribute name="tempDir"/>
  <element name="extra-deletes" optional="true"/>
  <sequential>
    <echoxml file="@{tempDir}/extra-deletes.xml"><stuff><extra-deletes/></stuff></echoxml>
    <local name="extra-deletes-prop"/>
    <loadfile property="extra-deletes-prop" srcfile="@{tempDir}/extra-deletes.xml"/>

    <if>
      <not><contains string="${extra-deletes-prop}" substring="&lt;stuff /&gt;"/></not>
      <then>
        <delete>
          <fileset dir="@{workDir}">
            <extra-deletes/>
          </fileset>
        </delete>
      </then>
    </if>
  </sequential>
</macrodef>

This macro would get called with some expression involving <filename .../> to identify which files to delete. (This is derived from a more complicated script, but basically there is some pattern of files to delete for every project and other projects have extra, project-specific delete patterns.)

So it would be called like this:

<processFiles workDir="..." tempDir="...">
  <extra-deletes>
    <or>
      <filename name="..."/>
      <filename regex="..."/>
    </or>
  </extra-deletes>
</processFiles>

... or in the case with no 'extra-deletes' to perform,

<processFiles workDir="..." tempDir="..."/>