Base class for Taskdef and Typedef - handles all
the attributes for Typedef. The uri and class
handling is handled by DefBase
| Method from org.apache.tools.ant.taskdefs.Definer Detail: |
protected void addDefinition(ClassLoader al,
String name,
String classname) throws BuildException {
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);
}
}
}
Add a definition using the attributes of Definer |
public void execute() throws BuildException {
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);
}
}
}
}
}
}
|
public String getClassname() {
return classname;
}
Returns the classname of the object we are defining.
May be null. |
public File getFile() {
return file;
}
|
public String getName() {
return name;
}
|
public String getResource() {
return resource;
}
|
protected void loadProperties(ClassLoader al,
URL url) {
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);
}
}
Load type definitions as properties from a URL. |
public static String makeResourceFromURI(String uri) {
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;
}
This is where the logic to map from a URI to an antlib resource
is kept. |
public void setAdaptTo(String adaptTo) {
this.adaptTo = adaptTo;
}
Set the classname of the class that the definition
must be compatible with, either directly or
by use of the adapter class. |
protected void setAdaptToClass(Class adaptToClass) {
this.adaptToClass = adaptToClass;
}
Set the class for adaptToClass, to be
used by derived classes, used instead of
the adaptTo attribute. |
public void setAdapter(String adapter) {
this.adapter = 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. |
protected void setAdapterClass(Class adapterClass) {
this.adapterClass = adapterClass;
}
|
public void setAntlib(String antlib) {
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;
}
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 |
public void setClassname(String classname) {
this.classname = classname;
}
The full class name of the object being defined.
Required, unless file or resource have
been specified. |
public void setFile(File file) {
if (definerSet) {
tooManyDefinitions();
}
definerSet = true;
this.file = file;
}
Name of the property file to load
ant name/classname pairs from. |
public void setFormat(Definer.Format format) {
this.format = format.getIndex();
}
Sets the format of the file or resource |
public void setName(String name) {
if (definerSet) {
tooManyDefinitions();
}
definerSet = true;
this.name = name;
}
|
public void setOnError(Definer.OnError onError) {
this.onError = onError.getIndex();
}
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
|
public void setResource(String res) {
if (definerSet) {
tooManyDefinitions();
}
definerSet = true;
this.resource = res;
}
Name of the property resource to load
ant name/classname pairs from. |