diff --git a/WHATSNEW b/WHATSNEW
index 35787f176..bae8309c2 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -258,6 +258,9 @@ Fixed bugs:
* Copy of UnknownElement in macroinstance was not recursive.
Bugzilla report 40238.
+* mixing of add and addConfigured methods in Mapper/ChainedMapper
+ causes incorrect chaining. Bugzilla report 40228.
+
Other changes:
--------------
diff --git a/src/etc/testcases/types/addtype.xml b/src/etc/testcases/types/addtype.xml
index fb9340d37..bdc0bed71 100644
--- a/src/etc/testcases/types/addtype.xml
+++ b/src/etc/testcases/types/addtype.xml
@@ -67,6 +67,9 @@
+
@@ -127,6 +130,12 @@
+
+
+ Value Set
+
+
+
diff --git a/src/main/org/apache/tools/ant/IntrospectionHelper.java b/src/main/org/apache/tools/ant/IntrospectionHelper.java
index 24ca3ee34..c45a175bd 100644
--- a/src/main/org/apache/tools/ant/IntrospectionHelper.java
+++ b/src/main/org/apache/tools/ant/IntrospectionHelper.java
@@ -267,7 +267,16 @@ public final class IntrospectionHelper implements BuildListener {
constructor =
args[0].getConstructor(new Class[] {Project.class});
}
+
String propName = getPropertyName(name, "add");
+ if (nestedTypes.get(propName) != null) {
+ /*
+ * Ignore this method as there is an addConfigured
+ * form of this method that has a higher
+ * priority
+ */
+ continue;
+ }
nestedTypes.put(propName, args[0]);
nestedCreators.put(propName, new AddNestedCreator(m,
constructor, AddNestedCreator.ADD));
@@ -1439,6 +1448,8 @@ public final class IntrospectionHelper implements BuildListener {
* the addTypeMethods array. The array is
* ordered so that the more derived classes
* are first.
+ * If both add and addConfigured are present, the addConfigured
+ * will take priority.
* @param method the Method
to insert.
*/
private void insertAddTypeMethod(Method method) {
@@ -1446,6 +1457,10 @@ public final class IntrospectionHelper implements BuildListener {
for (int c = 0; c < addTypeMethods.size(); ++c) {
Method current = (Method) addTypeMethods.get(c);
if (current.getParameterTypes()[0].equals(argClass)) {
+ if (method.getName().equals("addConfigured")) {
+ // add configured replaces the add method
+ addTypeMethods.set(c, method);
+ }
return; // Already present
}
if (current.getParameterTypes()[0].isAssignableFrom(
diff --git a/src/main/org/apache/tools/ant/types/Mapper.java b/src/main/org/apache/tools/ant/types/Mapper.java
index 5e6a00faa..903bfd1be 100644
--- a/src/main/org/apache/tools/ant/types/Mapper.java
+++ b/src/main/org/apache/tools/ant/types/Mapper.java
@@ -57,6 +57,15 @@ public class Mapper extends DataType implements Cloneable {
this.type = type;
}
+ /**
+ * Cannot mix add and addconfigured in same type, so
+ * provide this to override the add method.
+ * @param fileNameMapper the FileNameMapper
to add.
+ */
+ public void addConfigured(FileNameMapper fileNameMapper) {
+ add(fileNameMapper);
+ }
+
/**
* Add a nested FileNameMapper
.
* @param fileNameMapper the FileNameMapper
to add.
diff --git a/src/main/org/apache/tools/ant/util/ContainerMapper.java b/src/main/org/apache/tools/ant/util/ContainerMapper.java
index aa8d107b1..4b62b9be1 100755
--- a/src/main/org/apache/tools/ant/util/ContainerMapper.java
+++ b/src/main/org/apache/tools/ant/util/ContainerMapper.java
@@ -40,6 +40,19 @@ public abstract class ContainerMapper implements FileNameMapper {
add(mapper.getImplementation());
}
+ /**
+ * An add configured version of the add method.
+ * This class used to contain an add method and an
+ * addConfiguredMapper method. Dur to ordering,
+ * the add method was always called first. This
+ * addConfigued method has been added to allow
+ * chaining to work correctly.
+ * @param fileNameMapper a FileNameMapper
.
+ */
+ public void addConfigured(FileNameMapper fileNameMapper) {
+ add(fileNameMapper);
+ }
+
/**
* Add a FileNameMapper
.
* @param fileNameMapper a FileNameMapper
.
diff --git a/src/testcases/org/apache/tools/ant/types/AddTypeTest.java b/src/testcases/org/apache/tools/ant/types/AddTypeTest.java
index 7df3f6ec8..15a9a85c8 100644
--- a/src/testcases/org/apache/tools/ant/types/AddTypeTest.java
+++ b/src/testcases/org/apache/tools/ant/types/AddTypeTest.java
@@ -18,6 +18,7 @@
package org.apache.tools.ant.types;
import org.apache.tools.ant.BuildFileTest;
+import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.condition.Condition;
@@ -86,6 +87,12 @@ public class AddTypeTest extends BuildFileTest {
"myaddconfigured", "value is Value Setexecute: value is Value Set");
}
+ public void testAddConfiguredValue() {
+ expectLogContaining(
+ "myaddconfiguredvalue",
+ "value is Value Setexecute: value is Value Set");
+ }
+
public void testNamespace() {
executeTarget("namespacetest");
}
@@ -151,6 +158,25 @@ public class AddTypeTest extends BuildFileTest {
log("value is " + value);
this.value = value;
}
+ public void add(MyValue value) {
+ throw new BuildException("Should not be called");
+ }
+ public void execute() {
+ log("execute: value is " + value);
+ }
+ }
+
+ public static class MyAddConfiguredValue
+ extends Task
+ {
+ MyValue value;
+ public void addConfiguredValue(MyValue value) {
+ log("value is " + value);
+ this.value = value;
+ }
+ public void addValue(MyValue value) {
+ throw new BuildException("Should not be called");
+ }
public void execute() {
log("execute: value is " + value);
}