Return-Path: Delivered-To: apmail-ant-dev-archive@ant.apache.org Received: (qmail 93965 invoked by uid 500); 24 Jul 2003 13:48:47 -0000 Mailing-List: contact dev-help@ant.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Ant Developers List" Reply-To: "Ant Developers List" Delivered-To: mailing list dev@ant.apache.org Received: (qmail 93932 invoked by uid 500); 24 Jul 2003 13:48:46 -0000 Received: (qmail 93916 invoked from network); 24 Jul 2003 13:48:46 -0000 Received: from icarus.apache.org (208.185.179.13) by daedalus.apache.org with SMTP; 24 Jul 2003 13:48:46 -0000 Received: (qmail 85604 invoked by uid 1539); 24 Jul 2003 13:48:46 -0000 Date: 24 Jul 2003 13:48:46 -0000 Message-ID: <20030724134846.85603.qmail@icarus.apache.org> From: peterreilly@apache.org To: ant-cvs@apache.org Subject: cvs commit: ant/src/testcases/org/apache/tools/ant/taskdefs AntlibTest.java X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N peterreilly 2003/07/24 06:48:46 Modified: docs/manual/CoreTasks typedef.html src/main/org/apache/tools/ant/helper ProjectHelper2.java src/main/org/apache/tools/ant/taskdefs Definer.java Added: src/etc/testcases/taskdefs antlib.xml test.antlib.xml src/main/org/apache/tools/ant/taskdefs Antlib.java src/testcases/org/apache/tools/ant/taskdefs AntlibTest.java Log: Add antlib xml functionality 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 Revision Changes Path 1.8 +94 -25 ant/docs/manual/CoreTasks/typedef.html Index: typedef.html =================================================================== RCS file: /home/cvs/ant/docs/manual/CoreTasks/typedef.html,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- typedef.html 26 Jun 2003 08:54:27 -0000 1.7 +++ typedef.html 24 Jul 2003 13:48:45 -0000 1.8 @@ -9,23 +9,43 @@

Typedef

Description

-

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.

-

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:

-
  -typename=fully.qualified.java.classname
  -
-

Typedef should be used to add your own tasks and types to the system. Data -types are things like paths or filesets 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.

+

+ 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. +

+

+ Tasks are any class that extend org.apache.tools.ant.Task or + a class that is adapted to a Task using an adapter class. +

+

+ Data types are things like paths or + filesets 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. +

+

+ 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. +

+

+ 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. +

+

+ For property files each line defines a single data type in the + format:

+
  +    typename=fully.qualified.java.classname
  +  
+ +

+ The xml format is described below in the Antlib + section. +

+

Parameters

@@ -56,6 +76,19 @@ + + + + + @@ -102,15 +135,51 @@
No
formatThe 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 Antlib. + 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) + No
classpath the classpath to use when looking up classname. NoNo
-

Parameters specified as nested elements

-

classpath

-

Typedef's classpath attribute is a -PATH like structure and can also be set -via a nested classpath element.

+

Parameters specified as nested elements

+

classpath

+

Typedef's classpath attribute is a + PATH like structure and can also be set + via a nested classpath element.

+

Examples

-
  <typedef name="urlset" classname="com.mydomain.URLSet"/>
-

makes a data type called urlset available to Ant. The -class com.mydomain.URLSet implements this type.

+ The following fragment defines define a type called urlset. +
  +    <typedef name="urlset" classname="com.mydomain.URLSet"/> 
+ The data type is now availabe to Ant. The + class com.mydomain.URLSet implements this type.

+

+ Assuming a class org.acme.ant.RunnableAdapter that + extends Task and implements org.apache.tools.ant.TypeAdapter, + and in the execute method invokes run on the proxied object, + one may use a Runnable class as an Ant task. The following fragment + defines a task called runclock. +

  +    <typedef name="runclock"
  +             classname="com.acme.ant.RunClock"
  +             adapter="org.acme.ant.RunnableAdapter"/>
  +  
+

Antlib xml format

+ An antlib file is an xml file with a root element of "antlib". + Antlib is actually a Sequential task with + special treatment for tasks that are ant definition tasks - like typedef + and Taskdef. + + A group of tasks and types may be defined together in an antlib + file. For example the file sample.xml contains the following: +
  +    <?xml version="1.0"?>
  +    <antlib>
  +      <typedef name="if" classname="org.acme.ant.If"/>
  +      <typedef name="scriptpathmapper"
  +               classname="org.acme.ant.ScriptPathMapper"
  +               onerror="ignore"/>
  +    </antlib>
  +  
+ It defines two types or tasks, if and scriptpathmapper. + This antlib file may be used in a build script as follows: +
  +      <typedef file="sample.xml"/>
  +    

Copyright © 2001-2003 Apache Software 1.1 ant/src/etc/testcases/taskdefs/antlib.xml Index: antlib.xml =================================================================== 1.1 ant/src/etc/testcases/taskdefs/test.antlib.xml Index: test.antlib.xml =================================================================== 1.27 +72 -16 ant/src/main/org/apache/tools/ant/helper/ProjectHelper2.java Index: ProjectHelper2.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/helper/ProjectHelper2.java,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- ProjectHelper2.java 23 Jul 2003 10:24:39 -0000 1.26 +++ ProjectHelper2.java 24 Jul 2003 13:48:45 -0000 1.27 @@ -57,8 +57,10 @@ 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.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; @@ -103,6 +106,31 @@ 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. * * @param project the current project @@ -127,11 +155,11 @@ // 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 @@ 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 @@ */ 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,11 +404,20 @@ * 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; } /** 1.39 +63 -2 ant/src/main/org/apache/tools/ant/taskdefs/Definer.java Index: Definer.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Definer.java,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- Definer.java 22 Jul 2003 16:40:32 -0000 1.38 +++ Definer.java 24 Jul 2003 13:48:45 -0000 1.39 @@ -59,12 +59,14 @@ 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 @@ private String resource; private ClasspathUtils.Delegate cpDelegate; + private int format = Format.PROPERTIES; private boolean definerSet = false; private ClassLoader internalClassLoader; private int onError = OnError.FAIL; @@ -130,6 +133,24 @@ } /** + * 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. *

*
  • error - throw build exception
  • @@ -144,6 +165,14 @@ } /** + * 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 * @deprecated stop using this attribute @@ -289,7 +318,15 @@ 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); + } } } @@ -360,6 +397,30 @@ } /** + * 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 @@ } 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) { 1.3 +146 -667 ant/src/main/org/apache/tools/ant/taskdefs/Antlib.java 1.1 ant/src/testcases/org/apache/tools/ant/taskdefs/AntlibTest.java Index: AntlibTest.java =================================================================== /* * 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 * . */ 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"); } } } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org For additional commands, e-mail: dev-help@ant.apache.org