git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@908035 13f79535-47bb-0310-9956-ffa450edef68master
@@ -7,9 +7,18 @@ Changes that could break older environments: | |||
Fixed bugs: | |||
----------- | |||
* Tasks that iterate over task or type definitions, references or | |||
targets now iterate over copies instead of the live maps to avoid | |||
ConcurrentModificationExceptions if another thread changes the | |||
maps. | |||
Bugzilla Report 48310. | |||
Other changes: | |||
-------------- | |||
* Project provides new get methods that return copies instead of the | |||
live maps of task and type definitions, references and targets. | |||
Changes from Ant 1.8.0RC1 TO Ant 1.8.0 | |||
====================================== | |||
@@ -425,10 +425,10 @@ public class Project implements ResourceFactory { | |||
} | |||
/** | |||
* Return a copy of the list of build listeners for the project. | |||
* | |||
* @return a list of build listeners for the project | |||
*/ | |||
* Return a copy of the list of build listeners for the project. | |||
* | |||
* @return a list of build listeners for the project | |||
*/ | |||
public Vector getBuildListeners() { | |||
synchronized (listenersLock) { | |||
Vector r = new Vector(listeners.length); | |||
@@ -1024,6 +1024,19 @@ public class Project implements ResourceFactory { | |||
return ComponentHelper.getComponentHelper(this).getTaskDefinitions(); | |||
} | |||
/** | |||
* Return the current task definition map. The returned map is a | |||
* copy of the "live" definitions. | |||
* | |||
* @return a map of from task name to implementing class | |||
* (String to Class). | |||
* | |||
* @since Ant 1.8.1 | |||
*/ | |||
public Map getCopyOfTaskDefinitions() { | |||
return new HashMap(getTaskDefinitions()); | |||
} | |||
/** | |||
* Add a new datatype definition. | |||
* Attempting to override an existing definition with an | |||
@@ -1053,6 +1066,19 @@ public class Project implements ResourceFactory { | |||
return ComponentHelper.getComponentHelper(this).getDataTypeDefinitions(); | |||
} | |||
/** | |||
* Return the current datatype definition map. The returned | |||
* map is a copy pf the "live" definitions. | |||
* | |||
* @return a map of from datatype name to implementing class | |||
* (String to Class). | |||
* | |||
* @since Ant 1.8.1 | |||
*/ | |||
public Map getCopyOfDataTypeDefinitions() { | |||
return new HashMap(getDataTypeDefinitions()); | |||
} | |||
/** | |||
* Add a <em>new</em> target to the project. | |||
* | |||
@@ -1123,6 +1149,16 @@ public class Project implements ResourceFactory { | |||
return targets; | |||
} | |||
/** | |||
* Return the map of targets. The returned map | |||
* is a copy of the "live" targets. | |||
* @return a map from name to target (String to Target). | |||
* @since Ant 1.8.1 | |||
*/ | |||
public Map getCopyOfTargets() { | |||
return new HashMap(targets); | |||
} | |||
/** | |||
* Create a new instance of a task, adding it to a list of | |||
* created tasks for later invalidation. This causes all tasks | |||
@@ -1970,6 +2006,19 @@ public class Project implements ResourceFactory { | |||
return references.containsKey(key); | |||
} | |||
/** | |||
* Return a map of the references in the project (String to | |||
* Object). The returned hashtable is a copy of the | |||
* "live" references. | |||
* | |||
* @return a map of the references in the project (String to Object). | |||
* | |||
* @since Ant 1.8.1 | |||
*/ | |||
public Map getCopyOfReferences() { | |||
return new HashMap(references); | |||
} | |||
/** | |||
* Look up a reference by its key (ID). | |||
* | |||
@@ -27,6 +27,7 @@ import java.io.PrintWriter; | |||
import java.io.UnsupportedEncodingException; | |||
import java.util.Enumeration; | |||
import java.util.Hashtable; | |||
import java.util.Iterator; | |||
import java.util.Vector; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.IntrospectionHelper; | |||
@@ -95,22 +96,24 @@ public class AntStructure extends Task { | |||
} | |||
printer.printHead(out, getProject(), | |||
getProject().getTaskDefinitions(), | |||
getProject().getDataTypeDefinitions()); | |||
new Hashtable(getProject().getTaskDefinitions()), | |||
new Hashtable(getProject().getDataTypeDefinitions())); | |||
printer.printTargetDecl(out); | |||
Enumeration dataTypes = getProject().getDataTypeDefinitions().keys(); | |||
while (dataTypes.hasMoreElements()) { | |||
String typeName = (String) dataTypes.nextElement(); | |||
Iterator dataTypes = getProject().getCopyOfDataTypeDefinitions() | |||
.keySet().iterator(); | |||
while (dataTypes.hasNext()) { | |||
String typeName = (String) dataTypes.next(); | |||
printer.printElementDecl( | |||
out, getProject(), typeName, | |||
(Class) getProject().getDataTypeDefinitions().get(typeName)); | |||
} | |||
Enumeration tasks = getProject().getTaskDefinitions().keys(); | |||
while (tasks.hasMoreElements()) { | |||
String tName = (String) tasks.nextElement(); | |||
Iterator tasks = getProject().getCopyOfTaskDefinitions().keySet() | |||
.iterator(); | |||
while (tasks.hasNext()) { | |||
String tName = (String) tasks.next(); | |||
printer.printElementDecl(out, getProject(), tName, | |||
(Class) getProject().getTaskDefinitions().get(tName)); | |||
} | |||
@@ -306,8 +306,8 @@ public abstract class ScriptRunnerBase { | |||
project = component.getProject(); | |||
addBeans(project.getProperties()); | |||
addBeans(project.getUserProperties()); | |||
addBeans(project.getTargets()); | |||
addBeans(project.getReferences()); | |||
addBeans(project.getCopyOfTargets()); | |||
addBeans(project.getCopyOfReferences()); | |||
addBean("project", project); | |||
addBean("self", component); | |||
} | |||