git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@465065 13f79535-47bb-0310-9956-ffa450edef68master
@@ -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 | |||
============================================= | |||
@@ -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); | |||
} | |||
/** | |||
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
@@ -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(); | |||
@@ -491,6 +491,7 @@ public class Ant extends Task { | |||
continue; | |||
} | |||
copyReference(key, key); | |||
newProject.inheritIDReferences(getProject()); | |||
} | |||
} | |||
} | |||
@@ -5,10 +5,10 @@ | |||
<target name="test-notcalled"> | |||
<!-- bug 36955 --> | |||
<au:expectfailure> | |||
<pathconvert property="_output2" refid="ref1" | |||
pathsep="${line.separator}" /> | |||
</au:expectfailure> | |||
<pathconvert property="_output2" refid="ref1" | |||
pathsep="${line.separator}" /> | |||
<echo>${_output2}</echo> | |||
<au:assertLogContains text="Future versions of Ant"/> | |||
</target> | |||
<target name="test-macrodef-embedded-ref"> | |||