1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.scxml.model;
18
19 import java.io.Serializable;
20 import java.util.Collection;
21 import java.util.Map;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.scxml.ErrorReporter;
25 import org.apache.commons.scxml.EventDispatcher;
26 import org.apache.commons.scxml.SCInstance;
27 import org.apache.commons.scxml.SCXMLExpressionException;
28
29 /**
30 * An abstract base class for executable elements in SCXML,
31 * such as <assign>, <log> etc.
32 *
33 */
34 public abstract class Action implements NamespacePrefixesHolder,
35 Serializable {
36
37 /**
38 * Link to its parent or container.
39 */
40 private Executable parent;
41
42 /**
43 * The current XML namespaces in the SCXML document for this action node,
44 * preserved for deferred XPath evaluation.
45 */
46 private Map namespaces;
47
48 /**
49 * Current document namespaces are saved under this key in the parent
50 * state's context.
51 */
52 private static final String NAMESPACES_KEY = "_ALL_NAMESPACES";
53
54 /**
55 * Constructor.
56 */
57 public Action() {
58 super();
59 this.parent = null;
60 this.namespaces = null;
61 }
62
63 /**
64 * Get the Executable parent.
65 *
66 * @return Returns the parent.
67 */
68 public final Executable getParent() {
69 return parent;
70 }
71
72 /**
73 * Set the Executable parent.
74 *
75 * @param parent The parent to set.
76 */
77 public final void setParent(final Executable parent) {
78 this.parent = parent;
79 }
80
81 /**
82 * Get the XML namespaces at this action node in the SCXML document.
83 *
84 * @return Returns the map of namespaces.
85 */
86 public final Map getNamespaces() {
87 return namespaces;
88 }
89
90 /**
91 * Set the XML namespaces at this action node in the SCXML document.
92 *
93 * @param namespaces The document namespaces.
94 */
95 public final void setNamespaces(final Map namespaces) {
96 this.namespaces = namespaces;
97 }
98
99 /**
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 org.apache.commons.scxml.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