diff --git a/manual/Tasks/scriptdef.html b/manual/Tasks/scriptdef.html
index 680f1a864..a741fba35 100644
--- a/manual/Tasks/scriptdef.html
+++ b/manual/Tasks/scriptdef.html
@@ -147,6 +147,11 @@
attribute
the name of the attribute |
Yes |
+
+ default |
+ the default value of the attribute |
+ No |
+
element
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java b/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java
index 9f97b9615..f1c5d4e80 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/script/ScriptDef.java
@@ -21,10 +21,12 @@ import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
import org.apache.tools.ant.AntTypeDefinition;
import org.apache.tools.ant.BuildException;
@@ -104,14 +106,53 @@ public class ScriptDef extends DefBase {
/** The attribute name */
private String name;
+ /** The attribute's default value */
+ private String defaultValue;
+
/**
- * Sets the attribute name
+ * Sets the attribute name.
*
* @param name the attribute name
*/
public void setName(String name) {
this.name = name.toLowerCase(Locale.ENGLISH);
}
+
+ /**
+ * Get the name of this {@link Attribute}.
+ *
+ * @return {@link String}
+ */
+ String getName() {
+ return name;
+ }
+
+ /**
+ * Set the default value of this {@link Attribute}.
+ *
+ * @param defaultValue {@link String}
+ */
+ public void setDefault(String defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
+ /**
+ * Get the default value of this {@link Attribute}, {@code null} if
+ * unset.
+ *
+ * @return {@link String}
+ */
+ String getDefault() {
+ return defaultValue;
+ }
+
+ /**
+ * Learn whether this {@link Attribute} has a default value set.
+ * @return {@code boolean}
+ */
+ boolean hasDefault() {
+ return defaultValue != null;
+ }
}
/**
@@ -340,7 +381,8 @@ public class ScriptDef extends DefBase {
public void executeScript(Map attributes,
Map> elements, ScriptDefBase instance) {
ScriptRunnerBase runner = helper.getScriptRunner();
- runner.addBean("attributes", attributes);
+
+ runner.addBean("attributes", withDefault(attributes));
runner.addBean("elements", elements);
runner.addBean("project", getProject());
if (instance != null) {
@@ -422,4 +464,28 @@ public class ScriptDef extends DefBase {
public void add(ResourceCollection resource) {
helper.add(resource);
}
+
+ private Map withDefault(Map attributes) {
+ /*
+ * The following is checked in ScriptDefBase but some other caller to
+ * #executeScript() could pass in anything they like
+ */
+ final Set unsupported =
+ attributeSet.stream().filter(a -> !this.isAttributeSupported(a)).map(s -> '@' + s)
+ .collect(Collectors.toSet());
+
+ if (!unsupported.isEmpty()) {
+ throw new BuildException("Found unsupported attributes " + unsupported);
+ }
+ if (this.attributes.isEmpty()) {
+ return attributes;
+ }
+ final Map result =
+ this.attributes.stream().filter(Attribute::hasDefault).collect(Collectors
+ .toMap(Attribute::getName, Attribute::getDefault, (l, r) -> r, LinkedHashMap::new));
+
+ result.putAll(attributes);
+
+ return result;
+ }
}
diff --git a/src/tests/antunit/taskdefs/optional/script/scriptdef-test.xml b/src/tests/antunit/taskdefs/optional/script/scriptdef-test.xml
index e2a771883..3c76278cd 100644
--- a/src/tests/antunit/taskdefs/optional/script/scriptdef-test.xml
+++ b/src/tests/antunit/taskdefs/optional/script/scriptdef-test.xml
@@ -60,6 +60,7 @@
+
@@ -69,7 +70,6 @@
-
self.log("Hello");
@@ -132,4 +132,27 @@
+
+
+
+ project.setNewProperty(attributes.get('property'), 'live');
+
+
+
+
+
+
+
+ project.setNewProperty(attributes.get('propertywithdefault'), 'live');
+
+
+
+
+
+
+
+
+
+
+