git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271672 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -63,15 +63,12 @@ import java.util.Properties; | |||||
| import java.util.Enumeration; | import java.util.Enumeration; | ||||
| import java.util.Stack; | import java.util.Stack; | ||||
| import java.lang.reflect.Modifier; | import java.lang.reflect.Modifier; | ||||
| import java.lang.reflect.Method; | |||||
| import java.lang.reflect.InvocationTargetException; | |||||
| import org.apache.tools.ant.types.DataTypeAdapterTask; | import org.apache.tools.ant.types.DataTypeAdapterTask; | ||||
| import org.apache.tools.ant.types.FilterSet; | import org.apache.tools.ant.types.FilterSet; | ||||
| import org.apache.tools.ant.types.FilterSetCollection; | import org.apache.tools.ant.types.FilterSetCollection; | ||||
| import org.apache.tools.ant.util.FileUtils; | import org.apache.tools.ant.util.FileUtils; | ||||
| import org.apache.tools.ant.types.Path; | |||||
| /** | /** | ||||
| * Central representation of an Ant project. This class defines a | * Central representation of an Ant project. This class defines a | ||||
| @@ -171,26 +168,30 @@ public class Project { | |||||
| fileUtils = FileUtils.newFileUtils(); | fileUtils = FileUtils.newFileUtils(); | ||||
| symbols = new SymbolTable(); | symbols = new SymbolTable(); | ||||
| symbols.setProject(this); | symbols.setProject(this); | ||||
| loadDefinitions(); | |||||
| } | } | ||||
| /** | /** | ||||
| * create a new ant project that inherits from caler project | * create a new ant project that inherits from caler project | ||||
| * @param p the calling project | * @param p the calling project | ||||
| */ | */ | ||||
| private Project(Project p) { | |||||
| public Project(Project p) { | |||||
| fileUtils = FileUtils.newFileUtils(); | fileUtils = FileUtils.newFileUtils(); | ||||
| symbols = new SymbolTable(p.getSymbols()); | |||||
| symbols = new SymbolTable(p); | |||||
| symbols.setProject(this); | symbols.setProject(this); | ||||
| } | } | ||||
| /** | /** | ||||
| * Loads the core definitions into the Root project. | |||||
| * Initialise the project. | |||||
| * | |||||
| * This involves setting the default task definitions and loading the | |||||
| * system properties. | |||||
| */ | */ | ||||
| private void loadDefinitions() { | |||||
| // Initialize symbol table just in case | |||||
| symbols.addRole(TASK_ROLE, TaskContainer.class, TaskAdapter.class); | |||||
| symbols.addRole(DATATYPE_ROLE, TaskContainer.class, | |||||
| public void init() throws BuildException { | |||||
| setJavaVersionProperty(); | |||||
| // Initialize simbol table just in case | |||||
| symbols.addRole("task", TaskContainer.class, TaskAdapter.class); | |||||
| symbols.addRole("datatype", TaskContainer.class, | |||||
| DataTypeAdapterTask.class); | DataTypeAdapterTask.class); | ||||
| String defs = "/org/apache/tools/ant/taskdefs/defaults.properties"; | String defs = "/org/apache/tools/ant/taskdefs/defaults.properties"; | ||||
| @@ -250,23 +251,7 @@ public class Project { | |||||
| } catch (IOException ioe) { | } catch (IOException ioe) { | ||||
| throw new BuildException("Can't load default datatype list"); | throw new BuildException("Can't load default datatype list"); | ||||
| } | } | ||||
| } | |||||
| /** | |||||
| * Creates a subproject of the current project. | |||||
| */ | |||||
| public Project createSubProject() { | |||||
| return new Project(this); | |||||
| } | |||||
| /** | |||||
| * Initialise the project. | |||||
| * | |||||
| * This involves setting the default task definitions and loading the | |||||
| * system properties. | |||||
| */ | |||||
| public void init() throws BuildException { | |||||
| setJavaVersionProperty(); | |||||
| setSystemProperties(); | setSystemProperties(); | ||||
| } | } | ||||
| @@ -293,7 +278,7 @@ public class Project { | |||||
| /** | /** | ||||
| * Get the symbols associated with this project. | * Get the symbols associated with this project. | ||||
| */ | */ | ||||
| private SymbolTable getSymbols() { // Package protected on purpose | |||||
| public SymbolTable getSymbols() { | |||||
| return symbols; | return symbols; | ||||
| } | } | ||||
| @@ -622,20 +607,6 @@ public class Project { | |||||
| log("Detected OS: " + System.getProperty("os.name"), MSG_VERBOSE); | log("Detected OS: " + System.getProperty("os.name"), MSG_VERBOSE); | ||||
| } | } | ||||
| /** | |||||
| * turn all the system properties into ant properties. | |||||
| * user properties still override these values | |||||
| */ | |||||
| public void setSystemProperties() { | |||||
| Properties systemP = System.getProperties(); | |||||
| Enumeration e = systemP.keys(); | |||||
| while (e.hasMoreElements()) { | |||||
| Object name = e.nextElement(); | |||||
| String value = systemP.get(name).toString(); | |||||
| this.setPropertyInternal(name.toString(), value); | |||||
| } | |||||
| } | |||||
| public ClassLoader addToLoader(String loader, Path path) { | public ClassLoader addToLoader(String loader, Path path) { | ||||
| return symbols.addToLoader(loader, path); | return symbols.addToLoader(loader, path); | ||||
| } | } | ||||
| @@ -676,6 +647,20 @@ public class Project { | |||||
| return (symbols.get(role, name) != null); | return (symbols.get(role, name) != null); | ||||
| } | } | ||||
| /** | |||||
| * turn all the system properties into ant properties. | |||||
| * user properties still override these values | |||||
| */ | |||||
| public void setSystemProperties() { | |||||
| Properties systemP = System.getProperties(); | |||||
| Enumeration e = systemP.keys(); | |||||
| while (e.hasMoreElements()) { | |||||
| Object name = e.nextElement(); | |||||
| String value = systemP.get(name).toString(); | |||||
| this.setPropertyInternal(name.toString(), value); | |||||
| } | |||||
| } | |||||
| /** | /** | ||||
| * add a new task definition, complain if there is an overwrite attempt | * add a new task definition, complain if there is an overwrite attempt | ||||
| * @param taskName name of the task | * @param taskName name of the task | ||||
| @@ -685,14 +670,21 @@ public class Project { | |||||
| */ | */ | ||||
| public void addTaskDefinition(String taskName, Class taskClass) | public void addTaskDefinition(String taskName, Class taskClass) | ||||
| throws BuildException { | throws BuildException { | ||||
| addDefinitionOnRole(TASK_ROLE, taskName, taskClass); | |||||
| Class old = symbols.add("task", taskName, taskClass); | |||||
| if (null != old && !old.equals(taskClass)) { | |||||
| invalidateCreatedTasks(taskName); | |||||
| } | |||||
| String msg = | |||||
| " +User task: " + taskName + " " + taskClass.getName(); | |||||
| log(msg, MSG_DEBUG); | |||||
| checkTaskClass(taskClass); | |||||
| } | } | ||||
| /** | /** | ||||
| * Checks a class, whether it is suitable for serving as ant task. | * Checks a class, whether it is suitable for serving as ant task. | ||||
| * @throws BuildException and logs as Project.MSG_ERR for | * @throws BuildException and logs as Project.MSG_ERR for | ||||
| * conditions, that will cause the task execution to fail. | * conditions, that will cause the task execution to fail. | ||||
| * @deprecated this is done now when added to SymbolTable | |||||
| */ | */ | ||||
| public void checkTaskClass(final Class taskClass) throws BuildException { | public void checkTaskClass(final Class taskClass) throws BuildException { | ||||
| if( !Task.class.isAssignableFrom(taskClass) ) { | if( !Task.class.isAssignableFrom(taskClass) ) { | ||||
| @@ -704,7 +696,7 @@ public class Project { | |||||
| * get the current task definition hashtable | * get the current task definition hashtable | ||||
| */ | */ | ||||
| public Hashtable getTaskDefinitions() { | public Hashtable getTaskDefinitions() { | ||||
| return symbols.getDefinitions(TASK_ROLE); | |||||
| return symbols.getTaskDefinitions(); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -713,14 +705,18 @@ public class Project { | |||||
| * @param typeClass full datatype classname | * @param typeClass full datatype classname | ||||
| */ | */ | ||||
| public void addDataTypeDefinition(String typeName, Class typeClass) { | public void addDataTypeDefinition(String typeName, Class typeClass) { | ||||
| addDefinitionOnRole(DATATYPE_ROLE, typeName, typeClass); | |||||
| symbols.add("datatype", typeName, typeClass); | |||||
| String msg = | |||||
| " +User datatype: " + typeName + " " + typeClass.getName(); | |||||
| log(msg, MSG_DEBUG); | |||||
| } | } | ||||
| /** | /** | ||||
| * get the current task definition hashtable | * get the current task definition hashtable | ||||
| */ | */ | ||||
| public Hashtable getDataTypeDefinitions() { | public Hashtable getDataTypeDefinitions() { | ||||
| return symbols.getDefinitions(DATATYPE_ROLE); | |||||
| return symbols.getDataTypeDefinitions(); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -748,7 +744,7 @@ public class Project { | |||||
| * in the project. | * in the project. | ||||
| * @see Project#addOrReplaceTarget to replace existing Targets. | * @see Project#addOrReplaceTarget to replace existing Targets. | ||||
| */ | */ | ||||
| public void addTarget(String targetName, Target target) | |||||
| public void addTarget(String targetName, Target target) | |||||
| throws BuildException { | throws BuildException { | ||||
| if (targets.get(targetName) != null) { | if (targets.get(targetName) != null) { | ||||
| throw new BuildException("Duplicate target: `"+targetName+"'"); | throw new BuildException("Duplicate target: `"+targetName+"'"); | ||||
| @@ -784,88 +780,6 @@ public class Project { | |||||
| return targets; | return targets; | ||||
| } | } | ||||
| /** | |||||
| * Create a new element instance on a Role | |||||
| * @param role name of the role to use | |||||
| * @param type name of the element to create | |||||
| * @return null if element unknown on this role | |||||
| */ | |||||
| public Object createForRole(String role, String type) { | |||||
| SymbolTable.Factory f = symbols.get(role, type); | |||||
| if (f == null) return null; | |||||
| try { | |||||
| Object o = f.create(this); | |||||
| // Do special book keeping for ProjectComponents | |||||
| if ( o instanceof ProjectComponent ) { | |||||
| ((ProjectComponent)o).setProject(this); | |||||
| if (o instanceof Task) { | |||||
| Task task = (Task) o; | |||||
| task.setTaskType(type); | |||||
| // set default value, can be changed by the user | |||||
| task.setTaskName(type); | |||||
| addCreatedTask(type, task); | |||||
| } | |||||
| } | |||||
| String msg = " +" + role + ": " + type; | |||||
| log (msg, MSG_DEBUG); | |||||
| return o; | |||||
| } | |||||
| catch (Throwable t) { | |||||
| String msg = "Could not create " + role + " of type: " | |||||
| + type + " due to " + t; | |||||
| throw new BuildException(msg, t); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * | |||||
| */ | |||||
| public Object createInRole(Object container, String type) { | |||||
| Class clz = container.getClass(); | |||||
| String roles[] = symbols.findRoles(clz); | |||||
| Object theOne = null; | |||||
| Method add = null; | |||||
| for(int i = 0; i < roles.length; i++) { | |||||
| Object o = createForRole(roles[i], type); | |||||
| if (o != null) { | |||||
| if (theOne != null) { | |||||
| String msg = "Element " + type + | |||||
| " is ambiguous for container " + clz.getName(); | |||||
| if (theOne instanceof RoleAdapter) | |||||
| theOne = ((RoleAdapter)theOne).getProxy(); | |||||
| if (o instanceof RoleAdapter) | |||||
| o = ((RoleAdapter)o).getProxy(); | |||||
| log(msg, MSG_ERR); | |||||
| log("cannot distinguish between " + | |||||
| theOne.getClass().getName() + | |||||
| " and " + o.getClass().getName(), MSG_ERR); | |||||
| throw new BuildException(msg); | |||||
| } | |||||
| theOne = o; | |||||
| add = symbols.getRole(roles[i]).getInterfaceMethod(); | |||||
| } | |||||
| } | |||||
| if (theOne != null) { | |||||
| try { | |||||
| add.invoke(container, new Object[]{theOne}); | |||||
| } | |||||
| catch(InvocationTargetException ite) { | |||||
| if (ite.getTargetException() instanceof BuildException) { | |||||
| throw (BuildException)ite.getTargetException(); | |||||
| } | |||||
| throw new BuildException(ite.getTargetException()); | |||||
| } | |||||
| catch(Exception e) { | |||||
| throw new BuildException(e); | |||||
| } | |||||
| } | |||||
| return theOne; | |||||
| } | |||||
| /** | /** | ||||
| * create a new task instance | * create a new task instance | ||||
| * @param taskType name of the task | * @param taskType name of the task | ||||
| @@ -873,7 +787,39 @@ public class Project { | |||||
| * @return null if the task name is unknown | * @return null if the task name is unknown | ||||
| */ | */ | ||||
| public Task createTask(String taskType) throws BuildException { | public Task createTask(String taskType) throws BuildException { | ||||
| return (Task) createForRole(TASK_ROLE, taskType); | |||||
| Class c = symbols.get("task", taskType); | |||||
| if (c == null) { | |||||
| return null; | |||||
| } | |||||
| try { | |||||
| Object o = c.newInstance(); | |||||
| Task task = null; | |||||
| if( o instanceof Task ) { | |||||
| task=(Task)o; | |||||
| } else { | |||||
| // "Generic" Bean - use the setter pattern | |||||
| // and an Adapter | |||||
| TaskAdapter taskA=new TaskAdapter(); | |||||
| taskA.setProxy( o ); | |||||
| task=taskA; | |||||
| } | |||||
| task.setProject(this); | |||||
| task.setTaskType(taskType); | |||||
| // set default value, can be changed by the user | |||||
| task.setTaskName(taskType); | |||||
| String msg = " +Task: " + taskType; | |||||
| log (msg, MSG_DEBUG); | |||||
| addCreatedTask(taskType, task); | |||||
| return task; | |||||
| } catch (Throwable t) { | |||||
| String msg = "Could not create task of type: " | |||||
| + taskType + " due to " + t; | |||||
| throw new BuildException(msg, t); | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -917,11 +863,47 @@ public class Project { | |||||
| * @return null if the datatype name is unknown | * @return null if the datatype name is unknown | ||||
| */ | */ | ||||
| public Object createDataType(String typeName) throws BuildException { | public Object createDataType(String typeName) throws BuildException { | ||||
| // This is to make the function backward compatible | |||||
| // Since we know if it returning an adapter for it | |||||
| DataTypeAdapterTask dt = | |||||
| (DataTypeAdapterTask) createForRole(DATATYPE_ROLE, typeName); | |||||
| return (dt != null? dt.getProxy() : null); | |||||
| Class c = symbols.get("datatype", typeName); | |||||
| if (c == null) { | |||||
| return null; | |||||
| } | |||||
| try { | |||||
| java.lang.reflect.Constructor ctor = null; | |||||
| boolean noArg = false; | |||||
| // DataType can have a "no arg" constructor or take a single | |||||
| // Project argument. | |||||
| try { | |||||
| ctor = c.getConstructor(new Class[0]); | |||||
| noArg = true; | |||||
| } catch (NoSuchMethodException nse) { | |||||
| ctor = c.getConstructor(new Class[] {Project.class}); | |||||
| noArg = false; | |||||
| } | |||||
| Object o = null; | |||||
| if (noArg) { | |||||
| o = ctor.newInstance(new Object[0]); | |||||
| } else { | |||||
| o = ctor.newInstance(new Object[] {this}); | |||||
| } | |||||
| if (o instanceof ProjectComponent) { | |||||
| ((ProjectComponent)o).setProject(this); | |||||
| } | |||||
| String msg = " +DataType: " + typeName; | |||||
| log (msg, MSG_DEBUG); | |||||
| return o; | |||||
| } catch (java.lang.reflect.InvocationTargetException ite) { | |||||
| Throwable t = ite.getTargetException(); | |||||
| String msg = "Could not create datatype of type: " | |||||
| + typeName + " due to " + t; | |||||
| throw new BuildException(msg, t); | |||||
| } catch (Throwable t) { | |||||
| String msg = "Could not create datatype of type: " | |||||
| + typeName + " due to " + t; | |||||
| throw new BuildException(msg, t); | |||||
| } | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -1288,10 +1270,7 @@ public class Project { | |||||
| } | } | ||||
| public void addReference(String name, Object value) { | public void addReference(String name, Object value) { | ||||
| Object o = references.get(name); | |||||
| if (null != o && o != value | |||||
| && (!(o instanceof RoleAdapter) | |||||
| || ((RoleAdapter)o).getProxy() != value)) { | |||||
| if (null != references.get(name)) { | |||||
| log("Overriding previous definition of reference to " + name, | log("Overriding previous definition of reference to " + name, | ||||
| MSG_WARN); | MSG_WARN); | ||||
| } | } | ||||
| @@ -55,11 +55,6 @@ package org.apache.tools.ant; | |||||
| public interface RoleAdapter { | public interface RoleAdapter { | ||||
| /** | |||||
| * Obtain the id in case it is needed. | |||||
| */ | |||||
| public void setId(String id); | |||||
| /** | /** | ||||
| * Set the object being adapted. | * Set the object being adapted. | ||||
| * @param o the object being adapted | * @param o the object being adapted | ||||
| @@ -54,7 +54,6 @@ | |||||
| package org.apache.tools.ant; | package org.apache.tools.ant; | ||||
| import java.lang.reflect.InvocationTargetException; | import java.lang.reflect.InvocationTargetException; | ||||
| import java.lang.reflect.Constructor; | |||||
| import java.lang.reflect.Method; | import java.lang.reflect.Method; | ||||
| import java.lang.reflect.Modifier; | import java.lang.reflect.Modifier; | ||||
| import java.util.*; | import java.util.*; | ||||
| @@ -97,8 +96,8 @@ public class SymbolTable { | |||||
| * from that defined in the calling Project. | * from that defined in the calling Project. | ||||
| * @param p the calling project | * @param p the calling project | ||||
| */ | */ | ||||
| public SymbolTable(SymbolTable st) { | |||||
| parentTable = st; | |||||
| public SymbolTable(Project p) { | |||||
| parentTable = p.getSymbols(); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -109,54 +108,6 @@ public class SymbolTable { | |||||
| this.project = p; | this.project = p; | ||||
| } | } | ||||
| /** | |||||
| * Get the specified loader for the project. | |||||
| * @param name the name of the loader | |||||
| * @return the corresponding ANT classloader | |||||
| */ | |||||
| private AntClassLoader getLoader(String name) { | |||||
| AntClassLoader cl = (AntClassLoader) loaders.get(name); | |||||
| if (cl == null && parentTable != null) { | |||||
| return parentTable.getLoader(name); | |||||
| } | |||||
| return cl; | |||||
| } | |||||
| /** | |||||
| * Add the specified class-path to a loader. | |||||
| * If the loader is defined in an ancestor project then a new | |||||
| * classloader inheritin from the one already existing | |||||
| * will be created, otherwise the path willbe added to the existing | |||||
| * ClassLoader. | |||||
| * @param name the name of the loader to use. | |||||
| * @param clspath the path to be added to the classloader | |||||
| */ | |||||
| public ClassLoader addToLoader(String name, Path clspath) { | |||||
| // Find if the loader is already defined in the current project | |||||
| AntClassLoader cl = (AntClassLoader) loaders.get(name); | |||||
| if (cl == null) { | |||||
| // Is it inherited from the calling project | |||||
| if (parentTable != null) { | |||||
| cl = parentTable.getLoader(name); | |||||
| } | |||||
| cl = new AntClassLoader(cl, project, clspath, true); | |||||
| loaders.put(name, cl); | |||||
| } | |||||
| else { | |||||
| // Add additional path to the existing definition | |||||
| String[] pathElements = clspath.list(); | |||||
| for (int i = 0; i < pathElements.length; ++i) { | |||||
| try { | |||||
| cl.addPathElement(pathElements[i]); | |||||
| } | |||||
| catch (BuildException e) { | |||||
| // ignore path elements invalid relative to the project | |||||
| } | |||||
| } | |||||
| } | |||||
| return cl; | |||||
| } | |||||
| /** | /** | ||||
| * Find all the roles supported by a Class | * Find all the roles supported by a Class | ||||
| * on this symbol table. | * on this symbol table. | ||||
| @@ -182,13 +133,13 @@ public class SymbolTable { | |||||
| list.addElement(role); | list.addElement(role); | ||||
| } | } | ||||
| } | } | ||||
| if (parentTable != null) parentTable.findRoles(clz, list); | |||||
| if (parentTable != null) findRoles(clz, list); | |||||
| } | } | ||||
| /** | /** | ||||
| * Get the Role definition | * Get the Role definition | ||||
| * @param role the name of the role | * @param role the name of the role | ||||
| * @return the Role description | |||||
| * @return the method used to support objects on this role | |||||
| */ | */ | ||||
| public Role getRole(String role) { | public Role getRole(String role) { | ||||
| Role r = (Role) roles.get(role); | Role r = (Role) roles.get(role); | ||||
| @@ -220,6 +171,112 @@ public class SymbolTable { | |||||
| return (old != null); | return (old != null); | ||||
| } | } | ||||
| /** | |||||
| * Verify if the interface is valid. | |||||
| * @param clz the interface to validate | |||||
| * @return the method defined by the interface | |||||
| */ | |||||
| private Method validInterface(Class clz) { | |||||
| Method m[] = clz.getDeclaredMethods(); | |||||
| if (m.length == 1 | |||||
| && java.lang.Void.TYPE.equals(m[0].getReturnType())) { | |||||
| Class args[] = m[0].getParameterTypes(); | |||||
| if (args.length == 1 | |||||
| && !java.lang.String.class.equals(args[0]) | |||||
| && !args[0].isArray() | |||||
| && !args[0].isPrimitive()) { | |||||
| return m[0]; | |||||
| } | |||||
| else { | |||||
| throw new BuildException("Invalid role interface method in: " | |||||
| + clz.getName()); | |||||
| } | |||||
| } | |||||
| else { | |||||
| throw new BuildException("More than one method on role interface"); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Verify if the adapter is valid with respect to the interface. | |||||
| * @param clz the class adapter to validate | |||||
| * @param mtd the method whose only argument must match | |||||
| * @return the static method to use for validating adaptees | |||||
| */ | |||||
| private Method validAdapter(Class clz, Method mtd) { | |||||
| if (clz == null) return null; | |||||
| checkClass(clz); | |||||
| if (!mtd.getParameterTypes()[0].isAssignableFrom(clz)) { | |||||
| String msg = "Adapter " + clz.getName() + | |||||
| " is incompatible with role interface " + | |||||
| mtd.getDeclaringClass().getName(); | |||||
| throw new BuildException(msg); | |||||
| } | |||||
| String msg = "Class " + clz.getName() + " is not an adapter: "; | |||||
| if (!RoleAdapter.class.isAssignableFrom(clz)) { | |||||
| throw new BuildException(msg + "does not implement RoleAdapter"); | |||||
| } | |||||
| try { | |||||
| Method chk = clz.getMethod("checkClass", CHECK_ADAPTER_PARAMS); | |||||
| if (!Modifier.isStatic(chk.getModifiers())) { | |||||
| throw new BuildException(msg + "checkClass() is not static"); | |||||
| } | |||||
| return chk; | |||||
| } | |||||
| catch(NoSuchMethodException nme){ | |||||
| throw new BuildException(msg + "checkClass() not found", nme); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Get the specified loader for the project. | |||||
| * @param name the name of the loader | |||||
| * @return the corresponding ANT classloader | |||||
| */ | |||||
| private AntClassLoader getLoader(String name) { | |||||
| AntClassLoader cl = (AntClassLoader) loaders.get(name); | |||||
| if (cl == null && parentTable != null) { | |||||
| return parentTable.getLoader(name); | |||||
| } | |||||
| return cl; | |||||
| } | |||||
| /** | |||||
| * Add the specified class-path to a loader. | |||||
| * If the loader is defined in an ancestor project then a new | |||||
| * classloader inheritin from the one already existing | |||||
| * will be created, otherwise the path willbe added to the existing | |||||
| * ClassLoader. | |||||
| * @param name the name of the loader to use. | |||||
| * @param clspath the path to be added to the classloader | |||||
| */ | |||||
| public ClassLoader addToLoader(String name, Path clspath) { | |||||
| // Find if the loader is already defined in the current project | |||||
| AntClassLoader cl = (AntClassLoader) loaders.get(name); | |||||
| if (cl == null) { | |||||
| // Is it inherited from the calling project | |||||
| if (parentTable != null) { | |||||
| cl = parentTable.getLoader(name); | |||||
| } | |||||
| cl = new AntClassLoader(cl, project, clspath, true); | |||||
| loaders.put(name, cl); | |||||
| } | |||||
| else { | |||||
| // Add additional path to the existing definition | |||||
| String[] pathElements = clspath.list(); | |||||
| for (int i = 0; i < pathElements.length; ++i) { | |||||
| try { | |||||
| cl.addPathElement(pathElements[i]); | |||||
| } | |||||
| catch (BuildException e) { | |||||
| // ignore path elements invalid relative to the project | |||||
| } | |||||
| } | |||||
| } | |||||
| return cl; | |||||
| } | |||||
| /** | /** | ||||
| * Add a new type of element to a role. | * Add a new type of element to a role. | ||||
| * @param role the role for this Class. | * @param role the role for this Class. | ||||
| @@ -234,13 +291,13 @@ public class SymbolTable { | |||||
| throw new BuildException("Unknown role: " + role); | throw new BuildException("Unknown role: " + role); | ||||
| } | } | ||||
| // Check if it is already defined | // Check if it is already defined | ||||
| Factory old = get(role, name); | |||||
| Class old = get(role, name); | |||||
| if (old != null) { | if (old != null) { | ||||
| if (old.getOriginalClass().equals(clz)) { | |||||
| if (old.equals(clz)) { | |||||
| project.log("Ignoring override for "+ role + " " + name | project.log("Ignoring override for "+ role + " " + name | ||||
| + ", it is already defined by the same class.", | + ", it is already defined by the same class.", | ||||
| project.MSG_VERBOSE); | project.MSG_VERBOSE); | ||||
| return old.getOriginalClass(); | |||||
| return old; | |||||
| } | } | ||||
| else { | else { | ||||
| project.log("Trying to override old definition of " + | project.log("Trying to override old definition of " + | ||||
| @@ -248,33 +305,26 @@ public class SymbolTable { | |||||
| project.MSG_WARN); | project.MSG_WARN); | ||||
| } | } | ||||
| } | } | ||||
| Factory f = checkClass(clz); | |||||
| checkClass(clz); | |||||
| // Check that the Class is compatible with the role definition | // Check that the Class is compatible with the role definition | ||||
| f = r.verifyAdaptability(role, f); | |||||
| r.verifyAdaptability(role, clz); | |||||
| // Record the new type | // Record the new type | ||||
| Hashtable defTable = (Hashtable)defs.get(role); | Hashtable defTable = (Hashtable)defs.get(role); | ||||
| if (defTable == null) { | if (defTable == null) { | ||||
| defTable = new Hashtable(); | defTable = new Hashtable(); | ||||
| defs.put(role, defTable); | defs.put(role, defTable); | ||||
| } | } | ||||
| defTable.put(name, f); | |||||
| String msg = | |||||
| " +User " + role + ": " + name + " " + clz.getName(); | |||||
| project.log(msg, project.MSG_DEBUG); | |||||
| return (old != null ? old.getOriginalClass() : null); | |||||
| defTable.put(name, clz); | |||||
| return old; | |||||
| } | } | ||||
| /** | /** | ||||
| * Checks a class, whether it is suitable for serving in ANT. | * Checks a class, whether it is suitable for serving in ANT. | ||||
| * @return the factory to use when instantiating the class | |||||
| * @throws BuildException and logs as Project.MSG_ERR for | * @throws BuildException and logs as Project.MSG_ERR for | ||||
| * conditions, that will cause execution to fail. | * conditions, that will cause execution to fail. | ||||
| */ | */ | ||||
| Factory checkClass(final Class clz) // Package on purpose | |||||
| void checkClass(final Class clz) | |||||
| throws BuildException { | throws BuildException { | ||||
| if (clz == null) return null; | |||||
| if(!Modifier.isPublic(clz.getModifiers())) { | if(!Modifier.isPublic(clz.getModifiers())) { | ||||
| final String message = clz + " is not public"; | final String message = clz + " is not public"; | ||||
| project.log(message, Project.MSG_ERR); | project.log(message, Project.MSG_ERR); | ||||
| @@ -292,37 +342,8 @@ public class SymbolTable { | |||||
| // getConstructor finds public constructors only. | // getConstructor finds public constructors only. | ||||
| try { | try { | ||||
| clz.getConstructor(new Class[0]); | clz.getConstructor(new Class[0]); | ||||
| return new Factory(){ | |||||
| public Object create(Project p) { | |||||
| try { | |||||
| return clz.newInstance(); | |||||
| } | |||||
| catch(Exception e) { | |||||
| throw new BuildException(e); | |||||
| } | |||||
| } | |||||
| public Class getOriginalClass() { | |||||
| return clz; | |||||
| } | |||||
| }; | |||||
| } catch (NoSuchMethodException nse) { | } catch (NoSuchMethodException nse) { | ||||
| final Constructor c = | |||||
| clz.getConstructor(new Class[] {Project.class}); | |||||
| return new Factory(){ | |||||
| public Object create(Project p) { | |||||
| try { | |||||
| return c.newInstance(new Object[]{p}); | |||||
| } | |||||
| catch(Exception e) { | |||||
| throw new BuildException(e); | |||||
| } | |||||
| } | |||||
| public Class getOriginalClass() { | |||||
| return clz; | |||||
| } | |||||
| }; | |||||
| clz.getConstructor(new Class[] {Project.class}); | |||||
| } | } | ||||
| } catch(NoSuchMethodException e) { | } catch(NoSuchMethodException e) { | ||||
| final String message = | final String message = | ||||
| @@ -338,11 +359,11 @@ public class SymbolTable { | |||||
| * @param name the name of the element to sea | * @param name the name of the element to sea | ||||
| * @return the Class implementation | * @return the Class implementation | ||||
| */ | */ | ||||
| public Factory get(String role, String name) { | |||||
| public Class get(String role, String name) { | |||||
| Hashtable defTable = (Hashtable)defs.get(role); | Hashtable defTable = (Hashtable)defs.get(role); | ||||
| if (defTable != null) { | if (defTable != null) { | ||||
| Factory f = (Factory)defTable.get(name); | |||||
| if (f != null) return f; | |||||
| Class clz = (Class)defTable.get(name); | |||||
| if (clz != null) return clz; | |||||
| } | } | ||||
| if (parentTable != null) { | if (parentTable != null) { | ||||
| return parentTable.get(role, name); | return parentTable.get(role, name); | ||||
| @@ -351,12 +372,19 @@ public class SymbolTable { | |||||
| } | } | ||||
| /** | /** | ||||
| * Get a Hashtable that is usable for manipulating elements on Role. | |||||
| * @param role the role of the elements in the table | |||||
| * Get a Hashtable that is usable for manipulating Tasks, | |||||
| * @return a Hashtable that delegates to the Symbol table. | * @return a Hashtable that delegates to the Symbol table. | ||||
| */ | */ | ||||
| Hashtable getDefinitions(String role) { // package scope on purpose | |||||
| return new SymbolHashtable(role); | |||||
| public Hashtable getTaskDefinitions() { | |||||
| return new SymbolHashtable("task"); | |||||
| } | |||||
| /** | |||||
| * Get a Hashtable that is usable for manipulating Datatypes, | |||||
| * @return a Hashtable that delegates to the Symbol table. | |||||
| */ | |||||
| public Hashtable getDataTypeDefinitions() { | |||||
| return new SymbolHashtable("datatype"); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -374,43 +402,16 @@ public class SymbolTable { | |||||
| } | } | ||||
| public synchronized Object get(Object key) { | public synchronized Object get(Object key) { | ||||
| Factory f = SymbolTable.this.get(role, (String)key); | |||||
| return (f == null? null : f.getOriginalClass()); | |||||
| return SymbolTable.this.get(role, (String)key); | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Factory for creating ANT objects. | |||||
| * Class objects are not instanciated directly but through a Factory | |||||
| * which is able to resolve issues such as proxys and such. | |||||
| */ | |||||
| public static interface Factory { | |||||
| /** | |||||
| * Creates an object for the Role | |||||
| * @param the project in which it is created | |||||
| * @return the instantiated object with a proxy if necessary | |||||
| */ | |||||
| public Object create(Project p); | |||||
| /** | |||||
| * Creates an object for the Role, adapted if necessary | |||||
| * for a particular interface. | |||||
| */ | |||||
| // public Object adaptFor(Class clz, Project p, Object o); | |||||
| /** | |||||
| * The original class of the object without proxy. | |||||
| */ | |||||
| public Class getOriginalClass(); | |||||
| } | |||||
| /** | /** | ||||
| * The definition of a role | * The definition of a role | ||||
| */ | */ | ||||
| public class Role { | public class Role { | ||||
| private Method interfaceMethod; | private Method interfaceMethod; | ||||
| private Method adapterVerifier; | private Method adapterVerifier; | ||||
| private Factory adapterFactory; | |||||
| /** | /** | ||||
| * Creates a new Role object | * Creates a new Role object | ||||
| @@ -419,7 +420,6 @@ public class SymbolTable { | |||||
| */ | */ | ||||
| Role(Class roleClz, Class adapterClz) { | Role(Class roleClz, Class adapterClz) { | ||||
| interfaceMethod = validInterface(roleClz); | interfaceMethod = validInterface(roleClz); | ||||
| adapterFactory = checkClass(adapterClz); | |||||
| adapterVerifier = validAdapter(adapterClz, interfaceMethod); | adapterVerifier = validAdapter(adapterClz, interfaceMethod); | ||||
| } | } | ||||
| @@ -433,11 +433,12 @@ public class SymbolTable { | |||||
| /** | /** | ||||
| * Instantiate a new adapter for this role. | * Instantiate a new adapter for this role. | ||||
| */ | */ | ||||
| public RoleAdapter createAdapter(Project p) { | |||||
| if (adapterFactory == null) return null; | |||||
| public RoleAdapter createAdapter() { | |||||
| if (adapterVerifier == null) return null; | |||||
| try { | try { | ||||
| return (RoleAdapter) adapterFactory.create(p); | |||||
| return (RoleAdapter) | |||||
| adapterVerifier.getDeclaringClass().newInstance(); | |||||
| } | } | ||||
| catch(BuildException be) { | catch(BuildException be) { | ||||
| throw be; | throw be; | ||||
| @@ -450,12 +451,11 @@ public class SymbolTable { | |||||
| /** | /** | ||||
| * Verify if the class can be adapted to use by the role | * Verify if the class can be adapted to use by the role | ||||
| * @param role the name of the role to verify | * @param role the name of the role to verify | ||||
| * @param f the factory for the class to verify | |||||
| * @param clz the class to verify | |||||
| */ | */ | ||||
| public Factory verifyAdaptability(String role, final Factory f) { | |||||
| final Class clz = f.getOriginalClass(); | |||||
| public void verifyAdaptability(String role, Class clz) { | |||||
| if (interfaceMethod.getParameterTypes()[0].isAssignableFrom(clz)) { | if (interfaceMethod.getParameterTypes()[0].isAssignableFrom(clz)) { | ||||
| return f; | |||||
| return; | |||||
| } | } | ||||
| if (adapterVerifier == null) { | if (adapterVerifier == null) { | ||||
| String msg = "Class " + clz.getName() + | String msg = "Class " + clz.getName() + | ||||
| @@ -464,18 +464,8 @@ public class SymbolTable { | |||||
| } | } | ||||
| try { | try { | ||||
| try { | try { | ||||
| adapterVerifier.invoke(null, new Object[]{clz, project}); | |||||
| return new Factory(){ | |||||
| public Object create(Project p) { | |||||
| RoleAdapter ra = createAdapter(p); | |||||
| ra.setProxy(f.create(p)); | |||||
| return ra; | |||||
| } | |||||
| public Class getOriginalClass() { | |||||
| return clz; | |||||
| } | |||||
| }; | |||||
| adapterVerifier.invoke(null, | |||||
| new Object[]{clz, project}); | |||||
| } | } | ||||
| catch (InvocationTargetException ite) { | catch (InvocationTargetException ite) { | ||||
| throw ite.getTargetException(); | throw ite.getTargetException(); | ||||
| @@ -497,63 +487,5 @@ public class SymbolTable { | |||||
| public boolean isImplementedBy(Class clz) { | public boolean isImplementedBy(Class clz) { | ||||
| return interfaceMethod.getDeclaringClass().isAssignableFrom(clz); | return interfaceMethod.getDeclaringClass().isAssignableFrom(clz); | ||||
| } | } | ||||
| /** | |||||
| * Verify if the interface is valid. | |||||
| * @param clz the interface to validate | |||||
| * @return the method defined by the interface | |||||
| */ | |||||
| private Method validInterface(Class clz) { | |||||
| Method m[] = clz.getDeclaredMethods(); | |||||
| if (m.length == 1 | |||||
| && java.lang.Void.TYPE.equals(m[0].getReturnType())) { | |||||
| Class args[] = m[0].getParameterTypes(); | |||||
| if (args.length == 1 | |||||
| && !java.lang.String.class.equals(args[0]) | |||||
| && !args[0].isArray() | |||||
| && !args[0].isPrimitive()) { | |||||
| return m[0]; | |||||
| } | |||||
| else { | |||||
| throw new BuildException("Invalid role interface method in: " | |||||
| + clz.getName()); | |||||
| } | |||||
| } | |||||
| else { | |||||
| throw new BuildException("More than one method on role interface"); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Verify if the adapter is valid with respect to the interface. | |||||
| * @param clz the class adapter to validate | |||||
| * @param mtd the method whose only argument must match | |||||
| * @return the static method to use for validating adaptees | |||||
| */ | |||||
| private Method validAdapter(Class clz, Method mtd) { | |||||
| if (clz == null) return null; | |||||
| if (!mtd.getParameterTypes()[0].isAssignableFrom(clz)) { | |||||
| String msg = "Adapter " + clz.getName() + | |||||
| " is incompatible with role interface " + | |||||
| mtd.getDeclaringClass().getName(); | |||||
| throw new BuildException(msg); | |||||
| } | |||||
| String msg = "Class " + clz.getName() + " is not an adapter: "; | |||||
| if (!RoleAdapter.class.isAssignableFrom(clz)) { | |||||
| throw new BuildException(msg + "does not implement RoleAdapter"); | |||||
| } | |||||
| try { | |||||
| Method chk = clz.getMethod("checkClass", CHECK_ADAPTER_PARAMS); | |||||
| if (!Modifier.isStatic(chk.getModifiers())) { | |||||
| throw new BuildException(msg + "checkClass() is not static"); | |||||
| } | |||||
| return chk; | |||||
| } | |||||
| catch(NoSuchMethodException nme){ | |||||
| throw new BuildException(msg + "checkClass() not found", nme); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -165,5 +165,4 @@ public class TaskAdapter extends Task implements RoleAdapter { | |||||
| return this.proxy ; | return this.proxy ; | ||||
| } | } | ||||
| public void setId(String id) {} | |||||
| } | } | ||||
| @@ -0,0 +1,137 @@ | |||||
| <?xml version='1.0' ?> | |||||
| <!-- | |||||
| * The Apache Software License, Version 1.1 | |||||
| * | |||||
| * Copyright (c) 2000-2002 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 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/>. | |||||
| --> | |||||
| <antlib version="1.5" > | |||||
| <task name="mkdir" class="org.apache.tools.ant.taskdefs.Mkdir"/> | |||||
| <task name="javac" class="org.apache.tools.ant.taskdefs.Javac"/> | |||||
| <task name="chmod" class="org.apache.tools.ant.taskdefs.Chmod"/> | |||||
| <task name="delete" class="org.apache.tools.ant.taskdefs.Delete"/> | |||||
| <task name="copy" class="org.apache.tools.ant.taskdefs.Copy"/> | |||||
| <task name="move" class="org.apache.tools.ant.taskdefs.Move"/> | |||||
| <task name="jar" class="org.apache.tools.ant.taskdefs.Jar"/> | |||||
| <task name="rmic" class="org.apache.tools.ant.taskdefs.Rmic"/> | |||||
| <task name="cvs" class="org.apache.tools.ant.taskdefs.Cvs"/> | |||||
| <task name="unzip" class="org.apache.tools.ant.taskdefs.Expand"/> | |||||
| <task name="unjar" class="org.apache.tools.ant.taskdefs.Expand"/> | |||||
| <task name="unwar" class="org.apache.tools.ant.taskdefs.Expand"/> | |||||
| <task name="echo" class="org.apache.tools.ant.taskdefs.Echo"/> | |||||
| <task name="javadoc" class="org.apache.tools.ant.taskdefs.Javadoc"/> | |||||
| <task name="zip" class="org.apache.tools.ant.taskdefs.Zip"/> | |||||
| <task name="gzip" class="org.apache.tools.ant.taskdefs.GZip"/> | |||||
| <task name="gunzip" class="org.apache.tools.ant.taskdefs.GUnzip"/> | |||||
| <task name="replace" class="org.apache.tools.ant.taskdefs.Replace"/> | |||||
| <task name="java" class="org.apache.tools.ant.taskdefs.Java"/> | |||||
| <task name="tstamp" class="org.apache.tools.ant.taskdefs.Tstamp"/> | |||||
| <task name="property" class="org.apache.tools.ant.taskdefs.Property"/> | |||||
| <task name="taskdef" class="org.apache.tools.ant.taskdefs.Taskdef"/> | |||||
| <task name="ant" class="org.apache.tools.ant.taskdefs.Ant"/> | |||||
| <task name="exec" class="org.apache.tools.ant.taskdefs.ExecTask"/> | |||||
| <task name="tar" class="org.apache.tools.ant.taskdefs.Tar"/> | |||||
| <task name="untar" class="org.apache.tools.ant.taskdefs.Untar"/> | |||||
| <task name="available" class="org.apache.tools.ant.taskdefs.Available"/> | |||||
| <task name="filter" class="org.apache.tools.ant.taskdefs.Filter"/> | |||||
| <task name="fixcrlf" class="org.apache.tools.ant.taskdefs.FixCRLF"/> | |||||
| <task name="patch" class="org.apache.tools.ant.taskdefs.Patch"/> | |||||
| <task name="style" class="org.apache.tools.ant.taskdefs.XSLTProcess"/> | |||||
| <task name="touch" class="org.apache.tools.ant.taskdefs.Touch"/> | |||||
| <task name="signjar" class="org.apache.tools.ant.taskdefs.SignJar"/> | |||||
| <task name="genkey" class="org.apache.tools.ant.taskdefs.GenerateKey"/> | |||||
| <task name="antstructure" class="org.apache.tools.ant.taskdefs.AntStructure"/> | |||||
| <task name="execon" class="org.apache.tools.ant.taskdefs.ExecuteOn"/> | |||||
| <task name="antcall" class="org.apache.tools.ant.taskdefs.CallTarget"/> | |||||
| <task name="sql" class="org.apache.tools.ant.taskdefs.SQLExec"/> | |||||
| <task name="mail" class="org.apache.tools.ant.taskdefs.email.EmailTask"/> | |||||
| <task name="fail" class="org.apache.tools.ant.taskdefs.Exit"/> | |||||
| <task name="war" class="org.apache.tools.ant.taskdefs.War"/> | |||||
| <task name="uptodate" class="org.apache.tools.ant.taskdefs.UpToDate"/> | |||||
| <task name="apply" class="org.apache.tools.ant.taskdefs.Transform"/> | |||||
| <task name="record" class="org.apache.tools.ant.taskdefs.Recorder"/> | |||||
| <task name="cvspass" class="org.apache.tools.ant.taskdefs.CVSPass"/> | |||||
| <task name="typedef" class="org.apache.tools.ant.taskdefs.Typedef"/> | |||||
| <task name="sleep" class="org.apache.tools.ant.taskdefs.Sleep"/> | |||||
| <task name="pathconvert" class="org.apache.tools.ant.taskdefs.PathConvert"/> | |||||
| <task name="ear" class="org.apache.tools.ant.taskdefs.Ear"/> | |||||
| <task name="parallel" class="org.apache.tools.ant.taskdefs.Parallel"/> | |||||
| <task name="sequential" class="org.apache.tools.ant.taskdefs.Sequential"/> | |||||
| <task name="condition" class="org.apache.tools.ant.taskdefs.ConditionTask"/> | |||||
| <task name="dependset" class="org.apache.tools.ant.taskdefs.DependSet"/> | |||||
| <task name="bzip2" class="org.apache.tools.ant.taskdefs.BZip2"/> | |||||
| <task name="bunzip2" class="org.apache.tools.ant.taskdefs.BUnzip2"/> | |||||
| <task name="checksum" class="org.apache.tools.ant.taskdefs.Checksum"/> | |||||
| <task name="waitfor" class="org.apache.tools.ant.taskdefs.WaitFor"/> | |||||
| <task name="input" class="org.apache.tools.ant.taskdefs.Input"/> | |||||
| <task name="loadfile" class="org.apache.tools.ant.taskdefs.LoadFile"/> | |||||
| <task name="manifest" class="org.apache.tools.ant.taskdefs.Manifest"/> | |||||
| <task name="antjar" class="org.apache.tools.ant.taskdefs.Antjar"/> | |||||
| <task name="antlib" class="org.apache.tools.ant.taskdefs.Antlib"/> | |||||
| <data-type name="path" class="org.apache.tools.ant.types.Path"/> | |||||
| <data-type name="fileset" class="org.apache.tools.ant.types.FileSet"/> | |||||
| <data-type name="filelist" class="org.apache.tools.ant.types.FileList"/> | |||||
| <data-type name="patternset" class="org.apache.tools.ant.types.PatternSet"/> | |||||
| <data-type name="mapper" class="org.apache.tools.ant.types.Mapper"/> | |||||
| <data-type name="filterset" class="org.apache.tools.ant.types.FilterSet"/> | |||||
| <data-type name="description" class="org.apache.tools.ant.types.Description"/> | |||||
| <data-type name="substitution" class="org.apache.tools.ant.types.Substitution"/> | |||||
| <data-type name="regexp" class="org.apache.tools.ant.types.RegularExpression"/> | |||||
| <!-- deprecated ant tasks (kept for back compatibility) --> | |||||
| <task name="javadoc2" class="org.apache.tools.ant.taskdefs.Javadoc"/> | |||||
| <task name="copydir" class="org.apache.tools.ant.taskdefs.Copydir"/> | |||||
| <task name="copyfile" class="org.apache.tools.ant.taskdefs.Copyfile"/> | |||||
| <task name="deltree" class="org.apache.tools.ant.taskdefs.Deltree"/> | |||||
| <task name="rename" class="org.apache.tools.ant.taskdefs.Rename"/> | |||||
| </antlib> | |||||
| @@ -138,8 +138,10 @@ public class Ant extends Task { | |||||
| } | } | ||||
| public void init() { | public void init() { | ||||
| newProject = project.createSubProject(); | |||||
| newProject = new Project(project); | |||||
| newProject.setJavaVersionProperty(); | newProject.setJavaVersionProperty(); | ||||
| // newProject.addTaskDefinition("property", | |||||
| // (Class)project.getTaskDefinitions().get("property")); | |||||
| } | } | ||||
| private void reinit() { | private void reinit() { | ||||
| @@ -183,6 +185,26 @@ public class Ant extends Task { | |||||
| } | } | ||||
| } | } | ||||
| // Hashtable taskdefs = project.getTaskDefinitions(); | |||||
| // Enumeration et = taskdefs.keys(); | |||||
| // while (et.hasMoreElements()) { | |||||
| // String taskName = (String) et.nextElement(); | |||||
| // if (taskName.equals("property")) { | |||||
| // // we have already added this taskdef in #init | |||||
| // continue; | |||||
| // } | |||||
| // Class taskClass = (Class) taskdefs.get(taskName); | |||||
| // newProject.addTaskDefinition(taskName, taskClass); | |||||
| // } | |||||
| // Hashtable typedefs = project.getDataTypeDefinitions(); | |||||
| // Enumeration e = typedefs.keys(); | |||||
| // while (e.hasMoreElements()) { | |||||
| // String typeName = (String) e.nextElement(); | |||||
| // Class typeClass = (Class) typedefs.get(typeName); | |||||
| // newProject.addDataTypeDefinition(typeName, typeClass); | |||||
| // } | |||||
| // set user-defined or all properties from calling project | // set user-defined or all properties from calling project | ||||
| Hashtable prop1; | Hashtable prop1; | ||||
| if (inheritAll) { | if (inheritAll) { | ||||
| @@ -418,7 +418,7 @@ public class Antlib extends Task { | |||||
| if (classpath != null) { | if (classpath != null) { | ||||
| clspath.append(classpath); | clspath.append(classpath); | ||||
| } | } | ||||
| return project.addToLoader(loaderId, clspath); | |||||
| return project.getSymbols().addToLoader(loaderId, clspath); | |||||
| } | } | ||||
| @@ -505,6 +505,8 @@ public class Antlib extends Task { | |||||
| private int level = 0; | private int level = 0; | ||||
| private SymbolTable symbols = null; | |||||
| private String name = null; | private String name = null; | ||||
| private String className = null; | private String className = null; | ||||
| private String adapter = null; | private String adapter = null; | ||||
| @@ -518,6 +520,7 @@ public class Antlib extends Task { | |||||
| AntLibraryHandler(ClassLoader classloader, Properties als) { | AntLibraryHandler(ClassLoader classloader, Properties als) { | ||||
| this.classloader = classloader; | this.classloader = classloader; | ||||
| this.aliasMap = als; | this.aliasMap = als; | ||||
| this.symbols = project.getSymbols(); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -588,15 +591,15 @@ public class Antlib extends Task { | |||||
| try { | try { | ||||
| if ("role".equals(tag)) { | if ("role".equals(tag)) { | ||||
| if (project.isRoleDefined(name)) { | |||||
| if (isRoleInUse(name)) { | |||||
| String msg = "Cannot override role: " + name; | String msg = "Cannot override role: " + name; | ||||
| log(msg, Project.MSG_WARN); | log(msg, Project.MSG_WARN); | ||||
| return; | return; | ||||
| } | } | ||||
| // Defining a new role | // Defining a new role | ||||
| project.addRoleDefinition(name, loadClass(className), | |||||
| (adapter == null? | |||||
| null : loadClass(adapter))); | |||||
| symbols.addRole(name, loadClass(className), | |||||
| (adapter == null? | |||||
| null : loadClass(adapter))); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -607,12 +610,12 @@ public class Antlib extends Task { | |||||
| name = alias; | name = alias; | ||||
| } | } | ||||
| //catch an attempted override of an existing name | //catch an attempted override of an existing name | ||||
| if (!override && project.isDefinedOnRole(tag, name)) { | |||||
| if (!override && isInUse(tag, name)) { | |||||
| String msg = "Cannot override " + tag + ": " + name; | String msg = "Cannot override " + tag + ": " + name; | ||||
| log(msg, Project.MSG_WARN); | log(msg, Project.MSG_WARN); | ||||
| return; | return; | ||||
| } | } | ||||
| project.addDefinitionOnRole(tag, name, loadClass(className)); | |||||
| symbols.add(tag, name, loadClass(className)); | |||||
| } | } | ||||
| catch(BuildException be) { | catch(BuildException be) { | ||||
| throw new SAXParseException(be.getMessage(), locator, be); | throw new SAXParseException(be.getMessage(), locator, be); | ||||
| @@ -648,6 +651,26 @@ public class Antlib extends Task { | |||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * 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); | |||||
| } | |||||
| /** | |||||
| * 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); | |||||
| } | |||||
| //end inner class AntLibraryHandler | //end inner class AntLibraryHandler | ||||
| } | } | ||||