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