/* * Copyright (c) 2001-2004 Ant-Contrib project. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.moxie.ant; import java.util.Vector; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.taskdefs.Sequential; import org.apache.tools.ant.taskdefs.condition.Condition; import org.apache.tools.ant.taskdefs.condition.ConditionBase; import org.moxie.MoxieException; /** * Perform some tasks based on whether a given condition holds true or * not. * * <p>This task is heavily based on the Condition framework that can * be found in Ant 1.4 and later, therefore it cannot be used in * conjunction with versions of Ant prior to 1.4.</p> * * <p>This task doesn't have any attributes, the condition to test is * specified by a nested element - see the documentation of your * <code><condition></code> task (see * <a href="http://jakarta.apache.org/ant/manual/CoreTasks/condition.html">the * online documentation</a> for example) for a complete list of nested * elements.</p> * * <p>Just like the <code><condition></code> task, only a single * condition can be specified - you combine them using * <code><and></code> or <code><or></code> conditions.</p> * * <p>In addition to the condition, you can specify three different * child elements, <code><elseif></code>, <code><then></code> and * <code><else></code>. All three subelements are optional. * * Both <code><then></code> and <code><else></code> must not be * used more than once inside the if task. Both are * containers for Ant tasks, just like Ant's * <code><parallel></code> and <code><sequential></code> * tasks - in fact they are implemented using the same class as Ant's * <code><sequential></code> task.</p> * * The <code><elseif></code> behaves exactly like an <code><if></code> * except that it cannot contain the <code><else></code> element * inside of it. You may specify as may of these as you like, and the * order they are specified is the order they are evaluated in. If the * condition on the <code><if></code> is false, then the first * <code><elseif></code> who's conditional evaluates to true * will be executed. The <code><else></code> will be executed * only if the <code><if></code> and all <code><elseif></code> * conditions are false. * * <p>Use the following task to define the <code><if></code> * task before you use it the first time:</p> * * <pre><code> * <taskdef name="if" classname="net.sf.antcontrib.logic.IfTask" /> * </code></pre> * * <h3>Crude Example</h3> * * <pre><code> * <if> * <equals arg1="${foo}" arg2="bar" /> * <then> * <echo message="The value of property foo is bar" /> * </then> * <else> * <echo message="The value of property foo is not bar" /> * </else> * </if> * </code> * * <code> * <if> * <equals arg1="${foo}" arg2="bar" /> * <then> * <echo message="The value of property foo is 'bar'" /> * </then> * * <elseif> * <equals arg1="${foo}" arg2="foo" /> * <then> * <echo message="The value of property foo is 'foo'" /> * </then> * </elseif> * * <else> * <echo message="The value of property foo is not 'foo' or 'bar'" /> * </else> * </if> * </code></pre> * * @author <a href="mailto:stefan.bodewig@freenet.de">Stefan Bodewig</a> */ public class MxIf extends ConditionBase { public static final class ElseIf extends ConditionBase { private Sequential thenTasks = null; public void addThen(Sequential t) { if (thenTasks != null) { throw new MoxieException("You must not nest more than one <then> into <elseif>"); } thenTasks = t; } public boolean eval() throws MoxieException { if (countConditions() > 1) { throw new MoxieException("You must not nest more than one condition into <elseif>"); } if (countConditions() < 1) { throw new MoxieException("You must nest a condition into <elseif>"); } Condition c = (Condition) getConditions().nextElement(); return c.eval(); } public void execute() throws BuildException { if (thenTasks != null) { thenTasks.execute(); } } } private Sequential thenTasks = null; private Vector elseIfTasks = new Vector(); private Sequential elseTasks = null; public MxIf() { super(); setTaskName("mx:if"); } /*** * A nested Else if task */ public void addElseIf(ElseIf ei) { elseIfTasks.addElement(ei); } /** * A nested <then> element - a container of tasks that will * be run if the condition holds true. * * <p>Not required.</p> */ public void addThen(Sequential t) { if (thenTasks != null) { throw new MoxieException("You must not nest more than one <then> into <if>"); } thenTasks = t; } /** * A nested <else> element - a container of tasks that will * be run if the condition doesn't hold true. * * <p>Not required.</p> */ public void addElse(Sequential e) { if (elseTasks != null) { throw new MoxieException("You must not nest more than one <else> into <if>"); } elseTasks = e; } public void execute() throws BuildException { if (countConditions() > 1) { throw new MoxieException("You must not nest more than one condition into <if>"); } if (countConditions() < 1) { throw new MoxieException("You must nest a condition into <if>"); } Condition c = (Condition) getConditions().nextElement(); if (c.eval()) { if (thenTasks != null) { thenTasks.execute(); } } else { boolean done = false; int sz = elseIfTasks.size(); for (int i=0;i<sz && ! done;i++) { ElseIf ei = (ElseIf)(elseIfTasks.elementAt(i)); if (ei.eval()) { done = true; ei.execute(); } } if (!done && elseTasks != null) { elseTasks.execute(); } } } }