git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@676095 13f79535-47bb-0310-9956-ffa450edef68master
@@ -153,6 +153,8 @@ Other changes: | |||||
a build if a warning occurs. | a build if a warning occurs. | ||||
Bugzilla Report 41836. | Bugzilla Report 41836. | ||||
* Ant now supports local properties. Bugzilla report 23942. | |||||
Changes from Ant 1.7.0 TO Ant 1.7.1 | Changes from Ant 1.7.0 TO Ant 1.7.1 | ||||
============================================= | ============================================= | ||||
@@ -0,0 +1,53 @@ | |||||
<!-- | |||||
Licensed to the Apache Software Foundation (ASF) under one or more | |||||
contributor license agreements. See the NOTICE file distributed with | |||||
this work for additional information regarding copyright ownership. | |||||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
(the "License"); you may not use this file except in compliance with | |||||
the License. You may obtain a copy of the License at | |||||
http://www.apache.org/licenses/LICENSE-2.0 | |||||
Unless required by applicable law or agreed to in writing, software | |||||
distributed under the License is distributed on an "AS IS" BASIS, | |||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
See the License for the specific language governing permissions and | |||||
limitations under the License. | |||||
--> | |||||
<html> | |||||
<head> | |||||
<meta http-equiv="Content-Language" content="en-us"> | |||||
<link rel="stylesheet" type="text/css" href="../stylesheets/style.css"> | |||||
<title>Local Task</title> | |||||
</head> | |||||
<body> | |||||
<h2>Local</h2> | |||||
<h3>Description</h3> | |||||
<p>Adds a local property to the current scope. Property scopes exist at Ant's | |||||
various "block" levels. These include targets as well as the | |||||
<a href="parallel.html">Parallel</a> and <a href="sequential.html">Sequential</a> | |||||
task containers (including <a href="macrodef.html">Macrodef</a> bodies). A local | |||||
property at a given scope "shadows" properties of the same name at higher scopes, | |||||
including the global scope (declaring a local property at the global level, i.e. | |||||
outside of any scope block, has no effect). <b>Since Ant 1.8</b></p> | |||||
<h3>Parameters</h3> | |||||
<table border="1" cellpadding="2" cellspacing="0"> | |||||
<tr> | |||||
<td valign="top"><b>Attribute</b></td> | |||||
<td valign="top"><b>Description</b></td> | |||||
<td align="center" valign="top"><b>Required</b></td> | |||||
</tr> | |||||
<tr> | |||||
<td valign="top">name</td> | |||||
<td valign="top">The property to declare in the current scope</td> | |||||
<td valign="top" align="center">Yes</td> | |||||
</tr> | |||||
</table> | |||||
</body> | |||||
</html> | |||||
@@ -86,6 +86,7 @@ | |||||
<a href="CoreTasks/loadfile.html">LoadFile</a><br/> | <a href="CoreTasks/loadfile.html">LoadFile</a><br/> | ||||
<a href="CoreTasks/loadproperties.html">LoadProperties</a><br/> | <a href="CoreTasks/loadproperties.html">LoadProperties</a><br/> | ||||
<a href="CoreTasks/loadresource.html">LoadResource</a><br/> | <a href="CoreTasks/loadresource.html">LoadResource</a><br/> | ||||
<a href="CoreTasks/local.html">Local</a><br/> | |||||
<a href="CoreTasks/makeurl.html">MakeURL</a><br/> | <a href="CoreTasks/makeurl.html">MakeURL</a><br/> | ||||
<a href="CoreTasks/mail.html">Mail</a><br/> | <a href="CoreTasks/mail.html">Mail</a><br/> | ||||
<a href="CoreTasks/macrodef.html">MacroDef</a><br/> | <a href="CoreTasks/macrodef.html">MacroDef</a><br/> | ||||
@@ -174,6 +174,12 @@ public final class MagicNames { | |||||
*/ | */ | ||||
public static final String REFID_PROPERTY_HELPER = "ant.PropertyHelper"; | public static final String REFID_PROPERTY_HELPER = "ant.PropertyHelper"; | ||||
/** | |||||
* Reference used to store the local properties. | |||||
* Value: {@value} | |||||
*/ | |||||
public static final String REFID_LOCAL_PROPERTIES = "ant.LocalProperties"; | |||||
/** | /** | ||||
* Name of JVM system property which provides the name of the ProjectHelper class to use. | * Name of JVM system property which provides the name of the ProjectHelper class to use. | ||||
* Value: {@value} | * Value: {@value} | ||||
@@ -25,6 +25,8 @@ import java.util.Iterator; | |||||
import java.util.List; | import java.util.List; | ||||
import java.util.StringTokenizer; | import java.util.StringTokenizer; | ||||
import org.apache.tools.ant.property.LocalProperties; | |||||
/** | /** | ||||
* Class to implement a target object with required parameters. | * Class to implement a target object with required parameters. | ||||
* | * | ||||
@@ -347,14 +349,22 @@ public class Target implements TaskContainer { | |||||
*/ | */ | ||||
public void execute() throws BuildException { | public void execute() throws BuildException { | ||||
if (testIfCondition() && testUnlessCondition()) { | if (testIfCondition() && testUnlessCondition()) { | ||||
for (int taskPosition = 0; taskPosition < children.size(); ++taskPosition) { | |||||
Object o = children.get(taskPosition); | |||||
if (o instanceof Task) { | |||||
Task task = (Task) o; | |||||
task.perform(); | |||||
} else { | |||||
((RuntimeConfigurable) o).maybeConfigure(project); | |||||
LocalProperties localProperties | |||||
= LocalProperties.get(getProject()); | |||||
localProperties.enterScope(); | |||||
try { | |||||
for (int taskPosition = 0; taskPosition < children.size(); | |||||
++taskPosition) { | |||||
Object o = children.get(taskPosition); | |||||
if (o instanceof Task) { | |||||
Task task = (Task) o; | |||||
task.perform(); | |||||
} else { | |||||
((RuntimeConfigurable) o).maybeConfigure(project); | |||||
} | |||||
} | } | ||||
} finally { | |||||
localProperties.exitScope(); | |||||
} | } | ||||
} else if (!testIfCondition()) { | } else if (!testIfCondition()) { | ||||
project.log(this, "Skipped because property '" + project.replaceProperties(ifCondition) | project.log(this, "Skipped because property '" + project.replaceProperties(ifCondition) | ||||
@@ -0,0 +1,152 @@ | |||||
/* | |||||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||||
* contributor license agreements. See the NOTICE file distributed with | |||||
* this work for additional information regarding copyright ownership. | |||||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
* (the "License"); you may not use this file except in compliance with | |||||
* the License. You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* | |||||
*/ | |||||
package org.apache.tools.ant.property; | |||||
import org.apache.tools.ant.PropertyHelper; | |||||
import org.apache.tools.ant.Project; | |||||
import org.apache.tools.ant.MagicNames; | |||||
/** | |||||
* Thread local class containing local properties. | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public class LocalProperties | |||||
extends InheritableThreadLocal | |||||
implements PropertyHelper.PropertyEvaluator, | |||||
PropertyHelper.PropertySetter { | |||||
/** | |||||
* Get a localproperties for the given project. | |||||
* @param project the project to retieve the localproperties for. | |||||
* @return the localproperties. | |||||
*/ | |||||
public static synchronized LocalProperties get(Project project) { | |||||
LocalProperties l = (LocalProperties) project.getReference( | |||||
MagicNames.REFID_LOCAL_PROPERTIES); | |||||
if (l == null) { | |||||
l = new LocalProperties(); | |||||
project.addReference(MagicNames.REFID_LOCAL_PROPERTIES, l); | |||||
PropertyHelper.getPropertyHelper(project).add(l); | |||||
} | |||||
return l; | |||||
} | |||||
// -------------------------------------------------- | |||||
// | |||||
// Thread stuff | |||||
// | |||||
// -------------------------------------------------- | |||||
/** | |||||
* Construct a new LocalProperties object. | |||||
*/ | |||||
private LocalProperties() { | |||||
} | |||||
/** | |||||
* Get the initial value. | |||||
* @return a new localproperties stack. | |||||
*/ | |||||
protected synchronized Object initialValue() { | |||||
return new LocalPropertyStack(); | |||||
} | |||||
private LocalPropertyStack current() { | |||||
return (LocalPropertyStack) get(); | |||||
} | |||||
// -------------------------------------------------- | |||||
// | |||||
// Local property adding and scoping | |||||
// | |||||
// -------------------------------------------------- | |||||
/** | |||||
* Add a local property to the current scope. | |||||
* @param property the property name to add. | |||||
*/ | |||||
public void addLocal(String property) { | |||||
current().addLocal(property); | |||||
} | |||||
/** enter the scope */ | |||||
public void enterScope() { | |||||
current().enterScope(); | |||||
} | |||||
/** exit the scope */ | |||||
public void exitScope() { | |||||
current().exitScope(); | |||||
} | |||||
// -------------------------------------------------- | |||||
// | |||||
// Copy - used in parallel to make a new stack | |||||
// | |||||
// -------------------------------------------------- | |||||
/** | |||||
* Copy the stack for a parallel thread. | |||||
* To be called from the parallel thread itself. | |||||
*/ | |||||
public void copy() { | |||||
set(current().copy()); | |||||
} | |||||
// -------------------------------------------------- | |||||
// | |||||
// PropertyHelper delegate methods | |||||
// | |||||
// -------------------------------------------------- | |||||
/** | |||||
* Evaluate a property. | |||||
* @param property the property's String "identifier". | |||||
* @param helper the invoking PropertyHelper. | |||||
* @return Object value. | |||||
*/ | |||||
public Object evaluate(String property, PropertyHelper helper) { | |||||
return current().evaluate(property, helper); | |||||
} | |||||
/** | |||||
* Set a *new" property. | |||||
* @param property the property's String "identifier". | |||||
* @param value the value to set. | |||||
* @param propertyHelper the invoking PropertyHelper. | |||||
* @return true if this entity 'owns' the property. | |||||
*/ | |||||
public boolean setNew( | |||||
String property, Object value, PropertyHelper propertyHelper) { | |||||
return current().setNew(property, value, propertyHelper); | |||||
} | |||||
/** | |||||
* Set a property. | |||||
* @param property the property's String "identifier". | |||||
* @param value the value to set. | |||||
* @param propertyHelper the invoking PropertyHelper. | |||||
* @return true if this entity 'owns' the property. | |||||
*/ | |||||
public boolean set( | |||||
String property, Object value, PropertyHelper propertyHelper) { | |||||
return current().set(property, value, propertyHelper); | |||||
} | |||||
} | |||||
@@ -0,0 +1,151 @@ | |||||
/* | |||||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||||
* contributor license agreements. See the NOTICE file distributed with | |||||
* this work for additional information regarding copyright ownership. | |||||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
* (the "License"); you may not use this file except in compliance with | |||||
* the License. You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* | |||||
*/ | |||||
package org.apache.tools.ant.property; | |||||
import java.util.LinkedList; | |||||
import java.util.HashMap; | |||||
import java.util.Iterator; | |||||
import java.util.Map; | |||||
import org.apache.tools.ant.PropertyHelper; | |||||
/** | |||||
* A stack of local property maps. | |||||
* There is a map for each scope (target, sequential, macro). | |||||
* @since Ant 1.8.0 | |||||
*/ | |||||
public class LocalPropertyStack { | |||||
private LinkedList stack = new LinkedList(); | |||||
// -------------------------------------------------- | |||||
// | |||||
// Local property adding and scoping | |||||
// | |||||
// -------------------------------------------------- | |||||
/** | |||||
* Add a local property. | |||||
* @param property the name of the local proeprty. | |||||
*/ | |||||
public void addLocal(String property) { | |||||
if (!stack.isEmpty()) { | |||||
((Map) stack.getFirst()).put(property, NullReturn.NULL); | |||||
} | |||||
} | |||||
/** | |||||
* Enter the local scope. | |||||
*/ | |||||
public void enterScope() { | |||||
stack.addFirst(new HashMap()); | |||||
} | |||||
/** | |||||
* Exit the local scope. | |||||
*/ | |||||
public void exitScope() { | |||||
((HashMap) stack.removeFirst()).clear(); | |||||
} | |||||
// -------------------------------------------------- | |||||
// | |||||
// Copy - used in parallel to make a new stack | |||||
// | |||||
// -------------------------------------------------- | |||||
/** | |||||
* Copy the stack for a parallel thread. | |||||
* @return a copy. | |||||
*/ | |||||
public LocalPropertyStack copy() { | |||||
LocalPropertyStack ret = new LocalPropertyStack(); | |||||
ret.stack.addAll(stack); | |||||
return ret; | |||||
} | |||||
// -------------------------------------------------- | |||||
// | |||||
// PropertyHelper delegate methods | |||||
// | |||||
// -------------------------------------------------- | |||||
/** | |||||
* Evaluate a property. | |||||
* @param property the property's String "identifier". | |||||
* @param helper the invoking PropertyHelper. | |||||
* @return Object value. | |||||
*/ | |||||
public Object evaluate(String property, PropertyHelper helper) { | |||||
for (Iterator i = stack.iterator(); i.hasNext();) { | |||||
Map map = (Map) i.next(); | |||||
Object ret = map.get(property); | |||||
if (ret != null) { | |||||
return ret; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* Set a *new" property. | |||||
* @param property the property's String "identifier". | |||||
* @param value the value to set. | |||||
* @param propertyHelper the invoking PropertyHelper. | |||||
* @return true if this entity 'owns' the property. | |||||
*/ | |||||
public boolean setNew( | |||||
String property, Object value, PropertyHelper propertyHelper) { | |||||
Map map = getMapForProperty(property); | |||||
if (map == null) { | |||||
return false; | |||||
} | |||||
Object currValue = map.get(property); | |||||
if (currValue == NullReturn.NULL) { | |||||
map.put(property, value); | |||||
} | |||||
return true; | |||||
} | |||||
/** | |||||
* Set a property. | |||||
* @param property the property's String "identifier". | |||||
* @param value the value to set. | |||||
* @param propertyHelper the invoking PropertyHelper. | |||||
* @return true if this entity 'owns' the property. | |||||
*/ | |||||
public boolean set(String property, Object value, PropertyHelper propertyHelper) { | |||||
Map map = getMapForProperty(property); | |||||
if (map == null) { | |||||
return false; | |||||
} | |||||
map.put(property, value); | |||||
return true; | |||||
} | |||||
private Map getMapForProperty(String property) { | |||||
for (Iterator i = stack.iterator(); i.hasNext();) { | |||||
Map map = (Map) i.next(); | |||||
if (map.get(property) != null) { | |||||
return map; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
} | |||||
@@ -0,0 +1,47 @@ | |||||
/* | |||||
* Licensed to the Apache Software Foundation (ASF) under one or more | |||||
* contributor license agreements. See the NOTICE file distributed with | |||||
* this work for additional information regarding copyright ownership. | |||||
* The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
* (the "License"); you may not use this file except in compliance with | |||||
* the License. You may obtain a copy of the License at | |||||
* | |||||
* http://www.apache.org/licenses/LICENSE-2.0 | |||||
* | |||||
* Unless required by applicable law or agreed to in writing, software | |||||
* distributed under the License is distributed on an "AS IS" BASIS, | |||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
* See the License for the specific language governing permissions and | |||||
* limitations under the License. | |||||
* | |||||
*/ | |||||
package org.apache.tools.ant.taskdefs; | |||||
import org.apache.tools.ant.BuildException; | |||||
import org.apache.tools.ant.Task; | |||||
import org.apache.tools.ant.property.LocalProperties; | |||||
/** | |||||
* Task to create a local property in the current scope. | |||||
*/ | |||||
public class Local extends Task { | |||||
private String name; | |||||
/** | |||||
* Set the name attribute. | |||||
* @param name the name of the local property. | |||||
*/ | |||||
public void setName(String name) { | |||||
this.name = name; | |||||
} | |||||
/** | |||||
* Run the task. | |||||
*/ | |||||
public void execute() { | |||||
if (name == null) { | |||||
throw new BuildException("Missing attribute name"); | |||||
} | |||||
LocalProperties.get(getProject()).addLocal(name); | |||||
} | |||||
} |
@@ -37,6 +37,7 @@ import org.apache.tools.ant.Target; | |||||
import org.apache.tools.ant.Task; | import org.apache.tools.ant.Task; | ||||
import org.apache.tools.ant.TaskContainer; | import org.apache.tools.ant.TaskContainer; | ||||
import org.apache.tools.ant.UnknownElement; | import org.apache.tools.ant.UnknownElement; | ||||
import org.apache.tools.ant.property.LocalProperties; | |||||
/** | /** | ||||
* The class to be placed in the ant type definition. | * The class to be placed in the ant type definition. | ||||
@@ -390,6 +391,9 @@ public class MacroInstance extends Task implements DynamicAttribute, TaskContain | |||||
// need to set the project on unknown element | // need to set the project on unknown element | ||||
UnknownElement c = copy(macroDef.getNestedTask(), false); | UnknownElement c = copy(macroDef.getNestedTask(), false); | ||||
c.init(); | c.init(); | ||||
LocalProperties localProperties | |||||
= LocalProperties.get(getProject()); | |||||
localProperties.enterScope(); | |||||
try { | try { | ||||
c.perform(); | c.perform(); | ||||
} catch (BuildException ex) { | } catch (BuildException ex) { | ||||
@@ -403,6 +407,7 @@ public class MacroInstance extends Task implements DynamicAttribute, TaskContain | |||||
} finally { | } finally { | ||||
presentElements = null; | presentElements = null; | ||||
localAttributes = null; | localAttributes = null; | ||||
localProperties.exitScope(); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -26,6 +26,7 @@ import org.apache.tools.ant.BuildException; | |||||
import org.apache.tools.ant.Location; | import org.apache.tools.ant.Location; | ||||
import org.apache.tools.ant.Task; | import org.apache.tools.ant.Task; | ||||
import org.apache.tools.ant.TaskContainer; | import org.apache.tools.ant.TaskContainer; | ||||
import org.apache.tools.ant.property.LocalProperties; | |||||
import org.apache.tools.ant.util.StringUtils; | import org.apache.tools.ant.util.StringUtils; | ||||
/** | /** | ||||
@@ -451,6 +452,7 @@ public class Parallel extends Task | |||||
*/ | */ | ||||
public void run() { | public void run() { | ||||
try { | try { | ||||
LocalProperties.get(getProject()).copy(); | |||||
thread = Thread.currentThread(); | thread = Thread.currentThread(); | ||||
task.perform(); | task.perform(); | ||||
} catch (Throwable t) { | } catch (Throwable t) { | ||||
@@ -23,6 +23,8 @@ import org.apache.tools.ant.BuildException; | |||||
import org.apache.tools.ant.Task; | import org.apache.tools.ant.Task; | ||||
import org.apache.tools.ant.TaskContainer; | import org.apache.tools.ant.TaskContainer; | ||||
import org.apache.tools.ant.property.LocalProperties; | |||||
/** | /** | ||||
* Sequential is a container task - it can contain other Ant tasks. The nested | * Sequential is a container task - it can contain other Ant tasks. The nested | ||||
* tasks are simply executed in sequence. Sequential's primary use is to support | * tasks are simply executed in sequence. Sequential's primary use is to support | ||||
@@ -57,9 +59,16 @@ public class Sequential extends Task implements TaskContainer { | |||||
* @throws BuildException if one of the nested tasks fails. | * @throws BuildException if one of the nested tasks fails. | ||||
*/ | */ | ||||
public void execute() throws BuildException { | public void execute() throws BuildException { | ||||
for (Iterator i = nestedTasks.iterator(); i.hasNext();) { | |||||
Task nestedTask = (Task) i.next(); | |||||
nestedTask.perform(); | |||||
LocalProperties localProperties | |||||
= LocalProperties.get(getProject()); | |||||
localProperties.enterScope(); | |||||
try { | |||||
for (Iterator i = nestedTasks.iterator(); i.hasNext();) { | |||||
Task nestedTask = (Task) i.next(); | |||||
nestedTask.perform(); | |||||
} | |||||
} finally { | |||||
localProperties.exitScope(); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -61,6 +61,7 @@ length=org.apache.tools.ant.taskdefs.Length | |||||
loadfile=org.apache.tools.ant.taskdefs.LoadFile | loadfile=org.apache.tools.ant.taskdefs.LoadFile | ||||
loadproperties=org.apache.tools.ant.taskdefs.LoadProperties | loadproperties=org.apache.tools.ant.taskdefs.LoadProperties | ||||
loadresource=org.apache.tools.ant.taskdefs.LoadResource | loadresource=org.apache.tools.ant.taskdefs.LoadResource | ||||
local=org.apache.tools.ant.taskdefs.Local | |||||
macrodef=org.apache.tools.ant.taskdefs.MacroDef | macrodef=org.apache.tools.ant.taskdefs.MacroDef | ||||
mail=org.apache.tools.ant.taskdefs.email.EmailTask | mail=org.apache.tools.ant.taskdefs.email.EmailTask | ||||
manifest=org.apache.tools.ant.taskdefs.ManifestTask | manifest=org.apache.tools.ant.taskdefs.ManifestTask | ||||
@@ -0,0 +1,86 @@ | |||||
<?xml version="1.0"?> | |||||
<!-- | |||||
Licensed to the Apache Software Foundation (ASF) under one or more | |||||
contributor license agreements. See the NOTICE file distributed with | |||||
this work for additional information regarding copyright ownership. | |||||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
(the "License"); you may not use this file except in compliance with | |||||
the License. You may obtain a copy of the License at | |||||
http://www.apache.org/licenses/LICENSE-2.0 | |||||
Unless required by applicable law or agreed to in writing, software | |||||
distributed under the License is distributed on an "AS IS" BASIS, | |||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
See the License for the specific language governing permissions and | |||||
limitations under the License. | |||||
--> | |||||
<project default="antunit" xmlns:au="antlib:org.apache.ant.antunit"> | |||||
<import file="../antunit-base.xml" /> | |||||
<property name="foo" value="foo" /> | |||||
<target name="testBaseline"> | |||||
<au:assertPropertyEquals name="foo" value="foo" /> | |||||
</target> | |||||
<target name="testTarget"> | |||||
<au:assertPropertyEquals name="foo" value="foo" /> | |||||
<local name="foo" /> | |||||
<property name="foo" value="foo.target" /> | |||||
<au:assertPropertyEquals name="foo" value="foo.target" /> | |||||
</target> | |||||
<target name="testSequential"> | |||||
<sequential> | |||||
<local name="foo" /> | |||||
<property name="foo" value="foo.1" /> | |||||
<sequential> | |||||
<local name="foo" /> | |||||
<property name="foo" value="foo.2" /> | |||||
<au:assertPropertyEquals name="foo" value="foo.2" /> | |||||
</sequential> | |||||
<au:assertPropertyEquals name="foo" value="foo.1" /> | |||||
</sequential> | |||||
<au:assertPropertyEquals name="foo" value="foo" /> | |||||
</target> | |||||
<target name="testParallel"> | |||||
<macrodef name="p"> | |||||
<attribute name="value" /> | |||||
<attribute name="sleep" default="0" /> | |||||
<sequential> | |||||
<local name="foo" /> | |||||
<sleep seconds="@{sleep}" /> | |||||
<property name="foo" value="@{value}" /> | |||||
<au:assertPropertyEquals name="foo" value="@{value}" /> | |||||
</sequential> | |||||
</macrodef> | |||||
<parallel> | |||||
<p sleep="2" value="foo.a" /> | |||||
<au:assertPropertyEquals name="foo" value="foo" /> | |||||
<p sleep="1" value="foo.b" /> | |||||
<au:assertPropertyEquals name="foo" value="foo" /> | |||||
<p sleep="0" value="foo.c" /> | |||||
<au:assertPropertyEquals name="foo" value="foo" /> | |||||
</parallel> | |||||
<au:assertPropertyEquals name="foo" value="foo" /> | |||||
</target> | |||||
<target name="testMacrodef"> | |||||
<macrodef name="m"> | |||||
<sequential> | |||||
<local name="foo" /> | |||||
<property name="foo" value="foo.x" /> | |||||
<au:assertPropertyEquals name="foo" value="foo.x" /> | |||||
</sequential> | |||||
</macrodef> | |||||
<m /> | |||||
<au:assertPropertyEquals name="foo" value="foo" /> | |||||
<m /> | |||||
<au:assertPropertyEquals name="foo" value="foo" /> | |||||
<m /> | |||||
<au:assertPropertyEquals name="foo" value="foo" /> | |||||
</target> | |||||
</project> |