@@ -53,6 +53,12 @@ examples section.</p> | |||
</tr> | |||
</table> | |||
<h3>Parameters specified as nested elements</h3> | |||
<h4>Name</h4> | |||
<p>As an alternative to (or in conjunction with) the <code>name</code> attribute, the nested text of | |||
each of one or more nested <code><name></code> elements specifies a property name to declare in | |||
the local scope. | |||
<h3>Examples</h3> | |||
<h4>Temporarily shadow a global property's value</h4> | |||
@@ -171,5 +177,15 @@ come up with unique names in some cases.</p> | |||
<p>Each invocation gets its own property named <code>parent</code> and there will be no global | |||
property of that name at all.</p> | |||
<h4>Use of nested name elements</h4> | |||
This style declares and executes a single task, as compensation for requiring more lines of XML than | |||
would individual invocations using <code>@name</code>: | |||
<pre> | |||
<local> | |||
<name>foo</name> | |||
<name>bar</name> | |||
<name>baz</name> | |||
</local> | |||
</pre> | |||
</body> | |||
</html> |
@@ -17,15 +17,48 @@ | |||
*/ | |||
package org.apache.tools.ant.taskdefs; | |||
import java.util.LinkedHashSet; | |||
import java.util.Set; | |||
import java.util.function.Consumer; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.Task; | |||
import org.apache.tools.ant.property.LocalProperties; | |||
import org.apache.tools.ant.util.StringUtils; | |||
/** | |||
* Task to create a local property in the current scope. | |||
* Task to create local properties in the current scope. | |||
*/ | |||
public class Local extends Task { | |||
/** | |||
* Nested {@code name} element. | |||
*/ | |||
public static class Name implements Consumer<LocalProperties> { | |||
private String text; | |||
/** | |||
* Set the property name. | |||
* @param text | |||
*/ | |||
public void addText(String text) { | |||
this.text = text; | |||
} | |||
/** | |||
* {@inheritDoc} | |||
*/ | |||
@Override | |||
public void accept(LocalProperties localProperties) { | |||
if (text == null) { | |||
throw new BuildException("nested name element is missing text"); | |||
} | |||
localProperties.addLocal(text); | |||
} | |||
} | |||
private String name; | |||
private final Set<Name> nameElements = new LinkedHashSet<>(); | |||
/** | |||
* Set the name attribute. | |||
@@ -35,13 +68,28 @@ public class Local extends Task { | |||
this.name = name; | |||
} | |||
/** | |||
* Create a nested {@code name} element. | |||
* @return {@link Name} | |||
*/ | |||
public Name createName() { | |||
final Name result = new Name(); | |||
nameElements.add(result); | |||
return result; | |||
} | |||
/** | |||
* Run the task. | |||
*/ | |||
public void execute() { | |||
if (name == null) { | |||
throw new BuildException("Missing attribute name"); | |||
if (name == null && nameElements.isEmpty()) { | |||
throw new BuildException("Found no configured local property names"); | |||
} | |||
final LocalProperties localProperties = LocalProperties.get(getProject()); | |||
if (name != null) { | |||
localProperties.addLocal(name); | |||
} | |||
LocalProperties.get(getProject()).addLocal(name); | |||
nameElements.forEach(n -> n.accept(localProperties)); | |||
} | |||
} |
@@ -93,4 +93,24 @@ | |||
<au:assertPropertyEquals name="foo" value="foo" /> | |||
</target> | |||
<target name="testMulti"> | |||
<property name="bar" value="bar" /> | |||
<property name="baz" value="baz" /> | |||
<sequential> | |||
<local> | |||
<name>foo</name> | |||
<name>bar</name> | |||
<name>baz</name> | |||
</local> | |||
<property name="foo" value="FOO" /> | |||
<property name="bar" value="BAR" /> | |||
<property name="baz" value="BAZ" /> | |||
<au:assertPropertyEquals name="foo" value="FOO" /> | |||
<au:assertPropertyEquals name="bar" value="BAR" /> | |||
<au:assertPropertyEquals name="baz" value="BAZ" /> | |||
</sequential> | |||
<au:assertPropertyEquals name="foo" value="foo" /> | |||
<au:assertPropertyEquals name="bar" value="bar" /> | |||
<au:assertPropertyEquals name="baz" value="baz" /> | |||
</target> | |||
</project> |