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; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||