    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *     http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017    package org.apache.commons.scxml.model;
    018
    019    import java.util.ArrayList;
    020    import java.util.Collection;
    021    import java.util.Iterator;
    022    import java.util.List;
    023
    024    import org.apache.commons.logging.Log;
    025    import org.apache.commons.scxml.Context;
    026    import org.apache.commons.scxml.ErrorReporter;
    027    import org.apache.commons.scxml.Evaluator;
    028    import org.apache.commons.scxml.EventDispatcher;
    029    import org.apache.commons.scxml.SCInstance;
    030    import org.apache.commons.scxml.SCXMLExpressionException;
    031
    032    /**
    033     * The class in this SCXML object model that corresponds to the
    034     * <if> SCXML element, which serves as a container for conditionally
    035     * executed elements. <else> and <elseif> can optionally
    036     * appear within an <if> as immediate children, and serve to partition
    037     * the elements within an <if>.
    038     *
    039     */
    040    public class If extends Action {
    041
    042        /**
    043         * Serial version UID.
    044         */
    045        private static final long serialVersionUID = 1L;
    046
    047        /**
    048         * An conditional expression which can be evaluated to true or false.
    049         */
    050        private String cond;
    051
    052        /**
    053         * The set of executable elements (those that inheriting from
    054         * Action) that are contained in this <if> element.
    055         */
    056        private List actions;
    057
    058        /**
    059         * The boolean value that dictates whether the particular child action
    060         * should be executed.
    061         */
    062        private boolean execute;
    063
    064        /**
    065         * Constructor.
    066         */
    067        public If() {
    068            super();
    069            this.actions = new ArrayList();
    070            this.execute = false;
    071        }
    072
    073        /**
    074         * Get the executable actions contained in this <if>.
    075         *
    076         * @return Returns the actions.
    077         */
    078        public final List getActions() {
    079            return actions;
    080        }
    081
    082        /**
    083         * Add an Action to the list of executable actions contained in
    084         * this <if>.
    085         *
    086         * @param action The action to add.
    087         */
    088        public final void addAction(final Action action) {
    089            if (action != null) {
    090                this.actions.add(action);
    091            }
    092        }
    093
    094        /**
    095         * Get the conditional expression.
    096         *
    097         * @return Returns the cond.
    098         */
    099        public final String getCond() {
    100            return cond;
    101        }
    102
    103        /**
    104         * Set the conditional expression.
    105         *
    106         * @param cond The cond to set.
    107         */
    108        public final void setCond(final String cond) {
    109            this.cond = cond;
    110        }
    111
    112        /**
    113         * {@inheritDoc}
    114         */
    115        public void execute(final EventDispatcher evtDispatcher,
    116                final ErrorReporter errRep, final SCInstance scInstance,
    117                final Log appLog, final Collection derivedEvents)
    118        throws ModelException, SCXMLExpressionException {
    119            TransitionTarget parentTarget = getParentTransitionTarget();
    120            Context ctx = scInstance.getContext(parentTarget);
    121            Evaluator eval = scInstance.getEvaluator();
    122            ctx.setLocal(getNamespacesKey(), getNamespaces());
    123            execute = eval.evalCond(ctx, cond).booleanValue();
    124            ctx.setLocal(getNamespacesKey(), null);
    125            // The "if" statement is a "container"
    126            for (Iterator ifiter = actions.iterator(); ifiter.hasNext();) {
    127                Action aa = (Action) ifiter.next();
    128                if (execute && !(aa instanceof ElseIf)
    129                        && !(aa instanceof Else)) {
    130                    aa.execute(evtDispatcher, errRep, scInstance, appLog,
    131                        derivedEvents);
    132                } else if (execute
    133                        && (aa instanceof ElseIf || aa instanceof Else)) {
    134                    break;
    135                } else if (aa instanceof Else) {
    136                    execute = true;
    137                } else if (aa instanceof ElseIf) {
    138                    ctx.setLocal(getNamespacesKey(), getNamespaces());
    139                    execute = eval.evalCond(ctx, ((ElseIf) aa).getCond())
    140                            .booleanValue();
    141                    ctx.setLocal(getNamespacesKey(), null);
    142                }
    143            }
    144        }
    145
    146    }
    147