Also split Definer.java in a base class (DefBase) to allow it to be used for other defining tasks Also add AntlibInterface to allow antlib to set uri and classloader for other tasks/types that Definer. Bugzilla: 19897 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@275064 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -58,14 +58,19 @@ import org.apache.tools.ant.util.WeakishReference; | |||||
| import java.util.Enumeration; | import java.util.Enumeration; | ||||
| import java.util.Hashtable; | import java.util.Hashtable; | ||||
| import java.util.HashSet; | |||||
| import java.util.Iterator; | import java.util.Iterator; | ||||
| import java.util.Properties; | import java.util.Properties; | ||||
| import java.util.Set; | |||||
| import java.util.Stack; | |||||
| import java.util.Vector; | import java.util.Vector; | ||||
| import java.io.InputStream; | import java.io.InputStream; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.lang.reflect.Modifier; | import java.lang.reflect.Modifier; | ||||
| import org.apache.tools.ant.taskdefs.Typedef; | |||||
| /** | /** | ||||
| * Component creation and configuration. | * Component creation and configuration. | ||||
| * | * | ||||
| @@ -98,6 +103,17 @@ public class ComponentHelper { | |||||
| /** flag to rebuild typeClassDefinitions */ | /** flag to rebuild typeClassDefinitions */ | ||||
| private boolean rebuildTypeClassDefinitions = true; | private boolean rebuildTypeClassDefinitions = true; | ||||
| /** Set of namespaces that have been checked for antlibs */ | |||||
| private Set checkedNamespaces = new HashSet(); | |||||
| /** | |||||
| * Stack of antlib contexts used to resolve definitions while | |||||
| * processing antlib | |||||
| */ | |||||
| private Stack antLibStack = new Stack(); | |||||
| /** current antlib context */ | |||||
| private AntTypeTable antLibTypeTable = null; | |||||
| /** | /** | ||||
| * Map from task names to vectors of created tasks | * Map from task names to vectors of created tasks | ||||
| * (String to Vector of Task). This is used to invalidate tasks if | * (String to Vector of Task). This is used to invalidate tasks if | ||||
| @@ -175,32 +191,38 @@ public class ComponentHelper { | |||||
| AntTypeDefinition def = (AntTypeDefinition) i.next(); | AntTypeDefinition def = (AntTypeDefinition) i.next(); | ||||
| antTypeTable.put(def.getName(), def); | antTypeTable.put(def.getName(), def); | ||||
| } | } | ||||
| // add the parsed namespaces of the parent project | |||||
| checkedNamespaces.add(helper.checkedNamespaces); | |||||
| } | } | ||||
| /** Factory method to create the components. | /** Factory method to create the components. | ||||
| * | * | ||||
| * This should be called by UnknownElement. | * This should be called by UnknownElement. | ||||
| * | * | ||||
| * @param ue The component helper has access via ue to the entire XML tree. | |||||
| * @param ns Namespace. Also available as ue.getNamespace() | |||||
| * @param taskName The element name. Also available as ue.getTag() | |||||
| * @param ue The Unknown Element creating this component | |||||
| * @param ns Namespace URI. Also available as ue.getNamespace() | |||||
| * @param componentType The component type, | |||||
| * Also available as ue.getComponentName() | |||||
| * @return the created component | * @return the created component | ||||
| * @throws BuildException if an error occuries | * @throws BuildException if an error occuries | ||||
| */ | */ | ||||
| public Object createComponent(UnknownElement ue, | public Object createComponent(UnknownElement ue, | ||||
| String ns, | String ns, | ||||
| String taskName) | |||||
| String componentType) | |||||
| throws BuildException { | throws BuildException { | ||||
| Object component = createComponent(taskName); | |||||
| Object component = createComponent(componentType); | |||||
| if (component == null) { | if (component == null) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| if (component instanceof Task) { | if (component instanceof Task) { | ||||
| Task task = (Task) component; | Task task = (Task) component; | ||||
| task.setTaskType(taskName); | |||||
| task.setTaskName(taskName); | |||||
| addCreatedTask(taskName, task); | |||||
| task.setLocation(ue.getLocation()); | |||||
| task.setTaskType(componentType); | |||||
| task.setTaskName(ue.getTaskName()); | |||||
| task.setOwningTarget(ue.getOwningTarget()); | |||||
| task.init(); | |||||
| addCreatedTask(componentType, task); | |||||
| } | } | ||||
| return component; | return component; | ||||
| @@ -215,7 +237,11 @@ public class ComponentHelper { | |||||
| * @return the class if found or null if not. | * @return the class if found or null if not. | ||||
| */ | */ | ||||
| public Object createComponent(String componentName) { | public Object createComponent(String componentName) { | ||||
| return antTypeTable.create(componentName); | |||||
| AntTypeDefinition def = getDefinition(componentName); | |||||
| if (def == null) { | |||||
| return null; | |||||
| } | |||||
| return def.create(project); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -227,7 +253,11 @@ public class ComponentHelper { | |||||
| * @return the class if found or null if not. | * @return the class if found or null if not. | ||||
| */ | */ | ||||
| public Class getComponentClass(String componentName) { | public Class getComponentClass(String componentName) { | ||||
| return antTypeTable.getExposedClass(componentName); | |||||
| AntTypeDefinition def = getDefinition(componentName); | |||||
| if (def == null) { | |||||
| return null; | |||||
| } | |||||
| return def.getExposedClass(project); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -236,7 +266,15 @@ public class ComponentHelper { | |||||
| * @return the ant definition or null if not present | * @return the ant definition or null if not present | ||||
| */ | */ | ||||
| public AntTypeDefinition getDefinition(String componentName) { | public AntTypeDefinition getDefinition(String componentName) { | ||||
| return antTypeTable.getDefinition(componentName); | |||||
| checkNamespace(componentName); | |||||
| AntTypeDefinition ret = null; | |||||
| if (antLibTypeTable != null && componentName.indexOf(':') == -1) { | |||||
| ret = antLibTypeTable.getDefinition(componentName); | |||||
| } | |||||
| if (ret == null) { | |||||
| ret = antTypeTable.getDefinition(componentName); | |||||
| } | |||||
| return ret; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -474,7 +512,7 @@ public class ComponentHelper { | |||||
| * creation fails. | * creation fails. | ||||
| */ | */ | ||||
| private Task createNewTask(String taskType) throws BuildException { | private Task createNewTask(String taskType) throws BuildException { | ||||
| Class c = antTypeTable.getExposedClass(taskType); | |||||
| Class c = getComponentClass(taskType); | |||||
| if (c == null) { | if (c == null) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| @@ -482,7 +520,7 @@ public class ComponentHelper { | |||||
| if (!(Task.class.isAssignableFrom(c))) { | if (!(Task.class.isAssignableFrom(c))) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| Task task = (Task) antTypeTable.create(taskType); | |||||
| Task task = (Task) createComponent(taskType); | |||||
| if (task == null) { | if (task == null) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| @@ -557,7 +595,7 @@ public class ComponentHelper { | |||||
| * instance creation fails. | * instance creation fails. | ||||
| */ | */ | ||||
| public Object createDataType(String typeName) throws BuildException { | public Object createDataType(String typeName) throws BuildException { | ||||
| return antTypeTable.create(typeName); | |||||
| return createComponent(typeName); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -660,6 +698,31 @@ public class ComponentHelper { | |||||
| project.log(" +Datatype " + name + " " + def.getClassName(), | project.log(" +Datatype " + name + " " + def.getClassName(), | ||||
| Project.MSG_DEBUG); | Project.MSG_DEBUG); | ||||
| antTypeTable.put(name, def); | antTypeTable.put(name, def); | ||||
| if (antLibTypeTable != null && name.lastIndexOf(':') != -1) { | |||||
| String baseName = name.substring(name.lastIndexOf(':') + 1); | |||||
| antLibTypeTable.put(baseName, def); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Called at the start of processing an antlib | |||||
| */ | |||||
| public void enterAntLib() { | |||||
| antLibTypeTable = new AntTypeTable(project); | |||||
| antLibStack.push(antLibTypeTable); | |||||
| } | |||||
| /** | |||||
| * Called at the end of processing an antlib | |||||
| */ | |||||
| public void exitAntLib() { | |||||
| antLibStack.pop(); | |||||
| if (antLibStack.size() != 0) { | |||||
| antLibTypeTable = (AntTypeTable) antLibStack.peek(); | |||||
| } else { | |||||
| antLibTypeTable = null; | |||||
| } | } | ||||
| } | } | ||||
| @@ -751,6 +814,35 @@ public class ComponentHelper { | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * called for each component name, check if the | |||||
| * associated URI has been examined for antlibs. | |||||
| */ | |||||
| private void checkNamespace(String componentName) { | |||||
| if (componentName.indexOf(':') == -1) { | |||||
| return; // not a namespaced name | |||||
| } | |||||
| String uri = ProjectHelper.extractUriFromComponentName(componentName); | |||||
| if (!uri.startsWith(ProjectHelper.ANTLIB_URI)) { | |||||
| return; // namespace that does not contain antlib | |||||
| } | |||||
| if (checkedNamespaces.contains(uri)) { | |||||
| return; // Alreay processed | |||||
| } | |||||
| checkedNamespaces.add(uri); | |||||
| Typedef definer = new Typedef(); | |||||
| definer.setProject(project); | |||||
| definer.setURI(uri); | |||||
| definer.setResource( | |||||
| uri.substring("antlib:".length()).replace('.', '/') | |||||
| + "/antlib.xml"); | |||||
| // a fishing expedition :- ignore errors if antlib not present | |||||
| definer.setOnError(new Typedef.OnError("ignore")); | |||||
| definer.init(); | |||||
| definer.execute(); | |||||
| } | |||||
| /** | /** | ||||
| * map that contains the component definitions | * map that contains the component definitions | ||||
| */ | */ | ||||
| @@ -85,6 +85,12 @@ import org.xml.sax.AttributeList; | |||||
| * @author duncan@x180.com | * @author duncan@x180.com | ||||
| */ | */ | ||||
| public class ProjectHelper { | public class ProjectHelper { | ||||
| /** The URI for ant name space */ | |||||
| public static final String ANT_CORE_URI = "ant:core"; | |||||
| /** The URI for defined types/tasks - the format is antlib:<package> */ | |||||
| public static final String ANTLIB_URI = "antlib:"; | |||||
| /** | /** | ||||
| * Name of JVM system property which provides the name of the | * Name of JVM system property which provides the name of the | ||||
| * ProjectHelper class to use. | * ProjectHelper class to use. | ||||
| @@ -493,5 +499,34 @@ public class ProjectHelper { | |||||
| PropertyHelper.parsePropertyStringDefault(value, fragments, | PropertyHelper.parsePropertyStringDefault(value, fragments, | ||||
| propertyRefs); | propertyRefs); | ||||
| } | } | ||||
| /** | |||||
| * Map a namespaced {uri,name} to an internal string format. | |||||
| * For BC purposes the names from the ant core uri will be | |||||
| * mapped to "name", other names will be mapped to | |||||
| * uri + ":" + name. | |||||
| * @param uri The namepace URI | |||||
| * @param name The localname | |||||
| * @return The stringified form of the ns name | |||||
| */ | |||||
| public static String genComponentName(String uri, String name) { | |||||
| if (uri == null || uri.equals("") || uri.equals(ANT_CORE_URI)) { | |||||
| return name; | |||||
| } | |||||
| return uri + ":" + name; | |||||
| } | |||||
| /** | |||||
| * extract a uri from a component name | |||||
| * | |||||
| * @param componentName The stringified form for {uri, name} | |||||
| * @return The uri or "" if not present | |||||
| */ | |||||
| public static String extractUriFromComponentName(String componentName) { | |||||
| int index = componentName.lastIndexOf(':'); | |||||
| if (index == -1) { | |||||
| return ""; | |||||
| } | |||||
| return componentName.substring(0, index); | |||||
| } | |||||
| //end class | //end class | ||||
| } | } | ||||
| @@ -176,6 +176,14 @@ public class RuntimeConfigurable implements Serializable { | |||||
| return polyType; | return polyType; | ||||
| } | } | ||||
| /** | |||||
| * set the polymorphic type for this element | |||||
| * @param polyType the ant component type name, null if not set | |||||
| */ | |||||
| public void setPolyType(String polyType) { | |||||
| this.polyType = polyType; | |||||
| } | |||||
| /** | /** | ||||
| * Sets the attributes for the wrapped element. | * Sets the attributes for the wrapped element. | ||||
| * | * | ||||
| @@ -260,10 +268,10 @@ public class RuntimeConfigurable implements Serializable { | |||||
| /** | /** | ||||
| * Returns an enumeration of all child wrappers. | * Returns an enumeration of all child wrappers. | ||||
| * | |||||
| * @return an enumeration of the child wrappers. | |||||
| * @since Ant 1.5.1 | * @since Ant 1.5.1 | ||||
| */ | */ | ||||
| Enumeration getChildren() { | |||||
| public Enumeration getChildren() { | |||||
| if (children != null) { | if (children != null) { | ||||
| return Collections.enumeration(children); | return Collections.enumeration(children); | ||||
| } else { | } else { | ||||
| @@ -81,6 +81,11 @@ public class UnknownElement extends Task { | |||||
| */ | */ | ||||
| private String namespace; | private String namespace; | ||||
| /** | |||||
| * Holds the namespace qname of the element. | |||||
| */ | |||||
| private String qname; | |||||
| /** | /** | ||||
| * The real object after it has been loaded. | * The real object after it has been loaded. | ||||
| */ | */ | ||||
| @@ -129,6 +134,24 @@ public class UnknownElement extends Task { | |||||
| this.namespace = namespace; | this.namespace = namespace; | ||||
| } | } | ||||
| /** Return the qname of the XML element associated with this component. | |||||
| * | |||||
| * @return namespace Qname used in the element declaration. | |||||
| */ | |||||
| public String getQName() { | |||||
| return qname; | |||||
| } | |||||
| /** Set the namespace qname of the XML element. | |||||
| * This method is typically called by the XML processor. | |||||
| * | |||||
| * @param qname the qualified name of the element | |||||
| */ | |||||
| public void setQName(String qname) { | |||||
| this.qname = qname; | |||||
| } | |||||
| /** | /** | ||||
| * Get the RuntimeConfigurable instance for this UnknownElement, containing | * Get the RuntimeConfigurable instance for this UnknownElement, containing | ||||
| * the configuration information. | * the configuration information. | ||||
| @@ -334,6 +357,13 @@ public class UnknownElement extends Task { | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * @return the component name - uses ProjectHelper#genComponentName() | |||||
| */ | |||||
| protected String getComponentName() { | |||||
| return ProjectHelper.genComponentName(getNamespace(), getTag()); | |||||
| } | |||||
| /** | /** | ||||
| * Creates a named task or data type. If the real object is a task, | * Creates a named task or data type. If the real object is a task, | ||||
| * it is configured up to the init() stage. | * it is configured up to the init() stage. | ||||
| @@ -345,12 +375,17 @@ public class UnknownElement extends Task { | |||||
| * @return the task or data type represented by the given unknown element. | * @return the task or data type represented by the given unknown element. | ||||
| */ | */ | ||||
| protected Object makeObject(UnknownElement ue, RuntimeConfigurable w) { | protected Object makeObject(UnknownElement ue, RuntimeConfigurable w) { | ||||
| Object o = makeTask(ue, w); | |||||
| ComponentHelper helper = ComponentHelper.getComponentHelper( | |||||
| getProject()); | |||||
| String name = ue.getComponentName(); | |||||
| Object o = helper.createComponent(ue, ue.getNamespace(), name); | |||||
| if (o == null) { | if (o == null) { | ||||
| o = getProject().createDataType(ue.getTag()); | |||||
| throw getNotFoundException("task or type", name); | |||||
| } | } | ||||
| if (o == null) { | |||||
| throw getNotFoundException("task or type", ue.getTag()); | |||||
| if (o instanceof Task) { | |||||
| Task task = (Task) o; | |||||
| task.setOwningTarget(getOwningTarget()); | |||||
| task.init(); | |||||
| } | } | ||||
| return o; | return o; | ||||
| } | } | ||||
| @@ -54,6 +54,10 @@ | |||||
| package org.apache.tools.ant.helper; | package org.apache.tools.ant.helper; | ||||
| import java.io.File; | import java.io.File; | ||||
| import java.util.ArrayList; | |||||
| import java.util.HashMap; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| import java.util.Vector; | import java.util.Vector; | ||||
| import org.xml.sax.Locator; | import org.xml.sax.Locator; | ||||
| @@ -120,6 +124,11 @@ public class AntXMLContext { | |||||
| * when processing a particular build file. | * when processing a particular build file. | ||||
| */ | */ | ||||
| private boolean ignoreProjectTag = false; | private boolean ignoreProjectTag = false; | ||||
| /** Keeps track of prefix -> uri mapping during parsing */ | |||||
| private Map prefixMapping = new HashMap(); | |||||
| /** | /** | ||||
| * constructor | * constructor | ||||
| * @param project the project to which this antxml context belongs to | * @param project the project to which this antxml context belongs to | ||||
| @@ -263,7 +272,7 @@ public class AntXMLContext { | |||||
| /** | /** | ||||
| * sets the implicit target | * sets the implicit target | ||||
| * @param target | |||||
| * @param target the implicit target | |||||
| */ | */ | ||||
| public void setImplicitTarget(Target target) { | public void setImplicitTarget(Target target) { | ||||
| this.implicitTarget = target; | this.implicitTarget = target; | ||||
| @@ -284,6 +293,8 @@ public class AntXMLContext { | |||||
| * <p> | * <p> | ||||
| * This method was moved out of the configure method to allow | * This method was moved out of the configure method to allow | ||||
| * it to be executed at parse time. | * it to be executed at parse time. | ||||
| * @param element the current element | |||||
| * @param attr attributes of the current element | |||||
| */ | */ | ||||
| public void configureId(Object element, Attributes attr) { | public void configureId(Object element, Attributes attr) { | ||||
| String id = attr.getValue("id"); | String id = attr.getValue("id"); | ||||
| @@ -323,6 +334,48 @@ public class AntXMLContext { | |||||
| public void setIgnoreProjectTag(boolean flag) { | public void setIgnoreProjectTag(boolean flag) { | ||||
| this.ignoreProjectTag = flag; | this.ignoreProjectTag = flag; | ||||
| } | } | ||||
| /** | |||||
| * Called during parsing, stores the prefix to uri mapping. | |||||
| * | |||||
| * @param prefix a namespace prefix | |||||
| * @param uri a namespace uri | |||||
| */ | |||||
| public void startPrefixMapping(String prefix, String uri) { | |||||
| List list = (List) prefixMapping.get(prefix); | |||||
| if (list == null) { | |||||
| list = new ArrayList(); | |||||
| prefixMapping.put(prefix, list); | |||||
| } | |||||
| list.add(uri); | |||||
| } | |||||
| /** | |||||
| * End of prefix to uri mapping. | |||||
| * | |||||
| * @param prefix the namespace prefix | |||||
| */ | |||||
| public void endPrefixMapping(String prefix) { | |||||
| List list = (List) prefixMapping.get(prefix); | |||||
| if (list == null || list.size() == 0) { | |||||
| return; // Should not happen | |||||
| } | |||||
| list.remove(list.size() - 1); | |||||
| } | |||||
| /** | |||||
| * prefix to namespace uri mapping | |||||
| * | |||||
| * @param prefix the prefix to map | |||||
| * @return the uri for this prefix, null if not present | |||||
| */ | |||||
| public String getPrefixMapping(String prefix) { | |||||
| List list = (List) prefixMapping.get(prefix); | |||||
| if (list == null || list.size() == 0) { | |||||
| return null; | |||||
| } | |||||
| return (String) list.get(list.size() - 1); | |||||
| } | |||||
| } | } | ||||
| @@ -474,6 +474,9 @@ public class ProjectHelper2 extends ProjectHelper { | |||||
| */ | */ | ||||
| public void startElement(String uri, String tag, String qname, Attributes attrs) | public void startElement(String uri, String tag, String qname, Attributes attrs) | ||||
| throws SAXParseException { | throws SAXParseException { | ||||
| if (uri.equals(ANT_CORE_URI)) { | |||||
| uri = ""; | |||||
| } | |||||
| AntHandler next | AntHandler next | ||||
| = currentHandler.onStartChild(uri, tag, qname, attrs, context); | = currentHandler.onStartChild(uri, tag, qname, attrs, context); | ||||
| antHandlers.push(currentHandler); | antHandlers.push(currentHandler); | ||||
| @@ -506,6 +509,9 @@ public class ProjectHelper2 extends ProjectHelper { | |||||
| * | * | ||||
| */ | */ | ||||
| public void endElement(String uri, String name, String qName) throws SAXException { | public void endElement(String uri, String name, String qName) throws SAXException { | ||||
| if (uri.equals(ANT_CORE_URI)) { | |||||
| uri = ""; | |||||
| } | |||||
| currentHandler.onEndElement(uri, name, context); | currentHandler.onEndElement(uri, name, context); | ||||
| AntHandler prev = (AntHandler) antHandlers.pop(); | AntHandler prev = (AntHandler) antHandlers.pop(); | ||||
| currentHandler = prev; | currentHandler = prev; | ||||
| @@ -526,6 +532,25 @@ public class ProjectHelper2 extends ProjectHelper { | |||||
| throws SAXParseException { | throws SAXParseException { | ||||
| currentHandler.characters(buf, start, count, context); | currentHandler.characters(buf, start, count, context); | ||||
| } | } | ||||
| /** | |||||
| * Start a namespace prefix to uri mapping | |||||
| * | |||||
| * @param prefix the namespace prefix | |||||
| * @param uri the namespace uri | |||||
| */ | |||||
| public void startPrefixMapping(String prefix, String uri) { | |||||
| context.startPrefixMapping(prefix, uri); | |||||
| } | |||||
| /** | |||||
| * End a namepace prefix to uri mapping | |||||
| * | |||||
| * @param prefix the prefix that is not mapped anymore | |||||
| */ | |||||
| public void endPrefixMapping(String prefix) { | |||||
| context.endPrefixMapping(prefix); | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -550,7 +575,7 @@ public class ProjectHelper2 extends ProjectHelper { | |||||
| Attributes attrs, | Attributes attrs, | ||||
| AntXMLContext context) | AntXMLContext context) | ||||
| throws SAXParseException { | throws SAXParseException { | ||||
| if (qname.equals("project")) { | |||||
| if (name.equals("project") && uri.equals("")) { | |||||
| return ProjectHelper2.projectHandler; | return ProjectHelper2.projectHandler; | ||||
| } else { | } else { | ||||
| // if (context.importlevel > 0) { | // if (context.importlevel > 0) { | ||||
| @@ -610,7 +635,7 @@ public class ProjectHelper2 extends ProjectHelper { | |||||
| */ | */ | ||||
| for (int i = 0; i < attrs.getLength(); i++) { | for (int i = 0; i < attrs.getLength(); i++) { | ||||
| String key = attrs.getQName(i); | |||||
| String key = attrs.getLocalName(i); | |||||
| String value = attrs.getValue(i); | String value = attrs.getValue(i); | ||||
| if (key.equals("default")) { | if (key.equals("default")) { | ||||
| @@ -715,7 +740,7 @@ public class ProjectHelper2 extends ProjectHelper { | |||||
| Attributes attrs, | Attributes attrs, | ||||
| AntXMLContext context) | AntXMLContext context) | ||||
| throws SAXParseException { | throws SAXParseException { | ||||
| if (qname.equals("target")) { | |||||
| if (name.equals("target") && uri.equals("")) { | |||||
| return ProjectHelper2.targetHandler; | return ProjectHelper2.targetHandler; | ||||
| } else { | } else { | ||||
| return ProjectHelper2.elementHandler; | return ProjectHelper2.elementHandler; | ||||
| @@ -761,7 +786,7 @@ public class ProjectHelper2 extends ProjectHelper { | |||||
| context.addTarget(target); | context.addTarget(target); | ||||
| for (int i = 0; i < attrs.getLength(); i++) { | for (int i = 0; i < attrs.getLength(); i++) { | ||||
| String key = attrs.getQName(i); | |||||
| String key = attrs.getLocalName(i); | |||||
| String value = attrs.getValue(i); | String value = attrs.getValue(i); | ||||
| if (key.equals("name")) { | if (key.equals("name")) { | ||||
| @@ -904,7 +929,7 @@ public class ProjectHelper2 extends ProjectHelper { | |||||
| task.setNamespace(uri); | task.setNamespace(uri); | ||||
| task.setProject(context.getProject()); | task.setProject(context.getProject()); | ||||
| //XXX task.setTaskType(qname); | //XXX task.setTaskType(qname); | ||||
| task.setQName(qname); | |||||
| task.setTaskName(qname); | task.setTaskName(qname); | ||||
| Location location = new Location(context.getLocator().getSystemId(), | Location location = new Location(context.getLocator().getSystemId(), | ||||
| @@ -930,8 +955,26 @@ public class ProjectHelper2 extends ProjectHelper { | |||||
| = new RuntimeConfigurable(task, task.getTaskName()); | = new RuntimeConfigurable(task, task.getTaskName()); | ||||
| for (int i = 0; i < attrs.getLength(); i++) { | for (int i = 0; i < attrs.getLength(); i++) { | ||||
| wrapper.setAttribute(attrs.getQName(i), | |||||
| attrs.getValue(i)); | |||||
| String name = attrs.getLocalName(i); | |||||
| String value = attrs.getValue(i); | |||||
| // PR: Hack for ant-type value | |||||
| // an ant-type is a component name which can | |||||
| // be namespaced, need to extract the name | |||||
| // and convert from qualifed name to uri/name | |||||
| if (name.equals("ant-type")) { | |||||
| int index = value.indexOf(":"); | |||||
| if (index != -1) { | |||||
| String prefix = value.substring(0, index); | |||||
| String mappedUri = context.getPrefixMapping(prefix); | |||||
| if (mappedUri == null) { | |||||
| throw new BuildException( | |||||
| "Unable to find XML NS prefix " + prefix); | |||||
| } | |||||
| value = ProjectHelper.genComponentName( | |||||
| mappedUri, value.substring(index + 1)); | |||||
| } | |||||
| } | |||||
| wrapper.setAttribute(name, value); | |||||
| } | } | ||||
| if (parentWrapper != null) { | if (parentWrapper != null) { | ||||
| @@ -62,7 +62,7 @@ import java.util.List; | |||||
| import org.apache.tools.ant.TaskContainer; | import org.apache.tools.ant.TaskContainer; | ||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| import org.apache.tools.ant.Location; | |||||
| import org.apache.tools.ant.ComponentHelper; | |||||
| import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
| import org.apache.tools.ant.Task; | import org.apache.tools.ant.Task; | ||||
| import org.apache.tools.ant.helper.ProjectHelper2; | import org.apache.tools.ant.helper.ProjectHelper2; | ||||
| @@ -124,6 +124,7 @@ public class Antlib extends Task implements TaskContainer { | |||||
| // | // | ||||
| private ClassLoader classLoader; | private ClassLoader classLoader; | ||||
| private String prefix; | private String prefix; | ||||
| private String uri = ""; | |||||
| private List tasks = new ArrayList(); | private List tasks = new ArrayList(); | ||||
| /** | /** | ||||
| @@ -137,6 +138,14 @@ public class Antlib extends Task implements TaskContainer { | |||||
| this.classLoader = classLoader; | this.classLoader = classLoader; | ||||
| } | } | ||||
| /** | |||||
| * Set the URI for this antlib. | |||||
| * @param uri the namespace uri | |||||
| */ | |||||
| protected void setURI(String uri) { | |||||
| this.uri = uri; | |||||
| } | |||||
| private ClassLoader getClassLoader() { | private ClassLoader getClassLoader() { | ||||
| if (classLoader == null) { | if (classLoader == null) { | ||||
| classLoader = Antlib.class.getClassLoader(); | classLoader = Antlib.class.getClassLoader(); | ||||
| @@ -158,20 +167,28 @@ public class Antlib extends Task implements TaskContainer { | |||||
| * any tasks that derive from Definer. | * any tasks that derive from Definer. | ||||
| */ | */ | ||||
| public void execute() { | public void execute() { | ||||
| for (Iterator i = tasks.iterator(); i.hasNext();) { | |||||
| UnknownElement ue = (UnknownElement) i.next(); | |||||
| ue.maybeConfigure(); | |||||
| setLocation(ue.getLocation()); | |||||
| Task t = ue.getTask(); | |||||
| if (t == null) { | |||||
| continue; | |||||
| } | |||||
| if (t instanceof Definer) { | |||||
| Definer d = (Definer) t; | |||||
| d.setInternalClassLoader(getClassLoader()); | |||||
| ComponentHelper helper = | |||||
| ComponentHelper.getComponentHelper(getProject()); | |||||
| helper.enterAntLib(); | |||||
| try { | |||||
| for (Iterator i = tasks.iterator(); i.hasNext();) { | |||||
| UnknownElement ue = (UnknownElement) i.next(); | |||||
| ue.maybeConfigure(); | |||||
| setLocation(ue.getLocation()); | |||||
| Task t = ue.getTask(); | |||||
| if (t == null) { | |||||
| continue; | |||||
| } | |||||
| if (t instanceof AntlibInterface) { | |||||
| AntlibInterface d = (AntlibInterface) t; | |||||
| d.setURI(uri); | |||||
| d.setAntlibClassLoader(getClassLoader()); | |||||
| } | |||||
| t.init(); | |||||
| t.execute(); | |||||
| } | } | ||||
| t.init(); | |||||
| t.execute(); | |||||
| } finally { | |||||
| helper.exitAntLib(); | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,81 @@ | |||||
| /* | |||||
| * The Apache Software License, Version 1.1 | |||||
| * | |||||
| * Copyright (c) 2003 The Apache Software Foundation. All rights | |||||
| * reserved. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in | |||||
| * the documentation and/or other materials provided with the | |||||
| * distribution. | |||||
| * | |||||
| * 3. The end-user documentation included with the redistribution, if | |||||
| * any, must include the following acknowlegement: | |||||
| * "This product includes software developed by the | |||||
| * Apache Software Foundation (http://www.apache.org/)." | |||||
| * Alternately, this acknowlegement may appear in the software itself, | |||||
| * if and wherever such third-party acknowlegements normally appear. | |||||
| * | |||||
| * 4. The names "Ant" and "Apache Software | |||||
| * Foundation" must not be used to endorse or promote products derived | |||||
| * from this software without prior written permission. For written | |||||
| * permission, please contact apache@apache.org. | |||||
| * | |||||
| * 5. Products derived from this software may not be called "Apache" | |||||
| * nor may "Apache" appear in their names without prior written | |||||
| * permission of the Apache Group. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * ==================================================================== | |||||
| * | |||||
| * This software consists of voluntary contributions made by many | |||||
| * individuals on behalf of the Apache Software Foundation. For more | |||||
| * information on the Apache Software Foundation, please see | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| package org.apache.tools.ant.taskdefs; | |||||
| /** | |||||
| * Interface for tasks that should be informed when | |||||
| * they are loaded in antlib's. | |||||
| * For handling uri and and class loading. | |||||
| * | |||||
| * @author Peter Reilly | |||||
| * | |||||
| * @since Ant 1.6 | |||||
| */ | |||||
| public interface AntlibInterface { | |||||
| /** | |||||
| * The URI for this definition. | |||||
| * @param uri the namespace URI | |||||
| */ | |||||
| void setURI(String uri); | |||||
| /** | |||||
| * Set the class loader of the loading object | |||||
| * | |||||
| * @param classLoader a <code>ClassLoader</code> value | |||||
| */ | |||||
| void setAntlibClassLoader(ClassLoader classLoader); | |||||
| } | |||||
| @@ -0,0 +1,234 @@ | |||||
| /* | |||||
| * The Apache Software License, Version 1.1 | |||||
| * | |||||
| * Copyright (c) 2001-2003 The Apache Software Foundation. All rights | |||||
| * reserved. | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in | |||||
| * the documentation and/or other materials provided with the | |||||
| * distribution. | |||||
| * | |||||
| * 3. The end-user documentation included with the redistribution, if | |||||
| * any, must include the following acknowlegement: | |||||
| * "This product includes software developed by the | |||||
| * Apache Software Foundation (http://www.apache.org/)." | |||||
| * Alternately, this acknowlegement may appear in the software itself, | |||||
| * if and wherever such third-party acknowlegements normally appear. | |||||
| * | |||||
| * 4. The names "Ant" and "Apache Software | |||||
| * Foundation" must not be used to endorse or promote products derived | |||||
| * from this software without prior written permission. For written | |||||
| * permission, please contact apache@apache.org. | |||||
| * | |||||
| * 5. Products derived from this software may not be called "Apache" | |||||
| * nor may "Apache" appear in their names without prior written | |||||
| * permission of the Apache Group. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| * ==================================================================== | |||||
| * | |||||
| * This software consists of voluntary contributions made by many | |||||
| * individuals on behalf of the Apache Software Foundation. For more | |||||
| * information on the Apache Software Foundation, please see | |||||
| * <http://www.apache.org/>. | |||||
| */ | |||||
| package org.apache.tools.ant.taskdefs; | |||||
| import org.apache.tools.ant.AntClassLoader; | |||||
| import org.apache.tools.ant.BuildException; | |||||
| import org.apache.tools.ant.Project; | |||||
| import org.apache.tools.ant.ProjectHelper; | |||||
| import org.apache.tools.ant.Task; | |||||
| import org.apache.tools.ant.types.Path; | |||||
| import org.apache.tools.ant.types.Reference; | |||||
| import org.apache.tools.ant.util.ClasspathUtils; | |||||
| /** | |||||
| * Base class for Definitions | |||||
| * handling uri and and class loading. | |||||
| * (This was part of Definer) | |||||
| * | |||||
| * @author Costin Manolache | |||||
| * @author Stefan Bodewig | |||||
| * @author Peter Reilly | |||||
| * | |||||
| * @since Ant 1.6 | |||||
| */ | |||||
| public abstract class DefBase extends Task implements AntlibInterface { | |||||
| private String uri = ""; | |||||
| private ClassLoader internalClassLoader; | |||||
| private ClassLoader createdLoader; | |||||
| private ClasspathUtils.Delegate cpDelegate; | |||||
| /** | |||||
| * The URI for this definition. | |||||
| * If the URI is "ant:core", the uri will be set to "". (This | |||||
| * is the default uri). | |||||
| * URIs that start with "ant:" and are not | |||||
| * "ant:core" are reserved and are not allowed in this context. | |||||
| * @param uri the namespace URI | |||||
| * @throws BuildException if a reserved URI is used | |||||
| */ | |||||
| public void setURI(String uri) throws BuildException { | |||||
| if (uri.equals(ProjectHelper.ANT_CORE_URI)) { | |||||
| uri = ""; | |||||
| } | |||||
| if (uri.startsWith("ant:") && !uri.startsWith("antlib:")) { | |||||
| throw new BuildException("Attempt to use use a reserved URI " + uri); | |||||
| } | |||||
| this.uri = uri; | |||||
| } | |||||
| /** | |||||
| * @return the namespace uri for this definition | |||||
| */ | |||||
| public String getUri() { | |||||
| return uri; | |||||
| } | |||||
| /** | |||||
| * Set the class loader, overrides the cpDelagate | |||||
| * classloader. | |||||
| * | |||||
| * @param classLoader a <code>ClassLoader</code> value | |||||
| */ | |||||
| public void setAntlibClassLoader(ClassLoader classLoader) { | |||||
| this.internalClassLoader = classLoader; | |||||
| } | |||||
| /** | |||||
| * @param reverseLoader if true a delegated loader will take precedence over | |||||
| * the parent | |||||
| * @deprecated stop using this attribute | |||||
| * @ant.attribute ignore="true" | |||||
| */ | |||||
| public void setReverseLoader(boolean reverseLoader) { | |||||
| this.cpDelegate.setReverseLoader(reverseLoader); | |||||
| log("The reverseloader attribute is DEPRECATED. It will be removed", | |||||
| Project.MSG_WARN); | |||||
| } | |||||
| /** | |||||
| * @return the class path path for this definition | |||||
| */ | |||||
| public Path getClasspath() { | |||||
| return cpDelegate.getClasspath(); | |||||
| } | |||||
| /** | |||||
| * @return the reverse loader attribute of the classpath delegate. | |||||
| */ | |||||
| public boolean isReverseLoader() { | |||||
| return cpDelegate.isReverseLoader(); | |||||
| } | |||||
| /** | |||||
| * Returns the loader id of the class path Delegate. | |||||
| * @return the loader id | |||||
| */ | |||||
| public String getLoaderId() { | |||||
| return cpDelegate.getClassLoadId(); | |||||
| } | |||||
| /** | |||||
| * Returns the class path id of the class path delegate. | |||||
| * @return the class path id | |||||
| */ | |||||
| public String getClasspathId() { | |||||
| return cpDelegate.getClassLoadId(); | |||||
| } | |||||
| /** | |||||
| * Set the classpath to be used when searching for component being defined | |||||
| * | |||||
| * @param classpath an Ant Path object containing the classpath. | |||||
| */ | |||||
| public void setClasspath(Path classpath) { | |||||
| this.cpDelegate.setClasspath(classpath); | |||||
| } | |||||
| /** | |||||
| * Create the classpath to be used when searching for component being | |||||
| * defined | |||||
| * @return the classpath of the this definition | |||||
| */ | |||||
| public Path createClasspath() { | |||||
| return this.cpDelegate.createClasspath(); | |||||
| } | |||||
| /** | |||||
| * reference to a classpath to use when loading the files. | |||||
| * To actually share the same loader, set loaderref as well | |||||
| * @param r the reference to the classpath | |||||
| */ | |||||
| public void setClasspathRef(Reference r) { | |||||
| this.cpDelegate.setClasspathref(r); | |||||
| } | |||||
| /** | |||||
| * Use the reference to locate the loader. If the loader is not | |||||
| * found, taskdef will use the specified classpath and register it | |||||
| * with the specified name. | |||||
| * | |||||
| * This allow multiple taskdef/typedef to use the same class loader, | |||||
| * so they can be used together. It eliminate the need to | |||||
| * put them in the CLASSPATH. | |||||
| * | |||||
| * @param r the reference to locate the loader. | |||||
| * @since Ant 1.5 | |||||
| */ | |||||
| public void setLoaderRef(Reference r) { | |||||
| this.cpDelegate.setLoaderRef(r); | |||||
| } | |||||
| /** | |||||
| * create a classloader for this definition | |||||
| * @return the classloader from the cpDelegate | |||||
| */ | |||||
| protected ClassLoader createLoader() { | |||||
| if (internalClassLoader != null) { | |||||
| return internalClassLoader; | |||||
| } | |||||
| if (createdLoader == null) { | |||||
| createdLoader = this.cpDelegate.getClassLoader(); | |||||
| // need to load Task via system classloader or the new | |||||
| // task we want to define will never be a Task but always | |||||
| // be wrapped into a TaskAdapter. | |||||
| ((AntClassLoader) createdLoader) | |||||
| .addSystemPackageRoot("org.apache.tools.ant"); | |||||
| } | |||||
| return createdLoader; | |||||
| } | |||||
| /** | |||||
| * @see org.apache.tools.ant.Task#init() | |||||
| * @since Ant 1.6 | |||||
| */ | |||||
| public void init() throws BuildException { | |||||
| this.cpDelegate = ClasspathUtils.getDelegate(this); | |||||
| super.init(); | |||||
| } | |||||
| } | |||||
| @@ -63,32 +63,29 @@ import java.util.Locale; | |||||
| import java.util.Properties; | import java.util.Properties; | ||||
| import org.apache.tools.ant.AntTypeDefinition; | import org.apache.tools.ant.AntTypeDefinition; | ||||
| import org.apache.tools.ant.AntClassLoader; | |||||
| import org.apache.tools.ant.ComponentHelper; | import org.apache.tools.ant.ComponentHelper; | ||||
| import org.apache.tools.ant.BuildException; | import org.apache.tools.ant.BuildException; | ||||
| import org.apache.tools.ant.Location; | import org.apache.tools.ant.Location; | ||||
| import org.apache.tools.ant.Project; | import org.apache.tools.ant.Project; | ||||
| import org.apache.tools.ant.Task; | |||||
| import org.apache.tools.ant.types.Path; | |||||
| import org.apache.tools.ant.types.Reference; | |||||
| import org.apache.tools.ant.util.ClasspathUtils; | |||||
| import org.apache.tools.ant.ProjectHelper; | |||||
| import org.apache.tools.ant.types.EnumeratedAttribute; | import org.apache.tools.ant.types.EnumeratedAttribute; | ||||
| /** | /** | ||||
| * Base class for Taskdef and Typedef - does all the classpath | |||||
| * handling and and class loading. | |||||
| * Base class for Taskdef and Typedef - handles all | |||||
| * the attributes for Typedef. The uri and class | |||||
| * handling is handled by DefBase | |||||
| * | * | ||||
| * @author Costin Manolache | * @author Costin Manolache | ||||
| * @author Stefan Bodewig | * @author Stefan Bodewig | ||||
| * @author Peter Reilly | |||||
| * | * | ||||
| * @since Ant 1.4 | * @since Ant 1.4 | ||||
| */ | */ | ||||
| public abstract class Definer extends Task { | |||||
| public abstract class Definer extends DefBase { | |||||
| private String name; | private String name; | ||||
| private String classname; | private String classname; | ||||
| private File file; | private File file; | ||||
| private String resource; | private String resource; | ||||
| private ClasspathUtils.Delegate cpDelegate; | |||||
| private int format = Format.PROPERTIES; | private int format = Format.PROPERTIES; | ||||
| private boolean definerSet = false; | private boolean definerSet = false; | ||||
| @@ -172,18 +169,6 @@ public abstract class Definer extends Task { | |||||
| this.format = format.getIndex(); | this.format = format.getIndex(); | ||||
| } | } | ||||
| /** | |||||
| * @param reverseLoader if true a delegated loader will take precedence over | |||||
| * the parent | |||||
| * @deprecated stop using this attribute | |||||
| * @ant.attribute ignore="true" | |||||
| */ | |||||
| public void setReverseLoader(boolean reverseLoader) { | |||||
| this.cpDelegate.setReverseLoader(reverseLoader); | |||||
| log("The reverseloader attribute is DEPRECATED. It will be removed", | |||||
| Project.MSG_WARN); | |||||
| } | |||||
| /** | /** | ||||
| * @return the name for this definition | * @return the name for this definition | ||||
| */ | */ | ||||
| @@ -191,13 +176,6 @@ public abstract class Definer extends Task { | |||||
| return name; | return name; | ||||
| } | } | ||||
| /** | |||||
| * @return the class path path for this definition | |||||
| */ | |||||
| public Path getClasspath() { | |||||
| return cpDelegate.getClasspath(); | |||||
| } | |||||
| /** | /** | ||||
| * @return the file containing definitions | * @return the file containing definitions | ||||
| */ | */ | ||||
| @@ -212,72 +190,6 @@ public abstract class Definer extends Task { | |||||
| return resource; | return resource; | ||||
| } | } | ||||
| /** | |||||
| * @return the reverse loader attribute of the classpath delegate. | |||||
| */ | |||||
| public boolean isReverseLoader() { | |||||
| return cpDelegate.isReverseLoader(); | |||||
| } | |||||
| /** | |||||
| * Returns the loader id of the class path Delegate. | |||||
| * @return the loader id | |||||
| */ | |||||
| public String getLoaderId() { | |||||
| return cpDelegate.getClassLoadId(); | |||||
| } | |||||
| /** | |||||
| * Returns the class path id of the class path delegate. | |||||
| * @return the class path id | |||||
| */ | |||||
| public String getClasspathId() { | |||||
| return cpDelegate.getClassLoadId(); | |||||
| } | |||||
| /** | |||||
| * Set the classpath to be used when searching for component being defined | |||||
| * | |||||
| * @param classpath an Ant Path object containing the classpath. | |||||
| */ | |||||
| public void setClasspath(Path classpath) { | |||||
| this.cpDelegate.setClasspath(classpath); | |||||
| } | |||||
| /** | |||||
| * Create the classpath to be used when searching for component being | |||||
| * defined | |||||
| * @return the classpath of the this definition | |||||
| */ | |||||
| public Path createClasspath() { | |||||
| return this.cpDelegate.createClasspath(); | |||||
| } | |||||
| /** | |||||
| * reference to a classpath to use when loading the files. | |||||
| * To actually share the same loader, set loaderref as well | |||||
| * @param r the reference to the classpath | |||||
| */ | |||||
| public void setClasspathRef(Reference r) { | |||||
| this.cpDelegate.setClasspathref(r); | |||||
| } | |||||
| /** | |||||
| * Use the reference to locate the loader. If the loader is not | |||||
| * found, taskdef will use the specified classpath and register it | |||||
| * with the specified name. | |||||
| * | |||||
| * This allow multiple taskdef/typedef to use the same class loader, | |||||
| * so they can be used together. It eliminate the need to | |||||
| * put them in the CLASSPATH. | |||||
| * | |||||
| * @param r the reference to locate the loader. | |||||
| * @since Ant 1.5 | |||||
| */ | |||||
| public void setLoaderRef(Reference r) { | |||||
| this.cpDelegate.setLoaderRef(r); | |||||
| } | |||||
| /** | /** | ||||
| * Run the definition. | * Run the definition. | ||||
| @@ -406,6 +318,7 @@ public abstract class Definer extends Task { | |||||
| try { | try { | ||||
| Antlib antlib = Antlib.createAntlib(getProject(), url); | Antlib antlib = Antlib.createAntlib(getProject(), url); | ||||
| antlib.setClassLoader(classLoader); | antlib.setClassLoader(classLoader); | ||||
| antlib.setURI(getUri()); | |||||
| antlib.perform(); | antlib.perform(); | ||||
| } catch (BuildException ex) { | } catch (BuildException ex) { | ||||
| Location exLocation = ex.getLocation(); | Location exLocation = ex.getLocation(); | ||||
| @@ -420,23 +333,6 @@ public abstract class Definer extends Task { | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * create a classloader for this definition | |||||
| * @return the classloader from the cpDelegate | |||||
| */ | |||||
| protected ClassLoader createLoader() { | |||||
| if (internalClassLoader != null) { | |||||
| return internalClassLoader; | |||||
| } | |||||
| ClassLoader al = this.cpDelegate.getClassLoader(); | |||||
| // need to load Task via system classloader or the new | |||||
| // task we want to define will never be a Task but always | |||||
| // be wrapped into a TaskAdapter. | |||||
| ((AntClassLoader) al).addSystemPackageRoot("org.apache.tools.ant"); | |||||
| return al; | |||||
| } | |||||
| /** | /** | ||||
| * Name of the property file to load | * Name of the property file to load | ||||
| * ant name/classname pairs from. | * ant name/classname pairs from. | ||||
| @@ -474,7 +370,7 @@ public abstract class Definer extends Task { | |||||
| definerSet = true; | definerSet = true; | ||||
| this.name = name; | this.name = name; | ||||
| } | } | ||||
| /** | /** | ||||
| * Returns the classname of the object we are defining. | * Returns the classname of the object we are defining. | ||||
| * May be <code>null</code>. | * May be <code>null</code>. | ||||
| @@ -541,25 +437,6 @@ public abstract class Definer extends Task { | |||||
| } | } | ||||
| /** | |||||
| * Set the class loader, overrides the cpDelagate | |||||
| * classloader. | |||||
| * | |||||
| * @param classLoader a <code>ClassLoader</code> value | |||||
| */ | |||||
| protected void setInternalClassLoader(ClassLoader classLoader) { | |||||
| this.internalClassLoader = classLoader; | |||||
| } | |||||
| /** | |||||
| * @see org.apache.tools.ant.Task#init() | |||||
| * @since Ant 1.6 | |||||
| */ | |||||
| public void init() throws BuildException { | |||||
| this.cpDelegate = ClasspathUtils.getDelegate(this); | |||||
| super.init(); | |||||
| } | |||||
| /** | /** | ||||
| * Add a definition using the attributes of Definer | * Add a definition using the attributes of Definer | ||||
| * | * | ||||
| @@ -573,6 +450,8 @@ public abstract class Definer extends Task { | |||||
| Class cl = null; | Class cl = null; | ||||
| try { | try { | ||||
| try { | try { | ||||
| name = ProjectHelper.genComponentName(getUri(), name); | |||||
| if (onError != OnError.IGNORE) { | if (onError != OnError.IGNORE) { | ||||
| cl = Class.forName(classname, true, al); | cl = Class.forName(classname, true, al); | ||||
| } | } | ||||