Apache ANT If Else Condition without ANT-Contrib

Sometimes I must make an ANT Build file that will need to work on many different machines, where I cannot be sure of the version or configuration of ANT nor the environment it is running in. This can cause some discomfort when it comes to complex builds involving conditions. The ANT-Contrib library has a convenient If/Else condition but this library is not always installed with ANT or even when it is, the build environment may not be configured to use it. So in either case, I use the following method which, though a little wordy, gets the job done without relying on anything beyond a standard ANT install. The method uses three ANT targets to do the work, one for the <if>, one for the <then> and one for the <else>. As you can see it creates a bit of extra code, but I believe the portability is worth it.

Below the explanation, the example referred to in the post will be made available. Now lets get started.

First Create a target that should do some bit of work based on a condition. Make the target depend on two other targets (here these are “setup” and “fail”), and only allow it to execute if a boolean variable has the right value, using the “if” attribute of the “target” element.

<target name=”go” depends=”setup, fail” if=”allIsWellBool”>
<!– SOME WORK HAPPENS HERE –>
</target>

Next, have one of the dependencies create a boolean property based on the condition. The process is a little convoluted, in that you need to use a <condition> construct that has an <equals> test against text to create a boolean property. For instance, in the example for this post, this dependency target, “setup”, asks for some user input, then checks to see if an empty string was entered. A new boolean property is added based on the test.

<target name=”setup”>
<input message=”Please enter something:” addproperty=”somethingProp”/>

<condition property=”allIsWellBool”>
<not>
<equals arg1=”${somethingProp}” arg2=”” trim=”true”/>
</not>
</condition>
</target>

After this target either there is a new boolean property called “allIsWellBool” or there is not. Subsequent test for this property will pass if the property is there, and true, or fail if it is not.

Finally, create a target to execute if the test fails, the else condition basically. This is done by only allowing it to execute if a boolean variable has the right value again, but this time using the “unless” attribute of the “target” element. In the case of the example for this post, this target will execute unless the “allIsWellBool” exists and is true.

<target name=”fail” depends=”setup” unless=”allIsWellBool”>
<fail message=”You must enter something”/>
</target>

See also that we are adding the dependency for the “setup” target here as well. This is because this target depends on a property that is set in the “setup” target, and “setup” should therefore happen first.

The full source of the example mentioned in this post is below.

<?xml version="1.0" encoding="UTF-8"?>
<!--
    Simple example of how to do an If/Else condition in
    your build file without using the ANT-Contrib libs

    This source code is provided free of charge and placed in the
    public domain. It is not supported by anyone.

    Use this at your own risk.
-->
<project name="Test If Else Condition without ANT-Contrib" default="go">

    <!-- ======================= -->
    <!-- THE START OF THE SCRIPT -->
    <target name="go" depends="setup, fail" if="allIsWellBool">

        <echo message="Great, passed the test, lets do something!"/>
        <!-- SHOULD DO SOMETHING -->

    </target>

    <!-- =================================================== -->
    <!-- SETUP, GETS SOME INPUT THAT WE WILL TEST WITH LATER -->
    <target name="setup">

        <input message="Please enter something: " addproperty="somethingProp"/>

        <!-- SET A BOOLEAN PROPERTY IF WE GOT SOME INPUT  -->
        <condition property="allIsWellBool">
            <not>
                <equals arg1="${somethingProp}" arg2="" trim="true"/>
            </not>
        </condition>
    </target>

    <!-- ============================================ -->
    <!-- FAIL, WE DID NOT GET ANY INPUT FROM THE USER
         THIS DEPENDSON THE SETUP TASK AND WILL
         EXECUTE ONLY IF THE PROPERTY allIsWellBool
         IS FALSE
    -->
    <target name="fail" depends="setup" unless="allIsWellBool">
        <fail message="You must enter something"/>
    </target>

</project>

Advertisements

Apache XMLBeans – output XML without a namespace

This is again something that I need to know how to do but never remember how when time it tight.

Apache XMLBeans http://xmlbeans.apache.org/ is a great tool for working with XML in Java, but it requires the XML Schema being used to create the objects from XML to have a Namespace. The namespace ends up being part of the package structure for the Objects created and I guess having a unique path for these is a good idea. However, this requirement can be a bit of a pain, when working with some simple XML structures that do not have a namespace. Especially when your ready to persist the XML Bean objects to XML source. If a namespace is added to your XML Schema that the XML Bean objects are created from, XML source generated from them will by default also have the namespace. I can never remember how to output the XML source without a namespace and so I am writing it down here where I can get at it with a click, and maybe this will help someone else as well.

There are two key steps to remove the Namespace when outputting XML Source.

  1. Tell it to use the default namespace:
           xmlops.setUseDefaultNamespace();
       
  2. Tell it that you have already declared the default namespace:
           dnsMap.put("", "http://example.com/schemas/DefaultNnameSpace");
           xmlops.setSaveImplicitNamespaces(dnsMap);
      

After this, you can output as normal:

      xmlops.setSavePrettyPrint();
      xmlops.setSaveNamespacesFirst();
      retString = myXMLDoc.xmlText(xmlops);
      return retString;

Note: the research and testing to solve this was done using XMLBeans v2.4.0