Section 2.1. Using Properties to Control Tasks


2.1. Using Properties to Control Tasks

Ant provides extensive support for controlling the build process; though Ant is not a programming language, it has a number of control structures, and those control structures rely on properties. As if and TRy/catch allow you to handle several logic paths in Java, Ant's control tasks allow you the same flexibility within the context of a build process.

2.1.1. Setting Conditions

The foundation to any type of control processing is some form of the if statement. This typically involves two steps:

  1. Check or determine if a certain condition is true.

  2. If the condition is true, perform one action; if it is false, perform another.

In Java, this all happens in a single line of code; in Ant, the condition must be set in one step, and the evaluation of that condition occurs in another step. First, you need to set a condition based on some criteria; not surprisingly, condition is the name of the task Ant provides. condition allows you to specify one or more true/false tests (sometimes called criteria). If all the criteria evaluate to true, a property, supplied to the condition task, is set to TRue; if one or more of the criteria evaluate to false, the property is assigned a false value. You can check that property's value later in the build file.

In this example, the build file checks to see if two files exist using the available task (covered later in the chapter) and sets the property all.set (to true) if the files are found:

  <condition property="all.set">     <and>       <available file="file1.java"/>       <available file="file2.java"/>     </and>   </condition>

Here's another example where the build file checks to see if it's running on Mac OS but not Mac OS X, which Ant treats as part of the Unix family:

  <condition property="MacOs.Not.MacOsX">     <and>       <os family="mac"/>       <not>         <os family="unix"/>       </not>     </and>   </condition>

Here's how you can set a property; in this case, called do.abort--if the do.delete property value equals "yes":

<condition property="do.abort">   <equals arg1="yes" arg2="${do.delete}"/> </condition>

You can see the attributes of the condition task in Table 2-1.

Table 2-1. The condition task's attributes

Attribute

Description

Required

Default

property

The property you want to set.

Yes

 

value

The value you want to set the property to.

No

true


This task depends on nested elements for evaluation; you can see the possibilities in Table 2-2.

Table 2-2. Elements that can be nested within the condition task

Nested element

Functionality

and

True if all of its contained conditions are true.

available

Identical to the available task, which checks for the availabilty of files.

checksum

Identical to the Ant checksum task, which generates a checksum for files. If you compare two files that you think are the same, but their checksums are different, the files are different as well.

contains

Checks if one string (string) contains another (substring). Optionally, you can make the test case sensitive with the casesensitive attribute. The default is to make comparisons case insensitive.

equals

Checks whether two strings are identical. The strings are given using the (required) attributes arg1 and arg2. The optional attributes are casesensitive and TRim.

filesmatch

Checks to see whether two files have identical contents. The required attributes are file1 and file2.

http

Checks for a valid response from a web server at the specified URL. The required attribute is url, and the optional attribute is errorsBeginAt (the lowest HTTP response code that is an error).

isfalse

Behaves the same as istrue but returns the logically opposite value.

isreference

Checks if a particular reference has been defined. The required attribute is refid; the optional attribute is type, which holds the name of the datatype or task you expect this reference to be.

isset

Checks if a given property has been set. The required attribute is property.

istrue

Checks if a string equals any of the strings Ant considers true, that is, true, yes, or on. There is one required attribute: value (holds the value to test).

not

Logically negates the results of a condition.

or

True if at least one of the contained conditions is true.

os

True if the operating system matches the attributes you specify. The attributes (all optional) of this element are family ("windows", "dos", "unix", "mac", win9x, sunOS, etc.), name, arch (meaning architecture), and version.

socket

Checks for the existence of a TCP/IP listener. The required attributes are server (an IP address or DNS name) and port.

uptodate

Identical to the uptodate task. True if the target file is at least as up-to-date as its source code. The required attributes are property (the property to set), srcfile (source file to check), and targetfile (the file you want to check for up-to-dateness).


Here's an example that sets the property omit.debug.info to true if the property build.type contains either of the words "release" or "gold" and if the property explicitly.include.debug.info is false:

<condition property="omit.debug.info">     <and>         <or>             <contains string="${build.type}" substring="release"/>             <contains string="${build.type}" substring="gold"/>         </or>         <isfalse value="${explicitly.include.debug.info}"/>     </and> </condition>

Here's another example, which sets the property use.property.file true if the files build.properties and version.properties are available, or if the file core.jar is not current:

<condition property="use.property.file">     <or>         <and>             <available file="build.properties"/>             <available file="version.properties"/>         </and>         <not>             <uptodate srcfile="core.java" targetfile="core.jar"/>         </not>     </or> </condition>

2.1.2. Performing Conditional Actions

Actions can be conditionally executed based on two factors: if a certain condition has been met (using the if attribute) and if a certain condition has not been met (using the unless attribute). You can determine if a task runs using if and unless to check the values of properties. Three elements support if and unless attributes: target, patternset (which can group file-matching patterns like "*.java", "*.class", and so on. See "Working with Patterns" in this chapter); fail target is the simplest, as shown here:

<target name="buildModule" if="code.complied.OK"/>         .         .         . </target>

The buildModule target is executed only if the code.complied.OK property is true.

Example 2-1 demonstrates the unless attribute. In this case, the build file won't compile the source files if the file enduser.agreement exists, which sets a property named final.version.

