001    /*
002     * Copyright 1999-2001,2004 The Apache Software Foundation.
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     * 
008     *      http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */ 
016    
017    package org.apache.commons.workflow.core;
018    
019    
020    import java.util.EmptyStackException;
021    import org.apache.commons.workflow.Block;
022    import org.apache.commons.workflow.BlockState;
023    import org.apache.commons.workflow.Context;
024    import org.apache.commons.workflow.Descriptor;
025    import org.apache.commons.workflow.Iterator;
026    import org.apache.commons.workflow.Step;
027    import org.apache.commons.workflow.StepException;
028    import org.apache.commons.workflow.base.BaseBlock;
029    
030    
031    /**
032     * <p>Repeatedly evaluate the properties specified by the associated
033     * Descriptors, and execute the nested Steps if and only if
034     * <strong>ANY</strong> of them evaluate to a negative result.
035     * To avoid non-deterministic evaluation
036     * stack behavior, all of the specified Descriptors are always
037     * evaluated exactly once.</p>
038     *
039     * @version $Revision: 155475 $ $Date: 2005-02-26 13:31:11 +0000 (Sat, 26 Feb 2005) $
040     * @author Craig R. McClanahan
041     */
042    
043    public class WhileNotStep extends WhileStep {
044    
045    
046        // ----------------------------------------------------------= Constructors
047    
048    
049        /**
050         * Construct a default instance of this Step.
051         */
052        public WhileNotStep() {
053    
054            super();
055    
056        }
057    
058    
059        /**
060         * Construct an instance of this Step with the specified identifier.
061         *
062         * @param id Step identifier
063         */
064        public WhileNotStep(String id) {
065    
066            this(id, null);
067    
068        }
069    
070    
071        /**
072         * Construct a fully configured instance of this Step.
073         *
074         * @param id Step identifier of this step
075         * @param descriptor Initial descriptor to be added
076         */
077        public WhileNotStep(String id, Descriptor descriptor) {
078    
079            super();
080            setId(id);
081            if (descriptor != null)
082                addDescriptor(descriptor);
083    
084        }
085    
086    
087        // --------------------------------------------------------- Public Methods
088    
089    
090        /**
091         * Render a string representation of this Step.
092         */
093        public String toString() {
094    
095            StringBuffer sb = new StringBuffer("<core:whileAny");
096            if (getId() != null) {
097                sb.append(" id=\"");
098                sb.append(getId());
099                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:whileAny>");
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    }