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