craigmcc    01/12/15 19:44:21

  Modified:    workflow/src/java/org/apache/commons/workflow Block.java
                        Context.java
               workflow/src/java/org/apache/commons/workflow/base
                        BaseBlock.java BaseContext.java
  Added:       workflow/src/java/org/apache/commons/workflow
                        BlockState.java Iterator.java
  Log:
  Update the infrastructure required to support Blocks (conditionals and
  iteration).  Given these changes, it should now be possible to write Block
  implementations of things like "if", "while", "for", and to extend the
  existing family (and/or/notAnt/notOr) to do nesting instead fo a
  conditional GOTO if the "step" attribute is not defined.
  
  Of course, the only way to find out if the infrastructure is sufficient is
  to start writing such Blocks ... that's next ...
  
  Revision  Changes    Path
  1.2       +47 -3     
jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/Block.java
  
  Index: Block.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/Block.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Block.java        2001/12/16 02:29:29     1.1
  +++ Block.java        2001/12/16 03:44:20     1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/Block.java,v
 1.1 2001/12/16 02:29:29 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2001/12/16 02:29:29 $
  + * $Header: 
/home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/Block.java,v
 1.2 2001/12/16 03:44:20 craigmcc Exp $
  + * $Revision: 1.2 $
  + * $Date: 2001/12/16 03:44:20 $
    *
    * ====================================================================
    * 
  @@ -67,7 +67,51 @@
    * It is used to create Step implementations supporting conditional
    * execution and iteration.</p>
    *
  - * @version $Revision: 1.1 $ $Date: 2001/12/16 02:29:29 $
  + * <p><strong>DESIGN NOTES</strong> - The <code>execute()</code> method will
  + * be called when the Block is first encountered in the normal flow of
  + * execution (as with any other Step), and each time the execution of the
  + * nested Steps associated with this Block.  The Block implementation is
  + * responsible for satisfying the following contract requirements:</p>
  + * <ul>
  + * <li>Determine whether this is a first-time entry, or a repeated entry
  + *     after execution of the nested Steps for this Block:
  + *     <ul>
  + *     <li>Peek at the top item on the <code>BlockState</code> stack maintained
  + *         for us by the current <code>Context</code>.</li>
  + *     <li>If the top item exists, and has a <code>block</code> property
  + *         equal to the current Block, this is a repeated entry after execution
  + *         of the nested Steps for this Block.</li>
  + *     <li>If there is no top element, or the top element is for a different
  + *         <code>Block</code>, this is the initial entry from the preceeding
  + *         Step in the current Activity (or Block).</li>
  + *     </ul>
  + * <li>When this is the initial entry into the Block, make a decision about
  + *     whether the nested Steps should be executed:
  + *     <ul>
  + *     <li>If the nested Steps <strong>SHOULD</strong> be executed, create a
  + *         new <code>BlockState</code> object (associated with this
  + *         <code>Block</code>) and push it onto the <code>BlockState</code>
  + *         stack.  Then, set the next Step to be the first nested Step
  + *         for this Block.</li>
  + *     <li>If the nested Steps <strong>SHOULD NOT</strong> be executed,
  + *         simply return.  The next Step will have already been set to the
  + *         next Step of the current Activity (or Block) at the same nesting
  + *         level.</li>
  + *     </ul></li>
  + *  <li>When this is a repeated entry into the Block, make a decision about
  + *      whether the nested Steps should be executed again:
  + *      <ul>
  + *      <li>If the nested Steps <strong>SHOULD</strong> be executed again,
  + *          set the next Step to be the first nested Step for this Block.</li>
  + *      <li>If the nested Steps <strong>SHOULD NOT</strong> be executed again,
  + *          pop our <code>BlockState</code> object off of the stack
  + *          maintained by our <code>Context</code>.  Then, set the next Step
  + *          to the <code>nextStep</code> property of this Block, which will
  + *          cause execution to flow past the Block.</li>
  + *      </ul>
  + * </ul>
  + *
  + * @version $Revision: 1.2 $ $Date: 2001/12/16 03:44:20 $
    * @author Craig R. McClanahan
    */
   
  
  
  
  1.8       +43 -4     
jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/Context.java
  
  Index: Context.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/Context.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- Context.java      2001/08/27 05:57:25     1.7
  +++ Context.java      2001/12/16 03:44:20     1.8
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/Context.java,v
 1.7 2001/08/27 05:57:25 craigmcc Exp $
  - * $Revision: 1.7 $
  - * $Date: 2001/08/27 05:57:25 $
  + * $Header: 
