@@ -0,0 +1,115 @@ | |||
<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> |
@@ -161,6 +161,41 @@ public class ComponentHelper { | |||
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 | |||
@@ -58,8 +58,10 @@ import java.io.File; | |||
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; | |||
@@ -97,6 +99,11 @@ public class IntrospectionHelper implements BuildListener { | |||
*/ | |||
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 @@ public class IntrospectionHelper implements BuildListener { | |||
nestedTypes = new Hashtable(); | |||
nestedCreators = new Hashtable(); | |||
nestedStorers = new Hashtable(); | |||
addTypeMethods = new ArrayList(); | |||
this.bean = bean; | |||
@@ -209,6 +217,14 @@ public class IntrospectionHelper implements BuildListener { | |||
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 class IntrospectionHelper implements BuildListener { | |||
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 class IntrospectionHelper implements BuildListener { | |||
*/ | |||
public boolean supportsNestedElement(String elementName) { | |||
return nestedCreators.containsKey(elementName) || | |||
DynamicConfigurator.class.isAssignableFrom(bean); | |||
DynamicConfigurator.class.isAssignableFrom(bean) || | |||
addTypeMethods.size() != 0; | |||
} | |||
/** | |||
@@ -978,4 +1005,102 @@ public class IntrospectionHelper implements BuildListener { | |||
* @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; | |||
} | |||
} |
@@ -59,8 +59,8 @@ import java.util.Hashtable; | |||
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 @@ import org.apache.tools.ant.util.regexp.Regexp; | |||
*/ | |||
public class TokenFilter | |||
extends BaseFilterReader | |||
implements ChainableReader, DynamicConfigurator | |||
implements ChainableReader | |||
{ | |||
/** | |||
* input stream tokenizers implement this interface | |||
@@ -229,9 +229,7 @@ public class TokenFilter | |||
*/ | |||
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 class TokenFilter | |||
*/ | |||
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 @@ public class TokenFilter | |||
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 @@ public class TokenFilter | |||
* class to read the complete input into a string | |||
*/ | |||
public static class FileTokenizer | |||
extends ProjectComponent | |||
implements Tokenizer | |||
{ | |||
/** | |||
@@ -378,6 +341,7 @@ public class TokenFilter | |||
* 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 @@ public class TokenFilter | |||
* as delims flag is set). | |||
*/ | |||
public static class StringTokenizer | |||
extends ProjectComponent | |||
implements Tokenizer | |||
{ | |||
private String intraString = ""; | |||
@@ -585,6 +550,7 @@ public class TokenFilter | |||
// -------------------------------------------- | |||
public static abstract class ChainableReaderFilter | |||
extends ProjectComponent | |||
implements ChainableReader, Filter | |||
{ | |||
private boolean byLine = true; | |||
@@ -596,7 +562,7 @@ public class TokenFilter | |||
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 @@ public class TokenFilter | |||
* Simple filter to filter lines contains strings | |||
*/ | |||
public static class ContainsString | |||
extends ProjectComponent | |||
implements Filter | |||
{ | |||
private String contains; | |||
@@ -818,6 +785,7 @@ public class TokenFilter | |||
* Filter to delete characters | |||
*/ | |||
public static class DeleteCharacters | |||
extends ProjectComponent | |||
implements Filter, ChainableReader | |||
{ | |||
// Attributes | |||
@@ -76,6 +76,7 @@ import org.apache.tools.ant.types.selectors.OrSelector; | |||
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. | |||
@@ -418,6 +419,15 @@ public class Delete extends MatchingTask { | |||
super.addContainsRegexp(selector); | |||
} | |||
/** | |||
* add an arbitary selector | |||
* @since Ant 1.6 | |||
*/ | |||
public void add(FileSelector selector) { | |||
usedMatchingTask = true; | |||
super.add(selector); | |||
} | |||
/** | |||
* Delete the file(s). | |||
*/ | |||
@@ -426,6 +426,7 @@ public abstract class MatchingTask extends Task implements SelectorContainer { | |||
public void addDifferent(DifferentSelector selector) { | |||
fileset.addDifferent(selector); | |||
} | |||
/** | |||
* add a type selector entry on the type list | |||
* @param selector | |||
@@ -435,6 +436,14 @@ public abstract class MatchingTask extends Task implements SelectorContainer { | |||
fileset.addType(selector); | |||
} | |||
/** | |||
* add an arbitary selector | |||
* @since Ant 1.6 | |||
*/ | |||
public void add(FileSelector selector) { | |||
fileset.add(selector); | |||
} | |||
/** | |||
* Accessor for the implict fileset. | |||
* | |||
@@ -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 abstract class ConditionBase extends ProjectComponent { | |||
*/ | |||
public void addIsReference(IsReference i) {conditions.addElement(i);} | |||
/** | |||
* Add an arbitary condition | |||
* @since Ant 1.6 | |||
*/ | |||
public void add(Condition c) {conditions.addElement(c);} | |||
} |
@@ -649,6 +649,14 @@ public abstract class AbstractFileSet extends DataType implements Cloneable, | |||
appendSelector(selector); | |||
} | |||
/** | |||
* 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 | |||
* | |||
@@ -59,7 +59,6 @@ import java.io.Reader; | |||
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 @@ import org.apache.tools.ant.taskdefs.Concat; | |||
* @author Magesh Umasankar | |||
*/ | |||
public final class FilterChain extends DataType | |||
implements Cloneable, DynamicConfigurator | |||
implements Cloneable | |||
{ | |||
private Vector filterReaders = new Vector(); | |||
@@ -246,38 +245,14 @@ public final class FilterChain extends DataType | |||
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); | |||
} | |||
} |
@@ -220,6 +220,19 @@ public class Path extends DataType implements Cloneable { | |||
setChecked( false ); | |||
} | |||
/** | |||
* 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. | |||
*/ | |||
@@ -79,8 +79,6 @@ import org.apache.tools.ant.Task; | |||
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 */ | |||
@@ -94,16 +92,6 @@ public class ScriptFilter | |||
/** 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). | |||
* | |||
@@ -305,5 +305,14 @@ public abstract class BaseSelectorContainer extends BaseSelector | |||
appendSelector(selector); | |||
} | |||
/** | |||
* add an arbitary selector | |||
* @since Ant 1.6 | |||
*/ | |||
public void add(FileSelector selector) { | |||
appendSelector(selector); | |||
} | |||
} | |||
@@ -189,5 +189,11 @@ public interface SelectorContainer { | |||
* @since ant 1.6 | |||
*/ | |||
public void addDifferent(DifferentSelector selector); | |||
/** | |||
* add an arbitary selector | |||
* @since Ant 1.6 | |||
*/ | |||
public void add(FileSelector selector); | |||
} | |||
@@ -0,0 +1,164 @@ | |||
/* | |||
* 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 apache@apache.org. | |||
* | |||
* 5. Products derived from this software may not be called "Apache" | |||
* nor may "Apache" appear in their names without prior written | |||
* permission of the Apache Group. | |||
* | |||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
* SUCH DAMAGE. | |||
* ==================================================================== | |||
* | |||
* This software consists of voluntary contributions made by many | |||
* individuals on behalf of the Apache Software Foundation. For more | |||
* information on the Apache Software Foundation, please see | |||
* <http://www.apache.org/>. | |||
*/ | |||
package org.apache.tools.ant.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"); | |||
} | |||
} | |||
} |