diff --git a/WHATSNEW b/WHATSNEW
index a8971e7cd..ce82b7223 100644
--- a/WHATSNEW
+++ b/WHATSNEW
@@ -16,6 +16,9 @@ Other changes:
of Watchdog, ExecuteWatchdog and ExecuteJava, which could reduce the occurence
of race conditions here, especially on Java1.5+.
+* Allow broken reference build files. The defer reference processing would
+ break too many files - so allow them with a warning.
+
Changes from Ant 1.7.0Beta2 to Ant 1.7.0Beta3
=============================================
diff --git a/src/main/org/apache/tools/ant/Project.java b/src/main/org/apache/tools/ant/Project.java
index c52983a04..ace9e2956 100644
--- a/src/main/org/apache/tools/ant/Project.java
+++ b/src/main/org/apache/tools/ant/Project.java
@@ -33,6 +33,7 @@ import java.util.Stack;
import java.util.Vector;
import java.util.Set;
import java.util.HashSet;
+import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
import org.apache.tools.ant.input.DefaultInputHandler;
@@ -61,6 +62,8 @@ import org.apache.tools.ant.util.StringUtils;
*
*/
public class Project implements ResourceFactory {
+ private static final String LINE_SEP = System.getProperty("line.separator");
+
/** Message priority of "error". */
public static final int MSG_ERR = 0;
/** Message priority of "warning". */
@@ -136,6 +139,12 @@ public class Project implements ResourceFactory {
/** Map of references within the project (paths etc) (String to Object). */
private Hashtable references = new AntRefTable();
+ /** Map of id references - used for indicating broken build files */
+ private HashMap idReferences = new HashMap();
+
+ /** the parent project for old id resolution (if inheritreferences is set) */
+ private Project parentIdProject = null;
+
/** Name of the project's default target. */
private String defaultTarget;
@@ -1814,6 +1823,46 @@ public class Project implements ResourceFactory {
return new BuildException(new String(sb));
}
+ /**
+ * Inherit the id references.
+ * @param parent the parent project of this project.
+ */
+ public void inheritIDReferences(Project parent) {
+ parentIdProject = parent;
+ }
+
+ /**
+ * Attempt to resolve an Unknown Reference using the
+ * parsed id's - for BC.
+ */
+ private Object resolveIdReference(String key, Project callerProject) {
+ UnknownElement origUE = (UnknownElement) idReferences.get(key);
+ if (origUE == null) {
+ return parentIdProject == null
+ ? null
+ : parentIdProject.resolveIdReference(key, callerProject);
+ }
+ callerProject.log(
+ "Warning: Reference " + key + " has not been set at runtime,"
+ + " but was found during" + LINE_SEP
+ + "build file parsing, attempting to resolve."
+ + " Future versions of Ant may support" + LINE_SEP
+ + " referencing ids defined in non-executed targets.", MSG_WARN);
+ UnknownElement copyUE = origUE.copy(callerProject);
+ copyUE.maybeConfigure();
+ return copyUE.getRealThing();
+ }
+
+ /**
+ * Add an id reference.
+ * Used for broken build files.
+ * @param id the id to set.
+ * @param value the value to set it to (Unknown element in this case.
+ */
+ public void addIdReference(String id, Object value) {
+ idReferences.put(id, value);
+ }
+
/**
* Add a reference to the project.
*
@@ -1856,7 +1905,12 @@ public class Project implements ResourceFactory {
* there is no such reference in the project.
*/
public Object getReference(String key) {
- return references.get(key);
+ Object ret = references.get(key);
+ if (ret != null) {
+ return ret;
+ }
+ // Check for old id behaviour
+ return resolveIdReference(key, this);
}
/**
diff --git a/src/main/org/apache/tools/ant/UnknownElement.java b/src/main/org/apache/tools/ant/UnknownElement.java
index 9f87109cd..3eabf17ac 100644
--- a/src/main/org/apache/tools/ant/UnknownElement.java
+++ b/src/main/org/apache/tools/ant/UnknownElement.java
@@ -19,8 +19,10 @@
package org.apache.tools.ant;
import java.util.ArrayList;
+import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.io.IOException;
import org.apache.tools.ant.taskdefs.PreSetDef;
@@ -621,4 +623,45 @@ public class UnknownElement extends Task {
private static boolean equalsString(String a, String b) {
return (a == null) ? (b == null) : a.equals(b);
}
+
+ /**
+ * Make a copy of the unknown element and set it in the new project.
+ * @param newProject the project to create the UE in.
+ * @return the copied UE.
+ */
+ public UnknownElement copy(Project newProject) {
+ UnknownElement ret = new UnknownElement(getTag());
+ ret.setNamespace(getNamespace());
+ ret.setProject(newProject);
+ ret.setQName(getQName());
+ ret.setTaskType(getTaskType());
+ ret.setTaskName(getTaskName());
+ ret.setLocation(getLocation());
+ if (getOwningTarget() == null) {
+ Target t = new Target();
+ t.setProject(getProject());
+ ret.setOwningTarget(t);
+ } else {
+ ret.setOwningTarget(getOwningTarget());
+ }
+ RuntimeConfigurable copyRC = new RuntimeConfigurable(
+ ret, getTaskName());
+ copyRC.setPolyType(getWrapper().getPolyType());
+ Map m = getWrapper().getAttributeMap();
+ for (Iterator i = m.entrySet().iterator(); i.hasNext();) {
+ Map.Entry entry = (Map.Entry) i.next();
+ copyRC.setAttribute(
+ (String) entry.getKey(), (String) entry.getValue());
+ }
+ copyRC.addText(getWrapper().getText().toString());
+
+ for (Enumeration e = getWrapper().getChildren(); e.hasMoreElements();) {
+ RuntimeConfigurable r = (RuntimeConfigurable) e.nextElement();
+ UnknownElement ueChild = (UnknownElement) r.getProxy();
+ UnknownElement copyChild = ueChild.copy(newProject);
+ copyRC.addChild(copyChild.getWrapper());
+ ret.addChild(copyChild);
+ }
+ return ret;
+ }
}
diff --git a/src/main/org/apache/tools/ant/helper/AntXMLContext.java b/src/main/org/apache/tools/ant/helper/AntXMLContext.java
index f8faaabe4..dc2d40497 100644
--- a/src/main/org/apache/tools/ant/helper/AntXMLContext.java
+++ b/src/main/org/apache/tools/ant/helper/AntXMLContext.java
@@ -268,7 +268,7 @@ public class AntXMLContext {
public void configureId(Object element, Attributes attr) {
String id = attr.getValue("id");
if (id != null) {
- project.addReference(id, element);
+ project.addIdReference(id, element);
}
}
diff --git a/src/main/org/apache/tools/ant/helper/ProjectHelper2.java b/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
index 2f1efd428..74101a614 100644
--- a/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
+++ b/src/main/org/apache/tools/ant/helper/ProjectHelper2.java
@@ -1015,6 +1015,8 @@ public class ProjectHelper2 extends ProjectHelper {
context.getCurrentTarget().addTask(task);
}
+ context.configureId(task, attrs);
+
// container.addTask(task);
// This is a nop in UE: task.init();
diff --git a/src/main/org/apache/tools/ant/taskdefs/Ant.java b/src/main/org/apache/tools/ant/taskdefs/Ant.java
index b0ecc7d07..2eaa9db7e 100644
--- a/src/main/org/apache/tools/ant/taskdefs/Ant.java
+++ b/src/main/org/apache/tools/ant/taskdefs/Ant.java
@@ -491,6 +491,7 @@ public class Ant extends Task {
continue;
}
copyReference(key, key);
+ newProject.inheritIDReferences(getProject());
}
}
}
diff --git a/src/tests/antunit/types/defer-reference-test.xml b/src/tests/antunit/types/defer-reference-test.xml
index 5a87e3e6e..2c546df74 100644
--- a/src/tests/antunit/types/defer-reference-test.xml
+++ b/src/tests/antunit/types/defer-reference-test.xml
@@ -5,10 +5,10 @@
-
-
-
+
+ ${_output2}
+