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 other another definition | ||||
* @param project the project the definition | * @param project the project the definition | ||||
@@ -345,6 +345,69 @@ public class AntTypeDefinition { | |||||
if (!(other.getTypeClass(project).equals(getTypeClass(project)))) { | if (!(other.getTypeClass(project).equals(getTypeClass(project)))) { | ||||
return false; | 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)) { | if (sameDefinition(def, old)) { | ||||
return; | return; | ||||
} | } | ||||
int logLevel = Project.MSG_WARN; | |||||
if (def.similarDefinition(old, project)) { | |||||
logLevel = Project.MSG_VERBOSE; | |||||
} | |||||
Class oldClass = antTypeTable.getExposedClass(name); | 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); | invalidateCreatedTasks(name); | ||||
} else { | |||||
project.log( | |||||
"Trying to override old definition of datatype " | |||||
+ name, Project.MSG_WARN); | |||||
} | } | ||||
} | } | ||||
project.log(" +Datatype " + name + " " + def.getClassName(), | project.log(" +Datatype " + name + " " + def.getClassName(), | ||||
@@ -530,4 +530,52 @@ public class UnknownElement extends Task { | |||||
} | } | ||||
return false; | 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)) { | if (uri.equals(ProjectHelper.ANT_CORE_URI)) { | ||||
uri = ""; | uri = ""; | ||||
} | } | ||||
if (uri.startsWith("ant:") && !uri.startsWith("antlib:")) { | |||||
if (uri.startsWith("ant:")) { | |||||
throw new BuildException("Attempt to use a reserved URI " + uri); | throw new BuildException("Attempt to use a reserved URI " + uri); | ||||
} | } | ||||
this.uri = uri; | this.uri = uri; | ||||
@@ -102,7 +102,7 @@ public class MacroDef extends Task implements AntlibInterface, TaskContainer { | |||||
if (uri.equals(ProjectHelper.ANT_CORE_URI)) { | if (uri.equals(ProjectHelper.ANT_CORE_URI)) { | ||||
uri = ""; | uri = ""; | ||||
} | } | ||||
if (uri.startsWith("ant:") && !uri.startsWith("antlib:")) { | |||||
if (uri.startsWith("ant:")) { | |||||
throw new BuildException("Attempt to use a reserved URI " + uri); | throw new BuildException("Attempt to use a reserved URI " + uri); | ||||
} | } | ||||
this.uri = uri; | this.uri = uri; | ||||
@@ -283,6 +283,7 @@ public class MacroDef extends Task implements AntlibInterface, TaskContainer { | |||||
public static class Attribute { | public static class Attribute { | ||||
private String name; | private String name; | ||||
private String defaultValue; | private String defaultValue; | ||||
/** | /** | ||||
* The name of the attribute. | * The name of the attribute. | ||||
* | * | ||||
@@ -319,6 +320,35 @@ public class MacroDef extends Task implements AntlibInterface, TaskContainer { | |||||
public String getDefault() { | public String getDefault() { | ||||
return defaultValue; | 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() { | public boolean isOptional() { | ||||
return optional; | 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. | * is given. | ||||
*/ | */ | ||||
private static class MyAntTypeDefinition extends AntTypeDefinition { | private static class MyAntTypeDefinition extends AntTypeDefinition { | ||||
private MacroDef template; | |||||
private MacroDef macroDef; | |||||
/** | /** | ||||
* Creates a new <code>MyAntTypeDefinition</code> instance. | * 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) { | if (o == null) { | ||||
return null; | return null; | ||||
} | } | ||||
((MacroInstance) o).setTemplate(template); | |||||
((MacroInstance) o).setMacroDef(macroDef); | |||||
return o; | return o; | ||||
} | } | ||||
/** | /** | ||||
* Equality method for this definition | * Equality method for this definition | ||||
* This only checks for pointer equality. | |||||
* | * | ||||
* @param other another definition | * @param other another definition | ||||
* @param project the current project | * @param project the current project | ||||
* @return true if the definitions are the same | * @return true if the definitions are the same | ||||
*/ | */ | ||||
public boolean sameDefinition(AntTypeDefinition other, Project project) { | 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 | * @since Ant 1.6 | ||||
*/ | */ | ||||
public class MacroInstance extends Task implements DynamicConfigurator { | public class MacroInstance extends Task implements DynamicConfigurator { | ||||
private MacroDef template; | |||||
private MacroDef macroDef; | |||||
private Map map = new HashMap(); | private Map map = new HashMap(); | ||||
private Map elements = new HashMap(); | private Map elements = new HashMap(); | ||||
private Hashtable localProperties = new Hashtable(); | private Hashtable localProperties = new Hashtable(); | ||||
@@ -88,10 +88,10 @@ public class MacroInstance extends Task implements DynamicConfigurator { | |||||
/** | /** | ||||
* Called from MacroDef.MyAntTypeDefinition#create() | * 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 | * has already been seen | ||||
*/ | */ | ||||
public Object createDynamicElement(String name) throws BuildException { | 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); | throw new BuildException("unsupported element " + name); | ||||
} | } | ||||
if (elements.get(name) != null) { | if (elements.get(name) != null) { | ||||
@@ -130,7 +130,7 @@ public class MacroInstance extends Task implements DynamicConfigurator { | |||||
private List unknownElements = new ArrayList(); | 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 | * @param nestedTask an unknown element | ||||
*/ | */ | ||||
@@ -225,7 +225,7 @@ public class MacroInstance extends Task implements DynamicConfigurator { | |||||
} | } | ||||
private String macroSubs(String s, Map macroMapping) { | private String macroSubs(String s, Map macroMapping) { | ||||
if (template.getAttributeStyle() == MacroDef.AttributeStyle.ANT) { | |||||
if (macroDef.getAttributeStyle() == MacroDef.AttributeStyle.ANT) { | |||||
return macroSubsAnt(s, macroMapping); | return macroSubsAnt(s, macroMapping); | ||||
} else { | } else { | ||||
return macroSubsXPath(s, macroMapping); | return macroSubsXPath(s, macroMapping); | ||||
@@ -259,7 +259,7 @@ public class MacroInstance extends Task implements DynamicConfigurator { | |||||
UnknownElement unknownElement = (UnknownElement) r.getProxy(); | UnknownElement unknownElement = (UnknownElement) r.getProxy(); | ||||
String tag = unknownElement.getTag(); | String tag = unknownElement.getTag(); | ||||
MacroDef.TemplateElement templateElement = | MacroDef.TemplateElement templateElement = | ||||
(MacroDef.TemplateElement) template.getElements().get(tag); | |||||
(MacroDef.TemplateElement) macroDef.getElements().get(tag); | |||||
if (templateElement == null) { | if (templateElement == null) { | ||||
UnknownElement child = copy(unknownElement); | UnknownElement child = copy(unknownElement); | ||||
rc.addChild(child.getWrapper()); | rc.addChild(child.getWrapper()); | ||||
@@ -294,9 +294,9 @@ public class MacroInstance extends Task implements DynamicConfigurator { | |||||
public void execute() { | public void execute() { | ||||
localProperties = new Hashtable(); | localProperties = new Hashtable(); | ||||
Set copyKeys = new HashSet(map.keySet()); | 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 attribute = | ||||
(MacroDef.Attribute) template.getAttributes().get(i); | |||||
(MacroDef.Attribute) macroDef.getAttributes().get(i); | |||||
String value = (String) map.get(attribute.getName()); | String value = (String) map.get(attribute.getName()); | ||||
if (value == null) { | if (value == null) { | ||||
value = attribute.getDefault(); | value = attribute.getDefault(); | ||||
@@ -315,7 +315,7 @@ public class MacroInstance extends Task implements DynamicConfigurator { | |||||
} | } | ||||
// need to set the project on unknown element | // need to set the project on unknown element | ||||
UnknownElement c = copy(template.getNestedTask()); | |||||
UnknownElement c = copy(macroDef.getNestedTask()); | |||||
c.init(); | c.init(); | ||||
c.perform(); | c.perform(); | ||||
} | } | ||||
@@ -99,7 +99,7 @@ public class PreSetDef extends Task implements AntlibInterface, TaskContainer { | |||||
if (uri.equals(ProjectHelper.ANT_CORE_URI)) { | if (uri.equals(ProjectHelper.ANT_CORE_URI)) { | ||||
uri = ""; | uri = ""; | ||||
} | } | ||||
if (uri.startsWith("ant:") && !uri.startsWith("antlib:")) { | |||||
if (uri.startsWith("ant:")) { | |||||
throw new BuildException("Attempt to use a reserved URI " + uri); | throw new BuildException("Attempt to use a reserved URI " + uri); | ||||
} | } | ||||
this.uri = uri; | this.uri = uri; | ||||
@@ -266,14 +266,51 @@ public class PreSetDef extends Task implements AntlibInterface, TaskContainer { | |||||
/** | /** | ||||
* Equality method for this definition | * Equality method for this definition | ||||
* This only checks for pointer equality. | |||||
* | * | ||||
* @param other another definition | * @param other another definition | ||||
* @param project the current project | * @param project the current project | ||||
* @return true if the definitions are the same | * @return true if the definitions are the same | ||||
*/ | */ | ||||
public boolean sameDefinition(AntTypeDefinition other, Project project) { | 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; | |||||
} | } | ||||
} | } | ||||
} | } |