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 org.apache.commons.workflow.Context;
021    import org.apache.commons.workflow.Descriptor;
022    import org.apache.commons.workflow.Step;
023    import org.apache.commons.workflow.StepException;
024    
025    
026    /**
027     * <p>Evaluate properties specified by the associated Descriptors, and
028     * transfer control to the specified step if ALL of them are
029     * <code>true</code> (if boolean) or not null (if Object).  To avoid
030     * non-deterministic evaluation stack behavior, all of the specified
031     * Descriptors are always evaluated.</p>
032     *
033     * <p>Supported Attributes:</p>
034     * <ul>
035     * <li><strong>step</strong> - Identifier of the Step to which control
036     *     should be transferred if the condition is met.</li>
037     * </ul>
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 AndStep extends GotoStep {
044    
045    
046        // ----------------------------------------------------------= Constructors
047    
048    
049        /**
050         * Construct a default instance of this Step.
051         */
052        public AndStep() {
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 AndStep(String id) {
065    
066            this(id, null, 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 step Step identifier to which control should be redirected
076         */
077        public AndStep(String id, String step) {
078    
079            this(id, step, null);
080    
081        }
082    
083    
084        /**
085         * Construct a fully configured instance of this Step.
086         *
087         * @param id Step identifier of this step
088         * @param step Step identifier to which control should be redirected
089         * @param descriptor Initial descriptor to be added
090         */
091        public AndStep(String id, String step, Descriptor descriptor) {
092    
093            super();
094            setId(id);
095            setStep(step);
096            addDescriptor(descriptor);
097    
098        }
099    
100    
101        // --------------------------------------------------------- Public Methods
102    
103    
104        /**
105         * Perform the executable actions related to this Step, in the context of
106         * the specified Context.
107         *
108         * @param context The Context that is tracking our execution state
109         *
110         * @exception StepException if a processing error has occurred
111         */
112        public void execute(Context context) throws StepException {
113    
114            // Process all associated descriptors
115            boolean condition = true;
116            Descriptor descriptors[] = findDescriptors();
117            for (int i = 0; i < descriptors.length; i++) {
118                Object value = descriptors[i].get(context);
119                if (value == null)
120                    condition = false;
121                else if ((value instanceof Boolean) &&
122                         !((Boolean) value).booleanValue())
123                    condition = false;
124            }
125    
126            // Conditionally forward control to the specified step
127            if (condition) {
128                Step next = getOwner().findStep(this.step);
129                if (next == null)
130                    throw new StepException("Cannot find step '" + step + "'",
131                                            this);
132                context.setNextStep(next);
133            }
134                    
135        }
136    
137    
138    }