peterreilly 2003/05/28 09:27:38
Modified: src/main/org/apache/tools/ant ComponentHelper.java IntrospectionHelper.java src/main/org/apache/tools/ant/filters TokenFilter.java src/main/org/apache/tools/ant/taskdefs Delete.java MatchingTask.java src/main/org/apache/tools/ant/taskdefs/condition ConditionBase.java src/main/org/apache/tools/ant/types AbstractFileSet.java FilterChain.java Path.java src/main/org/apache/tools/ant/types/optional ScriptFilter.java src/main/org/apache/tools/ant/types/selectors BaseSelectorContainer.java SelectorContainer.java Added: src/etc/testcases/types addtype.xml src/testcases/org/apache/tools/ant/types AddTypeTest.java Log: PR: 19897 Submitted by: Peter Reilly This patch adds the add(Type) to the introspection rules and updates ConditionBase, FilterChain, Path, SelectorBase and TokenFilter to use the new introspection rule. ========================================= = Changed Files ========================================= src/main/org/apache/tools/ant/ProjectHelper.java add two methods used by introspection - getComponentClass and createComponent src/main/org/apache/tools/ant/IntrospectionHelper.java implement addTypeMethods add(Type) src/main/org/apache/tools/ant/filters/TokenFilter.java get TokenFilter to use add(Type) instead of dynamicconfigurator make all nested classes ProjectComponents src/main/org/apache/tools/ant/taskdefs/Delete.java implement an add(FileSelector) method src/main/org/apache/tools/ant/taskdefs/MatchingTask.java implement an add(FileSelector) method src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java add an add(Condition) method to demostrate use of add(Type) method src/main/org/apache/tools/ant/types/AbstractFileSet.java implement add(FileSelector) src/main/org/apache/tools/ant/types/FilterChain.java use add(ChainableReader) instead of DynamicConfigurator src/main/org/apache/tools/ant/types/Path.java add an add(Path) method src/main/org/apache/tools/ant/types/optional/ScriptFilter.java remove set/get project as parent imlements them now src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java implement the add(FileSelector) method src/main/org/apache/tools/ant/types/selectors/SelectorContainer.java add an add(FileSelector) method ========================================= = New Files ========================================= src/etc/testcases/types/addtype.xml testcases for addtype src/testcases/org/apache/tools/ant/types/AddTypeTest.java test cases for add type Revision Changes Path 1.1 ant/src/etc/testcases/types/addtype.xml Index: addtype.xml =================================================================== <project name="test" basedir="."> <target name="addpath"> <typedef name="mypath" classname="org.apache.tools.ant.types.Path"/> <path> <mypath path="build.xml"/> </path> </target> <target name="addcondition"> <typedef name="mycondition" classname="org.apache.tools.ant.taskdefs.condition.Equals"/> <condition property="mycondition.set"> <mycondition arg1="string" arg2="string"/> </condition> <fail unless="mycondition.set"/> </target> <target name="addfilter"> <typedef name="headfilter2" classname="org.apache.tools.ant.filters.HeadFilter"/> <concat>This is line 1 This is line 2 This is line 3 <filterchain> <headfilter2 lines="2"/> </filterchain> </concat> </target> <target name="addselector"> <typedef name="myselector" classname="org.apache.tools.ant.types.selectors.ContainsSelector"/> <fileset id="myselector.test" dir="${basedir}" includes="*"> <myselector text="myselector"/> </fileset> </target> <target name="init"> <property name="nested.package" value="org.apache.tools.ant.types."/> <path id="test-classes"> <pathelement location="../../../../build/testcases" /> <pathelement path="${java.class.path}" /> </path> <typedef loaderref="nested.loader" classpathref="test-classes" name = "nested.a" classname="${nested.package}AddTypeTest$AImpl"/> <typedef loaderref="nested.loader" classpathref="test-classes" name = "nested.b" classname="${nested.package}AddTypeTest$BImpl"/> <typedef loaderref="nested.loader" classpathref="test-classes" name = "nested.c" classname="${nested.package}AddTypeTest$CImpl"/> <typedef loaderref="nested.loader" classpathref="test-classes" name = "nested.ab" classname="${nested.package}AddTypeTest$ABImpl"/> <taskdef loaderref="nested.loader" classpathref="test-classes" name = "nested.container" classname="${nested.package}AddTypeTest$NestedContainer"/> <taskdef loaderref="nested.loader" classpathref="nested.classes" name = "nested.condition.task" classname="${nested.package}AddTypeTest$MyCondition"/> <typedef loaderref="nested.loader" classpathref="nested.classes" name = "nested.condition.type" classname="${nested.package}AddTypeTest$MyCondition"/> </target> <target name="nested.a" depends="init"> <nested.container> <nested.a/> </nested.container> </target> <target name="nested.b" depends="init"> <nested.container> <nested.b/> </nested.container> </target> <target name="nested.c" depends="init"> <nested.container> <nested.c/> </nested.container> </target> <target name="nested.ab" depends="init"> <nested.container> <nested.ab/> </nested.container> </target> <!-- tests for task adaptor --> <target name="condition.type" depends="init"> <echo>before</echo> <nested.condition.type/> <echo>after</echo> </target> <target name="condition.task" depends="init"> <echo>before</echo> <nested.condition.task/> <echo>after</echo> </target> <target name="condition.condition.type" depends="init"> <condition property="condition.condition.type"> <nested.condition.type/> </condition> </target> <target name="condition.condition.task" depends="init"> <condition property="condition.condition.task">> <nested.condition.task/> </condition> </target> </project> 1.10 +35 -0 ant/src/main/org/apache/tools/ant/ComponentHelper.java Index: ComponentHelper.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/ComponentHelper.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- ComponentHelper.java 5 May 2003 13:59:24 -0000 1.9 +++ ComponentHelper.java 28 May 2003 16:27:32 -0000 1.10 @@ -161,6 +161,41 @@ return component; } + /** + * get the class of a particular component + */ + public Class getComponentClass(String componentName) { + Class elementClass = + (Class) getTaskDefinitions().get(componentName); + if (elementClass != null) { + if (! (Task.class.isAssignableFrom(elementClass))) { + elementClass = TaskAdapter.class; + } + return elementClass; + } + return (Class) getDataTypeDefinitions().get(componentName); + } + + /** + * create a named component + */ + public Object createComponent(String componentName) + throws BuildException + { + Object obj = createTask(componentName); + if (obj == null) { + obj = createDataType(componentName); + } + if (obj == null) { + return obj; + } + project.setProjectReference(obj); + if (obj instanceof Task) { + ((Task)obj).init(); // Needed here ?? + } + return obj; + } + /** Initialization code - implementing the original ant component * loading from /org/apache/tools/ant/taskdefs/default.properties * and .../types/default.properties 1.56 +126 -1 ant/src/main/org/apache/tools/ant/IntrospectionHelper.java Index: IntrospectionHelper.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/IntrospectionHelper.java,v retrieving revision 1.55 retrieving revision 1.56 diff -u -r1.55 -r1.56 --- IntrospectionHelper.java 15 Apr 2003 17:23:15 -0000 1.55 +++ IntrospectionHelper.java 28 May 2003 16:27:32 -0000 1.56 @@ -58,8 +58,10 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; +import java.util.List; import java.util.Locale; import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.types.Path; @@ -98,6 +100,11 @@ private Hashtable nestedCreators; /** + * Vector of methods matching add[Configured](Class) pattern + */ + private List addTypeMethods; + + /** * Map from attribute names to methods to store configured nested types * (String to NestedStorer). */ @@ -199,6 +206,7 @@ nestedTypes = new Hashtable(); nestedCreators = new Hashtable(); nestedStorers = new Hashtable(); + addTypeMethods = new ArrayList(); this.bean = bean; @@ -209,6 +217,14 @@ Class returnType = m.getReturnType(); Class[] args = m.getParameterTypes(); + // check of add[Configured](Class) pattern + if (args.length == 1 + && java.lang.Void.TYPE.equals(returnType) + && (name.equals("add") /*|| name.equals("addConfigured")*/)) { + insertAddTypeMethod(m); + continue; + } + // not really user settable properties on tasks if (org.apache.tools.ant.Task.class.isAssignableFrom(bean) && args.length == 1 && isHiddenSetMethod(name, args[0])) { @@ -534,6 +550,16 @@ public Object createElement(Project project, Object parent, String elementName) throws BuildException { NestedCreator nc = (NestedCreator) nestedCreators.get(elementName); + if (nc == null && addTypeMethods.size() > 0) { + Object nestedElement = createAddTypeElement( + project, parent, elementName); + if (nestedElement != null) { + if (project != null) { + project.setProjectReference(nestedElement); + } + return nestedElement; + } + } if (nc == null && parent instanceof DynamicConfigurator) { DynamicConfigurator dc = (DynamicConfigurator) parent; Object nestedElement = dc.createDynamicElement(elementName); @@ -578,7 +604,8 @@ */ public boolean supportsNestedElement(String elementName) { return nestedCreators.containsKey(elementName) || - DynamicConfigurator.class.isAssignableFrom(bean); + DynamicConfigurator.class.isAssignableFrom(bean) || + addTypeMethods.size() != 0; } /** @@ -978,4 +1005,102 @@ * @param event Ignored in this implementation. */ public void messageLogged(BuildEvent event) {} + + /** + * Check if the parent accepts a typed nested element + * and if so, create the object, call the parents + * addmethod. + * This method is part of the initial support + * for add(Type) and addConfigured(Type). + * AddConfigured(Type) will be done later. + */ + + private Object createAddTypeElement( + Project project, Object parent, String elementName) + { + ComponentHelper helper = ComponentHelper.getComponentHelper(project); + Object addedObject = null; + Method addMethod = null; + + Class clazz = helper.getComponentClass(elementName); + if (clazz == null) { + return null; + } + addMethod = findMatchingMethod(clazz, addTypeMethods); + if (addMethod == null) { + return null; + } + addedObject = helper.createComponent(elementName); + if (addedObject == null) { + return null; + } + + try { + addMethod.invoke(parent, new Object[] {addedObject}); + } catch (IllegalAccessException ex) { + throw new BuildException(ex); + } catch (InvocationTargetException ex) { + Throwable t = ex.getTargetException(); + if (t instanceof BuildException) { + throw (BuildException) t; + } + throw new BuildException(t); + } catch (Throwable t) { + throw new BuildException(t); + } + return addedObject; + } + + /** + * Inserts an add or addConfigured method into + * the addTypeMethods array. The array is + * ordered so that the more derived classes + * are first. + */ + + private void insertAddTypeMethod(Method method) { + Class argClass = method.getParameterTypes()[0]; + for (int c = 0; c < addTypeMethods.size(); ++c) { + Method current = (Method) addTypeMethods.get(c); + if (current.getParameterTypes()[0].equals(argClass)) { + return; // Already present + } + if (current.getParameterTypes()[0].isAssignableFrom( + argClass)) { + addTypeMethods.add(c, method); + return; // higher derived + } + } + addTypeMethods.add(method); + } + + + /** + * Search the list of methods to find the first method + * that has a parameter that accepts the nested element object + */ + private Method findMatchingMethod(Class paramClass, List methods) { + Class matchedClass = null; + Method matchedMethod = null; + + for (int i = 0; i < methods.size(); ++i) { + Method method = (Method) methods.get(i); + Class methodClass = method.getParameterTypes()[0]; + if (methodClass.isAssignableFrom(paramClass)) { + if (matchedClass == null) { + matchedClass = methodClass; + matchedMethod = method; + } else { + if (! methodClass.isAssignableFrom(matchedClass)) { + throw new BuildException( + "ambiguous: types " + matchedClass.getName() + + " and " + methodClass.getName() + + " match " + paramClass.getName()); + } + } + } + } + return matchedMethod; + } + } 1.4 +21 -53 ant/src/main/org/apache/tools/ant/filters/TokenFilter.java Index: TokenFilter.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/filters/TokenFilter.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- TokenFilter.java 24 Apr 2003 09:37:48 -0000 1.3 +++ TokenFilter.java 28 May 2003 16:27:33 -0000 1.4 @@ -59,8 +59,8 @@ import java.util.Vector; import java.util.Enumeration; import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DynamicConfigurator; import org.apache.tools.ant.Project; +import org.apache.tools.ant.ProjectComponent; import org.apache.tools.ant.types.EnumeratedAttribute; import org.apache.tools.ant.types.Parameter; import org.apache.tools.ant.types.RegularExpression; @@ -80,7 +80,7 @@ */ public class TokenFilter extends BaseFilterReader - implements ChainableReader, DynamicConfigurator + implements ChainableReader { /** * input stream tokenizers implement this interface @@ -229,9 +229,7 @@ */ public void addLineTokenizer(LineTokenizer tokenizer) { - if (this.tokenizer != null) - throw new BuildException("Only one tokenizer allowed"); - this.tokenizer = tokenizer; + add(tokenizer); } /** @@ -239,21 +237,26 @@ */ public void addStringTokenizer(StringTokenizer tokenizer) { - if (this.tokenizer != null) - throw new BuildException("Only one tokenizer allowed"); - this.tokenizer = tokenizer; + add(tokenizer); } /** * add a file tokenizer */ public void addFileTokenizer(FileTokenizer tokenizer) { + add(tokenizer); + } + + /** + * add a tokenizer + */ + + public void add(Tokenizer tokenizer) { if (this.tokenizer != null) throw new BuildException("Only one tokenizer allowed"); this.tokenizer = tokenizer; } - - + // ----------------------------------------- // Predefined filters // ----------------------------------------- @@ -297,48 +300,7 @@ filters.addElement(filter); } - /** - * create the named datatype and check if it - * is a filter or a tokenizer - * - * @throws BuildException if unknown datatype or incorrect datatype - */ - - public Object createDynamicElement(String name) - { - if (getProject() == null) - throw new BuildException( - "createDynamicElement.TokenFilter" + - " - Unable to get the project"); - - Object obj = getProject().createDataType(name); - if (obj == null) - throw new BuildException("Unknown type " + name); - if (obj instanceof Filter) - filters.addElement(obj); - else if (obj instanceof Tokenizer) { - if (this.tokenizer != null) - throw new BuildException("Only one tokenizer allowed"); - tokenizer = (Tokenizer) obj; - } - else - throw new BuildException( - "type " + name + " is not a TokenFilter.Filter or " + - "TokenFiler.Tokenizer"); - return obj; - } - - - /** - * Needed for dynamic element support. - * - * @throws BuildException always - */ - - public void setDynamicAttribute(String name, String value) { - throw new BuildException("Unknown attribute " + name); - } - + // -------------------------------------------- // // Tokenizer Classes @@ -349,6 +311,7 @@ * class to read the complete input into a string */ public static class FileTokenizer + extends ProjectComponent implements Tokenizer { /** @@ -378,6 +341,7 @@ * by \r (mac style), \r\n (dos/windows style) or \n (unix style) */ public static class LineTokenizer + extends ProjectComponent implements Tokenizer { private String lineEnd = ""; @@ -466,6 +430,7 @@ * as delims flag is set). */ public static class StringTokenizer + extends ProjectComponent implements Tokenizer { private String intraString = ""; @@ -585,6 +550,7 @@ // -------------------------------------------- public static abstract class ChainableReaderFilter + extends ProjectComponent implements ChainableReader, Filter { private boolean byLine = true; @@ -596,7 +562,7 @@ public Reader chain(Reader reader) { TokenFilter tokenFilter = new TokenFilter(reader); if (!byLine) - tokenFilter.addFileTokenizer(new FileTokenizer()); + tokenFilter.add(new FileTokenizer()); tokenFilter.add(this); return tokenFilter; } @@ -656,6 +622,7 @@ * Simple filter to filter lines contains strings */ public static class ContainsString + extends ProjectComponent implements Filter { private String contains; @@ -818,6 +785,7 @@ * Filter to delete characters */ public static class DeleteCharacters + extends ProjectComponent implements Filter, ChainableReader { // Attributes 1.40 +10 -0 ant/src/main/org/apache/tools/ant/taskdefs/Delete.java Index: Delete.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/Delete.java,v retrieving revision 1.39 retrieving revision 1.40 diff -u -r1.39 -r1.40 --- Delete.java 18 Apr 2003 23:40:22 -0000 1.39 +++ Delete.java 28 May 2003 16:27:35 -0000 1.40 @@ -76,6 +76,7 @@ import org.apache.tools.ant.types.selectors.PresentSelector; import org.apache.tools.ant.types.selectors.SelectSelector; import org.apache.tools.ant.types.selectors.SizeSelector; +import org.apache.tools.ant.types.selectors.FileSelector; /** * Deletes a file or directory, or set of files defined by a fileset. @@ -416,6 +417,15 @@ public void addContainsRegexp(ContainsRegexpSelector selector) { usedMatchingTask = true; super.addContainsRegexp(selector); + } + + /** + * add an arbitary selector + * @since Ant 1.6 + */ + public void add(FileSelector selector) { + usedMatchingTask = true; + super.add(selector); } /** 1.36 +9 -0 ant/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java Index: MatchingTask.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/MatchingTask.java,v retrieving revision 1.35 retrieving revision 1.36 diff -u -r1.35 -r1.36 --- MatchingTask.java 28 May 2003 13:21:24 -0000 1.35 +++ MatchingTask.java 28 May 2003 16:27:35 -0000 1.36 @@ -426,6 +426,7 @@ public void addDifferent(DifferentSelector selector) { fileset.addDifferent(selector); } + /** * add a type selector entry on the type list * @param selector @@ -433,6 +434,14 @@ */ public void addType(TypeSelector selector) { fileset.addType(selector); + } + + /** + * add an arbitary selector + * @since Ant 1.6 + */ + public void add(FileSelector selector) { + fileset.add(selector); } /** 1.19 +8 -2 ant/src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java Index: ConditionBase.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/taskdefs/condition/ConditionBase.java,v retrieving revision 1.18 retrieving revision 1.19 diff -u -r1.18 -r1.19 --- ConditionBase.java 7 Mar 2003 11:23:05 -0000 1.18 +++ ConditionBase.java 28 May 2003 16:27:36 -0000 1.19 @@ -1,7 +1,7 @@ /* * The Apache Software License, Version 1.1 * - * Copyright (c) 2001-2002 The Apache Software Foundation. All rights + * Copyright (c) 2001-2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without @@ -203,4 +203,10 @@ */ public void addIsReference(IsReference i) {conditions.addElement(i);} + /** + * Add an arbitary condition + * @since Ant 1.6 + */ + public void add(Condition c) {conditions.addElement(c);} + } 1.21 +8 -0 ant/src/main/org/apache/tools/ant/types/AbstractFileSet.java Index: AbstractFileSet.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/types/AbstractFileSet.java,v retrieving revision 1.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- AbstractFileSet.java 27 May 2003 09:30:17 -0000 1.20 +++ AbstractFileSet.java 28 May 2003 16:27:36 -0000 1.21 @@ -650,6 +650,14 @@ } /** + * add an arbitary selector + * @since Ant 1.6 + */ + public void add(FileSelector selector) { + appendSelector(selector); + } + + /** * Returns included files as a list of semicolon-separated filenames * * @return String object with included filenames 1.11 +5 -30 ant/src/main/org/apache/tools/ant/types/FilterChain.java Index: FilterChain.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/types/FilterChain.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- FilterChain.java 14 Apr 2003 18:02:24 -0000 1.10 +++ FilterChain.java 28 May 2003 16:27:36 -0000 1.11 @@ -59,7 +59,6 @@ import java.io.IOException; import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DynamicConfigurator; import org.apache.tools.ant.filters.ChainableReader; import org.apache.tools.ant.filters.ClassConstants; import org.apache.tools.ant.filters.EscapeUnicode; @@ -85,7 +84,7 @@ * @author Magesh Umasankar */ public final class FilterChain extends DataType - implements Cloneable, DynamicConfigurator + implements Cloneable { private Vector filterReaders = new Vector(); @@ -246,38 +245,14 @@ super.setRefid(r); } - + /** - * create the named datatype and check if it - * is a filter. - * - * @throws BuildException if unknown datatype or incorrect datatype + * add a chainfilter * @since Ant 1.6 */ - - public Object createDynamicElement(String name) - { - if (getProject() == null) - throw new BuildException("Unable to get the project"); - - Object obj = getProject().createDataType(name); - if (obj == null) - throw new BuildException("Unknown type " + name); - if (! (obj instanceof ChainableReader)) - throw new BuildException( - "type " + name + " is not a filterreader"); - filterReaders.addElement(obj); - return obj; - } - /** - * Needed for dynamic element support. - * - * @throws BuildException always - */ - - public void setDynamicAttribute(String name, String value) { - throw new BuildException("Unknown attribute " + name); + public void add(ChainableReader filter) { + filterReaders.addElement(filter); } } 1.50 +13 -0 ant/src/main/org/apache/tools/ant/types/Path.java Index: Path.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/types/Path.java,v retrieving revision 1.49 retrieving revision 1.50 diff -u -r1.49 -r1.50 --- Path.java 27 May 2003 09:30:17 -0000 1.49 +++ Path.java 28 May 2003 16:27:36 -0000 1.50 @@ -221,6 +221,19 @@ } /** + * Adds a nested path + * @since Ant 1.6 + */ + public void add(Path path) throws BuildException { + if (isReference()) { + throw noChildrenAllowed(); + } + elements.addElement(path); + setChecked( false ); + + } + + /** * Creates a nested <code><path></code> element. */ public Path createPath() throws BuildException { 1.2 +0 -12 ant/src/main/org/apache/tools/ant/types/optional/ScriptFilter.java Index: ScriptFilter.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/types/optional/ScriptFilter.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ScriptFilter.java 14 Apr 2003 18:02:24 -0000 1.1 +++ ScriptFilter.java 28 May 2003 16:27:36 -0000 1.2 @@ -79,8 +79,6 @@ public class ScriptFilter extends TokenFilter.ChainableReaderFilter { - /** The current project - set by ant reflection */ - private Project project; /** The language - attribute of element */ private String language; /** The script - inline text or external file */ @@ -93,16 +91,6 @@ private BSFManager manager; /** the token used by the script */ private String token; - - /** Called by ant reflection to set the project */ - public void setProject(Project project) { - this.project = project; - } - - /** this is provided to allow easier CAP from the ScriptTask */ - private Project getProject() { - return project; - } /** * Defines the language (required). 1.9 +9 -0 ant/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java Index: BaseSelectorContainer.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/types/selectors/BaseSelectorContainer.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- BaseSelectorContainer.java 25 May 2003 11:40:54 -0000 1.8 +++ BaseSelectorContainer.java 28 May 2003 16:27:37 -0000 1.9 @@ -305,5 +305,14 @@ appendSelector(selector); } + + /** + * add an arbitary selector + * @since Ant 1.6 + */ + public void add(FileSelector selector) { + appendSelector(selector); + } + } 1.7 +6 -0 ant/src/main/org/apache/tools/ant/types/selectors/SelectorContainer.java Index: SelectorContainer.java =================================================================== RCS file: /home/cvs/ant/src/main/org/apache/tools/ant/types/selectors/SelectorContainer.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- SelectorContainer.java 28 May 2003 13:21:24 -0000 1.6 +++ SelectorContainer.java 28 May 2003 16:27:37 -0000 1.7 @@ -189,5 +189,11 @@ * @since ant 1.6 */ public void addDifferent(DifferentSelector selector); + + /** + * add an arbitary selector + * @since Ant 1.6 + */ + public void add(FileSelector selector); } 1.1 ant/src/testcases/org/apache/tools/ant/types/AddTypeTest.java Index: AddTypeTest.java =================================================================== /* * The Apache Software License, Version 1.1 * * Copyright (c) 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 "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 [EMAIL PROTECTED] * * 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.types; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildFileTest; import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; import org.apache.tools.ant.taskdefs.condition.Condition; public class AddTypeTest extends BuildFileTest { public AddTypeTest(String name) { super(name); } public void setUp() { configureProject("src/etc/testcases/types/addtype.xml"); } public void testAddPath() { executeTarget("addpath"); } public void testAddCondition() { executeTarget("addcondition"); } public void testAddFilter() { executeTarget("addfilter"); } public void testAddSelector() { executeTarget("addselector"); } public void testNestedA() { expectLogContaining("nested.a", "add A called"); } public void testNestedB() { expectLogContaining("nested.b", "add B called"); } public void testNestedC() { expectLogContaining("nested.c", "add C called"); } public void testNestedAB() { expectBuildExceptionContaining( "nested.ab", "Should have got ambiguous", "ambiguous"); } public void testConditionType() { expectLogContaining("condition.type", "beforeafter"); } public void testConditionTask() { expectLogContaining("condition.task", "My Condition execution"); } public void testConditionConditionType() { expectLogContaining("condition.condition.type", "My Condition eval"); } public void testConditionConditionTask() { expectBuildExceptionContaining( "condition.condition.task", "task masking condition", "doesn't support the nested"); } // The following will be used as types and tasks public static interface A {} public static interface B {} public static interface C extends A {} public static interface AB extends A, B {} public static class AImpl implements A{} public static class BImpl implements B{} public static class CImpl implements C{} public static class ABImpl implements AB{} public static class NestedContainer extends Task { public void add(A el) { log("add A called"); } public void add(B el) { log("add B called"); } public void add(C el) { log("add C called"); } } public static class MyCondition implements Condition { Project project; public void setProject(Project project) { this.project = project; } public boolean eval() { project.log("My Condition eval"); return true; } public void execute() { project.log("My Condition execution"); } } }