You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by cr...@apache.org on 2001/12/24 20:45:58 UTC

cvs commit: jakarta-commons-sandbox/workflow/src/test/org/apache/commons/workflow/core CoreBlockTestCase.java

craigmcc    01/12/24 11:45:58

  Modified:    workflow build.xml
               workflow/src/java/org/apache/commons/workflow
                        BlockState.java Descriptor.java
               workflow/src/java/org/apache/commons/workflow/base
                        BaseBlock.java BaseContext.java BaseDescriptor.java
                        BaseRuleSet.java
               workflow/src/java/org/apache/commons/workflow/core
                        CoreRuleSet.java StringStep.java package.html
               workflow/src/java/org/apache/commons/workflow/demo Main.java
                        main.xml
               workflow/src/java/org/apache/commons/workflow/io
                        IoRuleSet.java
               workflow/src/java/org/apache/commons/workflow/web
                        WebRuleSet.java
  Added:       workflow/src/java/org/apache/commons/workflow/core
                        BreakStep.java ContinueStep.java IfAnyStep.java
                        IfNotAnyStep.java IfNotStep.java IfStep.java
                        WhileAnyStep.java WhileNotAnyStep.java
                        WhileNotStep.java WhileStep.java
               workflow/src/test/org/apache/commons/workflow/core
                        CoreBlockTestCase.java
  Log:
  Major enhancement to the Workflow system's capabilities, to allow nested
  blocks of steps for conditional (such as "if") and iteration (such as
  "while") implementations.  See the Javadocs for the
  org.apache.commons.workflow.core package for details.
  
  New features:
  
  * Four variations of an "if" step (if, ifAny, ifNot, ifNotAny) that
    conditionally execute a nested block once.
  
  * Four variations of a "while" step (while, whileAny, whileNot, whileNotAny)
    that conditionally execute a nested block repeatedly.
  
  * Implementation of "break" and "continue" steps to exit a nested
    iteration prematurely, with semantics similar to the corresponding
    statements in programming languages like Java and C/C++.
  
  * RuleSet definitions have been modified so that all of the standard
    Steps are recognized at all arbitrary nesting levels.  You will want
    to do the same with any of your own RuleSet definitions, by changing
    the matching pattern from something like 'prefix + "invoke"' to
    '*/invoke' for each Step definition.
  
  Revision  Changes    Path
  1.11      +12 -2     jakarta-commons-sandbox/workflow/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/workflow/build.xml,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- build.xml	2001/11/18 22:26:58	1.10
  +++ build.xml	2001/12/24 19:45:57	1.11
  @@ -3,7 +3,7 @@
   
   <!--
           "Workflow" component of the Jakarta Commons Subproject
  -        $Id: build.xml,v 1.10 2001/11/18 22:26:58 craigmcc Exp $
  +        $Id: build.xml,v 1.11 2001/12/24 19:45:57 craigmcc Exp $
   -->
   
   
  @@ -15,7 +15,7 @@
     <property file="${user.home}/build.properties"/>   <!-- User local        -->
   
     <!-- The URL to be retrieved by the IOExecuteTestCase -->
  -  <property name="ioexecute.url" value="http://localhost:8080/index.html"/>
  +  <property name="ioexecute.url" value="http://localhost:8080/"/>
   
   <!-- ========== External Dependencies ===================================== -->
   
  @@ -261,6 +261,7 @@
                                   test.BaseActivity,
                                   test.BaseContext,
                                   test.BaseExecute,
  +                                test.CoreBlock,
                                   test.CoreExecute,
                                   test.IOExecute,
                                   test.WebContext,
  @@ -293,6 +294,15 @@
       <java classname="${test.runner}" fork="yes"
           failonerror="${test.failonerror}">
         <arg value="org.apache.commons.workflow.base.BaseExecuteTestCase"/>
  +      <classpath refid="test.classpath"/>
  +    </java>
  +  </target>
  +
  +  <target name="test.CoreBlock">
  +    <echo message="Running CoreBlock tests ..."/>
  +    <java classname="${test.runner}" fork="yes"
  +        failonerror="${test.failonerror}">
  +      <arg value="org.apache.commons.workflow.core.CoreBlockTestCase"/>
         <classpath refid="test.classpath"/>
       </java>
     </target>
  
  
  
  1.2       +20 -3     jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/BlockState.java
  
  Index: BlockState.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/BlockState.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BlockState.java	2001/12/16 03:44:20	1.1
  +++ BlockState.java	2001/12/24 19:45:57	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/BlockState.java,v 1.1 2001/12/16 03:44:20 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2001/12/16 03:44:20 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/BlockState.java,v 1.2 2001/12/24 19:45:57 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2001/12/24 19:45:57 $
    *
    * ====================================================================
    * 
  @@ -71,7 +71,7 @@
    * track of the starting and ending indexes, and the iteration counter).</p>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2001/12/16 03:44:20 $
  + * @version $Revision: 1.2 $ $Date: 2001/12/24 19:45:57 $
    */
   
   public class BlockState {
  @@ -124,5 +124,22 @@
           this.nest = nest;
       }
   
  +
  +    // --------------------------------------------------------- Public Methods
  +
  +
  +    /**
  +     * Render a String version of this object.
  +     */
  +    public String toString() {
  +
  +        StringBuffer sb = new StringBuffer("BlockState[block=");
  +        sb.append(block);
  +        sb.append(", nest=");
  +        sb.append(nest);
  +        sb.append("]");
  +        return (sb.toString());
  +
  +    }
   
   }
  
  
  
  1.3       +14 -4     jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/Descriptor.java
  
  Index: Descriptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/Descriptor.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Descriptor.java	2001/08/26 00:17:55	1.2
  +++ Descriptor.java	2001/12/24 19:45:57	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/Descriptor.java,v 1.2 2001/08/26 00:17:55 craigmcc Exp $
  - * $Revision: 1.2 $
  - * $Date: 2001/08/26 00:17:55 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/Descriptor.java,v 1.3 2001/12/24 19:45:57 craigmcc Exp $
  + * $Revision: 1.3 $
  + * $Date: 2001/12/24 19:45:57 $
    *
    * ====================================================================
    * 
  @@ -77,7 +77,7 @@
    *     evaluation stack of our current <code>Context</code> is consumed.</li>
    * </ul>
    *
  - * @version $Revision: 1.2 $ $Date: 2001/08/26 00:17:55 $
  + * @version $Revision: 1.3 $ $Date: 2001/12/24 19:45:57 $
    * @author Craig R. McClanahan
    */
   
  @@ -157,6 +157,16 @@
        * @param context Context from which to retrieve this value
        */
       public Object get(Context context);
  +
  +
  +    /**
  +     * <p>Call <code>get()</code> to retrieve the value specified by this
  +     * Descriptor, and then return <code>true</code> if this value represents
  +     * a positive result; otherwise return <code>false</code>.</p>
  +     *
  +     * @param context Context from which to retrieve this value
  +     */
  +    public boolean positive(Context context);
   
   
       /**
  
  
  
  1.3       +117 -17   jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseBlock.java
  
  Index: BaseBlock.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseBlock.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BaseBlock.java	2001/12/16 03:44:20	1.2
  +++ BaseBlock.java	2001/12/24 19:45:57	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseBlock.java,v 1.2 2001/12/16 03:44:20 craigmcc Exp $
  - * $Revision: 1.2 $
  - * $Date: 2001/12/16 03:44:20 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseBlock.java,v 1.3 2001/12/24 19:45:57 craigmcc Exp $
  + * $Revision: 1.3 $
  + * $Date: 2001/12/24 19:45:57 $
    *
    * ====================================================================
    * 
  @@ -63,8 +63,10 @@
   
   
   import java.util.ArrayList;
  +import java.util.EmptyStackException;
   import org.apache.commons.workflow.Activity;
   import org.apache.commons.workflow.Block;
  +import org.apache.commons.workflow.BlockState;
   import org.apache.commons.workflow.Context;
   import org.apache.commons.workflow.Owner;
   import org.apache.commons.workflow.Step;
  @@ -75,11 +77,9 @@
    * <p><strong>BaseBlock</strong> is a convenient base class for more
    * sophisticated <code>Block</code> implementations.  It includes management
    * of the static relationships of nested Steps for this Step (each of which
  - * could conceptually also be a Block and have its own nested Steps).  Like
  - * <code>BaseStep</code>, this implementation requires the implementation to
  - * provide an <code>execute()</code> method.</p>
  + * could conceptually also be a Block and have its own nested Steps).</p>
    *
  - * @version $Revision: 1.2 $ $Date: 2001/12/16 03:44:20 $
  + * @version $Revision: 1.3 $ $Date: 2001/12/24 19:45:57 $
    * @author Craig R. McClanahan
    */
   
  @@ -128,9 +128,13 @@
   
   
       /**
  -     * Add a new Step to the end of the sequence of Steps associated with
  -     * this Block.
  +     * <p>Add a new Step to the end of the sequence of Steps associated with
  +     * this Block.</p>
        *
  +     * <p><strong>IMPLEMENTATION NOTE</strong> - The last nested Step is looped
  +     * back to the owning Block in order to support the execution flow of
  +     * control required by our BaseContext.</p>
  +     *
        * @param step The new step to be added
        */
       public void addStep(Step step) {
  @@ -138,12 +142,12 @@
           step.setOwner(this);
           if (firstStep == null) {
               step.setPreviousStep(null);
  -            step.setNextStep(null);
  +            step.setNextStep(this);
               firstStep = step;
               lastStep = step;
           } else {
               step.setPreviousStep(lastStep);
  -            step.setNextStep(null);
  +            step.setNextStep(this);
               lastStep.setNextStep(step);
               lastStep = step;
           }
  @@ -157,8 +161,10 @@
       public void clearSteps() {
   
           Step current = firstStep;
  -        while (current != null) {
  +        while ((current != null) && (current != this)) {
               Step next = current.getNextStep();
  +            if (current instanceof Block)
  +                ((Block) current).clearSteps();
               current.setOwner(null);
               current.setPreviousStep(null);
               current.setNextStep(null);
  @@ -178,11 +184,13 @@
        */
       public Step findStep(String id) {
   
  -        Step current = getFirstStep();
  -        while (current != null) {
  -            if (id.equals(current.getId()))
  -                return (current);
  -            current = current.getNextStep();
  +        Step currentStep = getFirstStep();
  +        while (currentStep != null) {
  +            if (id.equals(currentStep.getId()))
  +                return (currentStep);
  +            if (currentStep == lastStep)
  +                break;
  +            currentStep = currentStep.getNextStep();
           }
           return (null);
   
  @@ -198,6 +206,8 @@
           Step currentStep = firstStep;
           while (currentStep != null) {
               list.add(currentStep);
  +            if (currentStep == lastStep)
  +                break;
               currentStep = currentStep.getNextStep();
           }
           Step steps[] = new Step[list.size()];
  @@ -217,6 +227,96 @@
           clearSteps();
           for (int i = 0; i < steps.length; i++)
               addStep(steps[i]);
  +
  +    }
  +
  +
  +    // --------------------------------------------------------- Public Methods
  +
  +
  +    /**
  +     * Perform the executable actions related to this Step, in the context of
  +     * the specified Context.
  +     *
  +     * @param context The Context that is tracking our execution state
  +     *
  +     * @exception StepException if a processing error has occurred
  +     */
  +    public void execute(Context context) throws StepException {
  +
  +        BlockState state = state(context);
  +        if (state == null)
  +            initial(context);
  +        else
  +            subsequent(context, state);
  +
  +    }
  +
  +
  +    // ------------------------------------------------------ Protected Methods
  +
  +
  +    /**
  +     * <p>Evaluate the condition specified by the Descriptors associated with
  +     * this Block, and return the resulting boolean value.  The default
  +     * implementation returns <code>false</code> unconditionally.</p>
  +     *
  +     * @param context Context within which to evaluate the descriptors
  +     */
  +    protected boolean evaluate(Context context) {
  +
  +        return (false);
  +
  +    }
  +
  +
  +    /**
  +     * <p>Process the initial entry into this Block.  The default
  +     * implementation unconditionally skips the nested Steps.</p>
  +     *
  +     * @param context Context within which to evaluate the condition
  +     */
  +    protected void initial(Context context) {
  +
  +        context.setNextStep(getNextStep());
  +
  +    }
  +
  +
  +    /**
  +     * <p>Peek at the top <code>BlockState</code> element on the stack
  +     * maintained by our <code>Context</code>, and return it.  If there
  +     * is no such top element, return <code>null</code> instead.</p>
  +     *
  +     * @param context Context within which to evaluate the current BlockState
  +     */
  +    protected BlockState state(Context context) {
  +
  +        try {
  +            BlockState state = context.peekBlockState();
  +            if (this == state.getBlock())
  +                return (state);
  +        } catch (EmptyStackException e) {
  +            ;
  +        }
  +        return (null);
  +
  +    }
  +
  +
  +    /**
  +     * <p>Process the return from nested execution of the Steps associated
  +     * with this Block.  The default implementation unconditionally
  +     * proceeds to the next Step at the current nesting level, without
  +     * iterating again.</p>
  +     *
  +     * @param context Context within which to evaluate the condition
  +     * @param state BlockState for our block
  +     */
  +    protected void subsequent(Context context, BlockState state) {
  +
  +        context.popBlockState();
  +        context.setNextStep(getNextStep());
   
       }
   
  
  
  
  1.13      +5 -5      jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseContext.java
  
  Index: BaseContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseContext.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- BaseContext.java	2001/12/16 03:44:21	1.12
  +++ BaseContext.java	2001/12/24 19:45:57	1.13
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseContext.java,v 1.12 2001/12/16 03:44:21 craigmcc Exp $
  - * $Revision: 1.12 $
  - * $Date: 2001/12/16 03:44:21 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseContext.java,v 1.13 2001/12/24 19:45:57 craigmcc Exp $
  + * $Revision: 1.13 $
  + * $Date: 2001/12/24 19:45:57 $
    *
    * ====================================================================
    * 
  @@ -87,7 +87,7 @@
    * class.  If it is used in a multiple thread environment, callers must
    * take suitable precations.</p>
    *
  - * @version $Revision: 1.12 $ $Date: 2001/12/16 03:44:21 $
  + * @version $Revision: 1.13 $ $Date: 2001/12/24 19:45:57 $
    * @author Craig R. McClanahan
    */
   
  @@ -558,7 +558,7 @@
        */
       public void pushBlockState(BlockState item) {
   
  -        stack.push(item);
  +        state.push(item);
   
       }
   
  
  
  
  1.7       +58 -10    jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseDescriptor.java
  
  Index: BaseDescriptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseDescriptor.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- BaseDescriptor.java	2001/11/18 22:02:04	1.6
  +++ BaseDescriptor.java	2001/12/24 19:45:57	1.7
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseDescriptor.java,v 1.6 2001/11/18 22:02:04 craigmcc Exp $
  - * $Revision: 1.6 $
  - * $Date: 2001/11/18 22:02:04 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseDescriptor.java,v 1.7 2001/12/24 19:45:57 craigmcc Exp $
  + * $Revision: 1.7 $
  + * $Date: 2001/12/24 19:45:57 $
    *
    * ====================================================================
    * 
  @@ -71,7 +71,7 @@
   /**
    * <p>Basic implementation of the <strong>Descriptor</strong> interface.</p>
    *
  - * @version $Revision: 1.6 $ $Date: 2001/11/18 22:02:04 $
  + * @version $Revision: 1.7 $ $Date: 2001/12/24 19:45:57 $
    * @author Craig R. McClanahan
    */
   
  @@ -319,6 +319,53 @@
   
   
       /**
  +     * <p>Call <code>get()</code> to retrieve the value specified by this
  +     * Descriptor, and then return <code>true</code> if this value represents
  +     * a positive result; otherwise return <code>false</code>.  A positive
  +     * result depends on the data type of the retrieved value:</p>
  +     * <ul>
  +     * <li>Value returned is a <code>String</code> of length greater than 0.
  +     *     </li>
  +     * <li>Value is a Boolean "true"</code>.</li>
  +     * <li>Value is a numeric primitive (byte, char, float, double, int,
  +     *     long, short), or an Object wrapper for one of these types, and
  +     *     the corresponding value is non-zero.</li>
  +     * <li>Value returned is a non-null Object.</li>
  +     * </ul>
  +     *
  +     * @param context Context from which to retrieve this value
  +     */
  +    public boolean positive(Context context) {
  +
  +        Object value = get(context);
  +        if (value == null)
  +            return (false);
  +        else if (value instanceof Boolean)
  +            return (((Boolean) value).booleanValue());
  +        else if (value instanceof Byte)
  +            return (((Byte) value).byteValue() != (byte) 0);
  +        else if (value instanceof Character)
  +            return (((Character) value).charValue() != (char) 0);
  +        else if (value instanceof Double)
  +            return (((Double) value).doubleValue() != (double) 0.0);
  +        else if (value instanceof Float)
  +            return (((Double) value).floatValue() != (float) 0.0);
  +        else if (value instanceof Integer)
  +            return (((Integer) value).intValue() != (int) 0);
  +        else if (value instanceof Long)
  +            return (((Long) value).longValue() != (long) 0);
  +        else if (value instanceof Short)
  +            return (((Short) value).shortValue() != (short) 0);
  +        else if (value instanceof String)
  +            return (((String) value).length() > 0);
  +        else
  +            return (true); // Non-null object
  +
  +
  +    }
  +
  +
  +    /**
        * Store the value into the destination specified by this Descriptor
        * in the specified Context, replacing any existing value.
        *
  @@ -374,15 +421,16 @@
               sb.append(" xpath=\"");
               sb.append(xpath);
               sb.append("\"");
  -        } else {
  +        }
  +        if (name != null) {
               sb.append(" name=\"");
               sb.append(name);
               sb.append("\"");
  -            if (scope != null) {
  -                sb.append(" scope=\"");
  -                sb.append(scope);
  -                sb.append("\"");
  -            }
  +        }
  +        if (scope != null) {
  +            sb.append(" scope=\"");
  +            sb.append(scope);
  +            sb.append("\"");
           }
           sb.append("/>");
           return (sb.toString());
  
  
  
  1.2       +49 -26    jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseRuleSet.java
  
  Index: BaseRuleSet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseRuleSet.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BaseRuleSet.java	2001/08/27 01:01:39	1.1
  +++ BaseRuleSet.java	2001/12/24 19:45:57	1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseRuleSet.java,v 1.1 2001/08/27 01:01:39 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2001/08/27 01:01:39 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseRuleSet.java,v 1.2 2001/12/24 19:45:57 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2001/12/24 19:45:57 $
    *
    * ====================================================================
    *
  @@ -79,13 +79,13 @@
    *
    * <p>This class also serves as a convenience base class for the
    * <code>RuleSet</code> implementations for Step libraries.  Subclasses
  - * MUST override the no-arguments constructor to set the correct default
  - * prefix and namespace URI, and MUST override (and replace) the
  + * MUST override the no-arguments constructor to set the correct
  + * namespace URI, and MUST override (and replace) the
    * <code>addRuleInstances()</code> method to add the relevant rules
    * for that particular library.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.1 $ $Date: 2001/08/27 01:01:39 $
  + * @version $Revision: 1.2 $ $Date: 2001/12/24 19:45:57 $
    */
   
   public class BaseRuleSet extends RuleSetBase {
  @@ -100,7 +100,6 @@
       public BaseRuleSet() {
   
           super();
  -        setPrefix("");
           setNamespaceURI("http://jakarta.apache.org/commons/workflow/base");
   
       }
  @@ -110,21 +109,6 @@
   
   
       /**
  -     * The prefix for each matching pattern added to the Digester instance,
  -     * or an empty String for no prefix.
  -     */
  -    protected String prefix = null;
  -
  -    public String getPrefix() {
  -        return (this.prefix);
  -    }
  -
  -    public void setPrefix(String prefix) {
  -        this.prefix = prefix;
  -    }
  -
  -
  -    /**
        * Set the namespace URI that these rules apply to.  This is only needed
        * if you want to reset the default value created by a subclass.
        *
  @@ -148,12 +132,51 @@
        *  should be added.
        */
       public void addRuleInstances(Digester digester) {
  +
  +        digester.addObjectCreate("activity",
  +                              "org.apache.commons.workflow.base.BaseActivity");
  +        digester.addSetProperties("activity");
  +
  +    }
  +
  +
  +    // ------------------------------------------------------ Protected Methods
  +
  +
  +    /**
  +     * Add the standard set of rules for a new Descriptor that should be
  +     * recognized.
  +     *
  +     * @param digester Digester to which we are adding new rules
  +     * @param element Element name to be matched
  +     */
  +    protected void addStandardDescriptor(Digester digester, String element) {
  +
  +        String pattern = "*/" + element;
  +        digester.addObjectCreate(pattern,
  +                            "org.apache.commons.workflow.base.BaseDescriptor");
  +        digester.addSetProperties(pattern);
  +        digester.addSetNext(pattern, "addDescriptor",
  +                            "org.apache.commons.workflow.Descriptor");
  +
  +    }
  +
  +
  +    /**
  +     * Add the standard set of rules for a new Step that should be recognized.
  +     *
  +     * @param digester Digester to which we are adding new rules
  +     * @param element Element name to be matched
  +     * @param name Fully qualified class name of the implementation class
  +     */
  +    protected void addStandardStep(Digester digester, String element,
  +                                   String name) {
   
  -        digester.addObjectCreate
  -            (prefix + "activity",
  -             "org.apache.commons.workflow.base.BaseActivity");
  -        digester.addSetProperties
  -            (prefix + "activity");
  +        String pattern = "*/" + element;
  +        digester.addObjectCreate(pattern, name);
  +        digester.addSetProperties(pattern);
  +        digester.addSetNext(pattern, "addStep",
  +                            "org.apache.commons.workflow.Step");
   
       }
   
  
  
  
  1.7       +62 -256   jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/CoreRuleSet.java
  
  Index: CoreRuleSet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/CoreRuleSet.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- CoreRuleSet.java	2001/11/29 03:01:25	1.6
  +++ CoreRuleSet.java	2001/12/24 19:45:57	1.7
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/CoreRuleSet.java,v 1.6 2001/11/29 03:01:25 sanders Exp $
  - * $Revision: 1.6 $
  - * $Date: 2001/11/29 03:01:25 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/CoreRuleSet.java,v 1.7 2001/12/24 19:45:57 craigmcc Exp $
  + * $Revision: 1.7 $
  + * $Date: 2001/12/24 19:45:57 $
    *
    * ====================================================================
    *
  @@ -77,7 +77,7 @@
    *
    * @author Craig R. McClanahan
    * @author Preston Sheldon
  - * @version $Revision: 1.6 $ $Date: 2001/11/29 03:01:25 $
  + * @version $Revision: 1.7 $ $Date: 2001/12/24 19:45:57 $
    */
   
   public class CoreRuleSet extends BaseRuleSet {
  @@ -92,7 +92,6 @@
       public CoreRuleSet() {
   
           super();
  -        setPrefix("activity/");
           setNamespaceURI("http://jakarta.apache.org/commons/workflow/core");
   
       }
  @@ -112,257 +111,64 @@
        */
       public void addRuleInstances(Digester digester) {
   
  -        digester.addObjectCreate
  -            (prefix + "and",
  -             "org.apache.commons.workflow.core.AndStep");
  -        digester.addSetProperties
  -            (prefix + "and");
  -        digester.addSetNext
  -            (prefix + "and", "addStep",
  -             "org.apache.commons.workflow.Step");
  -        digester.addObjectCreate
  -            (prefix + "and/descriptor",
  -             "org.apache.commons.workflow.base.BaseDescriptor");
  -        digester.addSetProperties
  -            (prefix + "and/descriptor");
  -        digester.addSetNext
  -            (prefix + "and/descriptor", "addDescriptor",
  -             "org.apache.commons.workflow.Descriptor");
  -
  -        digester.addObjectCreate
  -            (prefix + "call",
  -             "org.apache.commons.workflow.core.CallStep");
  -        digester.addSetProperties
  -            (prefix + "call");
  -        digester.addSetNext
  -            (prefix + "call", "addStep",
  -             "org.apache.commons.workflow.Step");
  -
  -        // First descriptor can be called "class" for clarity
  -        digester.addObjectCreate
  -            (prefix + "construct",
  -             "org.apache.commons.workflow.core.ConstructStep");
  -        digester.addSetProperties
  -            (prefix + "construct");
  -        digester.addSetNext
  -            (prefix + "construct", "addStep",
  -             "org.apache.commons.workflow.Step");
  -        digester.addObjectCreate
  -            (prefix + "construct/class",
  -             "org.apache.commons.workflow.base.BaseDescriptor");
  -        digester.addSetProperties
  -            (prefix + "construct/class");
  -        digester.addSetNext
  -            (prefix + "construct/class", "addDescriptor",
  -             "org.apache.commons.workflow.Descriptor");
  -        digester.addObjectCreate
  -            (prefix + "construct/descriptor",
  -             "org.apache.commons.workflow.base.BaseDescriptor");
  -        digester.addSetProperties
  -            (prefix + "construct/descriptor");
  -        digester.addSetNext
  -            (prefix + "construct/descriptor", "addDescriptor",
  -             "org.apache.commons.workflow.Descriptor");
  -
  -        digester.addObjectCreate
  -            (prefix + "duplicate",
  -             "org.apache.commons.workflow.core.DuplicateStep");
  -        digester.addSetProperties
  -            (prefix + "duplicate");
  -        digester.addSetNext
  -            (prefix + "duplicate", "addStep",
  -             "org.apache.commons.workflow.Step");
  -
  -        digester.addObjectCreate
  -            (prefix + "exit",
  -             "org.apache.commons.workflow.core.ExitStep");
  -        digester.addSetProperties
  -            (prefix + "exit");
  -        digester.addSetNext
  -            (prefix + "exit", "addStep",
  -             "org.apache.commons.workflow.Step");
  -
  -        digester.addObjectCreate
  -            (prefix + "get",
  -             "org.apache.commons.workflow.core.GetStep");
  -        digester.addSetProperties
  -            (prefix + "get");
  -        digester.addSetNext
  -            (prefix + "get", "addStep",
  -             "org.apache.commons.workflow.Step");
  -        digester.addObjectCreate
  -            (prefix + "get/descriptor",
  -             "org.apache.commons.workflow.base.BaseDescriptor");
  -        digester.addSetProperties
  -            (prefix + "get/descriptor");
  -        digester.addSetNext
  -            (prefix + "get/descriptor", "addDescriptor",
  -             "org.apache.commons.workflow.Descriptor");
  -
  -        digester.addObjectCreate
  -            (prefix + "goto",
  -             "org.apache.commons.workflow.core.GotoStep");
  -        digester.addSetProperties
  -            (prefix + "goto");
  -        digester.addSetNext
  -            (prefix + "goto", "addStep",
  -             "org.apache.commons.workflow.Step");
  -
  -        // First "descriptor" can be called "bean" for clarity
  -        digester.addObjectCreate
  -            (prefix + "invoke",
  -             "org.apache.commons.workflow.core.InvokeStep");
  -        digester.addSetProperties
  -            (prefix + "invoke");
  -        digester.addSetNext
  -            (prefix + "invoke", "addStep",
  -             "org.apache.commons.workflow.Step");
  -        digester.addObjectCreate
  -            (prefix + "invoke/bean",
  -             "org.apache.commons.workflow.base.BaseDescriptor");
  -        digester.addSetProperties
  -            (prefix + "invoke/bean");
  -        digester.addSetNext
  -            (prefix + "invoke/bean", "addDescriptor",
  -             "org.apache.commons.workflow.Descriptor");
  -        digester.addObjectCreate
  -            (prefix + "invoke/descriptor",
  -             "org.apache.commons.workflow.base.BaseDescriptor");
  -        digester.addSetProperties
  -            (prefix + "invoke/descriptor");
  -        digester.addSetNext
  -            (prefix + "invoke/descriptor", "addDescriptor",
  -             "org.apache.commons.workflow.Descriptor");
  -
  -        digester.addObjectCreate
  -            (prefix + "load",
  -             "org.apache.commons.workflow.core.LoadStep");
  -        digester.addSetProperties
  -            (prefix + "load");
  -        digester.addSetNext
  -            (prefix + "load", "addStep",
  -             "org.apache.commons.workflow.Step");
  -
  -        digester.addObjectCreate
  -            (prefix + "notAnd",
  -             "org.apache.commons.workflow.core.NotAndStep");
  -        digester.addSetProperties
  -            (prefix + "notAnd");
  -        digester.addSetNext
  -            (prefix + "notAnd", "addStep",
  -             "org.apache.commons.workflow.Step");
  -        digester.addObjectCreate
  -            (prefix + "notAnd/descriptor",
  -             "org.apache.commons.workflow.base.BaseDescriptor");
  -        digester.addSetProperties
  -            (prefix + "notAnd/descriptor");
  -        digester.addSetNext
  -            (prefix + "notAnd/descriptor", "addDescriptor",
  -             "org.apache.commons.workflow.Descriptor");        
  -            
  -        digester.addObjectCreate
  -            (prefix + "notOr",
  -             "org.apache.commons.workflow.core.NotOrStep");
  -        digester.addSetProperties
  -            (prefix + "notOr");
  -        digester.addSetNext
  -            (prefix + "notOr", "addStep",
  -             "org.apache.commons.workflow.Step");
  -        digester.addObjectCreate
  -            (prefix + "notOr/descriptor",
  -             "org.apache.commons.workflow.base.BaseDescriptor");
  -        digester.addSetProperties
  -            (prefix + "notOr/descriptor");
  -        digester.addSetNext
  -            (prefix + "notOr/descriptor", "addDescriptor",
  -             "org.apache.commons.workflow.Descriptor");            
  -             
  -        digester.addObjectCreate
  -            (prefix + "or",
  -             "org.apache.commons.workflow.core.OrStep");
  -        digester.addSetProperties
  -            (prefix + "or");
  -        digester.addSetNext
  -            (prefix + "or", "addStep",
  -             "org.apache.commons.workflow.Step");
  -        digester.addObjectCreate
  -            (prefix + "or/descriptor",
  -             "org.apache.commons.workflow.base.BaseDescriptor");
  -        digester.addSetProperties
  -            (prefix + "or/descriptor");
  -        digester.addSetNext
  -            (prefix + "or/descriptor", "addDescriptor",
  -             "org.apache.commons.workflow.Descriptor");
  -
  -        digester.addObjectCreate
  -            (prefix + "pop",
  -             "org.apache.commons.workflow.core.PopStep");
  -        digester.addSetProperties
  -            (prefix + "pop");
  -        digester.addSetNext
  -            (prefix + "pop", "addStep",
  -             "org.apache.commons.workflow.Step");
  -
  -        digester.addObjectCreate
  -            (prefix + "put",
  -             "org.apache.commons.workflow.core.PutStep");
  -        digester.addSetProperties
  -            (prefix + "put");
  -        digester.addSetNext
  -            (prefix + "put", "addStep",
  -             "org.apache.commons.workflow.Step");
  -        digester.addObjectCreate
  -            (prefix + "put/descriptor",
  -             "org.apache.commons.workflow.base.BaseDescriptor");
  -        digester.addSetProperties
  -            (prefix + "put/descriptor");
  -        digester.addSetNext
  -            (prefix + "put/descriptor", "addDescriptor",
  -             "org.apache.commons.workflow.Descriptor");
  -
  -        digester.addObjectCreate
  -            (prefix + "remove",
  -             "org.apache.commons.workflow.core.RemoveStep");
  -        digester.addSetProperties
  -            (prefix + "remove");
  -        digester.addSetNext
  -            (prefix + "remove", "addStep",
  -             "org.apache.commons.workflow.Step");
  -        digester.addObjectCreate
  -            (prefix + "remove/descriptor",
  -             "org.apache.commons.workflow.base.BaseDescriptor");
  -        digester.addSetProperties
  -            (prefix + "remove/descriptor");
  -        digester.addSetNext
  -            (prefix + "remove/descriptor", "addDescriptor",
  -             "org.apache.commons.workflow.Descriptor");
  -
  -        digester.addObjectCreate
  -            (prefix + "string",
  -             "org.apache.commons.workflow.core.StringStep");
  -        digester.addSetProperties
  -            (prefix + "string");
  -        digester.addSetNext
  -            (prefix + "string", "addStep",
  -             "org.apache.commons.workflow.Step");
  -
  -        digester.addObjectCreate
  -            (prefix + "suspend",
  -             "org.apache.commons.workflow.core.SuspendStep");
  -        digester.addSetProperties
  -            (prefix + "suspend");
  -        digester.addSetNext
  -            (prefix + "suspend", "addStep",
  -             "org.apache.commons.workflow.Step");
  -
  -        digester.addObjectCreate
  -            (prefix + "swap",
  -             "org.apache.commons.workflow.core.SwapStep");
  -        digester.addSetProperties
  -            (prefix + "swap");
  -        digester.addSetNext
  -            (prefix + "swap", "addStep",
  -             "org.apache.commons.workflow.Step");
  +        // Add rules for each Step defined in this package
  +        addStandardStep(digester, "and",
  +                        "org.apache.commons.workflow.core.AndStep");
  +        addStandardStep(digester, "break",
  +                        "org.apache.commons.workflow.core.BreakStep");
  +        addStandardStep(digester, "call",
  +                        "org.apache.commons.workflow.core.CallStep");
  +        addStandardStep(digester, "construct",
  +                        "org.apache.commons.workflow.core.ConstructStep");
  +        addStandardStep(digester, "duplicate",
  +                        "org.apache.commons.workflow.core.DuplicateStep");
  +        addStandardStep(digester, "exit",
  +                        "org.apache.commons.workflow.core.ExitStep");
  +        addStandardStep(digester, "get",
  +                        "org.apache.commons.workflow.core.GetStep");
  +        addStandardStep(digester, "if",
  +                        "org.apache.commons.workflow.core.IfStep");
  +        addStandardStep(digester, "ifAny",
  +                        "org.apache.commons.workflow.core.IfAnyStep");
  +        addStandardStep(digester, "ifNot",
  +                        "org.apache.commons.workflow.core.IfNotStep");
  +        addStandardStep(digester, "ifNotAny",
  +                        "org.apache.commons.workflow.core.IfNotAnyStep");
  +        addStandardStep(digester, "invoke",
  +                        "org.apache.commons.workflow.core.InvokeStep");
  +        addStandardStep(digester, "load",
  +                        "org.apache.commons.workflow.core.LoadStep");
  +        addStandardStep(digester, "notAnd",
  +                        "org.apache.commons.workflow.core.NotAndStep");
  +        addStandardStep(digester, "notOr",
  +                        "org.apache.commons.workflow.core.NotOrStep");
  +        addStandardStep(digester, "or",
  +                        "org.apache.commons.workflow.core.OrStep");
  +        addStandardStep(digester, "pop",
  +                        "org.apache.commons.workflow.core.PopStep");
  +        addStandardStep(digester, "put",
  +                        "org.apache.commons.workflow.core.PutStep");
  +        addStandardStep(digester, "remove",
  +                        "org.apache.commons.workflow.core.RemoveStep");
  +        addStandardStep(digester, "string",
  +                        "org.apache.commons.workflow.core.StringStep");
  +        addStandardStep(digester, "suspend",
  +                        "org.apache.commons.workflow.core.SuspendStep");
  +        addStandardStep(digester, "swap",
  +                        "org.apache.commons.workflow.core.SwapStep");
  +        addStandardStep(digester, "while",
  +                        "org.apache.commons.workflow.core.WhileStep");
  +        addStandardStep(digester, "whileAny",
  +                        "org.apache.commons.workflow.core.WhileAnyStep");
  +        addStandardStep(digester, "whileNot",
  +                        "org.apache.commons.workflow.core.WhileNotStep");
  +        addStandardStep(digester, "whileNotAny",
  +                        "org.apache.commons.workflow.core.WhileNotAnyStep");
  +
  +        // Add rules for all variations on descriptors being matched
  +        addStandardDescriptor(digester, "bean");         // For invoke
  +        addStandardDescriptor(digester, "class");        // For construct
  +        addStandardDescriptor(digester, "descriptor");   // Standard version
   
       }
   
  
  
  
  1.3       +26 -4     jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/StringStep.java
  
  Index: StringStep.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/StringStep.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- StringStep.java	2001/08/22 01:06:08	1.2
  +++ StringStep.java	2001/12/24 19:45:57	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/StringStep.java,v 1.2 2001/08/22 01:06:08 craigmcc Exp $
  - * $Revision: 1.2 $
  - * $Date: 2001/08/22 01:06:08 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/StringStep.java,v 1.3 2001/12/24 19:45:57 craigmcc Exp $
  + * $Revision: 1.3 $
  + * $Date: 2001/12/24 19:45:57 $
    *
    * ====================================================================
    * 
  @@ -76,7 +76,7 @@
    * <li><strong>value</strong> - String value to be pushed.</li>
    * </ul>
    *
  - * @version $Revision: 1.2 $ $Date: 2001/08/22 01:06:08 $
  + * @version $Revision: 1.3 $ $Date: 2001/12/24 19:45:57 $
    * @author Craig R. McClanahan
    */
   
  @@ -160,6 +160,28 @@
   
           // Push the value onto the evaluation stack
           context.push(value);
  +
  +    }
  +
  +
  +    /**
  +     * Render a string representation of this Step.
  +     */
  +    public String toString() {
  +
  +        StringBuffer sb = new StringBuffer("<core:string");
  +        if (getId() != null) {
  +            sb.append(" id=\"");
  +            sb.append(getId());
  +            sb.append("\"");
  +        }
  +        if (getValue() != null) {
  +            sb.append(" value=\"");
  +            sb.append(getValue());
  +            sb.append("\"");
  +        }
  +        sb.append("/>");
  +        return (sb.toString());
   
       }
   
  
  
  
  1.7       +381 -0    jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/package.html
  
  Index: package.html
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/package.html,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- package.html	2001/11/30 02:02:16	1.6
  +++ package.html	2001/12/24 19:45:57	1.7
  @@ -43,6 +43,10 @@
   [<a href="#core:exit">core:exit</a>]
   [<a href="#core:get">core:get</a>]
   [<a href="#core:goto">core:goto</a>]
  +[<a href="#core:if">core:if</a>]
  +[<a href="#core:ifAny">core:ifAny</a>]
  +[<a href="#core:ifNot">core:ifNot</a>]
  +[<a href="#core:ifNotAny">core:ifNotAny</a>]
   [<a href="#core:invoke">core:invoke</a>]
   [<a href="#core:load">core:load</a>]
   [<a href="#core:notAnd">core:notAnd</a>]
  @@ -98,6 +102,42 @@
     &lt;core:goto step="notOk"/&gt;
   </pre>
   
  +
  +<a name="core:break"></a>
  +<h3>core:break</h3>
  +
  +<p>The <em>core:break</em> Step can be used inside an iteration loop (such as
  +<code>core:while</code>, <code>core:whileAny</code>,
  +<code>core:whileNot</code>, and <code>core:whileNotAny</code>) to prematurely
  +exit from the current iteration, and force the termination of the loop.  Thus,
  +it has semantics similar to the "break" statement in programming languages
  +like Java and C/C++.</p>
  +
  +<p>The <em>core:break</em> element recognizes the following attributes:</p>
  +<ul>
  +<li><strong>id</strong> - Optional identifier of this Step, which can be used
  +    as the destination for control transfers.  If specified, must be unique
  +    within the current Activity.</li>
  +</ul>
  +
  +<p>In the example below, the loop will repeated as long as the
  +<code>loopNow</code> attribute returns a positive result.  However, the last
  +iteration will also be prematurely broken if the <code>breakNow</code>
  +attribute returns a positive loop:</p>
  +<pre>
  +  &lt;core:while&gt;
  +    &lt;core:descriptor xpath="loopNow"/&gt;
  +    ... Steps executed if "loopNow" is positive ...
  +    &lt;core:if&gt;
  +      &lt;core:descriptor xpath="breakNow"/&gt;
  +      <strong>&lt;core:break/&gt;</strong>
  +    &lt;/core:if&gt;
  +    ... Steps executed if "loopNow" is positive and ...
  +    ... "breakNow" is negative ...
  +  &lt;/core:while&gt;
  +</pre>
  +
  +
   <a name="core:call"></a>
   <h3>core:call</h3>
   
  @@ -178,6 +218,42 @@
   </pre>
   
   
  +<a name="core:continue"></a>
  +<h3>core:continue</h3>
  +
  +<p>The <em>core:continue</em> Step can be used inside an iteration loop (such
  +as <code>core:while</code>, <code>core:whileAny</code>,
  +<code>core:whileNot</code>, and <code>core:whileNotAny</code>) to prematurely
  +return to the conditional test at the top of the loop, to determine whether it
  +should be repeated again.  Thus, it has semantics similar to the "continue"
  +statement in programming languages like Java and C/C++.</p>
  +
  +<p>The <em>core:continue</em> element recognizes the following attributes:</p>
  +<ul>
  +<li><strong>id</strong> - Optional identifier of this Step, which can be used
  +    as the destination for control transfers.  If specified, must be unique
  +    within the current Activity.</li>
  +</ul>
  +
  +<p>In the example below, the loop will repeated as long as the
  +<code>loopNow</code> attribute returns a positive result.  If the
  +<code>continueNow</code> attribute is also positive, that iteration will be
  +prematurely stopped, and <code>loopNow</code> will be tested again for the
  +next iteration:</p>
  +<pre>
  +  &lt;core:while&gt;
  +    &lt;core:descriptor xpath="loopNow"/&gt;
  +    ... Steps executed if "loopNow" is positive ...
  +    &lt;core:if&gt;
  +      &lt;core:descriptor xpath="continueNow"/&gt;
  +      <strong>&lt;core:continue/&gt;</strong>
  +    &lt;/core:if&gt;
  +    ... Steps executed if "loopNow" is positive ...
  +    ... and "continueNow" is negative ...
  +  &lt;/core:while&gt;
  +</pre>
  +
  +
   <a name="core:duplicate"></a>
   <h3>core:duplicate</h3>
   
  @@ -270,6 +346,150 @@
   </ul>
   
   
  +<a name="core:if"></a>
  +<h3>core:if</h3>
  +
  +<p>The <em>core:if</em> Step conditionally executes the immediately
  +nested steps one time, if and only if <strong>ALL</strong> of the
  +nested Descriptors evaluate to a <strong>positive</strong> result (i.e.
  +boolean true, non-null String with length greater than zero, numeric value
  +other than zero, or non-null for an Object).  To avoid non-deterministic
  +evaluation stack behavior, all of the specified Descriptors are always
  +evaluated exactly once.</p>
  +
  +<p>The <em>core:if</em> element recognizes the following attributes:</p>
  +<ul>
  +<li><strong>id</strong> - Optional identifier of this Step, which can be used
  +    as the destination for control transfers.  If specified, must be unique
  +    within the current Activity.</li>
  +</ul>
  +
  +<p>At least one nested <em>core:descriptor</em> element is required, although
  +more than one are allowed.  Each of them is evaluated to determine whether it
  +returns a positive or negative result, then all of the results are combined
  +as described above to determine whether the nested Steps are executed.</p>
  +
  +<p>In the example below, the nested block is executed because both Descriptors
  +evaluate to positive results:</p>
  +<pre>
  +  &lt;core:string value="Non-Null String 1"/&gt;
  +  &lt;core:string value="Non-Null String 2"/&gt;
  +  <strong>&lt;core:if&gt;</strong>
  +    &lt;core:descriptor/&gt;    &lt;-- Pop top stack item --&gt;
  +    &lt;core:descriptor/&gt;    &lt;-- Pop next stack item --&gt;
  +    ... Steps placed here WILL be executed ...
  +  <strong>&lt;/core:if&gt;</strong>
  +</pre>
  +
  +
  +<a name="core:ifAny"></a>
  +<h3>core:ifAny</h3>
  +
  +<p>The <em>core:ifAny</em> Step conditionally executes the immediately
  +nested steps one time, if and only if <strong>ANY</strong> of the
  +nested Descriptors evaluate to a <strong>positive</strong> result (i.e.
  +boolean true, non-null String with length greater than zero, numeric value
  +other than zero, or non-null for an Object).  To avoid non-deterministic
  +evaluation stack behavior, all of the specified Descriptors are always
  +evaluated exactly once.</p>
  +
  +<p>The <em>core:ifAny</em> element recognizes the following attributes:</p>
  +<ul>
  +<li><strong>id</strong> - Optional identifier of this Step, which can be used
  +    as the destination for control transfers.  If specified, must be unique
  +    within the current Activity.</li>
  +</ul>
  +
  +<p>At least one nested <em>core:descriptor</em> element is required, although
  +more than one are allowed.  Each of them is evaluated to determine whether it
  +returns a positive or negative result, then all of the results are combined
  +as described above to determine whether the nested Steps are executed.</p>
  +
  +<p>In the example below, the nested block is executed because the second
  +Descriptor evaluates to a positive result:</p>
  +<pre>
  +  &lt;core:string value=""/&gt;
  +  &lt;core:string value="Non-Null String"/&gt;
  +  <strong>&lt;core:ifAny&gt;</strong>
  +    &lt;core:descriptor/&gt;    &lt;-- Pop top stack item --&gt;
  +    &lt;core:descriptor/&gt;    &lt;-- Pop next stack item --&gt;
  +    ... Steps placed here WILL be executed ...
  +  <strong>&lt;/core:ifAny&gt;</strong>
  +</pre>
  +
  +
  +<a name="core:ifNot"></a>
  +<h3>core:ifNot</h3>
  +
  +<p>The <em>core:ifNot</em> Step conditionally executes the immediately
  +nested steps one time, if and only if <strong>ANY</strong> of the
  +nested Descriptors evaluate to a <strong>negative</strong> result (i.e.
  +boolean false, null or zero-length String, numeric value
  +equal zero, or null for an Object).  To avoid non-deterministic
  +evaluation stack behavior, all of the specified Descriptors are always
  +evaluated exactly once.</p>
  +
  +<p>The <em>core:ifNot</em> element recognizes the following attributes:</p>
  +<ul>
  +<li><strong>id</strong> - Optional identifier of this Step, which can be used
  +    as the destination for control transfers.  If specified, must be unique
  +    within the current Activity.</li>
  +</ul>
  +
  +<p>At least one nested <em>core:descriptor</em> element is required, although
  +more than one are allowed.  Each of them is evaluated to determine whether it
  +returns a positive or negative result, then all of the results are combined
  +as described above to determine whether the nested Steps are executed.</p>
  +
  +<p>In the example below, the nested block is executed because the first
  +Descriptor evaluates to a negative result:</p>
  +<pre>
  +  &lt;core:string value=""/&gt;
  +  &lt;core:string value="Non-Null String"/&gt;
  +  <strong>&lt;core:ifNot&gt;</strong>
  +    &lt;core:descriptor/&gt;    &lt;-- Pop top stack item --&gt;
  +    &lt;core:descriptor/&gt;    &lt;-- Pop next stack item --&gt;
  +    ... Steps placed here WILL be executed ...
  +  <strong>&lt;/core:ifNot&gt;</strong>
  +</pre>
  +
  +
  +<a name="core:ifNotAny"></a>
  +<h3>core:ifNotAny</h3>
  +
  +<p>The <em>core:ifNotAny</em> Step conditionally executes the immediately
  +nested steps one time, if and only if <strong>ALL</strong> of the
  +nested Descriptors evaluate to a <strong>negative</strong> result (i.e.
  +boolean false, null or zero-length String, numeric value
  +equal zero, or null for an Object).  To avoid non-deterministic
  +evaluation stack behavior, all of the specified Descriptors are always
  +evaluated exactly once.</p>
  +
  +<p>The <em>core:ifNotAny</em> element recognizes the following attributes:</p>
  +<ul>
  +<li><strong>id</strong> - Optional identifier of this Step, which can be used
  +    as the destination for control transfers.  If specified, must be unique
  +    within the current Activity.</li>
  +</ul>
  +
  +<p>At least one nested <em>core:descriptor</em> element is required, although
  +more than one are allowed.  Each of them is evaluated to determine whether it
  +returns a positive or negative result, then all of the results are combined
  +as described above to determine whether the nested Steps are executed.</p>
  +
  +<p>In the example below, the nested block is executed because both
  +Descriptors evaluate to a negative result:</p>
  +<pre>
  +  &lt;core:string value=""/&gt;
  +  &lt;core:string value=""/&gt;
  +  <strong>&lt;core:ifNotAny&gt;</strong>
  +    &lt;core:descriptor/&gt;    &lt;-- Pop top stack item --&gt;
  +    &lt;core:descriptor/&gt;    &lt;-- Pop next stack item --&gt;
  +    ... Steps placed here WILL be executed ...
  +  <strong>&lt;/core:ifNotAny&gt;</strong>
  +</pre>
  +
  +
   <a name="core:invoke"></a>
   <h3>core:invoke</h3>
   
  @@ -637,6 +857,167 @@
       as the destination for control transfers.  If specified, must be unique
       within the current Activity.</li>
   </ul>
  +
  +
  +<a name="core:while"></a>
  +<h3>core:while</h3>
  +
  +<p>The <em>core:while</em> Step executes the immediately nested steps
  +zero or more times, if and only if <strong>ALL</strong> of the
  +nested Descriptors evaluate to a <strong>positive</strong> result (i.e.
  +boolean true, non-null String with length greater than zero, numeric value
  +other than zero, or non-null for an Object) at the beginning of the loop.
  +To avoid non-deterministic evaluation stack behavior, all of the specified
  +Descriptors are always evaluated exactly once.</p>
  +
  +<p>The <em>core:while</em> element recognizes the following attributes:</p>
  +<ul>
  +<li><strong>id</strong> - Optional identifier of this Step, which can be used
  +    as the destination for control transfers.  If specified, must be unique
  +    within the current Activity.</li>
  +</ul>
  +
  +<p>At least one nested <em>core:descriptor</em> element is required, although
  +more than one are allowed.  Each of them is evaluated to determine whether it
  +returns a positive or negative result, then all of the results are combined
  +as described above to determine whether the nested Steps are executed.</p>
  +
  +<p>You can nest a <em>core:continue</em> inside this block to cause control to
  +be transferred back to the top of the loop for the next test, or a
  +<em>core:break</em> to uncoditionally terminate execution of this iteration
  +and skip any further iterations.</p>
  +
  +<p>In the example below, the nested block is executed repeatedly, as long as
  +the value of both the <code>doit</code> and <code>again</code> attributes
  +are positive:</p>
  +<pre>
  +  <strong>&lt;core:while&gt;</strong>
  +    &lt;core:descriptor xpath="doit"/&gt;
  +    &lt;core:descriptor xpath="again"/&gt;
  +    ... Steps placed here may be repeatedly executed ...
  +  <strong>&lt;/core:while&gt;</strong>
  +</pre>
  +
  +
  +<a name="core:whileAny"></a>
  +<h3>core:whileAny</h3>
  +
  +<p>The <em>core:whileAny</em> Step executes the immediately nested steps
  +zero or more times, if and only if <strong>ANY</strong> of the
  +nested Descriptors evaluate to a <strong>positive</strong> result (i.e.
  +boolean true, non-null String with length greater than zero, numeric value
  +other than zero, or non-null for an Object) at the beginning of the loop.
  +To avoid non-deterministic evaluation stack behavior, all of the specified
  +Descriptors are always evaluated exactly once.</p>
  +
  +<p>The <em>core:whileAny</em> element recognizes the following attributes:</p>
  +<ul>
  +<li><strong>id</strong> - Optional identifier of this Step, which can be used
  +    as the destination for control transfers.  If specified, must be unique
  +    within the current Activity.</li>
  +</ul>
  +
  +<p>At least one nested <em>core:descriptor</em> element is required, although
  +more than one are allowed.  Each of them is evaluated to determine whether it
  +returns a positive or negative result, then all of the results are combined
  +as described above to determine whether the nested Steps are executed.</p>
  +
  +<p>You can nest a <em>core:continue</em> inside this block to cause control to
  +be transferred back to the top of the loop for the next test, or a
  +<em>core:break</em> to uncoditionally terminate execution of this iteration
  +and skip any further iterations.</p>
  +
  +<p>In the example below, the nested block is executed repeatedly, as long as
  +the value of either the <code>doit</code> or <code>again</code> attributes
  +are positive:</p>
  +<pre>
  +  <strong>&lt;core:whileAny&gt;</strong>
  +    &lt;core:descriptor xpath="doit"/&gt;
  +    &lt;core:descriptor xpath="again"/&gt;
  +    ... Steps placed here may be repeatedly executed ...
  +  <strong>&lt;/core:whileAny&gt;</strong>
  +</pre>
  +
  +
  +<a name="core:whileNot"></a>
  +<h3>core:whileNot</h3>
  +
  +<p>The <em>core:whileNot</em> Step executes the immediately nested steps
  +zero or more times, if and only if <strong>ALL</strong> of the
  +nested Descriptors evaluate to a <strong>negative</strong> result (i.e.
  +boolean false, null or zero-length String, numeric value
  +equal to zero, or null for an Object) at the beginning of the loop.
  +To avoid non-deterministic evaluation stack behavior, all of the specified
  +Descriptors are always evaluated exactly once.</p>
  +
  +<p>The <em>core:whileNot</em> element recognizes the following attributes:</p>
  +<ul>
  +<li><strong>id</strong> - Optional identifier of this Step, which can be used
  +    as the destination for control transfers.  If specified, must be unique
  +    within the current Activity.</li>
  +</ul>
  +
  +<p>At least one nested <em>core:descriptor</em> element is required, although
  +more than one are allowed.  Each of them is evaluated to determine whether it
  +returns a positive or negative result, then all of the results are combined
  +as described above to determine whether the nested Steps are executed.</p>
  +
  +<p>You can nest a <em>core:continue</em> inside this block to cause control to
  +be transferred back to the top of the loop for the next test, or a
  +<em>core:break</em> to uncoditionally terminate execution of this iteration
  +and skip any further iterations.</p>
  +
  +<p>In the example below, the nested block is executed repeatedly, as long as
  +the value of both the <code>doit</code> and <code>again</code> attributes
  +are negative:</p>
  +<pre>
  +  <strong>&lt;core:whileNot&gt;</strong>
  +    &lt;core:descriptor xpath="doit"/&gt;
  +    &lt;core:descriptor xpath="again"/&gt;
  +    ... Steps placed here may be repeatedly executed ...
  +  <strong>&lt;/core:whileNot&gt;</strong>
  +</pre>
  +
  +
  +<a name="core:whileNotAny"></a>
  +<h3>core:whileNotAny</h3>
  +
  +<p>The <em>core:whileNotAny</em> Step executes the immediately nested steps
  +zero or more times, if and only if <strong>ANY</strong> of the
  +nested Descriptors evaluate to a <strong>negative</strong> result (i.e.
  +boolean false, null or zero-length String, numeric value
  +equal to zero, or null for an Object) at the beginning of the loop.
  +To avoid non-deterministic evaluation stack behavior, all of the specified
  +Descriptors are always evaluated exactly once.</p>
  +
  +<p>The <em>core:whileNotAny</em> element recognizes the following
  +attributes:</p>
  +<ul>
  +<li><strong>id</strong> - Optional identifier of this Step, which can be used
  +    as the destination for control transfers.  If specified, must be unique
  +    within the current Activity.</li>
  +</ul>
  +
  +<p>At least one nested <em>core:descriptor</em> element is required, although
  +more than one are allowed.  Each of them is evaluated to determine whether it
  +returns a positive or negative result, then all of the results are combined
  +as described above to determine whether the nested Steps are executed.</p>
  +
  +<p>You can nest a <em>core:continue</em> inside this block to cause control to
  +be transferred back to the top of the loop for the next test, or a
  +<em>core:break</em> to uncoditionally terminate execution of this iteration
  +and skip any further iterations.</p>
  +
  +<p>In the example below, the nested block is executed repeatedly, as long as
  +the value of eiether the <code>doit</code> or <code>again</code> attributes
  +is negative:</p>
  +<pre>
  +  <strong>&lt;core:whileNotAny&gt;</strong>
  +    &lt;core:descriptor xpath="doit"/&gt;
  +    &lt;core:descriptor xpath="again"/&gt;
  +    ... Steps placed here may be repeatedly executed ...
  +  <strong>&lt;/core:whileNotAny&gt;</strong>
  +</pre>
   
   
   <div align="center">
  
  
  
  1.1                  jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/BreakStep.java
  
  Index: BreakStep.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/BreakStep.java,v 1.1 2001/12/24 19:45:57 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2001/12/24 19:45:57 $
   *
   * ====================================================================
   * 
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 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 "The Jakarta Project", "Commons", 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.commons.workflow.core;
  
  
  import java.util.EmptyStackException;
  import org.apache.commons.workflow.BlockState;
  import org.apache.commons.workflow.Context;
  import org.apache.commons.workflow.Iterator;
  import org.apache.commons.workflow.Step;
  import org.apache.commons.workflow.StepException;
  import org.apache.commons.workflow.base.BaseStep;
  
  
  /**
   * <p>Locate the closest surrounding Iterator, set the nesting control
   * to <code>false</code>, and transfer control to the Iterator.</p>
   *
   * @version $Revision: 1.1 $ $Date: 2001/12/24 19:45:57 $
   * @author Craig R. McClanahan
   */
  
  public class BreakStep extends BaseStep {
  
  
      // ----------------------------------------------------------= Constructors
  
  
      /**
       * Construct a default instance of this Step.
       */
      public BreakStep() {
  
          super();
  
      }
  
  
      /**
       * Construct an instance of this Step with the specified identifier.
       *
       * @param id Step identifier
       */
      public BreakStep(String id) {
  
          super();
          setId(id);
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Perform the executable actions related to this Step, in the context of
       * the specified Context.
       *
       * @param context The Context that is tracking our execution state
       *
       * @exception StepException if a processing error has occurred
       */
      public void execute(Context context) throws StepException {
  
          // Locate the closest surrounding Iterator's BlockState
          BlockState state = null;
          while (true) {
              try {
                  state = context.peekBlockState();
                  if (state.getBlock() instanceof Iterator)
                      break;
                  context.popBlockState();
                  continue;
              } catch (EmptyStackException e) {
                  throw new StepException("Must be nested in an Iterator block",
                                          this);
              }
          }
  
          // Set the nesting repeat indicator, and transfer control
          state.setNest(false);
          context.setNextStep(state.getBlock());
  
      }
  
  
      /**
       * Render a string representation of this Step.
       */
      public String toString() {
  
          StringBuffer sb = new StringBuffer("<core:break");
          if (getId() != null) {
              sb.append(" id=\"");
              sb.append(getId());
              sb.append("\"");
          }
          sb.append("/>");
          return (sb.toString());
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/ContinueStep.java
  
  Index: ContinueStep.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/ContinueStep.java,v 1.1 2001/12/24 19:45:57 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2001/12/24 19:45:57 $
   *
   * ====================================================================
   * 
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 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 "The Jakarta Project", "Commons", 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.commons.workflow.core;
  
  
  import java.util.EmptyStackException;
  import org.apache.commons.workflow.BlockState;
  import org.apache.commons.workflow.Context;
  import org.apache.commons.workflow.Iterator;
  import org.apache.commons.workflow.Step;
  import org.apache.commons.workflow.StepException;
  import org.apache.commons.workflow.base.BaseStep;
  
  
  /**
   * <p>Locate the closest surrounding Iterator, set the nesting control
   * to <code>true</code>, and transfer control to the Iterator.</p>
   *
   * @version $Revision: 1.1 $ $Date: 2001/12/24 19:45:57 $
   * @author Craig R. McClanahan
   */
  
  public class ContinueStep extends BaseStep {
  
  
      // ----------------------------------------------------------= Constructors
  
  
      /**
       * Construct a default instance of this Step.
       */
      public ContinueStep() {
  
          super();
  
      }
  
  
      /**
       * Construct an instance of this Step with the specified identifier.
       *
       * @param id Step identifier
       */
      public ContinueStep(String id) {
  
          super();
          setId(id);
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Perform the executable actions related to this Step, in the context of
       * the specified Context.
       *
       * @param context The Context that is tracking our execution state
       *
       * @exception StepException if a processing error has occurred
       */
      public void execute(Context context) throws StepException {
  
          // Locate the closest surrounding Iterator's BlockState
          BlockState state = null;
          while (true) {
              try {
                  state = context.peekBlockState();
                  if (state.getBlock() instanceof Iterator)
                      break;
                  context.popBlockState();
                  continue;
              } catch (EmptyStackException e) {
                  throw new StepException("Must be nested in an Iterator Block",
                                          this);
              }
          }
  
          // Set the nesting repeat indicator, and transfer control
          state.setNest(true);
          context.setNextStep(state.getBlock());
  
      }
  
  
      /**
       * Render a string representation of this Step.
       */
      public String toString() {
  
          StringBuffer sb = new StringBuffer("<core:continue");
          if (getId() != null) {
              sb.append(" id=\"");
              sb.append(getId());
              sb.append("\"");
          }
          sb.append("/>");
          return (sb.toString());
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/IfAnyStep.java
  
  Index: IfAnyStep.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/IfAnyStep.java,v 1.1 2001/12/24 19:45:57 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2001/12/24 19:45:57 $
   *
   * ====================================================================
   * 
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 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 "The Jakarta Project", "Commons", 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.commons.workflow.core;
  
  
  import java.util.EmptyStackException;
  import org.apache.commons.workflow.Block;
  import org.apache.commons.workflow.BlockState;
  import org.apache.commons.workflow.Context;
  import org.apache.commons.workflow.Descriptor;
  import org.apache.commons.workflow.Step;
  import org.apache.commons.workflow.StepException;
  import org.apache.commons.workflow.base.BaseBlock;
  
  
  /**
   * <p>Evaluate properties specified by the associated Descriptors, and
   * execute the nested Steps if and only if <strong>ANY</strong> of them
   * evaluate to a positive result.  To avoid non-deterministic evaluation
   * stack behavior, all of the specified Descriptors are always
   * evaluated exactly once.</p>
   *
   * @version $Revision: 1.1 $ $Date: 2001/12/24 19:45:57 $
   * @author Craig R. McClanahan
   */
  
  public class IfAnyStep extends IfStep {
  
  
      // ----------------------------------------------------------= Constructors
  
  
      /**
       * Construct a default instance of this Step.
       */
      public IfAnyStep() {
  
          super();
  
      }
  
  
      /**
       * Construct an instance of this Step with the specified identifier.
       *
       * @param id Step identifier
       */
      public IfAnyStep(String id) {
  
          this(id, null);
  
      }
  
  
      /**
       * Construct a fully configured instance of this Step.
       *
       * @param id Step identifier of this step
       * @param descriptor Initial descriptor to be added
       */
      public IfAnyStep(String id, Descriptor descriptor) {
  
          super();
          setId(id);
          if (descriptor != null)
              addDescriptor(descriptor);
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Render a string representation of this Step.
       */
      public String toString() {
  
          StringBuffer sb = new StringBuffer("<core:ifAny");
          if (getId() != null) {
              sb.append(" id=\"");
              sb.append(getId());
              sb.append("\"");
          }
          sb.append(">");
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++)
              sb.append(descriptors[i]);
          Step steps[] = getSteps();
          for (int i = 0; i < steps.length; i++)
              sb.append(steps[i]);
          sb.append("</core:ifAny>");
          return (sb.toString());
  
      }
  
  
      // ------------------------------------------------------ Protected Methods
  
  
      /**
       * Evaluate the condition specified by the Descriptors associated with
       * this Block, and return the resulting boolean value.
       *
       * @param context Context within which to evaluate the descriptors
       */
      protected boolean evaluate(Context context) {
  
          boolean condition = false;
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++) {
              if (descriptors[i].positive(context))
                  condition = true;
          }
          return (condition);
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/IfNotAnyStep.java
  
  Index: IfNotAnyStep.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/IfNotAnyStep.java,v 1.1 2001/12/24 19:45:57 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2001/12/24 19:45:57 $
   *
   * ====================================================================
   * 
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 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 "The Jakarta Project", "Commons", 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.commons.workflow.core;
  
  
  import java.util.EmptyStackException;
  import org.apache.commons.workflow.Block;
  import org.apache.commons.workflow.BlockState;
  import org.apache.commons.workflow.Context;
  import org.apache.commons.workflow.Descriptor;
  import org.apache.commons.workflow.Step;
  import org.apache.commons.workflow.StepException;
  import org.apache.commons.workflow.base.BaseBlock;
  
  
  /**
   * <p>Evaluate properties specified by the associated Descriptors, and
   * execute the nested Steps if and only if <strong>ALL</strong> of them
   * evaluate to a negative result.  To avoid non-deterministic evaluation
   * stack behavior, all of the specified Descriptors are always
   * evaluated exactly once.</p>
   *
   * @version $Revision: 1.1 $ $Date: 2001/12/24 19:45:57 $
   * @author Craig R. McClanahan
   */
  
  public class IfNotAnyStep extends IfStep {
  
  
      // ----------------------------------------------------------= Constructors
  
  
      /**
       * Construct a default instance of this Step.
       */
      public IfNotAnyStep() {
  
          super();
  
      }
  
  
      /**
       * Construct an instance of this Step with the specified identifier.
       *
       * @param id Step identifier
       */
      public IfNotAnyStep(String id) {
  
          this(id, null);
  
      }
  
  
      /**
       * Construct a fully configured instance of this Step.
       *
       * @param id Step identifier of this step
       * @param descriptor Initial descriptor to be added
       */
      public IfNotAnyStep(String id, Descriptor descriptor) {
  
          super();
          setId(id);
          if (descriptor != null)
              addDescriptor(descriptor);
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Render a string representation of this Step.
       */
      public String toString() {
  
          StringBuffer sb = new StringBuffer("<core:ifNotAny");
          if (getId() != null) {
              sb.append(" id=\"");
              sb.append(getId());
              sb.append("\"");
          }
          sb.append(">");
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++)
              sb.append(descriptors[i]);
          Step steps[] = getSteps();
          for (int i = 0; i < steps.length; i++)
              sb.append(steps[i]);
          sb.append("</core:ifNotAny>");
          return (sb.toString());
  
      }
  
  
      // ------------------------------------------------------ Protected Methods
  
  
      /**
       * Evaluate the condition specified by the Descriptors associated with
       * this Block, and return the resulting boolean value.
       *
       * @param context Context within which to evaluate the descriptors
       */
      protected boolean evaluate(Context context) {
  
          boolean condition = false;
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++) {
              if (descriptors[i].positive(context))
                  condition = true;
          }
          return (!condition);
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/IfNotStep.java
  
  Index: IfNotStep.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/IfNotStep.java,v 1.1 2001/12/24 19:45:57 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2001/12/24 19:45:57 $
   *
   * ====================================================================
   * 
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 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 "The Jakarta Project", "Commons", 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.commons.workflow.core;
  
  
  import java.util.EmptyStackException;
  import org.apache.commons.workflow.Block;
  import org.apache.commons.workflow.BlockState;
  import org.apache.commons.workflow.Context;
  import org.apache.commons.workflow.Descriptor;
  import org.apache.commons.workflow.Step;
  import org.apache.commons.workflow.StepException;
  import org.apache.commons.workflow.base.BaseBlock;
  
  
  /**
   * <p>Evaluate properties specified by the associated Descriptors, and
   * execute the nested Steps if and only if <strong>ANY</strong> of them
   * evaluate to a negative result.  To avoid non-deterministic evaluation
   * stack behavior, all of the specified Descriptors are always
   * evaluated exactly once.</p>
   *
   * @version $Revision: 1.1 $ $Date: 2001/12/24 19:45:57 $
   * @author Craig R. McClanahan
   */
  
  public class IfNotStep extends IfStep {
  
  
      // ----------------------------------------------------------= Constructors
  
  
      /**
       * Construct a default instance of this Step.
       */
      public IfNotStep() {
  
          super();
  
      }
  
  
      /**
       * Construct an instance of this Step with the specified identifier.
       *
       * @param id Step identifier
       */
      public IfNotStep(String id) {
  
          this(id, null);
  
      }
  
  
      /**
       * Construct a fully configured instance of this Step.
       *
       * @param id Step identifier of this step
       * @param descriptor Initial descriptor to be added
       */
      public IfNotStep(String id, Descriptor descriptor) {
  
          super();
          setId(id);
          if (descriptor != null)
              addDescriptor(descriptor);
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Render a string representation of this Step.
       */
      public String toString() {
  
          StringBuffer sb = new StringBuffer("<core:ifNot");
          if (getId() != null) {
              sb.append(" id=\"");
              sb.append(getId());
              sb.append("\"");
          }
          sb.append(">");
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++)
              sb.append(descriptors[i]);
          Step steps[] = getSteps();
          for (int i = 0; i < steps.length; i++)
              sb.append(steps[i]);
          sb.append("</core:ifNot>");
          return (sb.toString());
  
      }
  
  
      // ------------------------------------------------------ Protected Methods
  
  
      /**
       * Evaluate the condition specified by the Descriptors associated with
       * this Block, and return the resulting boolean value.
       *
       * @param context Context within which to evaluate the descriptors
       */
      protected boolean evaluate(Context context) {
  
          boolean condition = true;
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++) {
              if (descriptors[i] == null)
                  continue;
              if (!descriptors[i].positive(context))
                  condition = false;
          }
          return (!condition);
  
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/IfStep.java
  
  Index: IfStep.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/IfStep.java,v 1.1 2001/12/24 19:45:57 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2001/12/24 19:45:57 $
   *
   * ====================================================================
   * 
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 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 "The Jakarta Project", "Commons", 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.commons.workflow.core;
  
  
  import java.util.EmptyStackException;
  import org.apache.commons.workflow.Block;
  import org.apache.commons.workflow.BlockState;
  import org.apache.commons.workflow.Context;
  import org.apache.commons.workflow.Descriptor;
  import org.apache.commons.workflow.Step;
  import org.apache.commons.workflow.StepException;
  import org.apache.commons.workflow.base.BaseBlock;
  
  
  /**
   * <p>Evaluate properties specified by the associated Descriptors, and
   * execute the nested Steps if and only if they <strong>ALL</strong>
   * evaluate to a positive result.  To avoid non-deterministic evaluation
   * stack behavior, all of the specified Descriptors are always
   * evaluated exactly once.</p>
   *
   * @version $Revision: 1.1 $ $Date: 2001/12/24 19:45:57 $
   * @author Craig R. McClanahan
   */
  
  public class IfStep extends BaseBlock {
  
  
      // ----------------------------------------------------------= Constructors
  
  
      /**
       * Construct a default instance of this Step.
       */
      public IfStep() {
  
          super();
  
      }
  
  
      /**
       * Construct an instance of this Step with the specified identifier.
       *
       * @param id Step identifier
       */
      public IfStep(String id) {
  
          this(id, null);
  
      }
  
  
      /**
       * Construct a fully configured instance of this Step.
       *
       * @param id Step identifier of this step
       * @param descriptor Initial descriptor to be added
       */
      public IfStep(String id, Descriptor descriptor) {
  
          super();
          setId(id);
          if (descriptor != null)
              addDescriptor(descriptor);
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Render a string representation of this Step.
       */
      public String toString() {
  
          StringBuffer sb = new StringBuffer("<core:if");
          if (getId() != null) {
              sb.append(" id=\"");
              sb.append(getId());
              sb.append("\"");
          }
          sb.append(">");
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++)
              sb.append(descriptors[i]);
          Step steps[] = getSteps();
          for (int i = 0; i < steps.length; i++)
              sb.append(steps[i]);
          sb.append("</core:if>");
          return (sb.toString());
  
      }
  
  
      // ------------------------------------------------------ Protected Methods
  
  
      /**
       * Evaluate the condition specified by the Descriptors associated with
       * this Block, and return the resulting boolean value.
       *
       * @param context Context within which to evaluate the descriptors
       */
      protected boolean evaluate(Context context) {
  
          boolean condition = true;
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++) {
              if (descriptors[i] == null)
                  continue;
              if (!descriptors[i].positive(context))
                  condition = false;
          }
          return (condition);
  
      }
  
  
      /**
       * Process the initial entry into this Block.
       *
       * @param context Context within which to evaluate the condition
       */
      protected void initial(Context context) {
  
          if (evaluate(context)) {
              BlockState state = new BlockState(this, false);
              context.pushBlockState(state);
              context.setNextStep(getFirstStep());
          } else {
              context.setNextStep(getNextStep());
          }
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/WhileAnyStep.java
  
  Index: WhileAnyStep.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/WhileAnyStep.java,v 1.1 2001/12/24 19:45:57 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2001/12/24 19:45:57 $
   *
   * ====================================================================
   * 
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 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 "The Jakarta Project", "Commons", 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.commons.workflow.core;
  
  
  import java.util.EmptyStackException;
  import org.apache.commons.workflow.Block;
  import org.apache.commons.workflow.BlockState;
  import org.apache.commons.workflow.Context;
  import org.apache.commons.workflow.Descriptor;
  import org.apache.commons.workflow.Iterator;
  import org.apache.commons.workflow.Step;
  import org.apache.commons.workflow.StepException;
  import org.apache.commons.workflow.base.BaseBlock;
  
  
  /**
   * <p>Repeatedly evaluate the properties specified by the associated
   * Descriptors, and execute the nested Steps if and only if
   * <strong>ANY</strong> of them evaluate to a positive result.
   * To avoid non-deterministic evaluation
   * stack behavior, all of the specified Descriptors are always
   * evaluated exactly once.</p>
   *
   * @version $Revision: 1.1 $ $Date: 2001/12/24 19:45:57 $
   * @author Craig R. McClanahan
   */
  
  public class WhileAnyStep extends WhileStep {
  
  
      // ----------------------------------------------------------= Constructors
  
  
      /**
       * Construct a default instance of this Step.
       */
      public WhileAnyStep() {
  
          super();
  
      }
  
  
      /**
       * Construct an instance of this Step with the specified identifier.
       *
       * @param id Step identifier
       */
      public WhileAnyStep(String id) {
  
          this(id, null);
  
      }
  
  
      /**
       * Construct a fully configured instance of this Step.
       *
       * @param id Step identifier of this step
       * @param descriptor Initial descriptor to be added
       */
      public WhileAnyStep(String id, Descriptor descriptor) {
  
          super();
          setId(id);
          if (descriptor != null)
              addDescriptor(descriptor);
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Render a string representation of this Step.
       */
      public String toString() {
  
          StringBuffer sb = new StringBuffer("<core:whileAny");
          if (getId() != null) {
              sb.append(" id=\"");
              sb.append(getId());
              sb.append("\"");
          }
          sb.append(">");
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++)
              sb.append(descriptors[i]);
          Step steps[] = getSteps();
          for (int i = 0; i < steps.length; i++)
              sb.append(steps[i]);
          sb.append("</core:whileAny>");
          return (sb.toString());
  
      }
  
  
      // ------------------------------------------------------ Protected Methods
  
  
      /**
       * Evaluate the condition specified by the Descriptors associated with
       * this Block, and return the resulting boolean value.
       *
       * @param context Context within which to evaluate the descriptors
       */
      protected boolean evaluate(Context context) {
  
          boolean condition = false;
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++) {
              if (descriptors[i].positive(context))
                  condition = true;
          }
          return (condition);
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/WhileNotAnyStep.java
  
  Index: WhileNotAnyStep.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/WhileNotAnyStep.java,v 1.1 2001/12/24 19:45:57 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2001/12/24 19:45:57 $
   *
   * ====================================================================
   * 
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 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 "The Jakarta Project", "Commons", 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.commons.workflow.core;
  
  
  import java.util.EmptyStackException;
  import org.apache.commons.workflow.Block;
  import org.apache.commons.workflow.BlockState;
  import org.apache.commons.workflow.Context;
  import org.apache.commons.workflow.Descriptor;
  import org.apache.commons.workflow.Iterator;
  import org.apache.commons.workflow.Step;
  import org.apache.commons.workflow.StepException;
  import org.apache.commons.workflow.base.BaseBlock;
  
  
  /**
   * <p>Repeatedly evaluate the properties specified by the associated
   * Descriptors, and execute the nested Steps if and only if
   * <strong>ALL</strong> of them evaluate to a negative result.
   * To avoid non-deterministic evaluation
   * stack behavior, all of the specified Descriptors are always
   * evaluated exactly once.</p>
   *
   * @version $Revision: 1.1 $ $Date: 2001/12/24 19:45:57 $
   * @author Craig R. McClanahan
   */
  
  public class WhileNotAnyStep extends WhileStep {
  
  
      // ----------------------------------------------------------= Constructors
  
  
      /**
       * Construct a default instance of this Step.
       */
      public WhileNotAnyStep() {
  
          super();
  
      }
  
  
      /**
       * Construct an instance of this Step with the specified identifier.
       *
       * @param id Step identifier
       */
      public WhileNotAnyStep(String id) {
  
          this(id, null);
  
      }
  
  
      /**
       * Construct a fully configured instance of this Step.
       *
       * @param id Step identifier of this step
       * @param descriptor Initial descriptor to be added
       */
      public WhileNotAnyStep(String id, Descriptor descriptor) {
  
          super();
          setId(id);
          if (descriptor != null)
              addDescriptor(descriptor);
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Render a string representation of this Step.
       */
      public String toString() {
  
          StringBuffer sb = new StringBuffer("<core:whileAny");
          if (getId() != null) {
              sb.append(" id=\"");
              sb.append(getId());
              sb.append("\"");
          }
          sb.append(">");
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++)
              sb.append(descriptors[i]);
          Step steps[] = getSteps();
          for (int i = 0; i < steps.length; i++)
              sb.append(steps[i]);
          sb.append("</core:whileAny>");
          return (sb.toString());
  
      }
  
  
      // ------------------------------------------------------ Protected Methods
  
  
      /**
       * Evaluate the condition specified by the Descriptors associated with
       * this Block, and return the resulting boolean value.
       *
       * @param context Context within which to evaluate the descriptors
       */
      protected boolean evaluate(Context context) {
  
          boolean condition = false;
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++) {
              if (descriptors[i].positive(context))
                  condition = true;
          }
          return (!condition);
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/WhileNotStep.java
  
  Index: WhileNotStep.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/WhileNotStep.java,v 1.1 2001/12/24 19:45:57 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2001/12/24 19:45:57 $
   *
   * ====================================================================
   * 
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 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 "The Jakarta Project", "Commons", 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.commons.workflow.core;
  
  
  import java.util.EmptyStackException;
  import org.apache.commons.workflow.Block;
  import org.apache.commons.workflow.BlockState;
  import org.apache.commons.workflow.Context;
  import org.apache.commons.workflow.Descriptor;
  import org.apache.commons.workflow.Iterator;
  import org.apache.commons.workflow.Step;
  import org.apache.commons.workflow.StepException;
  import org.apache.commons.workflow.base.BaseBlock;
  
  
  /**
   * <p>Repeatedly evaluate the properties specified by the associated
   * Descriptors, and execute the nested Steps if and only if
   * <strong>ANY</strong> of them evaluate to a negative result.
   * To avoid non-deterministic evaluation
   * stack behavior, all of the specified Descriptors are always
   * evaluated exactly once.</p>
   *
   * @version $Revision: 1.1 $ $Date: 2001/12/24 19:45:57 $
   * @author Craig R. McClanahan
   */
  
  public class WhileNotStep extends WhileStep {
  
  
      // ----------------------------------------------------------= Constructors
  
  
      /**
       * Construct a default instance of this Step.
       */
      public WhileNotStep() {
  
          super();
  
      }
  
  
      /**
       * Construct an instance of this Step with the specified identifier.
       *
       * @param id Step identifier
       */
      public WhileNotStep(String id) {
  
          this(id, null);
  
      }
  
  
      /**
       * Construct a fully configured instance of this Step.
       *
       * @param id Step identifier of this step
       * @param descriptor Initial descriptor to be added
       */
      public WhileNotStep(String id, Descriptor descriptor) {
  
          super();
          setId(id);
          if (descriptor != null)
              addDescriptor(descriptor);
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Render a string representation of this Step.
       */
      public String toString() {
  
          StringBuffer sb = new StringBuffer("<core:whileAny");
          if (getId() != null) {
              sb.append(" id=\"");
              sb.append(getId());
              sb.append("\"");
          }
          sb.append(">");
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++)
              sb.append(descriptors[i]);
          Step steps[] = getSteps();
          for (int i = 0; i < steps.length; i++)
              sb.append(steps[i]);
          sb.append("</core:whileAny>");
          return (sb.toString());
  
      }
  
  
      // ------------------------------------------------------ Protected Methods
  
  
      /**
       * Evaluate the condition specified by the Descriptors associated with
       * this Block, and return the resulting boolean value.
       *
       * @param context Context within which to evaluate the descriptors
       */
      protected boolean evaluate(Context context) {
  
          boolean condition = true;
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++) {
              if (descriptors[i] == null)
                  continue;
              if (!descriptors[i].positive(context))
                  condition = false;
          }
          return (!condition);
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/WhileStep.java
  
  Index: WhileStep.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/core/WhileStep.java,v 1.1 2001/12/24 19:45:57 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2001/12/24 19:45:57 $
   *
   * ====================================================================
   * 
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 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 "The Jakarta Project", "Commons", 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.commons.workflow.core;
  
  
  import java.util.EmptyStackException;
  import org.apache.commons.workflow.Block;
  import org.apache.commons.workflow.BlockState;
  import org.apache.commons.workflow.Context;
  import org.apache.commons.workflow.Descriptor;
  import org.apache.commons.workflow.Iterator;
  import org.apache.commons.workflow.Step;
  import org.apache.commons.workflow.StepException;
  import org.apache.commons.workflow.base.BaseBlock;
  
  
  /**
   * <p>Repeatedly evaluate the properties specified by the associated
   * Descriptors, and execute the nested Steps if and only if
   * <strong>ALL</strong> of them evaluate to a positive result.
   * To avoid non-deterministic evaluation
   * stack behavior, all of the specified Descriptors are always
   * evaluated exactly once.</p>
   *
   * @version $Revision: 1.1 $ $Date: 2001/12/24 19:45:57 $
   * @author Craig R. McClanahan
   */
  
  public class WhileStep extends BaseBlock implements Iterator {
  
  
      // ----------------------------------------------------------= Constructors
  
  
      /**
       * Construct a default instance of this Step.
       */
      public WhileStep() {
  
          super();
  
      }
  
  
      /**
       * Construct an instance of this Step with the specified identifier.
       *
       * @param id Step identifier
       */
      public WhileStep(String id) {
  
          this(id, null);
  
      }
  
  
      /**
       * Construct a fully configured instance of this Step.
       *
       * @param id Step identifier of this step
       * @param descriptor Initial descriptor to be added
       */
      public WhileStep(String id, Descriptor descriptor) {
  
          super();
          setId(id);
          if (descriptor != null)
              addDescriptor(descriptor);
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Render a string representation of this Step.
       */
      public String toString() {
  
          StringBuffer sb = new StringBuffer("<core:while");
          if (getId() != null) {
              sb.append(" id=\"");
              sb.append(getId());
              sb.append("\"");
          }
          sb.append(">");
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++)
              sb.append(descriptors[i]);
          Step steps[] = getSteps();
          for (int i = 0; i < steps.length; i++)
              sb.append(steps[i]);
          sb.append("</core:while>");
          return (sb.toString());
  
      }
  
  
      // ------------------------------------------------------ Protected Methods
  
  
      /**
       * Evaluate the condition specified by the Descriptors associated with
       * this Block, and return the resulting boolean value.
       *
       * @param context Context within which to evaluate the descriptors
       */
      protected boolean evaluate(Context context) {
  
          boolean condition = true;
          Descriptor descriptors[] = findDescriptors();
          for (int i = 0; i < descriptors.length; i++) {
              if (descriptors[i] == null)
                  continue;
              if (!descriptors[i].positive(context))
                  condition = false;
          }
          return (condition);
  
      }
  
  
      /**
       * Process the initial entry into this Block.
       *
       * @param context Context within which to evaluate the condition
       */
      protected void initial(Context context) {
  
          if (evaluate(context)) {
              BlockState state = new BlockState(this, true);
              context.pushBlockState(state);
              context.setNextStep(getFirstStep());
          } else {
              context.setNextStep(getNextStep());
          }
  
      }
  
  
      /**
       * Process the return from nested execution of the Steps assocaited
       * with this Block.
       *
       * @param context Context within which to evaluate the condition
       * @param state BlockState for our block
       */
      protected void subsequent(Context context, BlockState state) {
  
  
          // Was a "break" Step executed within this Block?
          if (!state.getNest()) {
              context.popBlockState();
              context.setNextStep(getNextStep());
              return;
          }
  
          // Re-evaluate the loop conditions
          if (evaluate(context)) {
              context.setNextStep(getFirstStep());
          } else {
              context.popBlockState();
              context.setNextStep(getNextStep());
          }
          
  
      }
  
  
  }
  
  
  
  1.3       +64 -5     jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/demo/Main.java
  
  Index: Main.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/demo/Main.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Main.java	2001/08/27 02:55:54	1.2
  +++ Main.java	2001/12/24 19:45:57	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/demo/Main.java,v 1.2 2001/08/27 02:55:54 craigmcc Exp $
  - * $Revision: 1.2 $
  - * $Date: 2001/08/27 02:55:54 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/demo/Main.java,v 1.3 2001/12/24 19:45:57 craigmcc Exp $
  + * $Revision: 1.3 $
  + * $Date: 2001/12/24 19:45:57 $
    *
    * ====================================================================
    * 
  @@ -66,6 +66,8 @@
   import org.apache.commons.digester.Digester;
   import org.apache.commons.workflow.Activity;
   import org.apache.commons.workflow.Context;
  +import org.apache.commons.workflow.ContextEvent;
  +import org.apache.commons.workflow.ContextListener;
   import org.apache.commons.workflow.base.BaseContext;
   import org.apache.commons.workflow.base.BaseRuleSet;
   import org.apache.commons.workflow.core.CoreRuleSet;
  @@ -96,11 +98,11 @@
    * formal release of this technology, because that is key to the extensibility
    * of Step implementations.</p>
    *
  - * @version $Revision: 1.2 $ $Date: 2001/08/27 02:55:54 $
  + * @version $Revision: 1.3 $ $Date: 2001/12/24 19:45:57 $
    * @author Craig R. McClanahan
    */
   
  -public class Main {
  +public class Main implements ContextListener {
   
   
       // ----------------------------------------------------------- Main Program
  @@ -226,11 +228,68 @@
               System.out.println("Main:  Executing parsed activity");
               Context context = new BaseContext();
               context.setActivity(activity);
  +            context.addContextListener(this);
               context.execute();
           } catch (Throwable t) {
               t.printStackTrace(System.out);
               return;
           }
  +
  +    }
  +
  +
  +    // ------------------------------------------------ ContextListener Methods
  +
  +
  +    /**
  +     * Invoked immediately after execution of the related Activity has
  +     * been completed normally, been suspended, or been aborted by
  +     * the throwing of a StepException.  The Step included in this event
  +     * will be the last one to be executed.
  +     *
  +     * @param event The <code>ContextEvent</code> that has occurred
  +     */
  +    public void afterActivity(ContextEvent event) {
  +
  +        System.out.println("CL: afterActivity()");
  +
  +    }
  +
  +
  +    /**
  +     * Invoked immediately after the specified Step was executed.
  +     *
  +     * @param event The <code>ContextEvent</code> that has occurred
  +     */
  +    public void afterStep(ContextEvent event) {
  +
  +        System.out.println("CL: afterStep(" + event.getStep().getId() + ")");
  +
  +    }
  +
  +
  +    /**
  +     * Invoked immediately before execution of the related Activity has
  +     * started.  The Step included in this event will be the first one
  +     * to be executed.
  +     *
  +     * @param event The <code>ContextEvent</code> that has occurred
  +     */
  +    public void beforeActivity(ContextEvent event) {
  +
  +        System.out.println("CL: beforeActivity()");
  +
  +    }
  +
  +
  +    /**
  +     * Invoked immediately before the specified Step is executed.
  +     *
  +     * @param event The <code>ContextEvent</code> that has occurred
  +     */
  +    public void beforeStep(ContextEvent event) {
  +
  +        System.out.println("CL: beforeStep(" + event.getStep().getId() + ")");
   
       }
   
  
  
  
  1.3       +21 -0     jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/demo/main.xml
  
  Index: main.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/demo/main.xml,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- main.xml	2001/08/27 02:55:54	1.2
  +++ main.xml	2001/12/24 19:45:57	1.3
  @@ -16,4 +16,25 @@
   
     <io:peek id="04"/>
   
  +  <core:pop id="05"/>
  +
  +  <core:string id="06" value="Non-null String"/>
  +
  +  <core:if id="07">
  +    <core:descriptor/> <!-- Top of stack value -->
  +    <core:string id="07a" value="Correctly exected the conditional"/>
  +    <io:peek id="07b"/>
  +    <core:pop id="07c"/>
  +  </core:if>
  +
  +  <core:string id="08" value="Non-null String"/>
  +
  +  <core:while id="09">
  +    <core:descriptor/>
  +    <core:string id="09a" value="While should iterate once"/>
  +    <io:peek id="09b"/>
  +    <core:pop id="09c"/>
  +    <core:string id="09d" value=""/>
  +  </core:while>
  +
   </base:activity>
  
  
  
  1.3       +18 -57    jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/io/IoRuleSet.java
  
  Index: IoRuleSet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/io/IoRuleSet.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- IoRuleSet.java	2001/08/27 02:55:54	1.2
  +++ IoRuleSet.java	2001/12/24 19:45:58	1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/io/IoRuleSet.java,v 1.2 2001/08/27 02:55:54 craigmcc Exp $
  - * $Revision: 1.2 $
  - * $Date: 2001/08/27 02:55:54 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/io/IoRuleSet.java,v 1.3 2001/12/24 19:45:58 craigmcc Exp $
  + * $Revision: 1.3 $
  + * $Date: 2001/12/24 19:45:58 $
    *
    * ====================================================================
    *
  @@ -76,7 +76,7 @@
    * </pre>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.2 $ $Date: 2001/08/27 02:55:54 $
  + * @version $Revision: 1.3 $ $Date: 2001/12/24 19:45:58 $
    */
   
   public class IoRuleSet extends BaseRuleSet {
  @@ -91,7 +91,6 @@
       public IoRuleSet() {
   
           super();
  -        setPrefix("activity/");
           setNamespaceURI("http://jakarta.apache.org/commons/workflow/io");
   
       }
  @@ -111,58 +110,20 @@
        */
       public void addRuleInstances(Digester digester) {
   
  -        digester.addObjectCreate
  -            (prefix + "display",
  -             "org.apache.commons.workflow.io.DisplayStep");
  -        digester.addSetProperties
  -            (prefix + "display");
  -        digester.addSetNext
  -            (prefix + "display", "addStep",
  -             "org.apache.commons.workflow.Step");
  -        digester.addObjectCreate
  -            (prefix + "display/descriptor",
  -             "org.apache.commons.workflow.base.BaseDescriptor");
  -        digester.addSetProperties
  -            (prefix + "display/descriptor");
  -        digester.addSetNext
  -            (prefix + "display/descriptor", "addDescriptor",
  -             "org.apache.commons.workflow.Descriptor");
  -
  -        digester.addObjectCreate
  -            (prefix + "get",
  -             "org.apache.commons.workflow.io.GetStep");
  -        digester.addSetProperties
  -            (prefix + "get");
  -        digester.addSetNext
  -            (prefix + "get", "addStep",
  -             "org.apache.commons.workflow.Step");
  -
  -        digester.addObjectCreate
  -            (prefix + "peek",
  -             "org.apache.commons.workflow.io.PeekStep");
  -        digester.addSetProperties
  -            (prefix + "peek");
  -        digester.addSetNext
  -            (prefix + "peek", "addStep",
  -             "org.apache.commons.workflow.Step");
  -
  -        digester.addObjectCreate
  -            (prefix + "read",
  -             "org.apache.commons.workflow.io.ReadStep");
  -        digester.addSetProperties
  -            (prefix + "read");
  -        digester.addSetNext
  -            (prefix + "read", "addStep",
  -             "org.apache.commons.workflow.Step");
  -
  -        digester.addObjectCreate
  -            (prefix + "write",
  -             "org.apache.commons.workflow.io.WriteStep");
  -        digester.addSetProperties
  -            (prefix + "write");
  -        digester.addSetNext
  -            (prefix + "write", "addStep",
  -             "org.apache.commons.workflow.Step");
  +        // Add rules for each Step defined in this package
  +        addStandardStep(digester, "display",
  +                        "org.apache.commons.workflow.io.DisplayStep");
  +        addStandardStep(digester, "get",
  +                        "org.apache.commons.workflow.io.GetStep");
  +        addStandardStep(digester, "peek",
  +                        "org.apache.commons.workflow.io.PeekStep");
  +        addStandardStep(digester, "read",
  +                        "org.apache.commons.workflow.io.ReadStep");
  +        addStandardStep(digester, "write",
  +                        "org.apache.commons.workflow.io.WriteStep");
  +
  +        // Add rules for all variations on descriptors being matched
  +        addStandardDescriptor(digester, "descriptor");   // Standard version
   
       }
   
  
  
  
  1.4       +22 -54    jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/web/WebRuleSet.java
  
  Index: WebRuleSet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/web/WebRuleSet.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- WebRuleSet.java	2001/09/20 02:13:55	1.3
  +++ WebRuleSet.java	2001/12/24 19:45:58	1.4
  @@ -1,7 +1,7 @@
   /*
  - * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/web/WebRuleSet.java,v 1.3 2001/09/20 02:13:55 craigmcc Exp $
  - * $Revision: 1.3 $
  - * $Date: 2001/09/20 02:13:55 $
  + * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/web/WebRuleSet.java,v 1.4 2001/12/24 19:45:58 craigmcc Exp $
  + * $Revision: 1.4 $
  + * $Date: 2001/12/24 19:45:58 $
    *
    * ====================================================================
    *
  @@ -76,7 +76,7 @@
    * </pre>
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.3 $ $Date: 2001/09/20 02:13:55 $
  + * @version $Revision: 1.4 $ $Date: 2001/12/24 19:45:58 $
    */
   
   public class WebRuleSet extends BaseRuleSet {
  @@ -91,7 +91,6 @@
       public WebRuleSet() {
   
           super();
  -        setPrefix("activity/");
           setNamespaceURI("http://jakarta.apache.org/commons/workflow/web");
   
       }
  @@ -111,50 +110,21 @@
        */
       public void addRuleInstances(Digester digester) {
   
  -        digester.addObjectCreate
  -            (prefix + "forward",
  -             "org.apache.commons.workflow.web.ForwardStep");
  -        digester.addSetProperties
  -            (prefix + "forward");
  -        digester.addSetNext
  -            (prefix + "forward", "addStep",
  -             "org.apache.commons.workflow.Step");
  -
  -        digester.addObjectCreate
  -            (prefix + "goto",
  -             "org.apache.commons.workflow.web.GotoStep");
  -        digester.addSetProperties
  -            (prefix + "goto");
  -        digester.addSetNext
  -            (prefix + "goto", "addStep",
  -             "org.apache.commons.workflow.Step");
  -
  -        digester.addObjectCreate
  -            (prefix + "include",
  -             getIncludeClass());
  -        digester.addSetProperties
  -            (prefix + "include");
  -        digester.addSetNext
  -            (prefix + "include", "addStep",
  -             "org.apache.commons.workflow.Step");
  -
  -        digester.addObjectCreate
  -            (prefix + "populate",
  -             "org.apache.commons.workflow.web.PopulateStep");
  -        digester.addSetProperties
  -            (prefix + "populate");
  -        digester.addSetNext
  -            (prefix + "populate", "addStep",
  -             "org.apache.commons.workflow.Step");
  -        digester.addObjectCreate
  -            (prefix + "populate/descriptor",
  -             "org.apache.commons.workflow.base.BaseDescriptor");
  -        digester.addSetProperties
  -            (prefix + "populate/descriptor");
  -        digester.addSetNext
  -            (prefix + "populate/descriptor", "addDescriptor",
  -             "org.apache.commons.workflow.Descriptor");
  +        // Add rules for each Step defined in this package
  +        addStandardStep(digester, "forward",
  +                        "org.apache.commons.workflow.web.ForwardStep");
  +        addStandardStep(digester, "goto",
  +                        "org.apache.commons.workflow.web.GotoStep");
  +        if (isServlet23()) {
  +            addStandardStep(digester, "include",
  +                            "org.apache.commons.workflow.web.IncludeStep23");
  +        }
  +        addStandardStep(digester, "populate",
  +                        "org.apache.commons.workflow.web.PopulateStep");
   
  +        // Add rules for all variations on descriptors being matched
  +        addStandardDescriptor(digester, "descriptor");   // Standard version
  +
       }
   
   
  @@ -162,17 +132,15 @@
   
   
       /**
  -     * Determine which version of the <code>Include</code> step we should
  -     * generate, based on which version of the Servlet API is visible in
  -     * our class loading hierarchy.
  +     * Are we executing in a Servlet 2.3 (or later) environment?
        */
  -    public String getIncludeClass() {
  +    protected boolean isServlet23() {
   
           try {
               Class.forName("javax.servlet.Filter");  // 2.3-or-later class
  -            return ("org.apache.commons.workflow.web.IncludeStep23");
  +            return (true);
           } catch (ClassNotFoundException e) {
  -            return ("org.apache.commons.workflow.web.IncludeStep22");
  +            return (false);
           }
   
       }
  
  
  
  1.1                  jakarta-commons-sandbox/workflow/src/test/org/apache/commons/workflow/core/CoreBlockTestCase.java
  
  Index: CoreBlockTestCase.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons-sandbox/workflow/src/test/org/apache/commons/workflow/core/CoreBlockTestCase.java,v 1.1 2001/12/24 19:45:58 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2001/12/24 19:45:58 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2001 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 "The Jakarta Project", "Commons", 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.commons.workflow.core;
  
  
  import java.util.EmptyStackException;
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import org.apache.commons.workflow.Activity;
  import org.apache.commons.workflow.Block;
  import org.apache.commons.workflow.Context;
  import org.apache.commons.workflow.ContextEvent;
  import org.apache.commons.workflow.ContextListener;
  import org.apache.commons.workflow.Descriptor;
  import org.apache.commons.workflow.Scope;
  import org.apache.commons.workflow.Step;
  import org.apache.commons.workflow.StepException;
  import org.apache.commons.workflow.base.BaseActivity;
  import org.apache.commons.workflow.base.BaseContext;
  import org.apache.commons.workflow.base.BaseDescriptor;
  import org.apache.commons.workflow.base.BaseScope;
  import org.apache.commons.workflow.base.Employee;
  
  
  /**
   * <p>Test Case for the <code>core</code> library of <code>Block</code>
   * implementations the support conditional and iterated execution of
   * nexted Steps.</p>
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2001/12/24 19:45:58 $
   */
  
  public class CoreBlockTestCase extends TestCase
      implements ContextListener {
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The Activity we will use to contain the Steps that we will execute.
       */
      protected Activity activity = null;
  
  
      /**
       * The Context we will use to execute the Activity under test.
       */
      protected Context context = null;
  
  
      /**
       * The trail of execution, as recorded by our ContextListener methods.
       */
      protected StringBuffer trail = new StringBuffer();
  
  
      // ----------------------------------------------------------- Constructors
  
  
      /**
       * Construct a new instance of this test case.
       *
       * @param name Name of the test case
       */
      public CoreBlockTestCase(String name) {
  
          super(name);
  
      }
  
  
      // --------------------------------------------------- Overall Test Methods
  
  
      /**
       * Set up instance variables required by this test case.
       */
      public void setUp() {
  
          context = new BaseContext();
          activity = new BaseActivity();
          context.setActivity(activity);
          context.addContextListener(this);
      }
  
  
      /**
       * Return the tests included in this test suite.
       */
      public static Test suite() {
  
          return (new TestSuite(CoreBlockTestCase.class));
  
      }
  
  
      /**
       * Tear down instance variables required by this test case.
       */
      public void tearDown() {
  
          context.removeContextListener(this);
          activity = null;
          context = null;
  
      }
  
  
      // ------------------------------------------------ Individual Test Methods
  
  
      /**
       * Test "IfStep".
       */
      public void testIf() {
  
          // Configure the steps of this activity, which will assume
          // that two boolean values have been pushed onto the evaluation
          // stack before execution
          IfStep ifStep = new IfStep("01");
          ifStep.addDescriptor(new BaseDescriptor());
          ifStep.addDescriptor(new BaseDescriptor());
          ifStep.addStep(new StringStep("02", "If Executed"));
          activity.addStep(ifStep);
          activity.addStep(new StringStep("03", "If Completed"));
  
          // Test with various combinations of boolean arguments
          commonIfTest(true, true, true);
          commonIfTest(true, false, false);
          commonIfTest(false, true, false);
          commonIfTest(false, false, false);
  
      }
  
  
      /**
       * Test "IfAnyStep".
       */
      public void testIfAny() {
  
          // Configure the steps of this activity, which will assume
          // that two boolean values have been pushed onto the evaluation
          // stack before execution
          IfAnyStep ifStep = new IfAnyStep("01");
          ifStep.addDescriptor(new BaseDescriptor());
          ifStep.addDescriptor(new BaseDescriptor());
          ifStep.addStep(new StringStep("02", "If Executed"));
          activity.addStep(ifStep);
          activity.addStep(new StringStep("03", "If Completed"));
  
          // Test with various combinations of boolean arguments
          commonIfTest(true, true, true);
          commonIfTest(true, false, true);
          commonIfTest(false, true, true);
          commonIfTest(false, false, false);
  
      }
  
  
      /**
       * Test "IfNotStep".
       */
      public void testIfNot() {
  
          // Configure the steps of this activity, which will assume
          // that two boolean values have been pushed onto the evaluation
          // stack before execution
          IfNotStep ifStep = new IfNotStep("01");
          ifStep.addDescriptor(new BaseDescriptor());
          ifStep.addDescriptor(new BaseDescriptor());
          ifStep.addStep(new StringStep("02", "If Executed"));
          activity.addStep(ifStep);
          activity.addStep(new StringStep("03", "If Completed"));
  
          // Test with various combinations of boolean arguments
          commonIfTest(true, true, false);
          commonIfTest(true, false, true);
          commonIfTest(false, true, true);
          commonIfTest(false, false, true);
  
      }
  
  
      /**
       * Test "IfNotAnyStep".
       */
      public void testIfNotAny() {
  
          // Configure the steps of this activity, which will assume
          // that two boolean values have been pushed onto the evaluation
          // stack before execution
          IfNotAnyStep ifStep = new IfNotAnyStep("01");
          ifStep.addDescriptor(new BaseDescriptor());
          ifStep.addDescriptor(new BaseDescriptor());
          ifStep.addStep(new StringStep("02", "If Executed"));
          activity.addStep(ifStep);
          activity.addStep(new StringStep("03", "If Completed"));
  
          // Test with various combinations of boolean arguments
          commonIfTest(true, true, false);
          commonIfTest(true, false, false);
          commonIfTest(false, true, false);
          commonIfTest(false, false, true);
  
      }
  
  
      // -------------------------------------------------------- Private Methods
  
  
      /**
       * Common testing of "if" blocks with two boolean parameters and an
       * indication of the expected result.
       *
       * @param first First boolean parameter
       * @param second Second boolean parameter
       * @param result Should the nested block be executed?
       */
      private void commonIfTest(boolean first, boolean second, boolean result) {
  
          try {
  
              // Set up the execution environment
              context.clear();
              context.clearBlockState();
              context.push(new Boolean(second));
              context.push(new Boolean(first));
  
              // Execute the requested activity
              context.execute();
  
              // Validate the results
              if (result) {
                  assertEquals("Executed nested step",
                               "beforeActivity()/" +
                               "beforeStep(01)/afterStep(01)/" +
                               "beforeStep(02)/afterStep(02)/" +
                               "beforeStep(01)/afterStep(01)/" +
                               "beforeStep(03)/afterStep(03)/" +
                               "afterActivity()/",
                               trail.toString());
              } else {
                  assertEquals("Skipped nested step",
                               "beforeActivity()/" +
                               "beforeStep(01)/afterStep(01)/" +
                               "beforeStep(03)/afterStep(03)/" +
                               "afterActivity()/",
                               trail.toString());
              }
              assertTrue("Context is not suspended",
                         !context.getSuspend());
              assertTrue("Evaluation Stack is not empty",
                         !context.isEmpty());
              assertTrue("BlockState Stack is empty",
                         context.isEmptyBlockState());
              Object top = context.pop();
              assertTrue("Completed message is a String",
                         top instanceof String);
              assertEquals("Completed message is correct",
                           "If Completed", (String) top);
              if (result) {
                  assertTrue("Evaluation Stack is not empty",
                             !context.isEmpty());
                  top = context.pop();
                  assertTrue("Executed message is a String",
                             top instanceof String);
                  assertEquals("Executed message is correct",
                               "If Executed", (String) top);
              }
              assertTrue("Evaluation Stack is empty",
                         context.isEmpty());
          } catch (StepException e) {
              e.printStackTrace(System.out);
              if (e.getCause() != null) {
                  System.out.println("ROOT CAUSE");
                  e.getCause().printStackTrace(System.out);
              }
              fail("Threw StepException " + e);
          } catch (Throwable t) {
              t.printStackTrace(System.out);
              fail("Threw Exception " + t);
          }
  
      }
  
  
      // ------------------------------------------------ ContextListener Methods
  
  
      /**
       * Invoked immediately after execution of the related Activity has
       * been completed normally, been suspended, or been aborted by
       * the throwing of a StepException.  The Step included in this event
       * will be the last one to be executed.
       *
       * @param event The <code>ContextEvent</code> that has occurred
       */
      public void afterActivity(ContextEvent event) {
  
          trail.append("afterActivity()/");
  
      }
  
  
      /**
       * Invoked immediately after the specified Step was executed.
       *
       * @param event The <code>ContextEvent</code> that has occurred
       */
      public void afterStep(ContextEvent event) {
  
          trail.append("afterStep(");
          trail.append(event.getStep().getId());
          trail.append(")");
          /*
          StepException exception = event.getException();
          if (exception != null) {
              trail.append("-");
              trail.append(exception.toString());
          }
          */
          trail.append("/");
  
      }
  
  
      /**
       * Invoked immediately before execution of the related Activity has
       * started.  The Step included in this event will be the first one
       * to be executed.
       *
       * @param event The <code>ContextEvent</code> that has occurred
       */
      public void beforeActivity(ContextEvent event) {
  
          trail.setLength(0);
          trail.append("beforeActivity()/");
  
      }
  
  
      /**
       * Invoked immediately before the specified Step is executed.
       *
       * @param event The <code>ContextEvent</code> that has occurred
       */
      public void beforeStep(ContextEvent event) {
  
          trail.append("beforeStep(");
          trail.append(event.getStep().getId());
          trail.append(")/");
  
      }
  
  
  }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>