From 8dfa7abd4d64b0cbef6166a28440f39f46d6efd1 Mon Sep 17 00:00:00 2001 From: Erik Hatcher Date: Sat, 2 Mar 2002 22:21:19 +0000 Subject: [PATCH] for Jose Alberto git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271672 13f79535-47bb-0310-9956-ffa450edef68 --- .../main/org/apache/tools/ant/Project.java | 259 ++++++------- .../org/apache/tools/ant/RoleAdapter.java | 5 - .../org/apache/tools/ant/SymbolTable.java | 354 +++++++----------- .../org/apache/tools/ant/TaskAdapter.java | 1 - .../src/main/org/apache/tools/ant/antlib.xml | 137 +++++++ .../org/apache/tools/ant/taskdefs/Ant.java | 24 +- .../org/apache/tools/ant/taskdefs/Antlib.java | 37 +- 7 files changed, 452 insertions(+), 365 deletions(-) create mode 100644 proposal/sandbox/antlib/src/main/org/apache/tools/ant/antlib.xml diff --git a/proposal/sandbox/antlib/src/main/org/apache/tools/ant/Project.java b/proposal/sandbox/antlib/src/main/org/apache/tools/ant/Project.java index ab3a23b84..20f856f4b 100644 --- a/proposal/sandbox/antlib/src/main/org/apache/tools/ant/Project.java +++ b/proposal/sandbox/antlib/src/main/org/apache/tools/ant/Project.java @@ -63,15 +63,12 @@ import java.util.Properties; import java.util.Enumeration; import java.util.Stack; 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.FilterSet; import org.apache.tools.ant.types.FilterSetCollection; import org.apache.tools.ant.util.FileUtils; -import org.apache.tools.ant.types.Path; /** * Central representation of an Ant project. This class defines a @@ -171,26 +168,30 @@ public class Project { fileUtils = FileUtils.newFileUtils(); symbols = new SymbolTable(); symbols.setProject(this); - loadDefinitions(); } /** * create a new ant project that inherits from caler project * @param p the calling project */ - private Project(Project p) { + public Project(Project p) { fileUtils = FileUtils.newFileUtils(); - symbols = new SymbolTable(p.getSymbols()); + symbols = new SymbolTable(p); 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); String defs = "/org/apache/tools/ant/taskdefs/defaults.properties"; @@ -250,23 +251,7 @@ public class Project { } catch (IOException ioe) { 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(); } @@ -293,7 +278,7 @@ public class Project { /** * Get the symbols associated with this project. */ - private SymbolTable getSymbols() { // Package protected on purpose + public SymbolTable getSymbols() { return symbols; } @@ -622,20 +607,6 @@ public class Project { 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) { return symbols.addToLoader(loader, path); } @@ -676,6 +647,20 @@ public class Project { 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 * @param taskName name of the task @@ -685,14 +670,21 @@ public class Project { */ public void addTaskDefinition(String taskName, Class taskClass) 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. * @throws BuildException and logs as Project.MSG_ERR for * 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 { if( !Task.class.isAssignableFrom(taskClass) ) { @@ -704,7 +696,7 @@ public class Project { * get the current task definition hashtable */ public Hashtable getTaskDefinitions() { - return symbols.getDefinitions(TASK_ROLE); + return symbols.getTaskDefinitions(); } /** @@ -713,14 +705,18 @@ public class Project { * @param typeClass full datatype classname */ 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 */ public Hashtable getDataTypeDefinitions() { - return symbols.getDefinitions(DATATYPE_ROLE); + return symbols.getDataTypeDefinitions(); } /** @@ -748,7 +744,7 @@ public class Project { * in the project. * @see Project#addOrReplaceTarget to replace existing Targets. */ - public void addTarget(String targetName, Target target) + public void addTarget(String targetName, Target target) throws BuildException { if (targets.get(targetName) != null) { throw new BuildException("Duplicate target: `"+targetName+"'"); @@ -784,88 +780,6 @@ public class Project { 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 * @param taskType name of the task @@ -873,7 +787,39 @@ public class Project { * @return null if the task name is unknown */ 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 */ 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) { - 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, MSG_WARN); } diff --git a/proposal/sandbox/antlib/src/main/org/apache/tools/ant/RoleAdapter.java b/proposal/sandbox/antlib/src/main/org/apache/tools/ant/RoleAdapter.java index 57c1f62d9..e028ebe92 100644 --- a/proposal/sandbox/antlib/src/main/org/apache/tools/ant/RoleAdapter.java +++ b/proposal/sandbox/antlib/src/main/org/apache/tools/ant/RoleAdapter.java @@ -55,11 +55,6 @@ package org.apache.tools.ant; public interface RoleAdapter { - /** - * Obtain the id in case it is needed. - */ - public void setId(String id); - /** * Set the object being adapted. * @param o the object being adapted diff --git a/proposal/sandbox/antlib/src/main/org/apache/tools/ant/SymbolTable.java b/proposal/sandbox/antlib/src/main/org/apache/tools/ant/SymbolTable.java index e009e1438..e6b8c843b 100644 --- a/proposal/sandbox/antlib/src/main/org/apache/tools/ant/SymbolTable.java +++ b/proposal/sandbox/antlib/src/main/org/apache/tools/ant/SymbolTable.java @@ -54,7 +54,6 @@ package org.apache.tools.ant; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; @@ -97,8 +96,8 @@ public class SymbolTable { * from that defined in 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; } - /** - * 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 * on this symbol table. @@ -182,13 +133,13 @@ public class SymbolTable { list.addElement(role); } } - if (parentTable != null) parentTable.findRoles(clz, list); + if (parentTable != null) findRoles(clz, list); } /** * Get the Role definition * @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) { Role r = (Role) roles.get(role); @@ -220,6 +171,112 @@ public class SymbolTable { 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. * @param role the role for this Class. @@ -234,13 +291,13 @@ public class SymbolTable { throw new BuildException("Unknown role: " + role); } // Check if it is already defined - Factory old = get(role, name); + Class old = get(role, name); if (old != null) { - if (old.getOriginalClass().equals(clz)) { + if (old.equals(clz)) { project.log("Ignoring override for "+ role + " " + name + ", it is already defined by the same class.", project.MSG_VERBOSE); - return old.getOriginalClass(); + return old; } else { project.log("Trying to override old definition of " + @@ -248,33 +305,26 @@ public class SymbolTable { project.MSG_WARN); } } - Factory f = checkClass(clz); + checkClass(clz); // Check that the Class is compatible with the role definition - f = r.verifyAdaptability(role, f); + r.verifyAdaptability(role, clz); // Record the new type Hashtable defTable = (Hashtable)defs.get(role); if (defTable == null) { defTable = new Hashtable(); 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. - * @return the factory to use when instantiating the class * @throws BuildException and logs as Project.MSG_ERR for * conditions, that will cause execution to fail. */ - Factory checkClass(final Class clz) // Package on purpose + void checkClass(final Class clz) throws BuildException { - if (clz == null) return null; - if(!Modifier.isPublic(clz.getModifiers())) { final String message = clz + " is not public"; project.log(message, Project.MSG_ERR); @@ -292,37 +342,8 @@ public class SymbolTable { // getConstructor finds public constructors only. try { 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) { - 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) { final String message = @@ -338,11 +359,11 @@ public class SymbolTable { * @param name the name of the element to sea * @return the Class implementation */ - public Factory get(String role, String name) { + public Class get(String role, String name) { Hashtable defTable = (Hashtable)defs.get(role); 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) { 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. */ - 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) { - 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 */ public class Role { private Method interfaceMethod; private Method adapterVerifier; - private Factory adapterFactory; /** * Creates a new Role object @@ -419,7 +420,6 @@ public class SymbolTable { */ Role(Class roleClz, Class adapterClz) { interfaceMethod = validInterface(roleClz); - adapterFactory = checkClass(adapterClz); adapterVerifier = validAdapter(adapterClz, interfaceMethod); } @@ -433,11 +433,12 @@ public class SymbolTable { /** * 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 { - return (RoleAdapter) adapterFactory.create(p); + return (RoleAdapter) + adapterVerifier.getDeclaringClass().newInstance(); } catch(BuildException be) { throw be; @@ -450,12 +451,11 @@ public class SymbolTable { /** * Verify if the class can be adapted to use by the role * @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)) { - return f; + return; } if (adapterVerifier == null) { String msg = "Class " + clz.getName() + @@ -464,18 +464,8 @@ public class SymbolTable { } 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) { throw ite.getTargetException(); @@ -497,63 +487,5 @@ public class SymbolTable { public boolean isImplementedBy(Class 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); - } - } - } } diff --git a/proposal/sandbox/antlib/src/main/org/apache/tools/ant/TaskAdapter.java b/proposal/sandbox/antlib/src/main/org/apache/tools/ant/TaskAdapter.java index d083a92bd..213f4f014 100644 --- a/proposal/sandbox/antlib/src/main/org/apache/tools/ant/TaskAdapter.java +++ b/proposal/sandbox/antlib/src/main/org/apache/tools/ant/TaskAdapter.java @@ -165,5 +165,4 @@ public class TaskAdapter extends Task implements RoleAdapter { return this.proxy ; } - public void setId(String id) {} } diff --git a/proposal/sandbox/antlib/src/main/org/apache/tools/ant/antlib.xml b/proposal/sandbox/antlib/src/main/org/apache/tools/ant/antlib.xml new file mode 100644 index 000000000..6a2f0a731 --- /dev/null +++ b/proposal/sandbox/antlib/src/main/org/apache/tools/ant/antlib.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs/Ant.java b/proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs/Ant.java index 5d6d8d699..13d42380d 100644 --- a/proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs/Ant.java +++ b/proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs/Ant.java @@ -138,8 +138,10 @@ public class Ant extends Task { } public void init() { - newProject = project.createSubProject(); + newProject = new Project(project); newProject.setJavaVersionProperty(); +// newProject.addTaskDefinition("property", +// (Class)project.getTaskDefinitions().get("property")); } 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 Hashtable prop1; if (inheritAll) { diff --git a/proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs/Antlib.java b/proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs/Antlib.java index 924b81315..c084791c4 100644 --- a/proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs/Antlib.java +++ b/proposal/sandbox/antlib/src/main/org/apache/tools/ant/taskdefs/Antlib.java @@ -418,7 +418,7 @@ public class Antlib extends Task { if (classpath != null) { 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 SymbolTable symbols = null; + private String name = null; private String className = null; private String adapter = null; @@ -518,6 +520,7 @@ public class Antlib extends Task { AntLibraryHandler(ClassLoader classloader, Properties als) { this.classloader = classloader; this.aliasMap = als; + this.symbols = project.getSymbols(); } /** @@ -588,15 +591,15 @@ public class Antlib extends Task { try { if ("role".equals(tag)) { - if (project.isRoleDefined(name)) { + if (isRoleInUse(name)) { String msg = "Cannot override role: " + name; log(msg, Project.MSG_WARN); return; } // 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; } @@ -607,12 +610,12 @@ public class Antlib extends Task { name = alias; } //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; log(msg, Project.MSG_WARN); return; } - project.addDefinitionOnRole(tag, name, loadClass(className)); + symbols.add(tag, name, loadClass(className)); } catch(BuildException 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 }