Browse Source

Add ns support

Also split Definer.java in a base class (DefBase) to allow
it to be used for other defining tasks
Also add AntlibInterface to allow antlib to set uri and
classloader for other tasks/types that Definer.

Bugzilla: 19897


git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@275064 13f79535-47bb-0310-9956-ffa450edef68
master
Peter Reilly 22 years ago
parent
commit
ca5799fd8c
10 changed files with 650 additions and 173 deletions
  1. +106
    -14
      src/main/org/apache/tools/ant/ComponentHelper.java
  2. +35
    -0
      src/main/org/apache/tools/ant/ProjectHelper.java
  3. +10
    -2
      src/main/org/apache/tools/ant/RuntimeConfigurable.java
  4. +39
    -4
      src/main/org/apache/tools/ant/UnknownElement.java
  5. +54
    -1
      src/main/org/apache/tools/ant/helper/AntXMLContext.java
  6. +50
    -7
      src/main/org/apache/tools/ant/helper/ProjectHelper2.java
  7. +31
    -14
      src/main/org/apache/tools/ant/taskdefs/Antlib.java
  8. +81
    -0
      src/main/org/apache/tools/ant/taskdefs/AntlibInterface.java
  9. +234
    -0
      src/main/org/apache/tools/ant/taskdefs/DefBase.java
  10. +10
    -131
      src/main/org/apache/tools/ant/taskdefs/Definer.java

+ 106
- 14
src/main/org/apache/tools/ant/ComponentHelper.java View File

@@ -58,14 +58,19 @@ import org.apache.tools.ant.util.WeakishReference;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import java.util.Stack;

import java.util.Vector;
import java.io.InputStream;
import java.io.IOException;
import java.lang.reflect.Modifier;

import org.apache.tools.ant.taskdefs.Typedef;

/**
* Component creation and configuration.
*
@@ -98,6 +103,17 @@ public class ComponentHelper {
/** flag to rebuild typeClassDefinitions */
private boolean rebuildTypeClassDefinitions = true;

/** Set of namespaces that have been checked for antlibs */
private Set checkedNamespaces = new HashSet();

/**
* Stack of antlib contexts used to resolve definitions while
* processing antlib
*/
private Stack antLibStack = new Stack();
/** current antlib context */
private AntTypeTable antLibTypeTable = null;

