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