used to check if a new definition overriding a previous definition is actually the same definition via a ant or antcall command * remove pointless check for antlib: in setUri git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@275106 13f79535-47bb-0310-9956-ffa450edef68master
@@ -329,7 +329,7 @@ public class AntTypeDefinition { | |||
} | |||
/** | |||
* Equality method for this definition | |||
* Equality method for this definition (assumes the names are the same) | |||
* | |||
* @param other another definition | |||
* @param project the project the definition | |||
@@ -345,6 +345,69 @@ public class AntTypeDefinition { | |||
if (!(other.getTypeClass(project).equals(getTypeClass(project)))) { | |||
return false; | |||
} | |||
return other.getExposedClass(project).equals(getExposedClass(project)); | |||
if (!other.getExposedClass(project).equals(getExposedClass(project))) { | |||
return false; | |||
} | |||
if (other.adapterClass != adapterClass) { | |||
return false; | |||
} | |||
if (other.adaptToClass != adaptToClass) { | |||
return false; | |||
} | |||
return true; | |||
} | |||
/** | |||
* Similar definition | |||
* used to compare two definitions defined twice with the same | |||
* name and the same types. | |||
* the classloader may be different but have the same | |||
* path so #sameDefinition cannot | |||
* be used. | |||
* @param other the definition to compare to | |||
* @param project the current project | |||
* @return true if the definitions are the same | |||
*/ | |||
public boolean similarDefinition(AntTypeDefinition other, Project project) { | |||
if (other == null) { | |||
return false; | |||
} | |||
if (getClass() != other.getClass()) { | |||
return false; | |||
} | |||
if (!getClassName().equals(other.getClassName())) { | |||
return false; | |||
} | |||
if (!extractClassname(adapterClass).equals( | |||
extractClassname(other.adapterClass))) { | |||
return false; | |||
} | |||
if (!extractClassname(adaptToClass).equals( | |||
extractClassname(other.adaptToClass))) { | |||
return false; | |||
} | |||
// all the names are the same: check if the class path of the loader | |||
// is the same | |||
ClassLoader oldLoader = other.getClassLoader(); | |||
ClassLoader newLoader = this.getClassLoader(); | |||
if (oldLoader != null | |||
&& newLoader != null | |||
&& oldLoader instanceof AntClassLoader | |||
&& newLoader instanceof AntClassLoader | |||
&& ((AntClassLoader) oldLoader).getClasspath() | |||
.equals(((AntClassLoader) newLoader).getClasspath()) | |||
) { | |||
return true; | |||
} else { | |||
return false; | |||
} | |||
} | |||
private String extractClassname(Class c) { | |||
if (c == null) { | |||
return "<null>"; | |||
} else { | |||
return c.getClass().getName(); | |||
} | |||
} | |||
} |
@@ -670,21 +670,19 @@ public class ComponentHelper { | |||
if (sameDefinition(def, old)) { | |||
return; | |||
} | |||
int logLevel = Project.MSG_WARN; | |||
if (def.similarDefinition(old, project)) { | |||
logLevel = Project.MSG_VERBOSE; | |||
} | |||
Class oldClass = antTypeTable.getExposedClass(name); | |||
if (oldClass != null && Task.class.isAssignableFrom(oldClass)) { | |||
int logLevel = Project.MSG_WARN; | |||
if (def.getClassName().equals(old.getClassName()) | |||
&& def.getClassLoader() == old.getClassLoader()) { | |||
logLevel = Project.MSG_VERBOSE; | |||
} | |||
project.log( | |||
"Trying to override old definition of task " | |||
+ name, logLevel); | |||
boolean isTask = | |||
(oldClass != null && Task.class.isAssignableFrom(oldClass)); | |||
project.log( | |||
"Trying to override old definition of " | |||
+ (isTask ? "task" : "datatype") | |||
+ " " + name, logLevel); | |||
if (isTask) { | |||
invalidateCreatedTasks(name); | |||
} else { | |||
project.log( | |||
"Trying to override old definition of datatype " | |||
+ name, Project.MSG_WARN); | |||
} | |||
} | |||
project.log(" +Datatype " + name + " " + def.getClassName(), | |||
@@ -530,4 +530,52 @@ public class UnknownElement extends Task { | |||
} | |||
return false; | |||
} | |||
/** | |||
* like contents equals, but ignores project | |||
* @param obj the object to check against | |||
* @return true if this unknownelement has the same contents the other | |||
*/ | |||
public boolean similar(Object obj) { | |||
if (obj == null) { | |||
return false; | |||
} | |||
if (!getClass().getName().equals(obj.getClass().getName())) { | |||
return false; | |||
} | |||
UnknownElement other = (UnknownElement) obj; | |||
if (!equalsString(elementName, other.elementName)) { | |||
return false; | |||
} | |||
if (!namespace.equals(other.namespace)) { | |||
return false; | |||
} | |||
if (!qname.equals(other.qname)) { | |||
return false; | |||
} | |||
if (!getWrapper().getAttributeMap().equals( | |||
other.getWrapper().getAttributeMap())) { | |||
return false; | |||
} | |||
if (children == null) { | |||
return other.children == null; | |||
} | |||
if (children.size() != other.children.size()) { | |||
return false; | |||
} | |||
for (int i = 0; i < children.size(); ++i) { | |||
UnknownElement child = (UnknownElement) children.get(i); | |||
if (!child.similar(other.children.get(i))) { | |||
return false; | |||
} | |||
} | |||
return true; | |||
} | |||
private boolean equalsString(String a, String b) { | |||
if (a == null) { | |||
return b == null; | |||
} | |||
return a.equals(b); | |||
} | |||
} |
@@ -93,7 +93,7 @@ public abstract class DefBase extends Task implements AntlibInterface { | |||
if (uri.equals(ProjectHelper.ANT_CORE_URI)) { | |||
uri = ""; | |||
} | |||
if (uri.startsWith("ant:") && !uri.startsWith("antlib:")) { | |||
if (uri.startsWith("ant:")) { | |||
throw new BuildException("Attempt to use a reserved URI " + uri); | |||
} | |||
this.uri = uri; | |||
@@ -102,7 +102,7 @@ public class MacroDef extends Task implements AntlibInterface, TaskContainer { | |||
if (uri.equals(ProjectHelper.ANT_CORE_URI)) { | |||
uri = ""; | |||
} | |||
if (uri.startsWith("ant:") && !uri.startsWith("antlib:")) { | |||
if (uri.startsWith("ant:")) { | |||
throw new BuildException("Attempt to use a reserved URI " + uri); | |||
} | |||
this.uri = uri; | |||
@@ -283,6 +283,7 @@ public class MacroDef extends Task implements AntlibInterface, TaskContainer { | |||
public static class Attribute { | |||
private String name; | |||
private String defaultValue; | |||
/** | |||
* The name of the attribute. | |||
* | |||
@@ -319,6 +320,35 @@ public class MacroDef extends Task implements AntlibInterface, TaskContainer { | |||
public String getDefault() { | |||
return defaultValue; | |||
} | |||
/** | |||
* equality method | |||
* | |||
* @param obj an <code>Object</code> value | |||
* @return a <code>boolean</code> value | |||
*/ | |||
public boolean equals(Object obj) { | |||
if (obj == null) { | |||
return false; | |||
} | |||
if (obj.getClass() != getClass()) { | |||
return false; | |||
} | |||
Attribute other = (Attribute) obj; | |||
if (name == null) { | |||
return other.name == null; | |||
} | |||
if (!name.equals(other.name)) { | |||
return false; | |||
} | |||
if (defaultValue == null) { | |||
return other.defaultValue == null; | |||
} | |||
if (!name.equals(other.defaultValue)) { | |||
return false; | |||
} | |||
return true; | |||
} | |||
} | |||
/** | |||
@@ -364,6 +394,74 @@ public class MacroDef extends Task implements AntlibInterface, TaskContainer { | |||
public boolean isOptional() { | |||
return optional; | |||
} | |||
/** | |||
* equality method | |||
* | |||
* @param obj an <code>Object</code> value | |||
* @return a <code>boolean</code> value | |||
*/ | |||
public boolean equals(Object obj) { | |||
if (obj == null) { | |||
return false; | |||
} | |||
if (obj.getClass() != getClass()) { | |||
return false; | |||
} | |||
TemplateElement other = (TemplateElement) obj; | |||
if (name == null) { | |||
return other.name == null; | |||
} | |||
if (!name.equals(other.name)) { | |||
return false; | |||
} | |||
return optional == other.optional; | |||
} | |||
} | |||
/** | |||
* equality method for macrodef, ignores project and | |||
* runtime info. | |||
* | |||
* @param obj an <code>Object</code> value | |||
* @return a <code>boolean</code> value | |||
*/ | |||
public boolean equals(Object obj) { | |||
if (obj == null) { | |||
return false; | |||
} | |||
if (!obj.getClass().equals(getClass())) { | |||
return false; | |||
} | |||
MacroDef other = (MacroDef) obj; | |||
if (name == null) { | |||
return other.name == null; | |||
} | |||
if (!name.equals(other.name)) { | |||
return false; | |||
} | |||
if (uri == null || uri.equals("") | |||
|| uri.equals(ProjectHelper.ANT_CORE_URI)) { | |||
return other.uri == null || other.uri.equals("") | |||
|| other.uri.equals(ProjectHelper.ANT_CORE_URI); | |||
} | |||
if (!uri.equals(other.uri)) { | |||
return false; | |||
} | |||
if (attributeStyle != other.attributeStyle) { | |||
return false; | |||
} | |||
if (!nestedTask.similar(other.nestedTask)) { | |||
return false; | |||
} | |||
if (!attributes.equals(other.attributes)) { | |||
return false; | |||
} | |||
if (!elements.equals(other.elements)) { | |||
return false; | |||
} | |||
return true; | |||
} | |||
/** | |||
@@ -372,15 +470,15 @@ public class MacroDef extends Task implements AntlibInterface, TaskContainer { | |||
* is given. | |||
*/ | |||
private static class MyAntTypeDefinition extends AntTypeDefinition { | |||
private MacroDef template; | |||
private MacroDef macroDef; | |||
/** | |||
* Creates a new <code>MyAntTypeDefinition</code> instance. | |||
* | |||
* @param template a <code>MacroDef</code> value | |||
* @param macroDef a <code>MacroDef</code> value | |||
*/ | |||
public MyAntTypeDefinition(MacroDef template) { | |||
this.template = template; | |||
public MyAntTypeDefinition(MacroDef macroDef) { | |||
this.macroDef = macroDef; | |||
} | |||
/** | |||
@@ -394,20 +492,39 @@ public class MacroDef extends Task implements AntlibInterface, TaskContainer { | |||
if (o == null) { | |||
return null; | |||
} | |||
((MacroInstance) o).setTemplate(template); | |||
((MacroInstance) o).setMacroDef(macroDef); | |||
return o; | |||
} | |||
/** | |||
* Equality method for this definition | |||
* This only checks for pointer equality. | |||
* | |||
* @param other another definition | |||
* @param project the current project | |||
* @return true if the definitions are the same | |||
*/ | |||
public boolean sameDefinition(AntTypeDefinition other, Project project) { | |||
return this == other; | |||
if (!super.sameDefinition(other, project)) { | |||
return false; | |||
} | |||
MyAntTypeDefinition otherDef = (MyAntTypeDefinition) other; | |||
return macroDef.equals(otherDef.macroDef); | |||
} | |||
/** | |||
* Similiar method for this definition | |||
* | |||
* @param other another definition | |||
* @param project the current project | |||
* @return true if the definitions are the same | |||
*/ | |||
public boolean similarDefinition( | |||
AntTypeDefinition other, Project project) { | |||
if (!super.similarDefinition(other, project)) { | |||
return false; | |||
} | |||
MyAntTypeDefinition otherDef = (MyAntTypeDefinition) other; | |||
return macroDef.equals(otherDef.macroDef); | |||
} | |||
} | |||
} |
@@ -80,7 +80,7 @@ import org.apache.tools.ant.RuntimeConfigurable; | |||
* @since Ant 1.6 | |||
*/ | |||
public class MacroInstance extends Task implements DynamicConfigurator { | |||
private MacroDef template; | |||
private MacroDef macroDef; | |||
private Map map = new HashMap(); | |||
private Map elements = new HashMap(); | |||
private Hashtable localProperties = new Hashtable(); | |||
@@ -88,10 +88,10 @@ public class MacroInstance extends Task implements DynamicConfigurator { | |||
/** | |||
* Called from MacroDef.MyAntTypeDefinition#create() | |||
* | |||
* @param template a <code>MacroDef</code> value | |||
* @param macroDef a <code>MacroDef</code> value | |||
*/ | |||
protected void setTemplate(MacroDef template) { | |||
this.template = template; | |||
protected void setMacroDef(MacroDef macroDef) { | |||
this.macroDef = macroDef; | |||
} | |||
/** | |||
@@ -112,7 +112,7 @@ public class MacroInstance extends Task implements DynamicConfigurator { | |||
* has already been seen | |||
*/ | |||
public Object createDynamicElement(String name) throws BuildException { | |||
if (template.getElements().get(name) == null) { | |||
if (macroDef.getElements().get(name) == null) { | |||
throw new BuildException("unsupported element " + name); | |||
} | |||
if (elements.get(name) != null) { | |||
@@ -130,7 +130,7 @@ public class MacroInstance extends Task implements DynamicConfigurator { | |||
private List unknownElements = new ArrayList(); | |||
/** | |||
* Add an unknown element (to be snipped into the template instance) | |||
* Add an unknown element (to be snipped into the macroDef instance) | |||
* | |||
* @param nestedTask an unknown element | |||
*/ | |||
@@ -225,7 +225,7 @@ public class MacroInstance extends Task implements DynamicConfigurator { | |||
} | |||
private String macroSubs(String s, Map macroMapping) { | |||
if (template.getAttributeStyle() == MacroDef.AttributeStyle.ANT) { | |||
if (macroDef.getAttributeStyle() == MacroDef.AttributeStyle.ANT) { | |||
return macroSubsAnt(s, macroMapping); | |||
} else { | |||
return macroSubsXPath(s, macroMapping); | |||
@@ -259,7 +259,7 @@ public class MacroInstance extends Task implements DynamicConfigurator { | |||
UnknownElement unknownElement = (UnknownElement) r.getProxy(); | |||
String tag = unknownElement.getTag(); | |||
MacroDef.TemplateElement templateElement = | |||
(MacroDef.TemplateElement) template.getElements().get(tag); | |||
(MacroDef.TemplateElement) macroDef.getElements().get(tag); | |||
if (templateElement == null) { | |||
UnknownElement child = copy(unknownElement); | |||
rc.addChild(child.getWrapper()); | |||
@@ -294,9 +294,9 @@ public class MacroInstance extends Task implements DynamicConfigurator { | |||
public void execute() { | |||
localProperties = new Hashtable(); | |||
Set copyKeys = new HashSet(map.keySet()); | |||
for (int i = 0; i < template.getAttributes().size(); ++i) { | |||
for (int i = 0; i < macroDef.getAttributes().size(); ++i) { | |||
MacroDef.Attribute attribute = | |||
(MacroDef.Attribute) template.getAttributes().get(i); | |||
(MacroDef.Attribute) macroDef.getAttributes().get(i); | |||
String value = (String) map.get(attribute.getName()); | |||
if (value == null) { | |||
value = attribute.getDefault(); | |||
@@ -315,7 +315,7 @@ public class MacroInstance extends Task implements DynamicConfigurator { | |||
} | |||
// need to set the project on unknown element | |||
UnknownElement c = copy(template.getNestedTask()); | |||
UnknownElement c = copy(macroDef.getNestedTask()); | |||
c.init(); | |||
c.perform(); | |||
} | |||
@@ -99,7 +99,7 @@ public class PreSetDef extends Task implements AntlibInterface, TaskContainer { | |||
if (uri.equals(ProjectHelper.ANT_CORE_URI)) { | |||
uri = ""; | |||
} | |||
if (uri.startsWith("ant:") && !uri.startsWith("antlib:")) { | |||
if (uri.startsWith("ant:")) { | |||
throw new BuildException("Attempt to use a reserved URI " + uri); | |||
} | |||
this.uri = uri; | |||
@@ -266,14 +266,51 @@ public class PreSetDef extends Task implements AntlibInterface, TaskContainer { | |||
/** | |||
* Equality method for this definition | |||
* This only checks for pointer equality. | |||
* | |||
* @param other another definition | |||
* @param project the current project | |||
* @return true if the definitions are the same | |||
*/ | |||
public boolean sameDefinition(AntTypeDefinition other, Project project) { | |||
return this == other; | |||
if (other == null) { | |||
return false; | |||
} | |||
if (other.getClass() != getClass()) { | |||
return false; | |||
} | |||
MyAntTypeDefinition otherDef = (MyAntTypeDefinition) other; | |||
if (!parent.sameDefinition(otherDef.parent, project)) { | |||
return false; | |||
} | |||
if (!element.similar(otherDef.element)) { | |||
return false; | |||
} | |||
return true; | |||
} | |||
/** | |||
* Similiar method for this definition | |||
* | |||
* @param other another definition | |||
* @param project the current project | |||
* @return true if the definitions are the same | |||
*/ | |||
public boolean similarDefinition( | |||
AntTypeDefinition other, Project project) { | |||
if (other == null) { | |||
return false; | |||
} | |||
if (!other.getClass().getName().equals(getClass().getName())) { | |||
return false; | |||
} | |||
MyAntTypeDefinition otherDef = (MyAntTypeDefinition) other; | |||
if (!parent.similarDefinition(otherDef.parent, project)) { | |||
return false; | |||
} | |||
if (!element.similar(otherDef.element)) { | |||
return false; | |||
} | |||
return true; | |||
} | |||
} | |||
} |