You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by eh...@apache.org on 2002/03/03 13:37:41 UTC

cvs commit: jakarta-ant/proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs Antlib.java

ehatcher    02/03/03 04:37:41

  Modified:    proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs
                        Antlib.java
  Log:
  once again for Jose Alberto - think I got it right this time
  
  Revision  Changes    Path
  1.5       +426 -256  jakarta-ant/proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs/Antlib.java
  
  Index: Antlib.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs/Antlib.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Antlib.java	2 Mar 2002 22:21:19 -0000	1.4
  +++ Antlib.java	3 Mar 2002 12:37:41 -0000	1.5
  @@ -55,12 +55,14 @@
   
   import org.apache.tools.ant.*;
   import org.apache.tools.ant.types.*;
  +import org.apache.tools.ant.taskdefs.*;
   import org.xml.sax.*;
   import javax.xml.parsers.*;
   
   import java.util.*;
   import java.util.zip.*;
   import java.io.*;
  +import java.net.*;
   
   /**
    * Make available the tasks and types from an Ant library. <pre>
  @@ -76,6 +78,12 @@
    * @since ant1.5
    */
   public class Antlib extends Task {
  +
  +    /**
  +     * Location of descriptor in library
  +     */
  +    public static final String ANT_DESCRIPTOR = "META-INF/antlib.xml";
  +
       /**
        * The named classloader to use.
        * Defaults to the default classLoader.
  @@ -83,10 +91,6 @@
       private String loaderId = "";
   
       /**
  -     * library attribute
  -     */
  -    private String library = null;
  -    /**
        * file attribute
        */
       private File file = null;
  @@ -95,62 +99,200 @@
        */
       private boolean override = false;
       /**
  -     * attribute to control classloader use
  +     * attribute to control failure when loading
        */
  -    private boolean useCurrentClassloader = false;
  +    private FailureAction onerror = new FailureAction();
  +
       /**
        * classpath to build up
        */
       private Path classpath = null;
   
       /**
  +     * the manufacture set of classes to load
  +     */
  +    private Path loaderPath = null;
  +
  +    /**
        * our little xml parse
        */
       private SAXParserFactory saxFactory;
  -    
  +
       /**
        * table of aliases
        */
       private Vector aliases = new Vector();
   
       /**
  -     * Location of descriptor in library
  +     * Some internal constants.
        */
  -    public static String ANT_DESCRIPTOR = "META-INF/antlib.xml";
  +    private static final int FAIL = 0, REPORT = 1, IGNORE = 2;
   
       /**
  -     * 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
  +     * Posible actions when classes are not found
        */
  -    public static String ANTLIB_DTD_EXT = ".dtd";
  +    public static class FailureAction extends EnumeratedAttribute {
  +        public String[] getValues() {
  +            return new String[]{"fail", "report", "ignore"};
  +        }
  +    }
  +
  +    private static class DescriptorEnumeration implements Enumeration {
  +
  +        /**
  +         * The name of the resource being searched for.
  +         */
  +        private String resourceName;
  +
  +        /**
  +         * The index of the next file to search.
  +         */
  +        private int index;
  +
  +        /**
  +         * The list of files to search
  +         */
  +        private File files[];
  +
  +        /**
  +         * The URL of the next resource to return in the enumeration. If this
  +         * field is <code>null</code> then the enumeration has been completed,
  +         * i.e., there are no more elements to return.
  +         */
  +        private URL nextDescriptor;
  +
  +        /**
  +         * Construct a new enumeration of resources of the given name found
  +         * within this class loader's classpath.
  +         *
  +         * @param name the name of the resource to search for.
  +         */
  +        DescriptorEnumeration(String fileNames[], String name) {
  +            this.resourceName = name;
  +            this.index = 0;
  +            this.files = new File[fileNames.length];
  +            for (int i = 0; i < files.length; i++) {
  +                files[i] = new File(fileNames[i]);
  +            }
  +            findNextDescriptor();
  +        }
  +
  +        /**
  +         * Indicates whether there are more elements in the enumeration to
  +         * return.
  +         *
  +         * @return <code>true</code> if there are more elements in the
  +         *         enumeration; <code>false</code> otherwise.
  +         */
  +        public boolean hasMoreElements() {
  +            return (this.nextDescriptor != null);
  +        }
  +
  +        /**
  +         * Returns the next resource in the enumeration.
  +         *
  +         * @return the next resource in the enumeration.
  +         */
  +        public Object nextElement() {
  +            URL ret = this.nextDescriptor;
  +            findNextDescriptor();
  +            return ret;
  +        }
  +
  +        /**
  +         * Locates the next descriptor of the correct name in the files and
  +         * sets <code>nextDescriptor</code> to the URL of that resource. If no
  +         * more resources can be found, <code>nextDescriptor</code> is set to
  +         * <code>null</code>.
  +         */
  +        private void findNextDescriptor() {
  +            URL url = null;
  +            while (index < files.length && url == null) {
  +                try {
  +                    url = getDescriptorURL(files[index], this.resourceName);
  +                    index++;
  +                }
  +                catch (BuildException e) {
  +                    // ignore path elements which are not valid relative to the
  +                    // project
  +                }
  +            }
  +            this.nextDescriptor = url;
  +        }
  +
  +        /**
  +         * Get an URL to a given resource in the given file which may
  +         * either be a directory or a zip file.
  +         *
  +         * @param file the file (directory or jar) in which to search for
  +         *             the resource. Must not be <code>null</code>.
  +         * @param resourceName the name of the resource for which a URL
  +         *                     is required. Must not be <code>null</code>.
  +         *
  +         * @return a URL to the required resource or <code>null</code> if the
  +         *         resource cannot be found in the given file object
  +         * @todo This code is extracted from AntClassLoader.getResourceURL
  +         *       I hate when that happens but the code there is too tied to
  +         *       the ClassLoader internals. Maybe we can find a nice place
  +         *       to put it where both can use it.
  +         */
  +        private URL getDescriptorURL(File file, String resourceName) {
  +            try {
  +                if (!file.exists()) {
  +                    return null;
  +                }
   
  +                if (file.isDirectory()) {
  +                    File resource = new File(file, resourceName);
  +
  +                    if (resource.exists()) {
  +                        try {
  +                            return new URL("file:"+resource.toString());
  +                        } catch (MalformedURLException ex) {
  +                            return null;
  +                        }
  +                    }
  +                }
  +                else {
  +                    ZipFile zipFile = new ZipFile(file);
  +                    try {
  +                        ZipEntry entry = zipFile.getEntry(resourceName);
  +                        if (entry != null) {
  +                            try {
  +                                return new URL("jar:file:"+file.toString()+"!/"+entry);
  +                            } catch (MalformedURLException ex) {
  +                                return null;
  +                            }
  +                        }
  +                    }
  +                    finally {
  +                        zipFile.close();
  +                    }
  +                }
  +            }
  +            catch (Exception e) {
  +                e.printStackTrace();
  +            }
  +
  +            return null;
  +        }
  +
  +    }
   
       /**
        * constructor creates a validating sax parser
        */
       public Antlib() {
           super();
  +        // Default error action
  +        onerror.setValue("report");
           saxFactory = SAXParserFactory.newInstance();
  -        saxFactory.setValidating(true);
  +        saxFactory.setValidating(false);
       }
   
   
       /**
  -     * constructor binds to a project as well as setting up internal state
  +     * constructor binds to a project and sets ignore mode on errors
        *
        * @param p Description of Parameter
        */
  @@ -161,12 +303,12 @@
   
   
       /**
  -     * Set name of library to load. The library is located in $ANT_HOME/lib.
  +     * Set name of library to load. The library is located in $ANT_HOME/antlib.
        *
  -     * @param lib the name of library relative to $ANT_HOME/lib.
  +     * @param lib the name of library relative to $ANT_HOME/antlib.
        */
       public void setLibrary(String lib) {
  -        this.library = lib;
  +        setFile(libraryFile("antlib", lib));
       }
   
   
  @@ -180,13 +322,13 @@
       }
   
       /**
  -     * Set the ClassLoader to use for this library.
  +     * Set the ID of the ClassLoader to use for this library.
        *
  -     * @param id the id for the ClassLoader to use, 
  -     *           if other than the default.
  +     * @param id the id for the ClassLoader to use,
  +     *           <code>null</code> means use ANT's core classloader.
        */
       public void setLoaderid(String id) {
  -	this.loaderId = id;
  +        this.loaderId = id;
       }
   
       /**
  @@ -200,15 +342,26 @@
   
   
       /**
  -     * Set whether to use a new classloader or not. 
  -     * Default is <code>false</code>.
  +     * Get what to do if a definition cannot be loaded
  +     * This method is mostly used by the core when loading core tasks.
  +     *
  +     * @return what to do if a definition cannot be loaded
  +     */
  +    final protected FailureAction getOnerror() {
  +        return this.onerror;
  +    }
  +
  +
  +    /**
  +     * Set whether to fail if a definition cannot be loaded
  +     * Default is <code>true</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.
  +     * @param failedonerror if true loading will stop if classes
  +     *                      cannot be instantiated
        */
  -    public void setUseCurrentClassloader(boolean useCurrentClassloader) {
  -        this.useCurrentClassloader = useCurrentClassloader;
  +    public void setOnerror(FailureAction onerror) {
  +        this.onerror = onerror;
       }
   
   
  @@ -263,77 +416,96 @@
   
   
       /**
  +     * Obtain library file from ANT_HOME directory.
  +     *
  +     * @param lib the library name.
  +     * @return the File instance of the library
  +     */
  +    private File libraryFile(String homeSubDir, String lib) {
  +        // For the time being libraries live in $ANT_HOME/antlib.
  +        // The idea being that not to load all the jars there anymore
  +        String home = project.getProperty("ant.home");
  +
  +        if (home == null) {
  +            throw new BuildException("ANT_HOME not set as required.");
  +        }
  +
  +        return new File(new File(home, homeSubDir), lib);
  +    }
  +
  +    /**
        * 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/antlib.
  -            // 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, "antlib"), library);
  -        }
  -        else if (file == null) {
  -            String msg = "Must specify either library or file attribute.";
  +        if (file == null && classpath == null) {
  +            String msg =
  +                "Must specify either library or file attribute or classpath.";
               throw new BuildException(msg, location);
           }
  -        if (!realFile.exists()) {
  -            String msg = "Cannot find library: " + realFile;
  +        if (file != null && !file.exists()) {
  +            String msg = "Cannot find library: " + file;
               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);
  -        }
  +        loadDefinitions();
  +    }
   
  -        
  -        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 in library and classpath
  +     *
  +     * @exception BuildException failure to access the resource
  +     */
  +    public boolean loadDefinitions() throws BuildException {
  +        return loadDefinitions(ANT_DESCRIPTOR);
       }
   
  -
       /**
  -     * Load definitions directly from an external XML file.
  +     * Load definitions from resource name in library and classpath
        *
  -     * @param xmlfile XML file in the Antlib format.
  -     * @exception BuildException failure to open the file
  +     * @param res the name of the resources to load
  +     * @exception BuildException failure to access the resource
        */
  -    public void loadDefinitions(File xmlfile)
  +    final protected boolean loadDefinitions(String res)
           throws BuildException {
  +        Path path = makeLoaderClasspath();
  +        ClassLoader cl = makeClassLoader(path);
  +        boolean found = false;
           try {
  -            InputStream is = new FileInputStream(xmlfile);
  -            loadDefinitions(is);
  +            for (Enumeration e = getDescriptors(path, res); e.hasMoreElements(); ) {
  +                URL resURL = (URL)e.nextElement();
  +                InputStream is = resURL.openStream();
  +                loadDefinitions(cl, is);
  +                found = true;
  +            }
  +            if (!found && onerror.getIndex() != IGNORE) {
  +                String sPath = path.toString();
  +                if ("".equals(sPath.trim())) {
  +                    sPath = System.getProperty("java.classpath");
  +                }
  +                String msg = "Cannot find any " + res +
  +                    " antlib descriptors in: " + sPath;
  +                switch (onerror.getIndex()) {
  +                case FAIL:
  +                    throw new BuildException(msg);
  +                case REPORT:
  +                    log(msg, project.MSG_WARN);
  +                }
  +            }
           }
           catch (IOException io) {
  -            throw new BuildException("Cannot read file: " + file, io);
  +            String msg = "Cannot load definitions from: " + res;
  +            switch (onerror.getIndex()) {
  +            case FAIL:
  +                throw new BuildException(msg, io);
  +            case REPORT:
  +                log(io.getMessage(), project.MSG_WARN);
  +            }
           }
  +        return found;
       }
   
   
  @@ -343,46 +515,29 @@
        * @param is InputStream for the Antlib descriptor.
        * @exception BuildException trouble
        */
  -    public void loadDefinitions(InputStream is)
  +    private void loadDefinitions(ClassLoader cl, InputStream is)
           throws BuildException {
  -        evaluateDescriptor(null, processAliases(), is);
  +        evaluateDescriptor(cl, processAliases(), is);
       }
   
   
       /**
  -     * get a descriptor from the library file
  +     * get an Enumeration of URLs for all resouces corresponding to the
  +     * descriptor name.
        *
  -     * @param file jarfile to open
  -     * @return input stream to the Descriptor 
  +     * @param res the name of the resource to collect
  +     * @return input stream to the Descriptor or null if none existent
        * @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);
  +    private Enumeration getDescriptors(Path path, final String res)
  +        throws BuildException, IOException {
  +        if (loaderId == null) {
  +            // Path cannot be added to the CoreLoader so simply
  +            // ask for all instances of the resource descriptors
  +            return project.getCoreLoader().getResources(res);
           }
  +
  +        return new DescriptorEnumeration(path.list(), res);
       }
   
   
  @@ -410,18 +565,34 @@
        * @return classloader using te
        * @exception BuildException trouble creating the classloader
        */
  -    protected ClassLoader makeClassLoader(File file)
  +    protected ClassLoader makeClassLoader(Path clspath)
           throws BuildException {
  +        if (loaderId == null) {
  +            log("Loading definitions from CORE, <classpath> ignored",
  +                project.MSG_VERBOSE);
  +            return project.getCoreLoader();
  +        }
  +
  +        log("Using ClassLoader '" + loaderId + "' to load path: " + clspath,
  +            project.MSG_VERBOSE);
  +        return project.addToLoader(loaderId, clspath);
  +    }
  +
  +
  +    /**
  +     * Constructs the Path to add to the ClassLoader
  +     */
  +    private Path makeLoaderClasspath()
  +    {
           Path clspath = new Path(project);
  -        clspath.setLocation(file);
  +        if (file != null) clspath.setLocation(file);
           //append any build supplied classpath
           if (classpath != null) {
               clspath.append(classpath);
           }
  -	return project.getSymbols().addToLoader(loaderId, clspath);
  +        return clspath;
       }
   
  -
       /**
        * parse the antlib descriptor
        *
  @@ -431,8 +602,8 @@
        * @exception BuildException trouble
        */
       protected void evaluateDescriptor(ClassLoader cl,
  -            Properties als, InputStream is)
  -            throws BuildException {
  +                                      Properties als, InputStream is)
  +        throws BuildException {
           try {
               SAXParser saxParser = saxFactory.newSAXParser();
               Parser parser = saxParser.getParser();
  @@ -440,7 +611,7 @@
               InputSource inputSource = new InputSource(is);
               //inputSource.setSystemId(uri); //URI is nasty for jar entries
               project.log("parsing descriptor for library: " + file,
  -                    Project.MSG_VERBOSE);
  +                        Project.MSG_VERBOSE);
               saxParser.parse(inputSource, new AntLibraryHandler(cl, als));
           }
           catch (ParserConfigurationException exc) {
  @@ -485,8 +656,8 @@
   
   
       /**
  -     * Parses the document describing the content of the 
  -     * library. An inner class for access to Project.log 
  +     * Parses the document describing the content of the
  +     * library. An inner class for access to Project.log
        */
       private class AntLibraryHandler extends HandlerBase {
   
  @@ -503,13 +674,11 @@
            */
           private Locator locator = null;
   
  -	private int level = 0;
  -
  -	private SymbolTable symbols = null;
  +        private int level = 0;
   
  -	private String name = null;
  -	private String className = null;
  -	private String adapter = null;
  +        private String name = null;
  +        private String className = null;
  +        private String adapter = null;
   
           /**
            * Constructor for the AntLibraryHandler object
  @@ -520,7 +689,6 @@
           AntLibraryHandler(ClassLoader classloader, Properties als) {
               this.classloader = classloader;
               this.aliasMap = als;
  -	    this.symbols = project.getSymbols();
           }
   
           /**
  @@ -533,35 +701,35 @@
               this.locator = locator;
           }
   
  -	private void parseAttributes(String tag, AttributeList attrs) 
  -	    throws SAXParseException {
  -	    name = null;
  -	    className = null;
  -	    adapter = 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 if ("role".equals(tag) && key.equals("adapter")) {
  -		    adapter = value;
  -		}
  -		else {
  -		    throw new SAXParseException("Unexpected attribute \""
  -						+ key + "\"", locator);
  -		}
  -	    }
  -	    if (name == null || className == null) {
  -		String msg = "Underspecified " + tag + " declaration.";
  -		throw new SAXParseException(msg, locator);
  -	    }
  -	}
  +        private void parseAttributes(String tag, AttributeList attrs)
  +            throws SAXParseException {
  +            name = null;
  +            className = null;
  +            adapter = 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 if ("role".equals(tag) && key.equals("adapter")) {
  +                    adapter = value;
  +                }
  +                else {
  +                    throw new SAXParseException("Unexpected attribute \""
  +                                                + key + "\"", locator);
  +                }
  +            }
  +            if (name == null || className == null) {
  +                String msg = "Underspecified " + tag + " declaration.";
  +                throw new SAXParseException(msg, locator);
  +            }
  +        }
   
           /**
            * SAX callback handler
  @@ -572,103 +740,105 @@
            */
           public void startElement(String tag, AttributeList attrs)
               throws SAXParseException {
  -	    level ++;
  +            level ++;
               if ("antlib".equals(tag)) {
  -		if (level > 1) {
  -		    throw new SAXParseException("Unexpected element: " + tag,
  -						locator);
  -		}
  +                if (level > 1) {
  +                    throw new SAXParseException("Unexpected element: " + tag,
  +                                                locator);
  +                }
                   // No attributes to worry about
                   return;
               }
  -	    if (level == 1) {
  -		throw new SAXParseException("Missing antlib root element",
  -					    locator);
  -	    }
  -
  -	    // Must have the two attributes declared
  -	    parseAttributes(tag, attrs);
  -
  -	    try {
  -		if ("role".equals(tag)) {
  -		    if (isRoleInUse(name)) {
  -			String msg = "Cannot override role: " + name;
  -			log(msg, Project.MSG_WARN);
  -			return;			
  -		    }
  -		    // Defining a new role
  -		    symbols.addRole(name, loadClass(className),
  -				    (adapter == null? 
  -				     null : loadClass(adapter))); 
  -		    return;
  -		}
  -
  -		// Defining a new element kind
  -		//check for name alias
  -		String alias = aliasMap.getProperty(name);
  -		if (alias != null) {
  -		    name = alias;
  -		}
  -		//catch an attempted override of an existing name
  -		if (!override && isInUse(tag, name)) {
  -		    String msg = "Cannot override " + tag + ": " + name;
  -		    log(msg, Project.MSG_WARN);
  -		    return;
  -		}
  -		symbols.add(tag, name, loadClass(className));
  -	    }
  -	    catch(BuildException be) {
  -		throw new SAXParseException(be.getMessage(), locator, be);
  -	    }
  -        }
  -
  -	public void endElement(String tag) {
  -	    level--;
  -	}
  -
  -	private Class loadClass(String className)
  -	    throws SAXParseException {
  -	    try {
  -		//load the named class
  -		Class cls;
  -		if(classloader==null) {
  -		    cls=Class.forName(className);
  -		}
  -		else {
  -		    cls=classloader.loadClass(className);
  -		}
  -		return 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);
  -	    }
  -	}
  +            if (level == 1) {
  +                throw new SAXParseException("Missing antlib root element",
  +                                            locator);
  +            }
   
  -        /**
  -         * test for a name being in use already on this role
  -         *
  -         * @param name the name to test
  -         * @return true if it is a task or a datatype
  -         */
  -        private boolean isInUse(String role, String name) {
  -            return (symbols.get(role, name) != null);
  +            // Must have the two attributes declared
  +            parseAttributes(tag, attrs);
  +
  +            try {
  +                if ("role".equals(tag)) {
  +                    if (project.isRoleDefined(name)) {
  +                        String msg = "Cannot override role: " + name;
  +                        log(msg, Project.MSG_WARN);
  +                        return;
  +                    }
  +                    // Defining a new role
  +                    Class clz = loadClass(className);
  +                    if (clz != null) {
  +                        project.addRoleDefinition(name, clz,
  +                                                  (adapter == null? null :
  +                                                   loadClass(adapter)));
  +                    }
  +                    return;
  +                }
  +
  +                // Defining a new element kind
  +                //check for name alias
  +                String alias = aliasMap.getProperty(name);
  +                if (alias != null) {
  +                    name = alias;
  +                }
  +                //catch an attempted override of an existing name
  +                if (!override && project.isDefinedOnRole(tag, name)) {
  +                    String msg = "Cannot override " + tag + ": " + name;
  +                    log(msg, Project.MSG_WARN);
  +                    return;
  +                }
  +                Class clz = loadClass(className);
  +                if (clz != null)
  +                    project.addDefinitionOnRole(tag, name, clz);
  +            }
  +            catch(BuildException be) {
  +                switch (onerror.getIndex()) {
  +                case FAIL:
  +                    throw new SAXParseException(be.getMessage(), locator, be);
  +                case REPORT:
  +                    project.log(be.getMessage(), project.MSG_WARN);
  +                    break;
  +                default:
  +                    project.log(be.getMessage(), project.MSG_DEBUG);
  +                }
  +            }
           }
   
  -        /**
  -         * test for a role name being in use already
  -         *
  -         * @param name the name to test
  -         * @return true if it is a task or a datatype
  -         */
  -        private boolean isRoleInUse(String name) {
  -            return (symbols.getRole(name) != null);
  +        public void endElement(String tag) {
  +            level--;
  +        }
  +
  +        private Class loadClass(String className)
  +            throws SAXParseException {
  +            String msg = null;
  +            try {
  +                //load the named class
  +                Class cls;
  +                if(classloader==null) {
  +                    cls=Class.forName(className);
  +                }
  +                else {
  +                    cls=classloader.loadClass(className);
  +                }
  +                return cls;
  +            }
  +            catch (ClassNotFoundException cnfe) {
  +                msg = "Class " + className + " cannot be found";
  +                if (onerror.getIndex() == FAIL)
  +                    throw new SAXParseException(msg, locator, cnfe);
  +            }
  +            catch (NoClassDefFoundError ncdfe) {
  +                msg = "Class " + className + " cannot be loaded";
  +                if (onerror.getIndex() == FAIL)
  +                    throw new SAXParseException(msg, locator);
  +            }
  +
  +            if (onerror.getIndex() == REPORT) {
  +                project.log(msg, project.MSG_WARN);
  +            }
  +            else {
  +                project.log(msg, project.MSG_DEBUG);
  +            }
  +            return null;
           }
   
       //end inner class AntLibraryHandler
  @@ -712,7 +882,7 @@
           }
       //end inner class alias
       }
  -    
  +
   //end class Antlib
   }
   
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>