git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269901 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -1,94 +0,0 @@ | |||
| <html> | |||
| <head> | |||
| <meta http-equiv="Content-Language" content="en-us"> | |||
| <title>Ant User Manual</title> | |||
| </head> | |||
| <body> | |||
| <h2><a name="antjar">AntJar</a></h2> | |||
| <h3>Description</h3> | |||
| <p>An extension of the <a href="jar.html">Jar</a> task with special | |||
| treatment for the library descriptor file that should end up in the | |||
| <code>META-INF</code> directory of the Ant Archive.</p> | |||
| <p>This task validates the provided library descriptor making certain | |||
| it specifies the following SYSTEM ID: | |||
| <b>"http://jakarta.apache.org/ant/AntlibV1_0.dtd"</b>. | |||
| This DTD is defined as follows:</p> | |||
| <pre> | |||
| <?xml version='1.0' encoding="UTF8" ?> | |||
| <!-- | |||
| This file defines the XML format for ANT library descriptors. | |||
| Descriptors must especify a DOCTYPE of | |||
| "http://jakarta.apache.org/ant/Antlib-V1_0.dtd" | |||
| as the SystemId for the document. | |||
| --> | |||
| <!-- Root element for the Antlib descriptor. --> | |||
| <!ELEMENT antlib (task | type)* > | |||
| <!ATTLIST antlib | |||
| version CDATA #IMPLIED | |||
| > | |||
| <!-- Declaration of tasks contained in the library. --> | |||
| <!ELEMENT task EMPTY> | |||
| <!ATTLIST task | |||
| name CDATA #REQUIRED | |||
| class CDATA #REQUIRED | |||
| > | |||
| <!-- Declaration of datatypes contained in the library --> | |||
| <!ELEMENT type EMPTY> | |||
| <!ATTLIST type | |||
| name CDATA #REQUIRED | |||
| class CDATA #REQUIRED | |||
| > | |||
| </pre> | |||
| <h3>Parameters</h3> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| <td valign="top"><b>Attribute</b></td> | |||
| <td valign="top"><b>Description</b></td> | |||
| <td align="center" valign="top"><b>Required</b></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">antxml</td> | |||
| <td valign="top">The library descriptor to use (META-INF/antlib.xml).</td> | |||
| <td valign="top" align="center">Yes</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top"><b>Others...</b></td> | |||
| <td valign="top">All attributes inherited form the | |||
| <a href="jar.html">Jar task</a>.</td> | |||
| <td valign="top" align="center"> </td> | |||
| </tr> | |||
| </table> | |||
| <h3>Nested elements</h3> | |||
| See the nested elements of the <a href="jar.html">Jar task</a>. | |||
| <h3>Examples</h3> | |||
| <pre> <antjar file="${dist}/lib/app.jar" | |||
| antxml="${src}/applib.xml" basedir="${build}/classes"/></pre> | |||
| <p>jars all files in the <code>${build}/classes</code> directory into a file | |||
| called <code>app.jar</code> in the <code>${dist}/lib</code> directory and | |||
| sets the content of <code>${src}/applib.xml</code> as the library descriptor | |||
| in <code>META-INF/antlib.xml</code>.</p> | |||
| <p>Here is a sample <code>META-INF/antlib.xml</code>:</p> | |||
| <pre> | |||
| <?xml version="1.0" encoding="UTF8" ?> | |||
| <!DOCTYPE antlib SYSTEM "http://jakarta.apache.org/ant/Antlib-V1_0.dtd" > | |||
| <antlib version="1.0" > | |||
| <task name="case" class="org.apache.ant.contrib.Case" /> | |||
| </antlib> | |||
| </pre> | |||
| <hr> | |||
| <p align="center">Copyright © 2000,2001 Apache Software Foundation. All rights | |||
| Reserved.</p> | |||
| </body> | |||
| </html> | |||
| @@ -1,117 +0,0 @@ | |||
| <html> | |||
| <head> | |||
| <meta http-equiv="Content-Language" content="en-us"> | |||
| <title>Ant User Manual</title> | |||
| </head> | |||
| <body> | |||
| <h2><a name="antlib">AntLib</a></h2> | |||
| <h3>Description</h3> | |||
| <p>Defines and loads any tasks and datatypes contained in an ANT library.</p> | |||
| <p>It also allows the aliasing of the names being defined in order to avoid | |||
| collisions and provides means to override definitions with the ones defined | |||
| in the library.</p> | |||
| Ant libraries can be loaded in the current classloader, which is more efficient, | |||
| but requires the tasks to be in the path already (such as in the ant lib | |||
| directory) - set <tt>useCurrentClassloader</tt> to true to enable this. | |||
| It is also possible to add more libraries to the path, such as any | |||
| libraries the task is dependent on. | |||
| <h3>Parameters</h3> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| <td valign="top"><b>Attribute</b></td> | |||
| <td valign="top"><b>Description</b></td> | |||
| <td align="center" valign="top"><b>Required</b></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">file</td> | |||
| <td valign="top">The jar-file of the library.</td> | |||
| <td align="center" valign="middle" rowspan="2">at least one of the two</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">library</td> | |||
| <td valign="top">The name of a library relative to ${ant.home}/lib.</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">override</td> | |||
| <td valign="top">Replace any existing definition with the same name. ("true"/"false"). When "false" already defined tasks | |||
| and datatytes take precedence over those in the library. | |||
| Default is "false" when omitted.</td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">useCurrentClassloader</td> | |||
| <td valign="top">Set to "true" to avoid using a separate | |||
| ClassLoader for the tasks in the library. Using this option requires | |||
| that the library jar is already accessible by the ClassLoader of | |||
| the project. Default is "false". | |||
| </td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">classpath</td> | |||
| <td valign="top">A | |||
| <a href="../using.html#path">classpath</a> | |||
| for extra libraries to pull in. | |||
| </td> | |||
| <td valign="top" align="center">No</td> | |||
| </tr> | |||
| </table> | |||
| <h3><a name="nested">Parameters specified as nested elements</a></h3> | |||
| <h4>alias</h4> | |||
| <p>Specifies the usage of a different name from that defined in the library | |||
| descriptor.</p> | |||
| <table border="1" cellpadding="2" cellspacing="0"> | |||
| <tr> | |||
| <td valign="top"><b>Attribute</b></td> | |||
| <td valign="top"><b>Description</b></td> | |||
| <td align="center" valign="top"><b>Required</b></td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">name</td> | |||
| <td valign="top">The name used in the library descriptor.</td> | |||
| <td valign="top" align="center">Yes</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">as</td> | |||
| <td valign="top">The alias to use in the project.</td> | |||
| <td valign="top" align="center">Yes</td> | |||
| </tr> | |||
| </table> | |||
| <p>Specifies the usage of a different name from that defined in the library | |||
| descriptor. This is used to deal with name clashes </p> | |||
| <h4>classpath</h4> | |||
| <h4>classpath</h4> | |||
| A classpath of extra libraries to import to support this task. | |||
| <h4>classpathref</h4> | |||
| A reference to an existing classpath. | |||
| <h3>Examples</h3> | |||
| <pre> <antlib file="${build}/lib/mylib.jar"/></pre> | |||
| <p>loads the definitions from the library located at | |||
| <code>${build}/lib/ant.jar</code>.</p> | |||
| <pre> <antlib library="optional.jar"/></pre> | |||
| <p>loads the definitions from the library <code>optional.jar</code> | |||
| located at <code>${ant.home}/lib</code>.</p> | |||
| <pre> <antlib file="${build}/lib/mylib.jar"> | |||
| <alias name="echo" as="myecho"/> | |||
| </antlib> | |||
| </pre> | |||
| <p>loads the definitions from the library located at | |||
| <code>${build}/lib/ant.jar</code> but uses the name | |||
| "<code>myecho</code>" for the "<code>echo</code>" task | |||
| declared in the library.</p> | |||
| <hr><p align="center">Copyright © 2000,2001 Apache Software Foundation. All rights | |||
| Reserved.</p> | |||
| </body> | |||
| </html> | |||
| @@ -25,8 +25,6 @@ | |||
| <a href="CoreTasks/overview.html">Overview</a><br><br> | |||
| <a href="CoreTasks/ant.html">Ant</a><br> | |||
| <a href="CoreTasks/antcall.html">AntCall</a><br> | |||
| <a href="CoreTasks/antlib.html">AntLib</a><br> | |||
| <a href="CoreTasks/antjar.html">AntJar</a><br> | |||
| <a href="CoreTasks/antstructure.html">AntStructure</a><br> | |||
| <a href="CoreTasks/apply.html">Apply/<i>ExecOn</i></a><br> | |||
| <a href="CoreTasks/available.html">Available</a><br> | |||
| @@ -1,316 +0,0 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2000 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 "The Jakarta Project", "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.xml.sax.*; | |||
| import javax.xml.parsers.*; | |||
| import org.apache.tools.ant.*; | |||
| import org.apache.tools.ant.types.ZipFileSet; | |||
| import org.apache.tools.zip.*; | |||
| import java.io.*; | |||
| import java.util.*; | |||
| /** | |||
| * Creates a ANTLIB archive. Code is similar to the War class, but with | |||
| * bonus dtd validation. | |||
| * | |||
| * @author doc and layout changes by steve loughran, steve_l@iseran.com | |||
| * @author <a href="mailto:j_a_fernandez@yahoo.com">Jose Alberto Fernandez</a> | |||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
| * | |||
| * @since ant1.5 | |||
| */ | |||
| public class Antjar extends Jar { | |||
| /** | |||
| * location of the xml descriptor (antxml attribute) | |||
| */ | |||
| private File libraryDescriptor; | |||
| /** | |||
| * status flag | |||
| */ | |||
| private boolean descriptorAdded; | |||
| /** | |||
| * Constructor for the Antjar object | |||
| */ | |||
| public Antjar() { | |||
| super(); | |||
| archiveType = "jar"; | |||
| emptyBehavior = "create"; | |||
| } | |||
| /** | |||
| * Sets the Antxml attribute of the Antjar object | |||
| * | |||
| * @param descriptor The new Antxml value | |||
| */ | |||
| public void setAntxml(File descriptor) { | |||
| libraryDescriptor = descriptor; | |||
| if (!libraryDescriptor.exists()) { | |||
| throw new BuildException("Deployment descriptor: " + libraryDescriptor + " does not exist."); | |||
| } | |||
| //check | |||
| validateDescriptor(); | |||
| // Create a ZipFileSet for this file, and pass it up. | |||
| ZipFileSet fs = new ZipFileSet(); | |||
| fs.setDir(new File(libraryDescriptor.getParent())); | |||
| fs.setIncludes(libraryDescriptor.getName()); | |||
| fs.setFullpath(Antlib.ANT_DESCRIPTOR); | |||
| super.addFileset(fs); | |||
| } | |||
| /** | |||
| * override of superclass method; add check for | |||
| * valid descriptor | |||
| * @param zOut stream to init | |||
| * @exception IOException io trouble | |||
| * @exception BuildException other trouble | |||
| */ | |||
| protected void initZipOutputStream(ZipOutputStream zOut) | |||
| throws IOException, BuildException { | |||
| // If no antxml file is specified, it's an error. | |||
| if (libraryDescriptor == null) { | |||
| throw new BuildException("webxml attribute is required", location); | |||
| } | |||
| super.initZipOutputStream(zOut); | |||
| } | |||
| /** | |||
| * override of parent method; warn if a second descriptor is added | |||
| * | |||
| * @param file file to add | |||
| * @param zOut stream to add to | |||
| * @param vPath the path to add it to in the zipfile | |||
| * @exception IOException io trouble | |||
| */ | |||
| protected void zipFile(File file, ZipOutputStream zOut, String vPath) | |||
| throws IOException { | |||
| // If the file being added is META-INF/antlib.xml, we warn if it's not the | |||
| // one specified in the "antxml" attribute - or if it's being added twice, | |||
| // meaning the same file is specified by the "antxml" attribute and in | |||
| // a <fileset> element. | |||
| if (vPath.equalsIgnoreCase(Antlib.ANT_DESCRIPTOR)) { | |||
| if (libraryDescriptor == null || !libraryDescriptor.equals(file) || descriptorAdded) { | |||
| log("Warning: selected " + archiveType + " files include a " + | |||
| Antlib.ANT_DESCRIPTOR + " which will be ignored " + | |||
| "(please use antxml attribute to " + archiveType + " task)", Project.MSG_WARN); | |||
| } | |||
| else { | |||
| super.zipFile(file, zOut, vPath); | |||
| descriptorAdded = true; | |||
| } | |||
| } | |||
| else { | |||
| super.zipFile(file, zOut, vPath); | |||
| } | |||
| } | |||
| /** | |||
| * Make sure we don't think we already have a descriptor next time this | |||
| * task gets executed. | |||
| */ | |||
| protected void cleanUp() { | |||
| descriptorAdded = false; | |||
| super.cleanUp(); | |||
| } | |||
| /** | |||
| * validate the descriptor against the DTD | |||
| * | |||
| * @exception BuildException failure to validate | |||
| */ | |||
| protected void validateDescriptor() | |||
| throws BuildException { | |||
| SAXParserFactory saxFactory = SAXParserFactory.newInstance(); | |||
| saxFactory.setValidating(true); | |||
| InputStream is = null; | |||
| try { | |||
| SAXParser saxParser = saxFactory.newSAXParser(); | |||
| Parser parser = saxParser.getParser(); | |||
| is = new FileInputStream(libraryDescriptor); | |||
| InputSource inputSource = new InputSource(is); | |||
| inputSource.setSystemId("file:" + libraryDescriptor); | |||
| project.log("Validating library descriptor: " + libraryDescriptor, | |||
| Project.MSG_VERBOSE); | |||
| saxParser.parse(inputSource, new AntLibraryValidator()); | |||
| } | |||
| catch (ParserConfigurationException exc) { | |||
| throw new BuildException("Parser has not been configured correctly", exc); | |||
| } | |||
| catch (SAXParseException exc) { | |||
| Location location = | |||
| new Location(libraryDescriptor.toString(), | |||
| exc.getLineNumber(), exc.getColumnNumber()); | |||
| Throwable t = exc.getException(); | |||
| if (t instanceof BuildException) { | |||
| BuildException be = (BuildException) t; | |||
| if (be.getLocation() == Location.UNKNOWN_LOCATION) { | |||
| be.setLocation(location); | |||
| } | |||
| throw be; | |||
| } | |||
| throw new BuildException(exc.getMessage(), t, location); | |||
| } | |||
| catch (SAXException exc) { | |||
| Throwable t = exc.getException(); | |||
| if (t instanceof BuildException) { | |||
| throw (BuildException) t; | |||
| } | |||
| throw new BuildException(exc.getMessage(), t); | |||
| } | |||
| catch (IOException exc) { | |||
| throw new BuildException("Error reading library descriptor", exc); | |||
| } | |||
| finally { | |||
| if (is != null) { | |||
| try { | |||
| is.close(); | |||
| } | |||
| catch (IOException ioe) { | |||
| // ignore this | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * Parses the document describing the content of the library. | |||
| */ | |||
| private class AntLibraryValidator extends HandlerBase { | |||
| /** | |||
| * flag to track whether the DOCTYPE was hit in the prolog | |||
| */ | |||
| private boolean doctypePresent = false; | |||
| /** | |||
| * doc locator | |||
| */ | |||
| private Locator locator = null; | |||
| /** | |||
| * Sets the DocumentLocator attribute of the AntLibraryValidator | |||
| * object | |||
| * | |||
| * @param locator The new DocumentLocator value | |||
| */ | |||
| public void setDocumentLocator(Locator locator) { | |||
| this.locator = locator; | |||
| } | |||
| /** | |||
| * SAX callback handler | |||
| * | |||
| * @param tag XML tag | |||
| * @param attrs attributes | |||
| * @exception SAXParseException parse trouble | |||
| */ | |||
| public void startElement(String tag, AttributeList attrs) | |||
| throws SAXParseException { | |||
| // By the time an element is found | |||
| // the DOCTYPE should have been found. | |||
| if (!doctypePresent) { | |||
| String msg = "Missing DOCTYPE declaration or wrong SYSTEM ID"; | |||
| throw new SAXParseException(msg, locator); | |||
| } | |||
| } | |||
| /** | |||
| * Recognizes the DTD declaration for antlib and returns the corresponding | |||
| * DTD definition from a resource. <P> | |||
| * | |||
| * To allow for future versions of the DTD format it will search | |||
| * for any DTDs of the form "Antlib-V.*\.dtd". | |||
| * | |||
| * @param publicId public ID (ignored) | |||
| * @param systemId system ID (matched against) | |||
| * @return local DTD instance | |||
| */ | |||
| public InputSource resolveEntity(String publicId, | |||
| String systemId) { | |||
| log("Looking for entity with PublicID=" + publicId + | |||
| " and SystemId=" + systemId, Project.MSG_VERBOSE); | |||
| if (Antlib.matchDtdId(systemId)) { | |||
| String resId = | |||
| systemId.substring(Antlib.ANTLIB_DTD_URL.length()); | |||
| InputSource is = | |||
| new InputSource(this.getClass().getResourceAsStream(resId)); | |||
| is.setSystemId(systemId); | |||
| doctypePresent = true; | |||
| return is; | |||
| } | |||
| return null; | |||
| } | |||
| //end inner class AntLibraryValidator | |||
| } | |||
| } | |||
| @@ -1,27 +0,0 @@ | |||
| <?xml version='1.0' encoding="UTF8" ?> | |||
| <!-- | |||
| This file defines the XML format for ANT library descriptors. | |||
| Descriptors must especify a DOCTYPE using "Antlib-V1_0.dtd" | |||
| as the SystemId for the document. | |||
| --> | |||
| <!-- Root element for the Antlib descriptor. --> | |||
| <!ELEMENT antlib (task | type)* > | |||
| <!ATTLIST antlib | |||
| version CDATA #IMPLIED | |||
| > | |||
| <!-- Declaration of tasks contained in the library. --> | |||
| <!ELEMENT task EMPTY> | |||
| <!ATTLIST task | |||
| name CDATA #REQUIRED | |||
| class CDATA #REQUIRED | |||
| > | |||
| <!-- Declaration of datatypes contained in the library --> | |||
| <!ELEMENT type EMPTY> | |||
| <!ATTLIST type | |||
| name CDATA #REQUIRED | |||
| class CDATA #REQUIRED | |||
| > | |||
| @@ -1,711 +0,0 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 1999 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 "The Jakarta Project", "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.*; | |||
| import org.apache.tools.ant.types.*; | |||
| import org.xml.sax.*; | |||
| import javax.xml.parsers.*; | |||
| import java.util.*; | |||
| import java.util.zip.*; | |||
| import java.io.*; | |||
| /** | |||
| * Make available the tasks and types from an Ant library. <pre> | |||
| * <antlib library="libname.jar" > | |||
| * <alias name="nameOnLib" as="newName" /> | |||
| * </antlib> | |||
| * | |||
| * <antlib file="libname.jar" override="true" /> | |||
| * </pre> | |||
| * | |||
| * @author minor changes by steve loughran, steve_l@iseran.com | |||
| * @author <a href="j_a_fernandez@yahoo.com">Jose Alberto Fernandez</a> | |||
| * @since ant1.5 | |||
| */ | |||
| public class Antlib extends Task { | |||
| /* | |||
| * implements DeclaringTask | |||
| */ | |||
| /** | |||
| * library attribute | |||
| */ | |||
| private String library = null; | |||
| /** | |||
| * file attribute | |||
| */ | |||
| private File file = null; | |||
| /** | |||
| * override attribute | |||
| */ | |||
| private boolean override = false; | |||
| /** | |||
| * attribute to control classloader use | |||
| */ | |||
| private boolean useCurrentClassloader = false; | |||
| /** | |||
| * classpath to build up | |||
| */ | |||
| private Path classpath = null; | |||
| /** | |||
| * our little xml parse | |||
| */ | |||
| private SAXParserFactory saxFactory; | |||
| /** | |||
| * table of aliases | |||
| */ | |||
| private Vector aliases = new Vector(); | |||
| /** | |||
| * Location of descriptor in library | |||
| */ | |||
| public static String ANT_DESCRIPTOR = "META-INF/antlib.xml"; | |||
| /** | |||
| * Prefix name for DTD of descriptor | |||
| */ | |||
| public static String ANTLIB_DTD_URL = | |||
| "http://jakarta.apache.org/ant/"; | |||
| /** | |||
| * prefix of the antlib | |||
| */ | |||
| public static String ANTLIB_DTD_PREFIX = "Antlib-V"; | |||
| /** | |||
| * version counter | |||
| */ | |||
| public static String ANTLIB_DTD_VERSION = "1_0"; | |||
| /** | |||
| * dtd file extension | |||
| */ | |||
| public static String ANTLIB_DTD_EXT = ".dtd"; | |||
| /** | |||
| * constructor creates a validating sax parser | |||
| */ | |||
| public Antlib() { | |||
| super(); | |||
| saxFactory = SAXParserFactory.newInstance(); | |||
| saxFactory.setValidating(true); | |||
| } | |||
| /** | |||
| * constructor binds to a project as well as setting up internal state | |||
| * | |||
| * @param p Description of Parameter | |||
| */ | |||
| public Antlib(Project p) { | |||
| this(); | |||
| setProject(p); | |||
| } | |||
| /** | |||
| * Set name of library to load. The library is located in $ANT_HOME/lib. | |||
| * | |||
| * @param lib the name of library relative to $ANT_HOME/lib. | |||
| */ | |||
| public void setLibrary(String lib) { | |||
| this.library = lib; | |||
| } | |||
| /** | |||
| * Set file location of library to load. | |||
| * | |||
| * @param file the jar file for the library. | |||
| */ | |||
| public void setFile(File file) { | |||
| this.file = file; | |||
| } | |||
| /** | |||
| * Set whether to override any existing definitions. | |||
| * | |||
| * @param override if true new definitions will replace existing ones. | |||
| */ | |||
| public void setOverride(boolean override) { | |||
| this.override = override; | |||
| } | |||
| /** | |||
| * Set whether to use a new classloader or not. Default is <code>false</code> | |||
| * . This property is mostly used by the core when loading core tasks. | |||
| * | |||
| * @param useCurrentClassloader if true the current classloader will | |||
| * be used to load the definitions. | |||
| */ | |||
| public void setUseCurrentClassloader(boolean useCurrentClassloader) { | |||
| this.useCurrentClassloader = useCurrentClassloader; | |||
| } | |||
| /** | |||
| * Create new Alias element. | |||
| * | |||
| * @return Description of the Returned Value | |||
| */ | |||
| public Alias createAlias() { | |||
| Alias als = new Alias(); | |||
| aliases.add(als); | |||
| return als; | |||
| } | |||
| /** | |||
| * Set the classpath to be used for this compilation | |||
| * | |||
| * @param cp The new Classpath value | |||
| */ | |||
| public void setClasspath(Path cp) { | |||
| if (classpath == null) { | |||
| classpath = cp; | |||
| } | |||
| else { | |||
| classpath.append(cp); | |||
| } | |||
| } | |||
| /** | |||
| * create a nested classpath element. | |||
| * | |||
| * @return classpath to use | |||
| */ | |||
| public Path createClasspath() { | |||
| if (classpath == null) { | |||
| classpath = new Path(project); | |||
| } | |||
| return classpath.createPath(); | |||
| } | |||
| /** | |||
| * Adds a reference to a CLASSPATH defined elsewhere | |||
| * | |||
| * @param r The new ClasspathRef value | |||
| */ | |||
| public void setClasspathRef(Reference r) { | |||
| createClasspath().setRefid(r); | |||
| } | |||
| /** | |||
| * actually do the work of loading the library | |||
| * | |||
| * @exception BuildException Description of Exception | |||
| * @todo maybe have failonerror support for missing file? | |||
| */ | |||
| public void execute() | |||
| throws BuildException { | |||
| File realFile = file; | |||
| if (library != null) { | |||
| if (file != null) { | |||
| String msg = "You cannot specify both file and library."; | |||
| throw new BuildException(msg, location); | |||
| } | |||
| // For the time being libraries live in $ANT_HOME/lib. | |||
| // The idea being that we would not load all the jars there anymore | |||
| String home = project.getProperty("ant.home"); | |||
| if (home == null) { | |||
| throw new BuildException("ANT_HOME not set as required."); | |||
| } | |||
| realFile = new File(new File(home, "lib"), library); | |||
| } | |||
| else if (file == null) { | |||
| String msg = "Must specify either library or file attribute."; | |||
| throw new BuildException(msg, location); | |||
| } | |||
| if (!realFile.exists()) { | |||
| String msg = "Cannot find library: " + realFile; | |||
| throw new BuildException(msg, location); | |||
| } | |||
| //open the descriptor | |||
| InputStream is = getDescriptor(realFile); | |||
| if (is == null) { | |||
| String msg = "Missing descriptor on library: " + realFile; | |||
| throw new BuildException(msg, location); | |||
| } | |||
| ClassLoader classloader=null; | |||
| if (useCurrentClassloader && classpath != null) { | |||
| log("ignoring the useCurrentClassloader option as a classpath is defined", | |||
| Project.MSG_WARN); | |||
| useCurrentClassloader=false; | |||
| } | |||
| if (!useCurrentClassloader) { | |||
| classloader = makeClassLoader(realFile); | |||
| } | |||
| //parse it and evaluate it. | |||
| evaluateDescriptor(classloader, processAliases(), is); | |||
| } | |||
| /** | |||
| * Load definitions directly from an external XML file. | |||
| * | |||
| * @param xmlfile XML file in the Antlib format. | |||
| * @exception BuildException failure to open the file | |||
| */ | |||
| public void loadDefinitions(File xmlfile) | |||
| throws BuildException { | |||
| try { | |||
| InputStream is = new FileInputStream(xmlfile); | |||
| loadDefinitions(is); | |||
| } | |||
| catch (IOException io) { | |||
| throw new BuildException("Cannot read file: " + file, io); | |||
| } | |||
| } | |||
| /** | |||
| * Load definitions directly from InputStream. | |||
| * | |||
| * @param is InputStream for the Antlib descriptor. | |||
| * @exception BuildException trouble | |||
| */ | |||
| public void loadDefinitions(InputStream is) | |||
| throws BuildException { | |||
| evaluateDescriptor(null, processAliases(), is); | |||
| } | |||
| /** | |||
| * get a descriptor from the library file | |||
| * | |||
| * @param file jarfile to open | |||
| * @return input stream to the Descriptor | |||
| * @exception BuildException io trouble, or it isnt a zipfile | |||
| */ | |||
| private InputStream getDescriptor(File file) | |||
| throws BuildException { | |||
| try { | |||
| final ZipFile zipfile = new ZipFile(file); | |||
| ZipEntry entry = zipfile.getEntry(ANT_DESCRIPTOR); | |||
| if (entry == null) { | |||
| return null; | |||
| } | |||
| // Guarantee that when Entry is closed so does the zipfile instance. | |||
| return | |||
| new FilterInputStream(zipfile.getInputStream(entry)) { | |||
| public void close() | |||
| throws IOException { | |||
| super.close(); | |||
| zipfile.close(); | |||
| } | |||
| }; | |||
| } | |||
| catch (ZipException ze) { | |||
| throw new BuildException("Not a library file.", ze, location); | |||
| } | |||
| catch (IOException ioe) { | |||
| throw new BuildException("Cannot read library content.", | |||
| ioe, location); | |||
| } | |||
| } | |||
| /** | |||
| * turn the alias list to a property hashtable | |||
| * | |||
| * @return generated property hashtable | |||
| */ | |||
| private Properties processAliases() { | |||
| Properties p = new Properties(); | |||
| for (Enumeration e = aliases.elements(); e.hasMoreElements(); ) { | |||
| Alias a = (Alias) e.nextElement(); | |||
| p.put(a.name, a.as); | |||
| } | |||
| return p; | |||
| } | |||
| /** | |||
| * create the classpath for this library from the file passed in and | |||
| * any classpath parameters | |||
| * | |||
| * @param file library file to use | |||
| * @return classloader using te | |||
| * @exception BuildException trouble creating the classloader | |||
| */ | |||
| protected ClassLoader makeClassLoader(File file) | |||
| throws BuildException { | |||
| Path clspath = new Path(project); | |||
| clspath.setLocation(file); | |||
| //append any build supplied classpath | |||
| if (classpath != null) { | |||
| clspath.append(classpath); | |||
| } | |||
| AntClassLoader al = new AntClassLoader(project, clspath, true); | |||
| return al; | |||
| } | |||
| /** | |||
| * parse the antlib descriptor | |||
| * | |||
| * @param cl optional classloader | |||
| * @param als alias list as property hashtable | |||
| * @param is input stream to descriptor | |||
| * @exception BuildException trouble | |||
| */ | |||
| protected void evaluateDescriptor(ClassLoader cl, | |||
| Properties als, InputStream is) | |||
| throws BuildException { | |||
| try { | |||
| SAXParser saxParser = saxFactory.newSAXParser(); | |||
| Parser parser = saxParser.getParser(); | |||
| InputSource inputSource = new InputSource(is); | |||
| //inputSource.setSystemId(uri); //URI is nasty for jar entries | |||
| project.log("parsing descriptor for library: " + file, | |||
| Project.MSG_VERBOSE); | |||
| saxParser.parse(inputSource, new AntLibraryHandler(cl, als)); | |||
| } | |||
| catch (ParserConfigurationException exc) { | |||
| throw new BuildException("Parser has not been configured correctly", exc); | |||
| } | |||
| catch (SAXParseException exc) { | |||
| Location location = | |||
| new Location(ANT_DESCRIPTOR, | |||
| exc.getLineNumber(), exc.getColumnNumber()); | |||
| Throwable t = exc.getException(); | |||
| if (t instanceof BuildException) { | |||
| BuildException be = (BuildException) t; | |||
| if (be.getLocation() == Location.UNKNOWN_LOCATION) { | |||
| be.setLocation(location); | |||
| } | |||
| throw be; | |||
| } | |||
| throw new BuildException(exc.getMessage(), t, location); | |||
| } | |||
| catch (SAXException exc) { | |||
| Throwable t = exc.getException(); | |||
| if (t instanceof BuildException) { | |||
| throw (BuildException) t; | |||
| } | |||
| throw new BuildException(exc.getMessage(), t); | |||
| } | |||
| catch (IOException exc) { | |||
| throw new BuildException("Error reading library descriptor", exc); | |||
| } | |||
| finally { | |||
| if (is != null) { | |||
| try { | |||
| is.close(); | |||
| } | |||
| catch (IOException ioe) { | |||
| // ignore this | |||
| } | |||
| } | |||
| } | |||
| } | |||
| /** | |||
| * get a DTD URI from url, prefix and extension | |||
| * | |||
| * @return URI for this dtd version | |||
| */ | |||
| public static String dtdVersion() { | |||
| return ANTLIB_DTD_URL + ANTLIB_DTD_PREFIX + | |||
| ANTLIB_DTD_VERSION + ANTLIB_DTD_EXT; | |||
| } | |||
| /** | |||
| * compare system ID with the dtd string | |||
| * -ignoring any version number | |||
| * @param systemId Description of Parameter | |||
| * @return true if this is a an ant library descriptor | |||
| */ | |||
| public static boolean matchDtdId(String systemId) { | |||
| return (systemId != null && | |||
| systemId.startsWith(ANTLIB_DTD_URL + ANTLIB_DTD_PREFIX) && | |||
| systemId.endsWith(ANTLIB_DTD_EXT)); | |||
| } | |||
| /** | |||
| * Parses the document describing the content of the | |||
| * library. An inner class for access to Project.log | |||
| */ | |||
| private class AntLibraryHandler extends HandlerBase { | |||
| /** | |||
| * our classloader | |||
| */ | |||
| private final ClassLoader classloader; | |||
| /** | |||
| * the aliases | |||
| */ | |||
| private final Properties aliasMap; | |||
| /** | |||
| * doc locator | |||
| */ | |||
| private Locator locator = null; | |||
| /** | |||
| * Constructor for the AntLibraryHandler object | |||
| * | |||
| * @param cl optional classloader | |||
| * @param als alias list | |||
| */ | |||
| AntLibraryHandler(ClassLoader classloader, Properties als) { | |||
| this.classloader = classloader; | |||
| this.aliasMap = als; | |||
| } | |||
| /** | |||
| * Sets the DocumentLocator attribute of the AntLibraryHandler | |||
| * object | |||
| * | |||
| * @param locator The new DocumentLocator value | |||
| */ | |||
| public void setDocumentLocator(Locator locator) { | |||
| this.locator = locator; | |||
| } | |||
| /** | |||
| * SAX callback handler | |||
| * | |||
| * @param tag XML tag | |||
| * @param attrs attributes | |||
| * @exception SAXParseException parse trouble | |||
| */ | |||
| public void startElement(String tag, AttributeList attrs) | |||
| throws SAXParseException { | |||
| if ("antlib".equals(tag)) { | |||
| // No attributes to worry about | |||
| return; | |||
| } | |||
| if ("task".equals(tag) || "type".equals(tag)) { | |||
| String name = null; | |||
| String className = null; | |||
| for (int i = 0, last = attrs.getLength(); i < last; i++) { | |||
| String key = attrs.getName(i); | |||
| String value = attrs.getValue(i); | |||
| if (key.equals("name")) { | |||
| name = value; | |||
| } | |||
| else if (key.equals("class")) { | |||
| className = value; | |||
| } | |||
| else { | |||
| throw new SAXParseException("Unexpected attribute \"" | |||
| + key + "\"", locator); | |||
| } | |||
| } | |||
| if (name == null || className == null) { | |||
| String msg = "Underspecified " + tag + " declaration."; | |||
| throw new SAXParseException(msg, locator); | |||
| } | |||
| try { | |||
| //check for name alias | |||
| String alias = aliasMap.getProperty(name); | |||
| if (alias != null) { | |||
| name = alias; | |||
| } | |||
| //catch an attempted override of an existing name | |||
| if (!override && inUse(name)) { | |||
| String msg = "Cannot override " + tag + ": " + name; | |||
| log(msg, Project.MSG_WARN); | |||
| return; | |||
| } | |||
| //load the named class | |||
| Class cls; | |||
| if(classloader==null) { | |||
| cls=Class.forName(className); | |||
| } | |||
| else { | |||
| cls=classloader.loadClass(className); | |||
| } | |||
| //register it as a task or a datatype | |||
| if (tag.equals("task")) { | |||
| project.addTaskDefinition(name, cls); | |||
| } | |||
| else { | |||
| project.addDataTypeDefinition(name, cls); | |||
| } | |||
| } | |||
| catch (ClassNotFoundException cnfe) { | |||
| String msg = "Class " + className + | |||
| " cannot be found"; | |||
| throw new SAXParseException(msg, locator, cnfe); | |||
| } | |||
| catch (NoClassDefFoundError ncdfe) { | |||
| String msg = "Class " + className + | |||
| " cannot be found"; | |||
| throw new SAXParseException(msg, locator); | |||
| } | |||
| } | |||
| else { | |||
| throw new SAXParseException("Unexpected element \"" + | |||
| tag + "\"", | |||
| locator); | |||
| } | |||
| } | |||
| /** | |||
| * test for a name being in use already | |||
| * | |||
| * @param name the name to test | |||
| * @return true if it is a task or a datatype | |||
| */ | |||
| private boolean inUse(String name) { | |||
| return (project.getTaskDefinitions().get(name) != null || | |||
| project.getDataTypeDefinitions().get(name) != null); | |||
| } | |||
| /** | |||
| * Recognizes the DTD declaration for antlib and returns the corresponding | |||
| * DTD definition from a resource. <P> | |||
| * | |||
| * To allow for future versions of the DTD format it will search | |||
| * for any DTDs of the form "Antlib-V.*\.dtd". | |||
| * | |||
| * @param publicId public ID (ignored) | |||
| * @param systemId system ID (matched against) | |||
| * @return local DTD instance | |||
| */ | |||
| public InputSource resolveEntity(String publicId, | |||
| String systemId) { | |||
| log("Looking for entiry with PublicID=" + publicId + | |||
| " and SystemId=" + systemId, Project.MSG_VERBOSE); | |||
| if (matchDtdId(systemId)) { | |||
| String resId = systemId.substring(ANTLIB_DTD_URL.length()); | |||
| InputSource is = | |||
| new InputSource(this.getClass().getResourceAsStream(resId)); | |||
| is.setSystemId(systemId); | |||
| return is; | |||
| } | |||
| return null; | |||
| } | |||
| //end inner class AntLibraryHandler | |||
| } | |||
| /** | |||
| * this class is used for alias elements | |||
| * | |||
| * @author slo | |||
| * @created 11 November 2001 | |||
| */ | |||
| public static class Alias { | |||
| /** | |||
| * Description of the Field | |||
| */ | |||
| private String name; | |||
| /** | |||
| * Description of the Field | |||
| */ | |||
| private String as; | |||
| /** | |||
| * Sets the Name attribute of the Alias object | |||
| * | |||
| * @param name The new Name value | |||
| */ | |||
| public void setName(String name) { | |||
| this.name = name; | |||
| } | |||
| /** | |||
| * Sets the As attribute of the Alias object | |||
| * | |||
| * @param as The new As value | |||
| */ | |||
| public void setAs(String as) { | |||
| this.as = as; | |||
| } | |||
| //end inner class alias | |||
| } | |||
| //end class Antlib | |||
| } | |||
| @@ -53,8 +53,6 @@ parallel=org.apache.tools.ant.taskdefs.Parallel | |||
| sequential=org.apache.tools.ant.taskdefs.Sequential | |||
| condition=org.apache.tools.ant.taskdefs.ConditionTask | |||
| dependset=org.apache.tools.ant.taskdefs.DependSet | |||
| antlib=org.apache.tools.ant.taskdefs.Antlib | |||
| antjar=org.apache.tools.ant.taskdefs.Antjar | |||
| # optional tasks | |||
| script=org.apache.tools.ant.taskdefs.optional.Script | |||