The use of the local task changes the immutability of the ANT properties and makes them variables under the following conditions:
- the properties that are defined at project or target level, outside of any <local> task are immutable, as of the standard ANT contract.
- any properties that are defined or assigned nested between <local> and </local> become variable.
- the nested <local> tasks form a stack of environments that bind properties to values. At any moment of the execution of the ModelAnt script, the top of the environments stack is set by the current most nested <local>.
- within <local> visible are all properties defined in an outer <local> or outside any <local>, i.e. global properties, but
- defining a new property binds it in the environment at the top of the environments stack. When leaving the deepest <local> environment, the locally defined properties are just forgotten, i.e. the top of the environments stack is just removed from the stack.
- defining a property with a name from an outer environment hides it locally and defines a new property in the current deepest <local>
- the values of the properties in <local> environments could be overridden, thus way making the properties variable
- within <local> each thread running the script receives its own thread-specific environment stack.
- the <local> tasks allows setting the name of a local property whose value to be transferred to the outer environment when leaving the nested one, no matter if the outer environment is the global one or it is a local one, no matter if there is already a property with the same name or not.
The following examples use the assertion macros from assert.xml library from util package.
Example 1:
Once set, the global properties cannot change their values:
<property name="prop" value="value"/>
<assert.equal value1="${prop}" value2="value"/>
<property name=”prop” value=”overwrite”/>
<assert.equal value1=”${prop}” value2=”value”/>
Example 2:
In nested <local> environments the properties from the outer or global environments are inherited
<property name="prop" value="value"/>
<local>
<assert.equal value1="${prop}" value2="value"/>
</local>
Example 3:
In <local> environments the properties become variable and their properties can be changed.
<local>
<property name="prop" value="value"/>
<assert.equal value1="${prop}" value2="value"/>
<property name="prop" value="overwrite"/>
<assert.equal value1="${prop}" value2="overwrite"/>
</local>
Example 4:
After leaving a nested <local> environment the properties restore their values / no values as they were immediately before entering that <local> environment.
<property name="prop" value="original"/>
<assert.equal value1="${prop}" value2="original"/>
<local>
<property name="prop" value="overwrite"/>
<assert.equal value1="${prop}" value2="overwrite"/>
</local>
<assert.equal value1="${prop}" value2="original"/>
Example 5:
Properties from outer environments can be mixed in expressions
<property name="env1" value="1"/>
<local>
<property name="env2" value="2"/>
<local>
<property name="env3" value="3"/>
<assert.equal value1="${env1}" value2="1"/>
<assert.equal value1="${env2}" value2="2"/>
<assert.equal value1="${env3}" value2="3"/>
</local>
<assert.equal value1="${env1}" value2="1"/>
<assert.equal value1="${env2}" value2="2"/>
<assert.not.defined name="env3"/>
</local>
<assert.equal value1="${env1}" value2="1"/>
<assert.not.defined name="env2"/>
<assert.not.defined name="env3"/>
Example 6:
The properties in the LOCAL environments become VARIABLES
<local>
<property name="to.overwrite" value="original"/>
<assert.equal value1="${to.overwrite}" value2="original"/>
<property name=”to.overwrite” value=”changed”/>
<assert.equal value1=”${to.overwrite}” value2=”changed”/>
</local>
Example 7:
The value of one of the properties from the local environment can be transferred to the outer environment
<local name="prop">
<assert.equal value1="${prop}" value2="value"/>
<property name=”prop” value=”changed”/>
<assert.equal value1=”${prop}” value2=”changed”/>
</local>
<assert.equal value1=”${prop}” value2=”changed”/>