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.io.Serializable;
020 import java.util.Collection;
021 import java.util.Map;
022
023 import org.apache.commons.logging.Log;
024 import org.apache.commons.scxml.ErrorReporter;
025 import org.apache.commons.scxml.EventDispatcher;
026 import org.apache.commons.scxml.SCInstance;
027 import org.apache.commons.scxml.SCXMLExpressionException;
028
029 /**
030 * An abstract base class for executable elements in SCXML,
031 * such as <assign>, <log> etc.
032 *
033 */
034 public abstract class Action implements NamespacePrefixesHolder,
035 Serializable {
036
037 /**
038 * Link to its parent or container.
039 */
040 private Executable parent;
041
042 /**
043 * The current XML namespaces in the SCXML document for this action node,
044 * preserved for deferred XPath evaluation.
045 */
046 private Map namespaces;
047
048 /**
049 * Current document namespaces are saved under this key in the parent
050 * state's context.
051 */
052 private static final String NAMESPACES_KEY = "_ALL_NAMESPACES";
053
054 /**
055 * Constructor.
056 */
057 public Action() {
058 super();
059 this.parent = null;
060 this.namespaces = null;
061 }
062
063 /**
064 * Get the Executable parent.
065 *
066 * @return Returns the parent.
067 */
068 public final Executable getParent() {
069 return parent;
070 }
071
072 /**
073 * Set the Executable parent.
074 *
075 * @param parent The parent to set.
076 */
077 public final void setParent(final Executable parent) {
078 this.parent = parent;
079 }
080
081 /**
082 * Get the XML namespaces at this action node in the SCXML document.
083 *
084 * @return Returns the map of namespaces.
085 */
086 public final Map getNamespaces() {
087 return namespaces;
088 }
089
090 /**
091 * Set the XML namespaces at this action node in the SCXML document.
092 *
093 * @param namespaces The document namespaces.
094 */
095 public final void setNamespaces(final Map namespaces) {
096 this.namespaces = namespaces;
097 }
098
099 /**
100 * Return the parent state.
101 *
102 * @return The parent State
103 * @throws ModelException For an unknown TransitionTarget subclass
104 *
105 * @deprecated Use {@link #getParentTransitionTarget()} instead.
106 */
107 public final State getParentState() throws ModelException {
108 TransitionTarget tt = parent.getParent();
109 if (tt instanceof State) {
110 State st = (State) tt;
111 return st;
112 } else if (tt instanceof Parallel || tt instanceof History) {
113 State st = (State) tt.getParent();
114 return st;
115 } else {
116 throw new ModelException("Unknown TransitionTarget subclass:"
117 + tt.getClass().getName());
118 }
119 }
120
121 /**
122 * Return the {@link TransitionTarget} whose {@link Context} this action
123 * executes in.
124 *
125 * @return The parent {@link TransitionTarget}
126 * @throws ModelException For an unknown TransitionTarget subclass
127 *
128 * @since 0.9
129 */
130 public final TransitionTarget getParentTransitionTarget()
131 throws ModelException {
132 TransitionTarget tt = parent.getParent();
133 if (tt instanceof State || tt instanceof Parallel) {
134 return tt;
135 } else if (tt instanceof History || tt instanceof Initial) {
136 return tt.getParent();
137 } else {
138 throw new ModelException("Unknown TransitionTarget subclass:"
139 + tt.getClass().getName());
140 }
141 }
142
143 /**
144 * Execute this action instance.
145 *
146 * @param evtDispatcher The EventDispatcher for this execution instance
147 * @param errRep The ErrorReporter to broadcast any errors
148 * during execution.
149 * @param scInstance The state machine execution instance information.
150 * @param appLog The application Log.
151 * @param derivedEvents The collection to which any internal events
152 * arising from the execution of this action
153 * must be added.
154 *
155 * @throws ModelException If the execution causes the model to enter
156 * a non-deterministic state.
157 * @throws SCXMLExpressionException If the execution involves trying
158 * to evaluate an expression which is malformed.
159 */
160 public abstract void execute(final EventDispatcher evtDispatcher,
161 final ErrorReporter errRep, final SCInstance scInstance,
162 final Log appLog, final Collection derivedEvents)
163 throws ModelException, SCXMLExpressionException;
164
165 /**
166 * Return the key under which the current document namespaces are saved
167 * in the parent state's context.
168 *
169 * @return The namespaces key
170 */
171 protected static String getNamespacesKey() {
172 return NAMESPACES_KEY;
173 }
174
175 }
176