This is patch 7204 the fourth patch of the antlib + ns enhancement. The issues reported by Stephan will need be addressed, so the implementation may change before ant 1.6 is released. PR: 19897 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274930 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -9,23 +9,43 @@ | |||
| <h2><a name="typedef">Typedef</a></h2> | |||
| <h3>Description</h3> | |||
| <p>Adds a data type definition to the current project, such that this | |||
| new type can be used in the current project. Two attributes are | |||
| needed, the name that identifies this data type uniquely, and the full | |||
| name of the class (including the packages) that implements this | |||
| type.</p> | |||
| <p>You can also define a group of data types at once using the file or | |||
| resource attributes. These attributes point to files in the format of | |||
| Java property files. Each line defines a single data type in the | |||
| format:</p> | |||
| <pre> | |||
| typename=fully.qualified.java.classname | |||
| </pre> | |||
| <p>Typedef should be used to add your own tasks and types to the system. Data | |||
| types are things like <a href="../using.html#path">paths</a> or <a | |||
| href="../CoreTypes/fileset.html">filesets</a> that can be defined at | |||
| the project level and referenced via their ID attribute.</p> | |||
| <p>Custom data types usually need custom tasks to put them to good use.</p> | |||
| <p> | |||
| Adds a task or a data type definition to the current project | |||
| such that this new type or task can be used in the current project. | |||
| </p> | |||
| <p> | |||
| Tasks are any class that extend org.apache.tools.ant.Task or | |||
| a class that is adapted to a Task using an adapter class. | |||
| </p> | |||
| <p> | |||
| Data types are things like <a href="../using.html#path">paths</a> or | |||
| <a href="../CoreTypes/fileset.html">filesets</a> that can be defined at | |||
| the project level and referenced via their ID attribute. | |||
| Custom data types usually need custom tasks to put them to good use. | |||
| </p> | |||
| <p> | |||
| Two attributes are needed to make a definition, | |||
| the name that identifies this data type uniquely, and the full | |||
| name of the class (including the packages) that implements this | |||
| type. | |||
| </p> | |||
| <p> | |||
| You can also define a group of definitions at once using the file or | |||
| resource attributes. These attributes point to files in the format of | |||
| Java property files or an xml format. | |||
| </p> | |||
| <p> | |||
| For property files each line defines a single data type in the | |||
| format:</p> | |||
| <pre> | |||
| typename=fully.qualified.java.classname | |||
| </pre> | |||
| <p> | |||
| The xml format is described below in the <a href="#antlib">Antlib</a> | |||
| section. | |||
| </p> | |||
| <h3>Parameters</h3> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| @@ -55,6 +75,19 @@ the project level and referenced via their ID attribute.</p> | |||
| <td valign="top">Name of the resouce to load definitions from.</td> | |||
| <td valign="top" align="center">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">format</td> | |||
| <td valign="top">The format of the file or resource. The values | |||
| are "properties" or "xml". If the value is "properties" the file/resource | |||
| is a property file contains name to classname pairs. If the value | |||
| is "xml", the file/resource is an xml file/resource structured according | |||
| to <a href="#antlib">Antlib</a>. | |||
| The default is "properties" unless the file/resorce name ends with | |||
| ".xml", in which case the format attribute will have the value "xml". | |||
| (introduced in ant1.6) | |||
| </td> | |||
| <td valign="top" align="center">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">classpath</td> <td valign="top">the classpath to | |||
| use when looking up <code>classname</code>.</td> <td | |||
| @@ -102,15 +135,51 @@ the project level and referenced via their ID attribute.</p> | |||
| <td valign="top" align="center">No</td> | |||
| </tr> | |||
| </table> | |||
| <h3>Parameters specified as nested elements</h3> | |||
| <h4>classpath</h4> | |||
| <p><code>Typedef</code>'s <i>classpath</i> attribute is a | |||
| <a href="../using.html#path">PATH like structure</a> and can also be set | |||
| via a nested <i>classpath</i> element.</p> | |||
| <h3>Parameters specified as nested elements</h3> | |||
| <h4>classpath</h4> | |||
| <p><code>Typedef</code>'s <i>classpath</i> attribute is a | |||
| <a href="../using.html#path">PATH like structure</a> and can also be set | |||
| via a nested <i>classpath</i> element.</p> | |||
| <h3>Examples</h3> | |||
| <pre> <typedef name="urlset" classname="com.mydomain.URLSet"/></pre> | |||
| <p>makes a data type called <code>urlset</code> available to Ant. The | |||
| class <code>com.mydomain.URLSet</code> implements this type.</p> | |||
| The following fragment defines define a type called <i>urlset</i>. | |||
| <pre> | |||
| <typedef name="urlset" classname="com.mydomain.URLSet"/> </pre> | |||
| The data type is now availabe to Ant. The | |||
| class <code>com.mydomain.URLSet</code> implements this type.</p> | |||
| <p> | |||
| Assuming a class <i>org.acme.ant.RunnableAdapter</i> that | |||
| extends Task and implements <i>org.apache.tools.ant.TypeAdapter</i>, | |||
| and in the execute method invokes <i>run</i> on the proxied object, | |||
| one may use a Runnable class as an Ant task. The following fragment | |||
| defines a task called <i>runclock</i>. | |||
| <pre> | |||
| <typedef name="runclock" | |||
| classname="com.acme.ant.RunClock" | |||
| adapter="org.acme.ant.RunnableAdapter"/> | |||
| </pre> | |||
| <h3><a name="antlib">Antlib xml format</a></h3> | |||
| An antlib file is an xml file with a root element of "antlib". | |||
| Antlib is actually a <a href="sequential.html">Sequential</a> task with | |||
| special treatment for tasks that are ant definition tasks - like typedef | |||
| and <a href="taskdef.html">Taskdef</a>. | |||
| A group of tasks and types may be defined together in an antlib | |||
| file. For example the file <i>sample.xml</i> contains the following: | |||
| <pre> | |||
| <?xml version="1.0"?> | |||
| <antlib> | |||
| <typedef name="if" classname="org.acme.ant.If"/> | |||
| <typedef name="scriptpathmapper" | |||
| classname="org.acme.ant.ScriptPathMapper" | |||
| onerror="ignore"/> | |||
| </antlib> | |||
| </pre> | |||
| It defines two types or tasks, <i>if</i> and <i>scriptpathmapper</i>. | |||
| This antlib file may be used in a build script as follows: | |||
| <pre> | |||
| <typedef file="sample.xml"/> | |||
| </pre> | |||
| <hr> | |||
| <p align="center">Copyright © 2001-2003 Apache Software | |||
| @@ -0,0 +1,17 @@ | |||
| <?xml version="1.0"?> | |||
| <project name="test"> | |||
| <property name="testcases.dir" location="../../../../build/testcases"/> | |||
| <path id="testclasses"> | |||
| <pathelement location="${testcases.dir}" /> | |||
| <pathelement path="${java.class.path}" /> | |||
| </path> | |||
| <target name="antlib.file"> | |||
| <typedef file="test.antlib.xml" | |||
| classpathref="testclasses"/> | |||
| <mytask/> | |||
| </target> | |||
| </project> | |||
| @@ -0,0 +1,6 @@ | |||
| <?xml version="1.0"?> | |||
| <antlib> | |||
| <typedef | |||
| name="mytask" onerror="ignore" | |||
| classname="org.apache.tools.ant.taskdefs.AntlibTest$MyTask"/> | |||
| </antlib> | |||
| @@ -57,8 +57,10 @@ package org.apache.tools.ant.helper; | |||
| import java.io.File; | |||
| import java.io.FileInputStream; | |||
| import java.io.FileNotFoundException; | |||
| import java.io.InputStream; | |||
| import java.io.IOException; | |||
| import java.io.UnsupportedEncodingException; | |||
| import java.net.URL; | |||
| import java.util.Hashtable; | |||
| import java.util.Stack; | |||
| @@ -75,6 +77,7 @@ import org.apache.tools.ant.util.FileUtils; | |||
| import org.apache.tools.ant.ProjectHelper; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.Target; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.RuntimeConfigurable; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Location; | |||
| @@ -102,6 +105,31 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| */ | |||
| private static FileUtils fu = FileUtils.newFileUtils(); | |||
| /** | |||
| * Parse an unknown element from a url | |||
| * | |||
| * @param project the current project | |||
| * @param source the url containing the task | |||
| * @return a configured task | |||
| * @exception BuildException if an error occurs | |||
| */ | |||
| public UnknownElement parseUnknownElement(Project project, URL source) | |||
| throws BuildException { | |||
| Target dummyTarget = new Target(); | |||
| dummyTarget.setProject(project); | |||
| AntXMLContext context = new AntXMLContext(project); | |||
| context.addTarget(dummyTarget); | |||
| context.setImplicitTarget(dummyTarget); | |||
| parse(context.getProject(), source, | |||
| new RootHandler(context, elementHandler)); | |||
| Task[] tasks = dummyTarget.getTasks(); | |||
| if (tasks.length != 1) { | |||
| throw new BuildException("No tasks defined"); | |||
| } | |||
| return (UnknownElement) tasks[0]; | |||
| } | |||
| /** | |||
| * Parse a source xml input. | |||
| * | |||
| @@ -127,11 +155,11 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| // we are in an imported file. | |||
| context.setIgnoreProjectTag(true); | |||
| context.getCurrentTarget().startImportedTasks(); | |||
| parse(project, source, new RootHandler(context)); | |||
| parse(project, source, new RootHandler(context, mainHandler)); | |||
| context.getCurrentTarget().endImportedTasks(); | |||
| } else { | |||
| // top level file | |||
| parse(project, source, new RootHandler(context)); | |||
| parse(project, source, new RootHandler(context, mainHandler)); | |||
| // Execute the top-level target | |||
| context.getImplicitTarget().execute(); | |||
| } | |||
| @@ -152,22 +180,33 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| AntXMLContext context = handler.context; | |||
| File buildFile = null; | |||
| URL url = null; | |||
| String buildFileName = null; | |||
| if (source instanceof File) { | |||
| buildFile = (File) source; | |||
| // } else if (source instanceof InputStream) { | |||
| // } else if (source instanceof URL) { | |||
| // } else if (source instanceof InputSource) { | |||
| buildFile = new File(buildFile.getAbsolutePath()); | |||
| context.setBuildFile(buildFile); | |||
| buildFileName = buildFile.toString(); | |||
| // } else if (source instanceof InputStream ) { | |||
| } else if (source instanceof URL) { | |||
| if (handler.getCurrentAntHandler() != elementHandler) { | |||
| throw new BuildException( | |||
| "Source " + source.getClass().getName() | |||
| + " not supported by this plugin for " | |||
| + " non task xml"); | |||
| } | |||
| url = (URL) source; | |||
| buildFileName = url.toString(); | |||
| // } else if (source instanceof InputSource ) { | |||
| } else { | |||
| throw new BuildException("Source " + source.getClass().getName() | |||
| + " not supported by this plugin"); | |||
| + " not supported by this plugin"); | |||
| } | |||
| FileInputStream inputStream = null; | |||
| InputStream inputStream = null; | |||
| InputSource inputSource = null; | |||
| buildFile = new File(buildFile.getAbsolutePath()); | |||
| context.setBuildFile(buildFile); | |||
| try { | |||
| /** | |||
| @@ -175,13 +214,21 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| */ | |||
| XMLReader parser = JAXPUtils.getNamespaceXMLReader(); | |||
| String uri = fu.toURI(buildFile.getAbsolutePath()); | |||
| String uri = null; | |||
| if (buildFile != null) { | |||
| uri = fu.toURI(buildFile.getAbsolutePath()); | |||
| inputStream = new FileInputStream(buildFile); | |||
| } else { | |||
| inputStream = url.openStream(); | |||
| uri = url.toString(); // ?? OK ?? | |||
| } | |||
| inputStream = new FileInputStream(buildFile); | |||
| inputSource = new InputSource(inputStream); | |||
| inputSource.setSystemId(uri); | |||
| project.log("parsing buildfile " + buildFile | |||
| + " with URI = " + uri, Project.MSG_VERBOSE); | |||
| if (uri != null) { | |||
| inputSource.setSystemId(uri); | |||
| } | |||
| project.log("parsing buildfile " + buildFileName | |||
| + "with URI = " + uri, Project.MSG_VERBOSE); | |||
| DefaultHandler hb = handler; | |||
| @@ -357,13 +404,22 @@ public class ProjectHelper2 extends ProjectHelper { | |||
| * Creates a new RootHandler instance. | |||
| * | |||
| * @param context The context for the handler. | |||
| * @param rootHandler The handler for the root element. | |||
| */ | |||
| public RootHandler(AntXMLContext context) { | |||
| currentHandler = ProjectHelper2.mainHandler; | |||
| public RootHandler(AntXMLContext context, AntHandler rootHandler) { | |||
| currentHandler = rootHandler; | |||
| antHandlers.push(currentHandler); | |||
| this.context = context; | |||
| } | |||
| /** | |||
| * Returns the current ant handler object. | |||
| * @return the current ant handler. | |||
| */ | |||
| public AntHandler getCurrentAntHandler() { | |||
| return currentHandler; | |||
| } | |||
| /** | |||
| * Resolves file: URIs relative to the build file. | |||
| * | |||
| @@ -0,0 +1,190 @@ | |||
| /* | |||
| * 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; | |||
| import java.io.IOException; | |||
| import java.net.URL; | |||
| import java.util.ArrayList; | |||
| import java.util.Iterator; | |||
| import java.util.List; | |||
| import org.apache.tools.ant.TaskContainer; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Location; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.Target; | |||
| import org.apache.tools.ant.helper.ProjectHelper2; | |||
| import org.apache.tools.ant.UnknownElement; | |||
| /** | |||
| * Antlib task. | |||
| * | |||
| * @author Peter Reilly | |||
| * | |||
| * @since Ant 1.6 | |||
| */ | |||
| public class Antlib extends Task implements TaskContainer { | |||
| // | |||
| // Static | |||
| // | |||
| /** The name of this task */ | |||
| public static final String TAG = "antlib"; | |||
| /** | |||
| * Static method to read an ant lib definition from | |||
| * a url. | |||
| * | |||
| * @param project the current project | |||
| * @param antlibUrl the url to read the definitions from | |||
| * @return the ant lib task | |||
| */ | |||
| public static Antlib createAntlib(Project project, URL antlibUrl) { | |||
| // Check if we can contact the URL | |||
| try { | |||
| antlibUrl.openConnection().connect(); | |||
| } catch (IOException ex) { | |||
| throw new BuildException( | |||
| "Unable to find " + antlibUrl, ex); | |||
| } | |||
| // Should be safe to parse | |||
| try { | |||
| ProjectHelper2 parser = new ProjectHelper2(); | |||
| UnknownElement ue = | |||
| parser.parseUnknownElement(project, antlibUrl); | |||
| // Check name is "antlib" | |||
| if (!(ue.getTag().equals(TAG))) { | |||
| throw new BuildException( | |||
| "Unexpected tag " + ue.getTag() + " expecting " + | |||
| TAG, ue.getLocation()); | |||
| } | |||
| Antlib antlib = new Antlib(); | |||
| antlib.setProject(project); | |||
| antlib.setLocation(ue.getLocation()); | |||
| antlib.init(); | |||
| ue.configure(antlib); | |||
| return antlib; | |||
| } catch (BuildException ex) { | |||
| Location location = ex.getLocation(); | |||
| if (location == null) { | |||
| throw ex; | |||
| } | |||
| throw new BuildException( | |||
| "Error in " | |||
| + System.getProperty("line.separator") | |||
| + location.toString() | |||
| + " " + ex.getMessage()); | |||
| } | |||
| } | |||
| // | |||
| // Instance | |||
| // | |||
| private ClassLoader classLoader; | |||
| private String prefix; | |||
| private List tasks = new ArrayList(); | |||
| /** | |||
| * Set the class loader for this antlib. | |||
| * This class loader is used for any tasks that | |||
| * derive from Definer. | |||
| * | |||
| * @param classLoader the class loader | |||
| */ | |||
| protected void setClassLoader(ClassLoader classLoader) { | |||
| this.classLoader = classLoader; | |||
| } | |||
| private ClassLoader getClassLoader() { | |||
| if (classLoader == null) { | |||
| classLoader = Antlib.class.getClassLoader(); | |||
| } | |||
| return classLoader; | |||
| } | |||
| /** | |||
| * add a task to the list of tasks | |||
| * | |||
| * @param nestedTask Nested task to execute in antlibe | |||
| */ | |||
| public void addTask(Task nestedTask) { | |||
| tasks.add(nestedTask); | |||
| } | |||
| /** | |||
| * Execute the nested tasks, setting the classloader for | |||
| * any tasks that derive from Definer. | |||
| */ | |||
| public void execute() { | |||
| for (Iterator i = tasks.iterator(); i.hasNext();) { | |||
| UnknownElement ue = (UnknownElement) i.next(); | |||
| ue.maybeConfigure(); | |||
| Task t = ue.getTask(); | |||
| if (t == null) { | |||
| continue; | |||
| } | |||
| if (t instanceof Definer) { | |||
| Definer d = (Definer) t; | |||
| d.setInternalClassLoader(getClassLoader()); | |||
| } | |||
| t.init(); | |||
| t.execute(); | |||
| } | |||
| } | |||
| } | |||
| @@ -59,12 +59,14 @@ import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.net.URL; | |||
| import java.util.Enumeration; | |||
| import java.util.Locale; | |||
| import java.util.Properties; | |||
| import org.apache.tools.ant.AntTypeDefinition; | |||
| import org.apache.tools.ant.AntClassLoader; | |||
| import org.apache.tools.ant.ComponentHelper; | |||
| import org.apache.tools.ant.BuildException; | |||
| import org.apache.tools.ant.Location; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.Task; | |||
| import org.apache.tools.ant.types.Path; | |||
| @@ -88,6 +90,7 @@ public abstract class Definer extends Task { | |||
| private String resource; | |||
| private ClasspathUtils.Delegate cpDelegate; | |||
| private int format = Format.PROPERTIES; | |||
| private boolean definerSet = false; | |||
| private ClassLoader internalClassLoader; | |||
| private int onError = OnError.FAIL; | |||
| @@ -129,6 +132,24 @@ public abstract class Definer extends Task { | |||
| } | |||
| } | |||
| /** | |||
| * Enumerated type for format attribute | |||
| * | |||
| * @see EnumeratedAttribute | |||
| */ | |||
| public static class Format extends EnumeratedAttribute { | |||
| /** Enumerated values */ | |||
| public static final int PROPERTIES = 0, XML = 1; | |||
| /** | |||
| * get the values | |||
| * @return an array of the allowed values for this attribute. | |||
| */ | |||
| public String[] getValues() { | |||
| return new String[] {"properties", "xml"}; | |||
| } | |||
| } | |||
| /** | |||
| * What to do if there is an error in loading the class. | |||
| * <dl> | |||
| @@ -143,6 +164,14 @@ public abstract class Definer extends Task { | |||
| this.onError = onError.getIndex(); | |||
| } | |||
| /** | |||
| * Sets the format of the file or resource | |||
| * @param format the enumerated value - xml or properties | |||
| */ | |||
| public void setFormat(Format format) { | |||
| this.format = format.getIndex(); | |||
| } | |||
| /** | |||
| * @param reverseLoader if true a delegated loader will take precedence over | |||
| * the parent | |||
| @@ -289,7 +318,15 @@ public abstract class Definer extends Task { | |||
| return; | |||
| } | |||
| loadProperties(al, url); | |||
| if (url.toString().toLowerCase(Locale.US).endsWith(".xml")) { | |||
| format = Format.XML; | |||
| } | |||
| if (format == Format.PROPERTIES) { | |||
| loadProperties(al, url); | |||
| } else { | |||
| loadAntlib(al, url); | |||
| } | |||
| } | |||
| } | |||
| @@ -359,6 +396,30 @@ public abstract class Definer extends Task { | |||
| } | |||
| } | |||
| /** | |||
| * Load an antlib from a url. | |||
| * | |||
| * @param classLoader the classloader to use. | |||
| * @param url the url to load the definitions from. | |||
| */ | |||
| private void loadAntlib(ClassLoader classLoader, URL url) { | |||
| try { | |||
| Antlib antlib = Antlib.createAntlib(getProject(), url); | |||
| antlib.setClassLoader(classLoader); | |||
| antlib.perform(); | |||
| } catch (BuildException ex) { | |||
| Location location = ex.getLocation(); | |||
| if (location == null) { | |||
| throw ex; | |||
| } | |||
| throw new BuildException( | |||
| "Error in " | |||
| + System.getProperty("line.separator") | |||
| + getLocation().toString() | |||
| + " " + ex.getMessage()); | |||
| } | |||
| } | |||
| /** | |||
| * create a classloader for this definition | |||
| * @return the classloader from the cpDelegate | |||
| @@ -543,7 +604,7 @@ public abstract class Definer extends Task { | |||
| } catch (NoClassDefFoundError ncdfe) { | |||
| String msg = getTaskName() + " A class needed by class " | |||
| + classname + " cannot be found: " + ncdfe.getMessage(); | |||
| throw new BuildException(msg, ncdfe, location); | |||
| throw new BuildException(msg, ncdfe, getLocation()); | |||
| } | |||
| } catch (BuildException ex) { | |||
| switch (onError) { | |||
| @@ -0,0 +1,84 @@ | |||
| /* | |||
| * 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; | |||
| import org.apache.tools.ant.BuildFileTest; | |||
| import org.apache.tools.ant.Project; | |||
| import org.apache.tools.ant.Task; | |||
| /** | |||
| * @author Peter Reilly | |||
| */ | |||
| public class AntlibTest extends BuildFileTest { | |||
| public AntlibTest(String name) { | |||
| super(name); | |||
| } | |||
| public void setUp() { | |||
| configureProject("src/etc/testcases/taskdefs/antlib.xml"); | |||
| } | |||
| public void testAntlibFile() { | |||
| expectLog("antlib.file", "MyTask called"); | |||
| } | |||
| public static class MyTask extends Task { | |||
| public void execute() { | |||
| log("MyTask called"); | |||
| } | |||
| } | |||
| } | |||