/home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/Context.java,v
 1.8 2001/12/16 03:44:20 craigmcc Exp $
  + * $Revision: 1.8 $
  + * $Date: 2001/12/16 03:44:20 $
    *
    * ====================================================================
    * 
  @@ -88,7 +88,7 @@
    * the Step implementations that are executed to maintain the stack's
    * integrity.</p>
    *
  - * @version $Revision: 1.7 $ $Date: 2001/08/27 05:57:25 $
  + * @version $Revision: 1.8 $ $Date: 2001/12/16 03:44:20 $
    * @author Craig R. McClanahan
    */
   
  @@ -307,6 +307,45 @@
        * @param item New item to be pushed
        */
       public void push(Object item);
  +
  +
  +    // ----------------------------------------------- BlockState Stack Methods
  +
  +
  +    /**
  +     * Clear the BlockState stack.
  +     */
  +    public void clearBlockState();
  +
  +
  +    /**
  +     * Is the BlockState stack currently empty?
  +     */
  +    public boolean isEmptyBlockState();
  +
  +
  +    /**
  +     * Return the top item from the BlockState stack without removing it.
  +     *
  +     * @exception EmptyStackException if the stack is empty
  +     */
  +    public BlockState peekBlockState() throws EmptyStackException;
  +
  +
  +    /**
  +     * Pop and return the top item from the BlockState stack.
  +     *
  +     * @exception EmptyStackException if the stack is empty
  +     */
  +    public BlockState popBlockState() throws EmptyStackException;
  +
  +
  +    /**
  +     * Push a new item onto the top of the BlockState stack.
  +     *
  +     * @param item New item to be pushed
  +     */
  +    public void pushBlockState(BlockState item);
   
   
       // ---------------------------------------------- Dynamic Execution Methods
  
  
  
  1.1                  
jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/BlockState.java
  
  Index: BlockState.java
  ===================================================================
  /*
   * $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 $
   *
   * ====================================================================
   * 
   * 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 [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */ 
  
  package org.apache.commons.workflow;
  
  
  /**
   * <p><strong>BlockState</strong> represents the current dynamic execution
   * state of a <code>Block</code> that is executing nested <code>Steps</code>.
   * This class will serve for most <code>Block</code> implementations, but
   * may be subclassed for <code>Blocks</code> with a requirement to maintain
   * additional state information (such as a "for" loop that needs to keep
   * 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 $
   */
  
  public class BlockState {
  
  
      // ----------------------------------------------------------- Constructors
  
  
      /**
       * Construct a new <code>BlockState</code> instance, associated with the
       * specified <code>block</code>, and with the specified initial value
       * for the <code>nest</code> property.
       *
       * @param block The <code>block</code> whose state this object represents
       * @param nest The initial state of the <code>nest</code> property
       */
      public BlockState(Block block, boolean nest) {
  
          super();
          this.block = block;
          this.nest = nest;
  
      }
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * The <code>Block</code> whose state is represented by this object.
       */
      protected Block block = null;
  
      public Block getBlock() {
          return (this.block);
      }
  
  
      /**
       * Should we execute the nested <code>Steps</code> of this
       * <code>Block</code> again when the current execution finishes?
       */
      protected boolean nest = false;
  
      public boolean getNest() {
          return (this.nest);
      }
  
      public void setNest(boolean nest) {
          this.nest = nest;
      }
  
  
  }
  
  
  
  1.1                  
jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/Iterator.java
  
  Index: Iterator.java
  ===================================================================
  /*
   * $Header: 
/home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/Iterator.java,v
 1.1 2001/12/16 03:44:20 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2001/12/16 03:44:20 $
   *
   * ====================================================================
   * 
   * 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 [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   */ 
  
  package org.apache.commons.workflow;
  
  
  /**
   * <p>An <strong>Iterator</strong> is a <code>Block</code> that conditionally
   * repeats the nested Steps associated with the Block more than once (such as
   * a Block that implements "while" or "for" functionality).  This is a tagging
   * interface only - it is useful to help Steps that implement "break" or
   * "continue" type processing to detect whether they have been invoked
   * correctly (nested inside an Iterator) or not.</p>
   *
   * @version $Revision: 1.1 $ $Date: 2001/12/16 03:44:20 $
   * @author Craig R. McClanahan
   */
  
  public interface Iterator extends Block {
  
  
      // No extra functionality is defined
  
  
  }
  
  
  
  1.2       +6 -6      
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.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- BaseBlock.java    2001/12/16 02:29:29     1.1
  +++ BaseBlock.java    2001/12/16 03:44:20     1.2
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseBlock.java,v
 1.1 2001/12/16 02:29:29 craigmcc Exp $
  - * $Revision: 1.1 $
  - * $Date: 2001/12/16 02:29:29 $
  + * $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 $
    *
    * ====================================================================
    * 
  @@ -77,13 +77,13 @@
    * 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.
  + * provide an <code>execute()</code> method.</p>
    *
  - * @version $Revision: 1.1 $ $Date: 2001/12/16 02:29:29 $
  + * @version $Revision: 1.2 $ $Date: 2001/12/16 03:44:20 $
    * @author Craig R. McClanahan
    */
   
  -public abstract class BaseBlock implements Block {
  +public abstract class BaseBlock extends DescriptorStep implements Block {
   
   
       // ----------------------------------------------------- Instance Variables
  
  
  
  1.12      +83 -11    
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.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- BaseContext.java  2001/12/16 02:29:29     1.11
  +++ BaseContext.java  2001/12/16 03:44:21     1.12
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-commons-sandbox/workflow/src/java/org/apache/commons/workflow/base/BaseContext.java,v
 1.11 2001/12/16 02:29:29 craigmcc Exp $
  - * $Revision: 1.11 $
  - * $Date: 2001/12/16 02:29:29 $
  + * $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 $
    *
    * ====================================================================
    * 
  @@ -66,9 +66,12 @@
   import org.apache.commons.collections.ArrayStack;
   import org.apache.commons.jxpath.JXPathContext;
   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.ContextEvent;
   import org.apache.commons.workflow.ContextListener;
  +import org.apache.commons.workflow.Owner;
   import org.apache.commons.workflow.Step;
   import org.apache.commons.workflow.StepException;
   import org.apache.commons.workflow.Scope;
  @@ -84,7 +87,7 @@
    * class.  If it is used in a multiple thread environment, callers must
    * take suitable precations.</p>
    *
  - * @version $Revision: 1.11 $ $Date: 2001/12/16 02:29:29 $
  + * @version $Revision: 1.12 $ $Date: 2001/12/16 03:44:21 $
    * @author Craig R. McClanahan
    */
   
  @@ -161,6 +164,12 @@
   
   
       /**
  +     * The BlockState stack of BlockState objects used to manage iteration.
  +     */
  +    protected ArrayStack state = new ArrayStack();
  +
  +
  +    /**
        * The event listener support object for this <code>Context</code>.
        */
       protected ContextSupport support = new ContextSupport(this);
  @@ -495,6 +504,65 @@
       }
   
   
  +    // ----------------------------------------------- BlockState Stack Methods
  +
  +
  +    /**
  +     * Clear the BlockState stack.
  +     */
  +    public void clearBlockState() {
  +
  +        state.clear();
  +
  +    }
  +
  +
  +    /**
  +     * Is the BlockState stack currently empty?
  +     */
  +    public boolean isEmptyBlockState() {
  +
  +        return (state.size() == 0);
  +
  +    }
  +
  +
  +    /**
  +     * Return the top item from the BlockState stack without removing it.
  +     *
  +     * @exception EmptyStackException if the stack is empty
  +     */
  +    public BlockState peekBlockState() throws EmptyStackException {
  +
  +        return ((BlockState) state.peek());
  +
  +    }
  +
  +
  +    /**
  +     * Pop and return the top item from the BlockState stack.
  +     *
  +     * @exception EmptyStackException if the stack is empty
  +     */
  +    public BlockState popBlockState() throws EmptyStackException {
  +
  +        return ((BlockState) state.pop());
  +
  +    }
  +
  +
  +    /**
  +     * Push a new item onto the top of the BlockState stack.
  +     *
  +     * @param item New item to be pushed
  +     */
  +    public void pushBlockState(BlockState item) {
  +
  +        stack.push(item);
  +
  +    }
  +
  +
       // ---------------------------------------------- Dynamic Execution Methods
   
   
  @@ -575,7 +643,6 @@
                   // If there are active calls, resume the most recent one
                   try {
                       nextStep = (Step) calls.pop();
  -                    // FIXME - Update this for nested Steps!!!
                       this.activity = (Activity) nextStep.getOwner();
                   } catch (EmptyStackException e) {
                       ; // Can not happen
  @@ -586,7 +653,7 @@
   
               // Execute the (now) current Step
               thisStep = nextStep;
  -            nextStep = thisStep.getNextStep();
  +            nextStep = thisStep.getNextStep(); // Assume sequential execution
               try {
                   support.fireBeforeStep(thisStep);
                   thisStep.execute(this);
  @@ -692,6 +759,7 @@
               this.activity = null;
               this.nextStep = null;
               clear();
  +            clearBlockState();
           } else {
               this.activity = activity;
               this.nextStep = activity.getFirstStep();
  @@ -714,11 +782,15 @@
        */
       public void setNextStep(Step nextStep) {
   
  -        // FIXME - Update for nested steps execution!
  -        if ((nextStep != null) &&
  -            (this.activity != (Activity) nextStep.getOwner()))
  -            throw new IllegalArgumentException
  -                ("Step is not part of the current Activity");
  +        // Make sure the specified next Step is within the current Activity
  +        if (nextStep != null) {
  +            Owner owner = nextStep.getOwner();
  +            while (owner instanceof Block)
  +                owner = ((Block) owner).getOwner();
  +            if (this.activity != (Activity) owner)
  +                throw new IllegalArgumentException
  +                    ("Step is not part of the current Activity");
  +        }
           this.nextStep = nextStep;
   
       }
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to