support default value for scriptdef attribute

This commit is contained in:
Matt Benson 2022-02-24 20:45:08 -06:00
parent 137218fd6a
commit f1570a246e
3 changed files with 97 additions and 3 deletions

View File

@ -147,6 +147,11 @@ <h4>attribute</h4>
<td>the name of the attribute</td>
<td>Yes</td>
</tr>
<tr>
<td>default</td>
<td>the default value of the attribute</td>
<td>No</td>
</tr>
</table>
<h4>element</h4>

View File

@ -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<String, String> attributes,
Map<String, List<Object>> 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<String, String> withDefault(Map<String, String> attributes) {
/*
* The following is checked in ScriptDefBase but some other caller to
* #executeScript() could pass in anything they like
*/
final Set<String> 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<String, String> result =
this.attributes.stream().filter(Attribute::hasDefault).collect(Collectors
.toMap(Attribute::getName, Attribute::getDefault, (l, r) -> r, LinkedHashMap::new));
result.putAll(attributes);
return result;
}
}

View File

@ -60,6 +60,7 @@
<scriptdef language="javascript" name="scripttest" manager="${script.manager}">
<!-- optional property attribute-->
<attribute name="property" />
<attribute name="propertywithdefault" default="prop_dv" />
</scriptdef>
</presetdef>
@ -69,7 +70,6 @@
<au:assertPropertyEquals name="property" value="live" />
</presetdef>
<!--purely to test that everything works -->
<target name="testInline" if="prereqs-ok">
<js>self.log("Hello");</js>
@ -132,4 +132,27 @@
<quickfail />
</au:expectfailure>
</target>
<target name="testAttribute" if="prereqs-ok">
<js>
project.setNewProperty(attributes.get('property'), 'live');
</js>
<scripttest property="property" />
<assertPropSet />
</target>
<target name="testAttributeDefaultValue" if="prereqs-ok">
<js>
project.setNewProperty(attributes.get('propertywithdefault'), 'live');
</js>
<scripttest />
<assertPropSet name="prop_dv" />
</target>
<target name="testInvalidAttribute" if="prereqs-ok">
<js />
<au:expectfailure message="Found unsupported attributes">
<scripttest foo="bar" />
</au:expectfailure>
</target>
</project>