Coverage Report - org.apache.commons.workflow.base.BaseBlock
 
Classes in this File Line Coverage Branch Coverage Complexity
BaseBlock
0%
0/67
0%
0/24
2.167
 
 1  
 /*
 2  
  * Copyright 1999-2001,2004 The Apache Software Foundation.
 3  
  * 
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  * 
 8  
  *      http://www.apache.org/licenses/LICENSE-2.0
 9  
  * 
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */ 
 16  
 
 17  
 package org.apache.commons.workflow.base;
 18  
 
 19  
 
 20  
 import java.util.ArrayList;
 21  
 import java.util.EmptyStackException;
 22  
 import org.apache.commons.workflow.Activity;
 23  
 import org.apache.commons.workflow.Block;
 24  
 import org.apache.commons.workflow.BlockState;
 25  
 import org.apache.commons.workflow.Context;
 26  
 import org.apache.commons.workflow.Owner;
 27  
 import org.apache.commons.workflow.Step;
 28  
 import org.apache.commons.workflow.StepException;
 29  
 
 30  
 
 31  
 /**
 32  
  * <p><strong>BaseBlock</strong> is a convenient base class for more
 33  
  * sophisticated <code>Block</code> implementations.  It includes management
 34  
  * of the static relationships of nested Steps for this Step (each of which
 35  
  * could conceptually also be a Block and have its own nested Steps).</p>
 36  
  *
 37  
  * @version $Revision: 155475 $ $Date: 2005-02-26 13:31:11 +0000 (Sat, 26 Feb 2005) $
 38  
  * @author Craig R. McClanahan
 39  
  */
 40  
 
 41  0
 public abstract class BaseBlock extends DescriptorStep implements Block {
 42  
 
 43  
 
 44  
     // ----------------------------------------------------- Instance Variables
 45  
 
 46  
 
 47  
     /**
 48  
      * The first Step associated with this Block.
 49  
      */
 50  0
     protected Step firstStep = null;
 51  
 
 52  
 
 53  
     /**
 54  
      * The last Step associated with this Block.
 55  
      */
 56  0
     protected Step lastStep = null;
 57  
 
 58  
 
 59  
     // ------------------------------------------------------------- Properties
 60  
 
 61  
 
 62  
     /**
 63  
      * Return the first Step associated with this Block.
 64  
      */
 65  
     public Step getFirstStep() {
 66  
 
 67  0
         return (this.firstStep);
 68  
 
 69  
     }
 70  
 
 71  
 
 72  
     /**
 73  
      * Return the last Step associated with this Activity.
 74  
      */
 75  
     public Step getLastStep() {
 76  
 
 77  0
         return (this.lastStep);
 78  
 
 79  
     }
 80  
 
 81  
 
 82  
     // ---------------------------------------------------------- Owner Methods
 83  
 
 84  
 
 85  
     /**
 86  
      * <p>Add a new Step to the end of the sequence of Steps associated with
 87  
      * this Block.</p>
 88  
      *
 89  
      * <p><strong>IMPLEMENTATION NOTE</strong> - The last nested Step is looped
 90  
      * back to the owning Block in order to support the execution flow of
 91  
      * control required by our BaseContext.</p>
 92  
      *
 93  
      * @param step The new step to be added
 94  
      */
 95  
     public void addStep(Step step) {
 96  
 
 97  0
         step.setOwner(this);
 98  0
         if (firstStep == null) {
 99  0
             step.setPreviousStep(null);
 100  0
             step.setNextStep(this);
 101  0
             firstStep = step;
 102  0
             lastStep = step;
 103  
         } else {
 104  0
             step.setPreviousStep(lastStep);
 105  0
             step.setNextStep(this);
 106  0
             lastStep.setNextStep(step);
 107  0
             lastStep = step;
 108  
         }
 109  
 
 110  0
     }
 111  
 
 112  
 
 113  
     /**
 114  
      * Clear any existing Steps associated with this Block.
 115  
      */
 116  
     public void clearSteps() {
 117  
 
 118  0
         Step current = firstStep;
 119  0
         while ((current != null) && (current != this)) {
 120  0
             Step next = current.getNextStep();
 121  0
             if (current instanceof Block)
 122  0
                 ((Block) current).clearSteps();
 123  0
             current.setOwner(null);
 124  0
             current.setPreviousStep(null);
 125  0
             current.setNextStep(null);
 126  0
             current = next;
 127  0
         }
 128  0
         firstStep = null;
 129  0
         lastStep = null;
 130  
 
 131  0
     }
 132  
 
 133  
 
 134  
     /**
 135  
      * Return the identified Step from this Block, if it exists.
 136  
      * Otherwise, return <code>null</code>.
 137  
      *
 138  
      * @param id Identifier of the desired Step
 139  
      */
 140  
     public Step findStep(String id) {
 141  
 
 142  0
         Step currentStep = getFirstStep();
 143  0
         while (currentStep != null) {
 144  0
             if (id.equals(currentStep.getId()))
 145  0
                 return (currentStep);
 146  0
             if (currentStep == lastStep)
 147  0
                 break;
 148  0
             currentStep = currentStep.getNextStep();
 149  
         }
 150  0
         return (null);
 151  
 
 152  
     }
 153  
 
 154  
 
 155  
     /**
 156  
      * Return the set of Steps associated with this Block.
 157  
      */
 158  
     public Step[] getSteps() {
 159  
 
 160  0
         ArrayList list = new ArrayList();
 161  0
         Step currentStep = firstStep;
 162  0
         while (currentStep != null) {
 163  0
             list.add(currentStep);
 164  0
             if (currentStep == lastStep)
 165  0
                 break;
 166  0
             currentStep = currentStep.getNextStep();
 167  
         }
 168  0
         Step steps[] = new Step[list.size()];
 169  0
         return ((Step[]) list.toArray(steps));
 170  
 
 171  
     }
 172  
 
 173  
 
 174  
     /**
 175  
      * Set the set of Steps associated with this Block, replacing any
 176  
      * existing ones.
 177  
      *
 178  
      * @param steps The new set of steps.
 179  
      */
 180  
     public void setSteps(Step steps[]) {
 181  
 
 182  0
         clearSteps();
 183  0
         for (int i = 0; i < steps.length; i++)
 184  0
             addStep(steps[i]);
 185  
 
 186  0
     }
 187  
 
 188  
 
 189  
     // --------------------------------------------------------- Public Methods
 190  
 
 191  
 
 192  
     /**
 193  
      * Perform the executable actions related to this Step, in the context of
 194  
      * the specified Context.
 195  
      *
 196  
      * @param context The Context that is tracking our execution state
 197  
      *
 198  
      * @exception StepException if a processing error has occurred
 199  
      */
 200  
     public void execute(Context context) throws StepException {
 201  
 
 202  0
         BlockState state = state(context);
 203  0
         if (state == null)
 204  0
             initial(context);
 205  
         else
 206  0
             subsequent(context, state);
 207  
 
 208  0
     }
 209  
 
 210  
 
 211  
     // ------------------------------------------------------ Protected Methods
 212  
 
 213  
 
 214  
     /**
 215  
      * <p>Evaluate the condition specified by the Descriptors associated with
 216  
      * this Block, and return the resulting boolean value.  The default
 217  
      * implementation returns <code>false</code> unconditionally.</p>
 218  
      *
 219  
      * @param context Context within which to evaluate the descriptors
 220  
      */
 221  
     protected boolean evaluate(Context context) {
 222  
 
 223  0
         return (false);
 224  
 
 225  
     }
 226  
 
 227  
 
 228  
     /**
 229  
      * <p>Process the initial entry into this Block.  The default
 230  
      * implementation unconditionally skips the nested Steps.</p>
 231  
      *
 232  
      * @param context Context within which to evaluate the condition
 233  
      */
 234  
     protected void initial(Context context) {
 235  
 
 236  0
         context.setNextStep(getNextStep());
 237  
 
 238  0
     }
 239  
 
 240  
 
 241  
     /**
 242  
      * <p>Peek at the top <code>BlockState</code> element on the stack
 243  
      * maintained by our <code>Context</code>, and return it.  If there
 244  
      * is no such top element, return <code>null</code> instead.</p>
 245  
      *
 246  
      * @param context Context within which to evaluate the current BlockState
 247  
      */
 248  
     protected BlockState state(Context context) {
 249  
 
 250  
         try {
 251  0
             BlockState state = context.peekBlockState();
 252  0
             if (this == state.getBlock())
 253  0
                 return (state);
 254  0
         } catch (EmptyStackException e) {
 255  
             ;
 256  0
         }
 257  0
         return (null);
 258  
 
 259  
     }
 260  
 
 261  
 
 262  
     /**
 263  
      * <p>Process the return from nested execution of the Steps associated
 264  
      * with this Block.  The default implementation unconditionally
 265  
      * proceeds to the next Step at the current nesting level, without
 266  
      * iterating again.</p>
 267  
      *
 268  
      * @param context Context within which to evaluate the condition
 269  
      * @param state BlockState for our block
 270  
      */
 271  
     protected void subsequent(Context context, BlockState state) {
 272  
 
 273  0
         context.popBlockState();
 274  0
         context.setNextStep(getNextStep());
 275  
 
 276  0
     }
 277  
 
 278  
 
 279  
 }