git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@276428 13f79535-47bb-0310-9956-ffa450edef68master
@@ -41,10 +41,10 @@ or character data nested into the element.</p> | |||
<h3>Parameters specified as nested elements</h3> | |||
<p>As an alternative to the <i>if</i>/<i>unless</i> attributes, | |||
conditional failure can be achieved using a single nested condition. | |||
For a complete list of core conditions, as well as information | |||
about custom conditions, see <a href="conditions.html">here</a>.<br /> | |||
<b>Since Ant 1.6.2</b> | |||
conditional failure can be achieved using a single nested | |||
<condition> element, which should contain exactly one | |||
core or custom condition. For information about conditions, see | |||
<a href="conditions.html">here</a>.<br /><b>Since Ant 1.6.2</b> | |||
</p> | |||
<h3>Examples</h3> | |||
@@ -79,12 +79,15 @@ BUILD FAILED | |||
build.xml:2: unless=thisdoesnotexist | |||
</pre> | |||
A simple example using conditions to achieve the same effect: | |||
Using a condition to achieve the same effect: | |||
<pre> | |||
<fail> | |||
<not> | |||
<isset property="thisdoesnotexist"/> | |||
</not> | |||
<condition> | |||
<not> | |||
<isset property="thisdoesnotexist"/> | |||
</not> | |||
</condition> | |||
</fail> | |||
</pre> | |||
@@ -28,54 +28,87 @@ | |||
<target name="testNested1" description="should fail with default message"> | |||
<fail> | |||
<and /> | |||
<condition> | |||
<and /> | |||
</condition> | |||
</fail> | |||
</target> | |||
<target name="testNested2" description="should pass"> | |||
<fail> | |||
<or /> | |||
<condition> | |||
<or /> | |||
</condition> | |||
</fail> | |||
</target> | |||
<target name="testNested3" description="should fail"> | |||
<fail message="testNested3"> | |||
<and /> | |||
<condition> | |||
<and /> | |||
</condition> | |||
</fail> | |||
</target> | |||
<target name="testNested4a" description="should error"> | |||
<fail if="if"> | |||
<and /> | |||
<condition> | |||
<and /> | |||
</condition> | |||
</fail> | |||
</target> | |||
<target name="testNested4b" description="should error"> | |||
<fail unless="unless"> | |||
<and /> | |||
<condition> | |||
<and /> | |||
</condition> | |||
</fail> | |||
</target> | |||
<target name="testNested4c" description="should error"> | |||
<fail if="if" unless="unless"> | |||
<and /> | |||
<condition> | |||
<and /> | |||
</condition> | |||
</fail> | |||
</target> | |||
<target name="testNested5" description="should error"> | |||
<fail> | |||
<and /> | |||
<or /> | |||
<condition> | |||
<or /> | |||
</condition> | |||
<condition> | |||
<and /> | |||
</condition> | |||
</fail> | |||
</target> | |||
<target name="testNested6" description="should fail with message"> | |||
<fail> | |||
<and /> | |||
<condition> | |||
<and /> | |||
</condition> | |||
testNested6 | |||
testNested6 | |||
testNested6 | |||
</fail> | |||
</target> | |||
<target name="testNested7a" description="should error"> | |||
<fail> | |||
<condition /> | |||
</fail> | |||
</target> | |||
<target name="testNested7b" description="should error"> | |||
<fail> | |||
<condition> | |||
<and /> | |||
<and /> | |||
</condition> | |||
</fail> | |||
</target> | |||
</project> |
@@ -17,6 +17,8 @@ | |||
package org.apache.tools.ant.taskdefs; | |||
import java.util.Vector; | |||
import org.apache.tools.ant.Task; | |||
import org.apache.tools.ant.BuildException; | |||
import org.apache.tools.ant.taskdefs.condition.Condition; | |||
import org.apache.tools.ant.taskdefs.condition.ConditionBase; | |||
@@ -42,9 +44,21 @@ import org.apache.tools.ant.taskdefs.condition.ConditionBase; | |||
* | |||
* @ant.task name="fail" category="control" | |||
*/ | |||
public class Exit extends ConditionBase { | |||
public class Exit extends Task { | |||
private class NestedCondition extends ConditionBase implements Condition { | |||
public boolean eval() { | |||
if (countConditions() != 1) { | |||
throw new BuildException( | |||
"A single nested condition is required."); | |||
} | |||
return ((Condition)(getConditions().nextElement())).eval(); | |||
} | |||
} | |||
private String message; | |||
private String ifCondition, unlessCondition; | |||
private NestedCondition nestedCondition; | |||
/** | |||
* A message giving further information on why the build exited. | |||
@@ -128,6 +142,19 @@ public class Exit extends ConditionBase { | |||
message += getProject().replaceProperties(msg); | |||
} | |||
/** | |||
* Add a condition element. | |||
* @return <CODE>ConditionBase</CODE>. | |||
* @since Ant 1.6.2 | |||
*/ | |||
public ConditionBase createCondition() { | |||
if (nestedCondition != null) { | |||
throw new BuildException("Only one nested condition is allowed."); | |||
} | |||
nestedCondition = new NestedCondition(); | |||
return nestedCondition; | |||
} | |||
/** | |||
* test the if condition | |||
* @return true if there is no if condition, or the named property exists | |||
@@ -156,21 +183,22 @@ public class Exit extends ConditionBase { | |||
* @return true if there is none, or it evaluates to true | |||
*/ | |||
private boolean testNestedCondition() { | |||
if (ifCondition != null || unlessCondition != null) { | |||
throw new BuildException("Nested conditions " | |||
+ "not permitted in conjunction with if/unless attributes"); | |||
} | |||
boolean result = nestedConditionPresent(); | |||
int count = countConditions(); | |||
if (count > 1) { | |||
throw new BuildException("Too many conditions: " + count); | |||
if (result && ifCondition != null || unlessCondition != null) { | |||
throw new BuildException("Nested conditions " | |||
+ "not permitted in conjunction with if/unless attributes"); | |||
} | |||
return (count == 0) ? true | |||
: (((Condition)(getConditions().nextElement())).eval()); | |||
return result && nestedCondition.eval(); | |||
} | |||
/** | |||
* test whether there is a nested condition. | |||
* @return <CODE>boolean</CODE>. | |||
*/ | |||
private boolean nestedConditionPresent() { | |||
return (countConditions() > 0); | |||
return (nestedCondition != null); | |||
} | |||
} |
@@ -138,7 +138,7 @@ public class FailTest extends BuildFileTest { | |||
public void testNested5() { | |||
expectSpecificBuildException("testNested5", | |||
"it is required to fail :-)", | |||
"Too many conditions: 2"); | |||
"Only one nested condition is allowed."); | |||
} | |||
public void testNested6() { | |||
@@ -147,4 +147,17 @@ public class FailTest extends BuildFileTest { | |||
"testNested6\ntestNested6\ntestNested6"); | |||
} | |||
} | |||
public void testNested7() { | |||
String specificMessage = "A single nested condition is required."; | |||
char[] c = {'a', 'b'}; | |||
StringBuffer target = new StringBuffer("testNested7x"); | |||
for (int i = 0; i < c.length; i++) { | |||
target.setCharAt(target.length() - 1, c[i]); | |||
expectSpecificBuildException(target.toString(), | |||
"it is required to fail :-)", specificMessage); | |||
} | |||
} | |||
} |