View Javadoc

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.core;
18  
19  
20  import java.util.EmptyStackException;
21  import org.apache.commons.workflow.Block;
22  import org.apache.commons.workflow.BlockState;
23  import org.apache.commons.workflow.Context;
24  import org.apache.commons.workflow.Descriptor;
25  import org.apache.commons.workflow.Iterator;
26  import org.apache.commons.workflow.Step;
27  import org.apache.commons.workflow.StepException;
28  import org.apache.commons.workflow.base.BaseBlock;
29  
30  
31  /**
32   * <p>Repeatedly evaluate the properties specified by the associated
33   * Descriptors, and execute the nested Steps if and only if
34   * <strong>ALL</strong> of them evaluate to a positive result.
35   * To avoid non-deterministic evaluation
36   * stack behavior, all of the specified Descriptors are always
37   * evaluated exactly once.</p>
38   *
39   * @version $Revision: 155475 $ $Date: 2005-02-26 13:31:11 +0000 (Sat, 26 Feb 2005) $
40   * @author Craig R. McClanahan
41   */
42  
43  public class WhileStep extends BaseBlock implements Iterator {
44  
45  
46      // ----------------------------------------------------------= Constructors
47  
48  
49      /**
50       * Construct a default instance of this Step.
51       */
52      public WhileStep() {
53  
54          super();
55  
56      }
57  
58  
59      /**
60       * Construct an instance of this Step with the specified identifier.
61       *
62       * @param id Step identifier
63       */
64      public WhileStep(String id) {
65  
66          this(id, null);
67  
68      }
69  
70  
71      /**
72       * Construct a fully configured instance of this Step.
73       *
74       * @param id Step identifier of this step
75       * @param descriptor Initial descriptor to be added
76       */
77      public WhileStep(String id, Descriptor descriptor) {
78  
79          super();
80          setId(id);
81          if (descriptor != null)
82              addDescriptor(descriptor);
83  
84      }
85  
86  
87      // --------------------------------------------------------- Public Methods
88  
89  
90      /**
91       * Render a string representation of this Step.
92       */
93      public String toString() {
94  
95          StringBuffer sb = new StringBuffer("<core:while");
96          if (getId() != null) {
97              sb.append(" id=\"");
98              sb.append(getId());
99              sb.append("\"");
100         }
101         sb.append(">");
102         Descriptor descriptors[] = findDescriptors();
103         for (int i = 0; i < descriptors.length; i++)
104             sb.append(descriptors[i]);
105         Step steps[] = getSteps();
106         for (int i = 0; i < steps.length; i++)
107             sb.append(steps[i]);
108         sb.append("</core:while>");
109         return (sb.toString());
110 
111     }
112 
113 
114     // ------------------------------------------------------ Protected Methods
115 
116 
117     /**
118      * Evaluate the condition specified by the Descriptors associated with
119      * this Block, and return the resulting boolean value.
120      *
121      * @param context Context within which to evaluate the descriptors
122      */
123     protected boolean evaluate(Context context) {
124 
125         boolean condition = true;
126         Descriptor descriptors[] = findDescriptors();
127         for (int i = 0; i < descriptors.length; i++) {
128             if (descriptors[i] == null)
129                 continue;
130             if (!descriptors[i].positive(context))
131                 condition = false;
132         }
133         return (condition);
134 
135     }
136 
137 
138     /**
139      * Process the initial entry into this Block.
140      *
141      * @param context Context within which to evaluate the condition
142      */
143     protected void initial(Context context) {
144 
145         if (evaluate(context)) {
146             BlockState state = new BlockState(this, true);
147             context.pushBlockState(state);
148             context.setNextStep(getFirstStep());
149         } else {
150             context.setNextStep(getNextStep());
151         }
152 
153     }
154 
155 
156     /**
157      * Process the return from nested execution of the Steps assocaited
158      * with this Block.
159      *
160      * @param context Context within which to evaluate the condition
161      * @param state BlockState for our block
162      */
163     protected void subsequent(Context context, BlockState state) {
164 
165 
166         // Was a "break" Step executed within this Block?
167         if (!state.getNest()) {
168             context.popBlockState();
169             context.setNextStep(getNextStep());
170             return;
171         }
172 
173         // Re-evaluate the loop conditions
174         if (evaluate(context)) {
175             context.setNextStep(getFirstStep());
176         } else {
177             context.popBlockState();
178             context.setNextStep(getNextStep());
179         }
180         
181 
182     }
183 
184 
185 }