Example 2-1. Using the unless attribute (ch02/if/build.xml)
<?xml version="1.0" ?> <project default="main">     <property name="message" value="Building the .jar file." />     <property name="src" location="source" />     <property name="output" location="bin" />     <available file="${output}/enduser.agreement" property="final.version"/>     <target name="main" depends="init, compile, compress">         <echo>             ${message}         </echo>     </target>        <target name="init">         <mkdir dir="${output}" />     </target>        <target name="compile" unless="final.version">         <javac srcdir="${src}" destdir="${output}" />     </target>      <target name="compress">         <jar destfile="${output}/Project.jar" basedir="${output}"              includes="*.class" />   </target> </project>

2.1.3. Stopping Builds

You can make a build fail at runtime using property values and the fail task.

The fail task has been made more useful since Ant 1.5 with the addition of support for the if and unless attributes.


For example, this build will fail with a message unless the specified classes are found in the classpath:

<target name=     <condition property="classes.available">         <and>             <available classname="org.steven.SAXparser" />             <available classname="org.steven.DOMparser" />         </and>     </condition>     <fail message="Could not find all classes." unless="classes.available" />         .         .         . </target>

You can see the available attributes of fail in Table 2-3.

Table 2-3. The fail task's attributes

Attribute

Description

Required

Default

message

A message indicating why the build exited

No

 

if

Fails if the property of the given name is true in the current project

No

 

unless

Fails if a property of the given name is false in the current project

No

 


2.1.4. Property-Setting Tasks

A few tasks allow you to indirectly set properties; that is, you specify a task (like available) and assign the result of that task's processing to a property. These function are like the condition task, though the syntax is different.

2.1.4.1 Availability of resources

The available task sets a property to true if a resource is available at runtime. The resource can be a file, a directory, a class in the classpath, or a JVM system resource. If the resource is available, the property value is set to true; otherwise, the property is not set.

For example, the following build fragment will set the property Math.present to true if org.steve.Math is in Ant's classpath:

<available classname="org.steve.Math" property="Math.present"/>

Here's another example, which sets file.present to true if the file build.properties exists in the current directory:

<available file="build.properties" property="file.present"/>

You can see the attributes of this task in Table 2-4. You can set the property value to something other than the default by using the value attribute.

This task is handy for setting properties that avoid or allow target execution depending on system parameters or the presence of various files. For example, you may want to load in properties from a property file (see Section 2.2 in this chapter) rather than use default values if that property file exists.


Table 2-4. The available task's attributes

Attribute

Description

Required

Default

classname

Class to search for.

One of classname, file, or resource

 

classpath

Classpath to use when searching for classname or resource.

No

 

classpathref

A reference to the classpath to use for searches.

No

 

file

The file to search for.

One of classname, file, or resource

 

filepath

The path to use when searching for a file.

No

 

ignoresystemclasses

Set to true to ignore Ant's runtime classes in searches, using only the specified classpath instead. Affects the classname attribute.

No

false

property

The name of the property to set with the results of the search.

Yes

 

resource

The resource to look for.

One of classname, file, or resource

 

type

The type of file to look for. Set this to a directory (type="dir") or a file (type="file").

No

 

value

Specifies the value you want to set the property to for a successful match.

No

TRue


2.1.4.2 Checking file modification dates

The uptodate task sets a property to true under certain conditions. In this case, the property is set to true if a target file, or set of target files, is more current than a source file or set of source files. You can specify the file you want to check with the targetfile attribute and the source file that is used to create it with the srcfile attribute. If you want to check a set of source files, use nested srcfiles elements. If the target (or targets) is current, based on the source file or files, the property whose name you specify will be set to true.

In this example, the property Do.Not.Build will be set to true if the target file, classes.jar, is current when compared to its source .java files:

<uptodate property="Do.Not.Build" targetfile="classes.jar" >     <srcfiles dir= "${src}" includes="*.java"/> </uptodate>

You can use the ** wildcard to stand for the current directory and any subdirectory of that directory, which makes it easy to work with a directory hierarchy in depth. For example, if you want to check the ${src} directory for .java files, as in the previous example, and any subdirectory of ${src}, you could set includes to **/*.java. Doing so would match the .java files in the ${src} directory and in any subdirectories of ${src}. Here's how that might look:

<uptodate property="Do.Not.Build" targetfile="classes.jar" >     <srcfiles dir= "${src}" includes="**/*.java"/> </uptodate>

Here's an example checking against a single source file, using the srcfile attribute:

<uptodate property="Do.Not.Build" targetfile="classes.jar" >     <srcfile includes="/usr/local/bin/classes.java"/> </uptodate>

You can see attributes for the uptodate task in Table 2-5.

Table 2-5. The uptodate task's attributes

Attribute

Description

Required

Default

property

The name of the property to set with the results of this task

Yes.

 

value

The value you want to set the property to if the target is current

No.

true

srcfile

The file you want to check against the target file(s)

Yes, unless a nested srcfiles element is present

 

targetfile

The file you want to check for current status

Yes, unless a nested mapper element is present

 




    Ant. The Definitive Guide
    Ant: The Definitive Guide, 2nd Edition
    ISBN: 0596006098
    EAN: 2147483647
    Year: 2003
    Pages: 115
    Authors: Steve Holzner

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net