FileDocCategorySizeDatePackage
Definer.javaAPI DocApache Ant 1.7020343Wed Dec 13 06:16:20 GMT 2006org.apache.tools.ant.taskdefs

Definer

public abstract class Definer extends DefBase
Base class for Taskdef and Typedef - handles all the attributes for Typedef. The uri and class handling is handled by DefBase
since
Ant 1.4

Fields Summary
private static final String
ANTLIB_XML
the extension of an antlib file for autoloading. {@value[
private static ResourceStack
resourceStack
private String
name
private String
classname
private File
file
private String
resource
private int
format
private boolean
definerSet
private int
onError
private String
adapter
private String
adaptTo
private Class
adapterClass
private Class
adaptToClass
Constructors Summary
Methods Summary
protected voidaddDefinition(java.lang.ClassLoader al, java.lang.String name, java.lang.String classname)
Add a definition using the attributes of Definer

param
al the ClassLoader to use
param
name the name of the definition
param
classname the classname of the definition
exception
BuildException if an error occurs

        Class cl = null;
        try {
            try {
                name = ProjectHelper.genComponentName(getURI(), name);

                if (onError != OnError.IGNORE) {
                    cl = Class.forName(classname, true, al);
                }

                if (adapter != null) {
                    adapterClass = Class.forName(adapter, true, al);
                }

                if (adaptTo != null) {
                    adaptToClass = Class.forName(adaptTo, true, al);
                }

                AntTypeDefinition def = new AntTypeDefinition();
                def.setName(name);
                def.setClassName(classname);
                def.setClass(cl);
                def.setAdapterClass(adapterClass);
                def.setAdaptToClass(adaptToClass);
                def.setClassLoader(al);
                if (cl != null) {
                    def.checkClass(getProject());
                }
                ComponentHelper.getComponentHelper(getProject())
                    .addDataTypeDefinition(def);
            } catch (ClassNotFoundException cnfe) {
                String msg = getTaskName() + " class " + classname
                    + " cannot be found";
                throw new BuildException(msg, cnfe, getLocation());
            } catch (NoClassDefFoundError ncdfe) {
                String msg = getTaskName() + " A class needed by class "
                    + classname + " cannot be found: " + ncdfe.getMessage();
                throw new BuildException(msg, ncdfe, getLocation());
            }
        } catch (BuildException ex) {
            switch (onError) {
                case OnError.FAIL_ALL:
                case OnError.FAIL:
                    throw ex;
                case OnError.REPORT:
                    log(ex.getLocation() + "Warning: " + ex.getMessage(),
                        Project.MSG_WARN);
                    break;
                default:
                    log(ex.getLocation() + ex.getMessage(),
                        Project.MSG_DEBUG);
            }
        }
    
public voidexecute()
Run the definition.

exception
BuildException if an error occurs

        ClassLoader al = createLoader();

        if (!definerSet) {
            //we arent fully defined yet. this is an error unless
            //we are in an antlib, in which case the resource name is determined
            //automatically.
            //NB: URIs in the ant core package will be "" at this point.
            if (getURI() == null) {
                throw new BuildException(
                        "name, file or resource attribute of "
                                + getTaskName() + " is undefined",
                        getLocation());
            }

            if (getURI().startsWith(MagicNames.ANTLIB_PREFIX)) {
                //convert the URI to a resource
                String uri1 = getURI();
                setResource(makeResourceFromURI(uri1));
            } else {
                throw new BuildException(
                        "Only antlib URIs can be located from the URI alone,"
                                + "not the URI " + getURI());
            }
        }

        if (name != null) {
            if (classname == null) {
                throw new BuildException(
                    "classname attribute of " + getTaskName() + " element "
                    + "is undefined", getLocation());
            }
            addDefinition(al, name, classname);
        } else {
            if (classname != null) {
                String msg = "You must not specify classname "
                    + "together with file or resource.";
                throw new BuildException(msg, getLocation());
            }
            Enumeration/*<URL>*/ urls = null;
            if (file != null) {
                final URL url = fileToURL();
                if (url == null) {
                    return;
                }
                urls = new Enumeration() {
                    private boolean more = true;
                    public boolean hasMoreElements() {
                        return more;
                    }
                    public Object nextElement() throws NoSuchElementException {
                        if (more) {
                            more = false;
                            return url;
                        } else {
                            throw new NoSuchElementException();
                        }
                    }
                };
            } else {
                urls = resourceToURLs(al);
            }

            while (urls.hasMoreElements()) {
                URL url = (URL) urls.nextElement();

                int fmt = this.format;
                if (url.toString().toLowerCase(Locale.US).endsWith(".xml")) {
                    fmt = Format.XML;
                }

                if (fmt == Format.PROPERTIES) {
                    loadProperties(al, url);
                    break;
                } else {
                    if (resourceStack.getStack().get(url) != null) {
                        log("Warning: Recursive loading of " + url
                            + " ignored"
                            + " at " + getLocation()
                            + " originally loaded at "
                            + resourceStack.getStack().get(url),
                            Project.MSG_WARN);
                    } else {
                        try {
                            resourceStack.getStack().put(url, getLocation());
                            loadAntlib(al, url);
                        } finally {
                            resourceStack.getStack().remove(url);
                        }
                    }
                }
            }
        }
    
private java.net.URLfileToURL()
Convert a file to a file: URL.

return
the URL, or null if it isn't valid and the active error policy is not to raise a fault
throws
BuildException if the file is missing/not a file and the policy requires failure at this point.

        String message = null;
        if (!(file.exists())) {
            message = "File " + file + " does not exist";
        }
        if (message == null && !(file.isFile())) {
            message = "File " + file + " is not a file";
        }
        try {
            if (message == null) {
                return file.toURL();
            }
        } catch (Exception ex) {
            message =
                "File " + file + " cannot use as URL: "
                + ex.toString();
        }
        // Here if there is an error
        switch (onError) {
            case OnError.FAIL_ALL:
                throw new BuildException(message);
            case OnError.FAIL:
                // Fall Through
            case OnError.REPORT:
                log(message, Project.MSG_WARN);
                break;
            case OnError.IGNORE:
                // log at a lower level
                log(message, Project.MSG_VERBOSE);
                break;
            default:
                // Ignore the problem
                break;
        }
        return null;
    
public java.lang.StringgetClassname()
Returns the classname of the object we are defining. May be null.

return
the class name

        return classname;
    
public java.io.FilegetFile()

return
the file containing definitions

        return file;
    
public java.lang.StringgetName()

return
the name for this definition

        return name;
    
public java.lang.StringgetResource()

return
the resource containing definitions

        return resource;
    
private voidloadAntlib(java.lang.ClassLoader classLoader, java.net.URL url)
Load an antlib from a URL.

param
classLoader the classloader to use.
param
url the url to load the definitions from.

        try {
            Antlib antlib = Antlib.createAntlib(getProject(), url, getURI());
            antlib.setClassLoader(classLoader);
            antlib.setURI(getURI());
            antlib.execute();
        } catch (BuildException ex) {
            throw ProjectHelper.addLocationToBuildException(
                ex, getLocation());
        }
    
protected voidloadProperties(java.lang.ClassLoader al, java.net.URL url)
Load type definitions as properties from a URL.

param
al the classloader to use
param
url the url to get the definitions from

        InputStream is = null;
        try {
            is = url.openStream();
            if (is == null) {
                log("Could not load definitions from " + url,
                    Project.MSG_WARN);
                return;
            }
            Properties props = new Properties();
            props.load(is);
            Enumeration keys = props.keys();
            while (keys.hasMoreElements()) {
                name = ((String) keys.nextElement());
                classname = props.getProperty(name);
                addDefinition(al, name, classname);
            }
        } catch (IOException ex) {
            throw new BuildException(ex, getLocation());
        } finally {
            FileUtils.close(is);
        }
    
public static java.lang.StringmakeResourceFromURI(java.lang.String uri)
This is where the logic to map from a URI to an antlib resource is kept.

param
uri the xml namespace uri that to convert.
return
the name of a resource. It may not exist

        String path = uri.substring(MagicNames.ANTLIB_PREFIX.length());
        String resource;
        if (path.startsWith("//")) {
            //handle new style full paths to an antlib, in which
            //all but the forward slashes are allowed.
            resource = path.substring("//".length());
            if (!resource.endsWith(".xml")) {
                //if we haven't already named an XML file, it gets antlib.xml
                resource = resource + ANTLIB_XML;
            }
        } else {
            //convert from a package to a path
            resource = path.replace('.", '/") + ANTLIB_XML;
        }
        return resource;
    
private java.util.EnumerationresourceToURLs(java.lang.ClassLoader classLoader)

        Enumeration ret;
        try {
            ret = classLoader.getResources(resource);
        } catch (IOException e) {
            throw new BuildException(
                "Could not fetch resources named " + resource,
                e, getLocation());
        }
        if (!ret.hasMoreElements()) {
            String message = "Could not load definitions from resource "
                + resource + ". It could not be found.";
            switch (onError) {
                case OnError.FAIL_ALL:
                    throw new BuildException(message);
                case OnError.FAIL:
                case OnError.REPORT:
                    log(message, Project.MSG_WARN);
                    break;
                case OnError.IGNORE:
                    log(message, Project.MSG_VERBOSE);
                    break;
                default:
                    // Ignore the problem
                    break;
            }
        }
        return ret;
    
public voidsetAdaptTo(java.lang.String adaptTo)
Set the classname of the class that the definition must be compatible with, either directly or by use of the adapter class.

param
adaptTo the name of the adaptto class

        this.adaptTo = adaptTo;
    
protected voidsetAdaptToClass(java.lang.Class adaptToClass)
Set the class for adaptToClass, to be used by derived classes, used instead of the adaptTo attribute.

param
adaptToClass the class for adapto.

        this.adaptToClass = adaptToClass;
    
public voidsetAdapter(java.lang.String adapter)
Set the class name of the adapter class. An adapter class is used to proxy the definition class. It is used if the definition class is not assignable to the adaptto class, or if the adaptto class is not present.

param
adapter the name of the adapter class

        this.adapter = adapter;
    
protected voidsetAdapterClass(java.lang.Class adapterClass)
Set the adapter class.

param
adapterClass the class to use to adapt the definition class

        this.adapterClass = adapterClass;
    
public voidsetAntlib(java.lang.String antlib)
Antlib attribute, sets resource and uri. uri is set the antlib value and, resource is set to the antlib.xml resource in the classpath. For example antlib="antlib:org.acme.bland.cola" corresponds to uri="antlib:org.acme.bland.cola" resource="org/acme/bland/cola/antlib.xml". ASF Bugzilla Bug 31999

param
antlib the value to set.

        if (definerSet) {
            tooManyDefinitions();
        }
        if (!antlib.startsWith("antlib:")) {
            throw new BuildException(
                "Invalid antlib attribute - it must start with antlib:");
        }
        setURI(antlib);
        this.resource = antlib.substring("antlib:".length()).replace('.", '/")
            + "/antlib.xml";
        definerSet = true;
    
public voidsetClassname(java.lang.String classname)
The full class name of the object being defined. Required, unless file or resource have been specified.

param
classname the name of the class

        this.classname = classname;
    
public voidsetFile(java.io.File file)
Name of the property file to load ant name/classname pairs from.

param
file the file

        if (definerSet) {
            tooManyDefinitions();
        }
        definerSet = true;
        this.file = file;
    
public voidsetFormat(org.apache.tools.ant.taskdefs.Definer$Format format)
Sets the format of the file or resource

param
format the enumerated value - xml or properties

        this.format = format.getIndex();
    
public voidsetName(java.lang.String name)
Name of the definition

param
name the name of the definition

        if (definerSet) {
            tooManyDefinitions();
        }
        definerSet = true;
        this.name = name;
    
public voidsetOnError(org.apache.tools.ant.taskdefs.Definer$OnError onError)
What to do if there is an error in loading the class.
  • error - throw build exception
  • report - output at warning level
  • ignore - output at debug level
  • param
    onError an OnError value

            this.onError = onError.getIndex();
        
    public voidsetResource(java.lang.String res)
    Name of the property resource to load ant name/classname pairs from.

    param
    res the resource to use

            if (definerSet) {
                tooManyDefinitions();
            }
            definerSet = true;
            this.resource = res;
        
    private voidtooManyDefinitions()
    handle too many definitions by raising an exception.

    throws
    BuildException always.

            throw new BuildException(
                "Only one of the attributes name, file and resource"
                + " can be set", getLocation());