/**
* Map from task names to vectors of created tasks
* (String to Vector of Task). This is used to invalidate tasks if
@@ -175,32 +191,38 @@ public class ComponentHelper {
AntTypeDefinition def = (AntTypeDefinition) i.next();
antTypeTable.put(def.getName(), def);
}
// add the parsed namespaces of the parent project
checkedNamespaces.add(helper.checkedNamespaces);
}

/** Factory method to create the components.
*
* This should be called by UnknownElement.
*
* @param ue The component helper has access via ue to the entire XML tree.
* @param ns Namespace. Also available as ue.getNamespace()
* @param taskName The element name. Also available as ue.getTag()
* @param ue The Unknown Element creating this component
* @param ns Namespace URI. Also available as ue.getNamespace()
* @param componentType The component type,
* Also available as ue.getComponentName()
* @return the created component
* @throws BuildException if an error occuries
*/
public Object createComponent(UnknownElement ue,
String ns,
String taskName)
String componentType)
throws BuildException {
Object component = createComponent(taskName);
Object component = createComponent(componentType);
if (component == null) {
return null;
}

if (component instanceof Task) {
Task task = (Task) component;
task.setTaskType(taskName);
task.setTaskName(taskName);
addCreatedTask(taskName, task);
task.setLocation(ue.getLocation());
task.setTaskType(componentType);
task.setTaskName(ue.getTaskName());
task.setOwningTarget(ue.getOwningTarget());
task.init();
addCreatedTask(componentType, task);
}

return component;
@@ -215,7 +237,11 @@ public class ComponentHelper {
* @return the class if found or null if not.
*/
public Object createComponent(String componentName) {
return antTypeTable.create(componentName);
AntTypeDefinition def = getDefinition(componentName);
if (def == null) {
return null;
}
return def.create(project);
}

/**
@@ -227,7 +253,11 @@ public class ComponentHelper {
* @return the class if found or null if not.
*/
public Class getComponentClass(String componentName) {
return antTypeTable.getExposedClass(componentName);
AntTypeDefinition def = getDefinition(componentName);
if (def == null) {
return null;
}
return def.getExposedClass(project);
}

/**
@@ -236,7 +266,15 @@ public class ComponentHelper {
* @return the ant definition or null if not present
*/
public AntTypeDefinition getDefinition(String componentName) {
return antTypeTable.getDefinition(componentName);
checkNamespace(componentName);
AntTypeDefinition ret = null;
if (antLibTypeTable != null && componentName.indexOf(':') == -1) {
ret = antLibTypeTable.getDefinition(componentName);
}
if (ret == null) {
ret = antTypeTable.getDefinition(componentName);
}
return ret;
}

/**
@@ -474,7 +512,7 @@ public class ComponentHelper {
* creation fails.
*/
private Task createNewTask(String taskType) throws BuildException {
Class c = antTypeTable.getExposedClass(taskType);
Class c = getComponentClass(taskType);
if (c == null) {
return null;
}
@@ -482,7 +520,7 @@ public class ComponentHelper {
if (!(Task.class.isAssignableFrom(c))) {
return null;
}
Task task = (Task) antTypeTable.create(taskType);
Task task = (Task) createComponent(taskType);
if (task == null) {
return null;
}
@@ -557,7 +595,7 @@ public class ComponentHelper {
* instance creation fails.
*/
public Object createDataType(String typeName) throws BuildException {
return antTypeTable.create(typeName);
return createComponent(typeName);
}

/**
@@ -660,6 +698,31 @@ public class ComponentHelper {
project.log(" +Datatype " + name + " " + def.getClassName(),
Project.MSG_DEBUG);
antTypeTable.put(name, def);

if (antLibTypeTable != null && name.lastIndexOf(':') != -1) {
String baseName = name.substring(name.lastIndexOf(':') + 1);
antLibTypeTable.put(baseName, def);
}
}
}

/**
* Called at the start of processing an antlib
*/
public void enterAntLib() {
antLibTypeTable = new AntTypeTable(project);
antLibStack.push(antLibTypeTable);
}

/**
* Called at the end of processing an antlib
*/
public void exitAntLib() {
antLibStack.pop();
if (antLibStack.size() != 0) {
antLibTypeTable = (AntTypeTable) antLibStack.peek();
} else {
antLibTypeTable = null;
}
}

@@ -751,6 +814,35 @@ public class ComponentHelper {
}
}

/**
* called for each component name, check if the
* associated URI has been examined for antlibs.
*/
private void checkNamespace(String componentName) {
if (componentName.indexOf(':') == -1) {
return; // not a namespaced name
}

String uri = ProjectHelper.extractUriFromComponentName(componentName);
if (!uri.startsWith(ProjectHelper.ANTLIB_URI)) {
return; // namespace that does not contain antlib
}
if (checkedNamespaces.contains(uri)) {
return; // Alreay processed
}
checkedNamespaces.add(uri);
Typedef definer = new Typedef();
definer.setProject(project);
definer.setURI(uri);
definer.setResource(
uri.substring("antlib:".length()).replace('.', '/')
+ "/antlib.xml");
// a fishing expedition :- ignore errors if antlib not present
definer.setOnError(new Typedef.OnError("ignore"));
definer.init();
definer.execute();
}

/**
* map that contains the component definitions
*/


+ 35
- 0
src/main/org/apache/tools/ant/ProjectHelper.java View File

@@ -85,6 +85,12 @@ import org.xml.sax.AttributeList;
* @author duncan@x180.com
*/
public class ProjectHelper {
/** The URI for ant name space */
public static final String ANT_CORE_URI = "ant:core";

/** The URI for defined types/tasks - the format is antlib:<package> */
public static final String ANTLIB_URI = "antlib:";

/**
* Name of JVM system property which provides the name of the
* ProjectHelper class to use.
@@ -493,5 +499,34 @@ public class ProjectHelper {
PropertyHelper.parsePropertyStringDefault(value, fragments,
propertyRefs);
}
/**
* Map a namespaced {uri,name} to an internal string format.
* For BC purposes the names from the ant core uri will be
* mapped to "name", other names will be mapped to
* uri + ":" + name.
* @param uri The namepace URI
* @param name The localname
* @return The stringified form of the ns name
*/
public static String genComponentName(String uri, String name) {
if (uri == null || uri.equals("") || uri.equals(ANT_CORE_URI)) {
return name;
}
return uri + ":" + name;
}

/**
* extract a uri from a component name
*
* @param componentName The stringified form for {uri, name}
* @return The uri or "" if not present
*/
public static String extractUriFromComponentName(String componentName) {
int index = componentName.lastIndexOf(':');
if (index == -1) {
return "";
}
return componentName.substring(0, index);
}
//end class
}

+ 10
- 2
src/main/org/apache/tools/ant/RuntimeConfigurable.java View File

@@ -176,6 +176,14 @@ public class RuntimeConfigurable implements Serializable {
return polyType;
}

/**
* set the polymorphic type for this element
* @param polyType the ant component type name, null if not set
*/
public void setPolyType(String polyType) {
this.polyType = polyType;
}

/**
* Sets the attributes for the wrapped element.
*
@@ -260,10 +268,10 @@ public class RuntimeConfigurable implements Serializable {

/**
* Returns an enumeration of all child wrappers.
*
* @return an enumeration of the child wrappers.
* @since Ant 1.5.1
*/
Enumeration getChildren() {
public Enumeration getChildren() {
if (children != null) {
return Collections.enumeration(children);
} else {


+ 39
- 4
src/main/org/apache/tools/ant/UnknownElement.java View File

@@ -81,6 +81,11 @@ public class UnknownElement extends Task {
*/
private String namespace;

/**
* Holds the namespace qname of the element.
*/
private String qname;

/**
* The real object after it has been loaded.
*/
@@ -129,6 +134,24 @@ public class UnknownElement extends Task {
this.namespace = namespace;
}

/** Return the qname of the XML element associated with this component.
*
* @return namespace Qname used in the element declaration.
*/
public String getQName() {
return qname;
}

/** Set the namespace qname of the XML element.
* This method is typically called by the XML processor.
*
* @param qname the qualified name of the element
*/
public void setQName(String qname) {
this.qname = qname;
}


/**
* Get the RuntimeConfigurable instance for this UnknownElement, containing
* the configuration information.
@@ -334,6 +357,13 @@ public class UnknownElement extends Task {
}
}

/**
* @return the component name - uses ProjectHelper#genComponentName()
*/
protected String getComponentName() {
return ProjectHelper.genComponentName(getNamespace(), getTag());
}

/**
* Creates a named task or data type. If the real object is a task,
* it is configured up to the init() stage.
@@ -345,12 +375,17 @@ public class UnknownElement extends Task {
* @return the task or data type represented by the given unknown element.
*/
protected Object makeObject(UnknownElement ue, RuntimeConfigurable w) {
Object o = makeTask(ue, w);
ComponentHelper helper = ComponentHelper.getComponentHelper(
getProject());
String name = ue.getComponentName();
Object o = helper.createComponent(ue, ue.getNamespace(), name);
if (o == null) {
o = getProject().createDataType(ue.getTag());
throw getNotFoundException("task or type", name);
}
if (o == null) {
throw getNotFoundException("task or type", ue.getTag());
if (o instanceof Task) {
Task task = (Task) o;
task.setOwningTarget(getOwningTarget());
task.init();
}
return o;
}


+ 54
- 1
src/main/org/apache/tools/ant/helper/AntXMLContext.java View File

@@ -54,6 +54,10 @@
package org.apache.tools.ant.helper;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.xml.sax.Locator;
@@ -120,6 +124,11 @@ public class AntXMLContext {
* when processing a particular build file.
*/
private boolean ignoreProjectTag = false;

/** Keeps track of prefix -> uri mapping during parsing */
private Map prefixMapping = new HashMap();


/**
* constructor
* @param project the project to which this antxml context belongs to
@@ -263,7 +272,7 @@ public class AntXMLContext {

/**
* sets the implicit target
* @param target
* @param target the implicit target
*/
public void setImplicitTarget(Target target) {
this.implicitTarget = target;
@@ -284,6 +293,8 @@ public class AntXMLContext {
* <p>
* This method was moved out of the configure method to allow
* it to be executed at parse time.
* @param element the current element
* @param attr attributes of the current element
*/
public void configureId(Object element, Attributes attr) {
String id = attr.getValue("id");
@@ -323,6 +334,48 @@ public class AntXMLContext {
public void setIgnoreProjectTag(boolean flag) {
this.ignoreProjectTag = flag;
}

/**
* Called during parsing, stores the prefix to uri mapping.
*
* @param prefix a namespace prefix
* @param uri a namespace uri
*/
public void startPrefixMapping(String prefix, String uri) {
List list = (List) prefixMapping.get(prefix);
if (list == null) {
list = new ArrayList();
prefixMapping.put(prefix, list);
}
list.add(uri);
}

/**
* End of prefix to uri mapping.
*
* @param prefix the namespace prefix
*/
public void endPrefixMapping(String prefix) {
List list = (List) prefixMapping.get(prefix);
if (list == null || list.size() == 0) {
return; // Should not happen
}
list.remove(list.size() - 1);
}

/**
* prefix to namespace uri mapping
*
* @param prefix the prefix to map
* @return the uri for this prefix, null if not present
*/
public String getPrefixMapping(String prefix) {
List list = (List) prefixMapping.get(prefix);
if (list == null || list.size() == 0) {
return null;
}
return (String) list.get(list.size() - 1);
}
}



+ 50
- 7
src/main/org/apache/tools/ant/helper/ProjectHelper2.java View File

@@ -474,6 +474,9 @@ public class ProjectHelper2 extends ProjectHelper {
*/
public void startElement(String uri, String tag, String qname, Attributes attrs)
throws SAXParseException {
if (uri.equals(ANT_CORE_URI)) {
uri = "";
}
AntHandler next
= currentHandler.onStartChild(uri, tag, qname, attrs, context);
antHandlers.push(currentHandler);
@@ -506,6 +509,9 @@ public class ProjectHelper2 extends ProjectHelper {
*
*/
public void endElement(String uri, String name, String qName) throws SAXException {
if (uri.equals(ANT_CORE_URI)) {
uri = "";
}
currentHandler.onEndElement(uri, name, context);
AntHandler prev = (AntHandler) antHandlers.pop();
currentHandler = prev;
@@ -526,6 +532,25 @@ public class ProjectHelper2 extends ProjectHelper {
throws SAXParseException {
currentHandler.characters(buf, start, count, context);
}

/**
* Start a namespace prefix to uri mapping
*
* @param prefix the namespace prefix
* @param uri the namespace uri
*/
public void startPrefixMapping(String prefix, String uri) {
context.startPrefixMapping(prefix, uri);
}

/**
* End a namepace prefix to uri mapping
*
* @param prefix the prefix that is not mapped anymore
*/
public void endPrefixMapping(String prefix) {
context.endPrefixMapping(prefix);
}
}

/**
@@ -550,7 +575,7 @@ public class ProjectHelper2 extends ProjectHelper {
Attributes attrs,
AntXMLContext context)
throws SAXParseException {
if (qname.equals("project")) {
if (name.equals("project") && uri.equals("")) {
return ProjectHelper2.projectHandler;
} else {
// if (context.importlevel > 0) {
@@ -610,7 +635,7 @@ public class ProjectHelper2 extends ProjectHelper {
*/

for (int i = 0; i < attrs.getLength(); i++) {
String key = attrs.getQName(i);
String key = attrs.getLocalName(i);
String value = attrs.getValue(i);

if (key.equals("default")) {
@@ -715,7 +740,7 @@ public class ProjectHelper2 extends ProjectHelper {
Attributes attrs,
AntXMLContext context)
throws SAXParseException {
if (qname.equals("target")) {
if (name.equals("target") && uri.equals("")) {
return ProjectHelper2.targetHandler;
} else {
return ProjectHelper2.elementHandler;
@@ -761,7 +786,7 @@ public class ProjectHelper2 extends ProjectHelper {
context.addTarget(target);

for (int i = 0; i < attrs.getLength(); i++) {
String key = attrs.getQName(i);
String key = attrs.getLocalName(i);
String value = attrs.getValue(i);

if (key.equals("name")) {
@@ -904,7 +929,7 @@ public class ProjectHelper2 extends ProjectHelper {
task.setNamespace(uri);
task.setProject(context.getProject());
//XXX task.setTaskType(qname);
task.setQName(qname);
task.setTaskName(qname);

Location location = new Location(context.getLocator().getSystemId(),
@@ -930,8 +955,26 @@ public class ProjectHelper2 extends ProjectHelper {
= new RuntimeConfigurable(task, task.getTaskName());

for (int i = 0; i < attrs.getLength(); i++) {
wrapper.setAttribute(attrs.getQName(i),
attrs.getValue(i));
String name = attrs.getLocalName(i);
String value = attrs.getValue(i);
// PR: Hack for ant-type value
// an ant-type is a component name which can
// be namespaced, need to extract the name
// and convert from qualifed name to uri/name
if (name.equals("ant-type")) {
int index = value.indexOf(":");
if (index != -1) {
String prefix = value.substring(0, index);
String mappedUri = context.getPrefixMapping(prefix);
if (mappedUri == null) {
throw new BuildException(
"Unable to find XML NS prefix " + prefix);
}
value = ProjectHelper.genComponentName(
mappedUri, value.substring(index + 1));
}
}
wrapper.setAttribute(name, value);
}

if (parentWrapper != null) {


+ 31
- 14
src/main/org/apache/tools/ant/taskdefs/Antlib.java View File

@@ -62,7 +62,7 @@ import java.util.List;

import org.apache.tools.ant.TaskContainer;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Location;
import org.apache.tools.ant.ComponentHelper;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.helper.ProjectHelper2;
@@ -124,6 +124,7 @@ public class Antlib extends Task implements TaskContainer {
//
private ClassLoader classLoader;
private String prefix;
private String uri = "";
private List tasks = new ArrayList();

/**
@@ -137,6 +138,14 @@ public class Antlib extends Task implements TaskContainer {
this.classLoader = classLoader;
}

/**
* Set the URI for this antlib.
* @param uri the namespace uri
*/
protected void setURI(String uri) {
this.uri = uri;
}

private ClassLoader getClassLoader() {
if (classLoader == null) {
classLoader = Antlib.class.getClassLoader();
@@ -158,20 +167,28 @@ public class Antlib extends Task implements TaskContainer {
* any tasks that derive from Definer.
*/
public void execute() {
for (Iterator i = tasks.iterator(); i.hasNext();) {
UnknownElement ue = (UnknownElement) i.next();
ue.maybeConfigure();
setLocation(ue.getLocation());
Task t = ue.getTask();
if (t == null) {
continue;
}
if (t instanceof Definer) {
Definer d = (Definer) t;
d.setInternalClassLoader(getClassLoader());
ComponentHelper helper =
ComponentHelper.getComponentHelper(getProject());
helper.enterAntLib();
try {
for (Iterator i = tasks.iterator(); i.hasNext();) {
UnknownElement ue = (UnknownElement) i.next();
ue.maybeConfigure();
setLocation(ue.getLocation());
Task t = ue.getTask();
if (t == null) {
continue;
}
if (t instanceof AntlibInterface) {
AntlibInterface d = (AntlibInterface) t;
d.setURI(uri);
d.setAntlibClassLoader(getClassLoader());
}
t.init();
t.execute();
}
t.init();
t.execute();
} finally {
helper.exitAntLib();
}
}



+ 81
- 0
src/main/org/apache/tools/ant/taskdefs/AntlibInterface.java View File

@@ -0,0 +1,81 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 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 "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;

/**
* Interface for tasks that should be informed when
* they are loaded in antlib's.
* For handling uri and and class loading.
*
* @author Peter Reilly
*
* @since Ant 1.6
*/
public interface AntlibInterface {

/**
* The URI for this definition.
* @param uri the namespace URI
*/
void setURI(String uri);

/**
* Set the class loader of the loading object
*
* @param classLoader a <code>ClassLoader</code> value
*/
void setAntlibClassLoader(ClassLoader classLoader);

}

+ 234
- 0
src/main/org/apache/tools/ant/taskdefs/DefBase.java View File

@@ -0,0 +1,234 @@
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2003 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 "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.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.util.ClasspathUtils;

/**
* Base class for Definitions
* handling uri and and class loading.
* (This was part of Definer)
*
* @author Costin Manolache
* @author Stefan Bodewig
* @author Peter Reilly
*
* @since Ant 1.6
*/
public abstract class DefBase extends Task implements AntlibInterface {
private String uri = "";
private ClassLoader internalClassLoader;
private ClassLoader createdLoader;
private ClasspathUtils.Delegate cpDelegate;

/**
* The URI for this definition.
* If the URI is "ant:core", the uri will be set to "". (This
* is the default uri).
* URIs that start with "ant:" and are not
* "ant:core" are reserved and are not allowed in this context.
* @param uri the namespace URI
* @throws BuildException if a reserved URI is used
*/
public void setURI(String uri) throws BuildException {
if (uri.equals(ProjectHelper.ANT_CORE_URI)) {
uri = "";
}
if (uri.startsWith("ant:") && !uri.startsWith("antlib:")) {
throw new BuildException("Attempt to use use a reserved URI " + uri);
}
this.uri = uri;
}

/**
* @return the namespace uri for this definition
*/
public String getUri() {
return uri;
}


/**
* Set the class loader, overrides the cpDelagate
* classloader.
*
* @param classLoader a <code>ClassLoader</code> value
*/
public void setAntlibClassLoader(ClassLoader classLoader) {
this.internalClassLoader = classLoader;
}

/**
* @param reverseLoader if true a delegated loader will take precedence over
* the parent
* @deprecated stop using this attribute
* @ant.attribute ignore="true"
*/
public void setReverseLoader(boolean reverseLoader) {
this.cpDelegate.setReverseLoader(reverseLoader);
log("The reverseloader attribute is DEPRECATED. It will be removed",
Project.MSG_WARN);
}

/**
* @return the class path path for this definition
*/
public Path getClasspath() {
return cpDelegate.getClasspath();
}

/**
* @return the reverse loader attribute of the classpath delegate.
*/
public boolean isReverseLoader() {
return cpDelegate.isReverseLoader();
}

/**
* Returns the loader id of the class path Delegate.
* @return the loader id
*/
public String getLoaderId() {
return cpDelegate.getClassLoadId();
}

/**
* Returns the class path id of the class path delegate.
* @return the class path id
*/
public String getClasspathId() {
return cpDelegate.getClassLoadId();
}

/**
* Set the classpath to be used when searching for component being defined
*
* @param classpath an Ant Path object containing the classpath.
*/
public void setClasspath(Path classpath) {
this.cpDelegate.setClasspath(classpath);
}

/**
* Create the classpath to be used when searching for component being
* defined
* @return the classpath of the this definition
*/
public Path createClasspath() {
return this.cpDelegate.createClasspath();
}

/**
* reference to a classpath to use when loading the files.
* To actually share the same loader, set loaderref as well
* @param r the reference to the classpath
*/
public void setClasspathRef(Reference r) {
this.cpDelegate.setClasspathref(r);
}

/**
* Use the reference to locate the loader. If the loader is not
* found, taskdef will use the specified classpath and register it
* with the specified name.
*
* This allow multiple taskdef/typedef to use the same class loader,
* so they can be used together. It eliminate the need to
* put them in the CLASSPATH.
*
* @param r the reference to locate the loader.
* @since Ant 1.5
*/
public void setLoaderRef(Reference r) {
this.cpDelegate.setLoaderRef(r);
}

/**
* create a classloader for this definition
* @return the classloader from the cpDelegate
*/
protected ClassLoader createLoader() {
if (internalClassLoader != null) {
return internalClassLoader;
}
if (createdLoader == null) {
createdLoader = this.cpDelegate.getClassLoader();
// need to load Task via system classloader or the new
// task we want to define will never be a Task but always
// be wrapped into a TaskAdapter.
((AntClassLoader) createdLoader)
.addSystemPackageRoot("org.apache.tools.ant");
}
return createdLoader;
}

/**
* @see org.apache.tools.ant.Task#init()
* @since Ant 1.6
*/
public void init() throws BuildException {
this.cpDelegate = ClasspathUtils.getDelegate(this);
super.init();
}


}

+ 10
- 131
src/main/org/apache/tools/ant/taskdefs/Definer.java View File

@@ -63,32 +63,29 @@ import java.util.Locale;
import java.util.Properties;

import org.apache.tools.ant.AntTypeDefinition;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.ComponentHelper;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Location;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
import org.apache.tools.ant.util.ClasspathUtils;
import org.apache.tools.ant.ProjectHelper;
import org.apache.tools.ant.types.EnumeratedAttribute;

/**
* Base class for Taskdef and Typedef - does all the classpath
* handling and and class loading.
* Base class for Taskdef and Typedef - handles all
* the attributes for Typedef. The uri and class
* handling is handled by DefBase
*
* @author Costin Manolache
* @author Stefan Bodewig
* @author Peter Reilly
*
* @since Ant 1.4
*/
public abstract class Definer extends Task {
public abstract class Definer extends DefBase {
private String name;
private String classname;
private File file;
private String resource;
private ClasspathUtils.Delegate cpDelegate;

private int format = Format.PROPERTIES;
private boolean definerSet = false;
@@ -172,18 +169,6 @@ public abstract class Definer extends Task {
this.format = format.getIndex();
}

/**
* @param reverseLoader if true a delegated loader will take precedence over
* the parent
* @deprecated stop using this attribute
* @ant.attribute ignore="true"
*/
public void setReverseLoader(boolean reverseLoader) {
this.cpDelegate.setReverseLoader(reverseLoader);
log("The reverseloader attribute is DEPRECATED. It will be removed",
Project.MSG_WARN);
}

/**
* @return the name for this definition
*/
@@ -191,13 +176,6 @@ public abstract class Definer extends Task {
return name;
}

/**
* @return the class path path for this definition
*/
public Path getClasspath() {
return cpDelegate.getClasspath();
}

/**
* @return the file containing definitions
*/
@@ -212,72 +190,6 @@ public abstract class Definer extends Task {
return resource;
}

/**
* @return the reverse loader attribute of the classpath delegate.
*/
public boolean isReverseLoader() {
return cpDelegate.isReverseLoader();
}

/**
* Returns the loader id of the class path Delegate.
* @return the loader id
*/
public String getLoaderId() {
return cpDelegate.getClassLoadId();
}

/**
* Returns the class path id of the class path delegate.
* @return the class path id
*/
public String getClasspathId() {
return cpDelegate.getClassLoadId();
}

/**
* Set the classpath to be used when searching for component being defined
*
* @param classpath an Ant Path object containing the classpath.
*/
public void setClasspath(Path classpath) {
this.cpDelegate.setClasspath(classpath);
}

/**
* Create the classpath to be used when searching for component being
* defined
* @return the classpath of the this definition
*/
public Path createClasspath() {
return this.cpDelegate.createClasspath();
}

/**
* reference to a classpath to use when loading the files.
* To actually share the same loader, set loaderref as well
* @param r the reference to the classpath
*/
public void setClasspathRef(Reference r) {
this.cpDelegate.setClasspathref(r);
}

/**
* Use the reference to locate the loader. If the loader is not
* found, taskdef will use the specified classpath and register it
* with the specified name.
*
* This allow multiple taskdef/typedef to use the same class loader,
* so they can be used together. It eliminate the need to
* put them in the CLASSPATH.
*
* @param r the reference to locate the loader.
* @since Ant 1.5
*/
public void setLoaderRef(Reference r) {
this.cpDelegate.setLoaderRef(r);
}


/**
* Run the definition.
@@ -406,6 +318,7 @@ public abstract class Definer extends Task {
try {
Antlib antlib = Antlib.createAntlib(getProject(), url);
antlib.setClassLoader(classLoader);
antlib.setURI(getUri());
antlib.perform();
} catch (BuildException ex) {
Location exLocation = ex.getLocation();
@@ -420,23 +333,6 @@ public abstract class Definer extends Task {
}
}

/**
* create a classloader for this definition
* @return the classloader from the cpDelegate
*/
protected ClassLoader createLoader() {
if (internalClassLoader != null) {
return internalClassLoader;
}
ClassLoader al = this.cpDelegate.getClassLoader();
// need to load Task via system classloader or the new
// task we want to define will never be a Task but always
// be wrapped into a TaskAdapter.
((AntClassLoader) al).addSystemPackageRoot("org.apache.tools.ant");

return al;
}

/**
* Name of the property file to load
* ant name/classname pairs from.
@@ -474,7 +370,7 @@ public abstract class Definer extends Task {
definerSet = true;
this.name = name;
}
/**
* Returns the classname of the object we are defining.
* May be <code>null</code>.
@@ -541,25 +437,6 @@ public abstract class Definer extends Task {
}


/**
* Set the class loader, overrides the cpDelagate
* classloader.
*
* @param classLoader a <code>ClassLoader</code> value
*/
protected void setInternalClassLoader(ClassLoader classLoader) {
this.internalClassLoader = classLoader;
}

/**
* @see org.apache.tools.ant.Task#init()
* @since Ant 1.6
*/
public void init() throws BuildException {
this.cpDelegate = ClasspathUtils.getDelegate(this);
super.init();
}

/**
* Add a definition using the attributes of Definer
*
@@ -573,6 +450,8 @@ public abstract class Definer extends Task {
Class cl = null;
try {
try {
name = ProjectHelper.genComponentName(getUri(), name);

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


Loading…
Cancel
Save