stevel 01/11/26 22:53:22 Added: proposal/sandbox/antlib/docs/manual/CoreTasks antjar.html antlib.html proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs Antjar.java Antlib-V1_0.dtd Antlib.java Log: Jose Alberto Fernandez's prototype antlib/antjar code. This code lacks a build file of its own right now; it can drop in on top of build\classes. Revision Changes Path 1.1 jakarta-ant/proposal/sandbox/antlib/docs/manual/CoreTasks/antjar.html Index: antjar.html =================================================================== <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.1 jakarta-ant/proposal/sandbox/antlib/docs/manual/CoreTasks/antlib.html Index: antlib.html =================================================================== <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> 1.1 jakarta-ant/proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs/Antjar.java Index: Antjar.java =================================================================== /* * 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 [EMAIL PROTECTED] * * 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, [EMAIL PROTECTED] * @author <a href="mailto:[EMAIL PROTECTED]">Jose Alberto Fernandez</a> * @author <a href="mailto:[EMAIL PROTECTED]">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.1 jakarta-ant/proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs/Antlib-V1_0.dtd Index: Antlib-V1_0.dtd =================================================================== <?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.1 jakarta-ant/proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs/Antlib.java Index: Antlib.java =================================================================== /* * 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 [EMAIL PROTECTED] * * 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, [EMAIL PROTECTED] * @author <a href="[EMAIL PROTECTED]">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 }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>