1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  package org.apache.commons.scxml2.model;
18  
19  import java.util.HashMap;
20  import java.util.Map;
21  
22  import org.apache.commons.scxml2.ActionExecutionContext;
23  import org.apache.commons.scxml2.Context;
24  import org.apache.commons.scxml2.Evaluator;
25  import org.apache.commons.scxml2.PathResolver;
26  import org.apache.commons.scxml2.SCXMLExecutionContext;
27  import org.apache.commons.scxml2.SCXMLExpressionException;
28  import org.apache.commons.scxml2.SCXMLSystemContext;
29  import org.apache.commons.scxml2.TriggerEvent;
30  import org.apache.commons.scxml2.invoke.Invoker;
31  import org.apache.commons.scxml2.invoke.InvokerException;
32  import org.apache.commons.scxml2.semantics.ErrorConstants;
33  import org.w3c.dom.Node;
34  
35  
36  
37  
38  
39  
40  public class Invoke extends NamelistHolder implements PathResolverHolder, ContentContainer {
41  
42      
43  
44  
45      private static final long serialVersionUID = 1L;
46  
47      
48  
49  
50      private static final String CURRENT_EXECUTION_CONTEXT_KEY = "_CURRENT_EXECUTION_CONTEXT";
51  
52      
53  
54  
55      private String id;
56  
57      
58  
59  
60      private String idlocation;
61  
62      
63  
64  
65      private String type;
66  
67      
68  
69  
70      private String typeexpr;
71  
72      
73  
74  
75      private String src;
76  
77      
78  
79  
80  
81      private String srcexpr;
82  
83      
84  
85  
86      private Boolean autoForward;
87  
88      
89  
90  
91      private Finalize finalize;
92  
93      
94  
95  
96      private PathResolver pathResolver;
97  
98      
99  
100 
101     private Content content;
102 
103     private EnterableState parent;
104 
105     
106 
107 
108 
109 
110     public final String getId() {
111         return id;
112     }
113 
114     
115 
116 
117 
118 
119     public final void setId(final String id) {
120         this.id = id;
121     }
122 
123     
124 
125 
126     public String getIdlocation() {
127         return idlocation;
128     }
129 
130     
131 
132 
133 
134     public void setIdlocation(final String idlocation) {
135         this.idlocation = idlocation;
136     }
137 
138     
139 
140 
141 
142 
143     public final String getType() {
144         return type;
145     }
146 
147     
148 
149 
150 
151 
152     public final void setType(final String type) {
153         this.type = type;
154     }
155 
156     
157 
158 
159     public String getTypeexpr() {
160         return typeexpr;
161     }
162 
163     
164 
165 
166 
167     public void setTypeexpr(final String typeexpr) {
168         this.typeexpr = typeexpr;
169     }
170 
171     
172 
173 
174 
175 
176     public final String getSrc() {
177         return src;
178     }
179 
180     
181 
182 
183 
184 
185     public final void setSrc(final String src) {
186         this.src = src;
187     }
188 
189     
190 
191 
192 
193 
194 
195     public final String getSrcexpr() {
196         return srcexpr;
197     }
198 
199     
200 
201 
202 
203 
204 
205     public final void setSrcexpr(final String srcexpr) {
206         this.srcexpr = srcexpr;
207     }
208 
209 
210     
211 
212 
213     public final boolean isAutoForward() {
214         return autoForward != null && autoForward;
215     }
216 
217     
218 
219 
220     public final Boolean getAutoForward() {
221         return autoForward;
222     }
223 
224     
225 
226 
227 
228     public final void setAutoForward(final Boolean autoForward) {
229         this.autoForward = autoForward;
230     }
231 
232     
233 
234 
235 
236 
237     public final Finalize getFinalize() {
238         return finalize;
239     }
240 
241     
242 
243 
244 
245 
246     public final void setFinalize(final Finalize finalize) {
247         this.finalize = finalize;
248     }
249 
250     
251 
252 
253 
254 
255     public PathResolver getPathResolver() {
256         return pathResolver;
257     }
258 
259     
260 
261 
262 
263 
264     public void setPathResolver(final PathResolver pathResolver) {
265         this.pathResolver = pathResolver;
266     }
267 
268     
269 
270 
271 
272 
273     @Override
274     public final boolean equals(final Object other) {
275         return this == other;
276     }
277 
278     
279 
280 
281 
282     @Override
283     public final int hashCode() {
284         return System.identityHashCode(this);
285     }
286 
287     
288 
289 
290 
291 
292     public Content getContent() {
293         return content;
294     }
295 
296     
297 
298 
299     public String getCurrentSCXMLExecutionContextKey() {
300         return CURRENT_EXECUTION_CONTEXT_KEY;
301     }
302 
303     
304 
305 
306 
307 
308     public void setContent(final Content content) {
309         this.content = content;
310     }
311 
312     
313 
314 
315 
316 
317     public EnterableState getParentEnterableState() {
318         return parent;
319     }
320 
321     
322 
323 
324 
325     public void setParentEnterableState(final EnterableState parent) {
326         if (parent == null) {
327             throw new IllegalArgumentException("Parent parameter cannot be null");
328         }
329         this.parent = parent;
330     }
331 
332     @SuppressWarnings("unchecked")
333     @Override
334     public void execute(final ActionExecutionContext axctx) throws ModelException {
335         EnterableState parentState = getParentEnterableState();
336         Context ctx = axctx.getContext(parentState);
337         SCXMLExecutionContext exctx = (SCXMLExecutionContext)ctx.getVars().get(getCurrentSCXMLExecutionContextKey());
338         if (exctx == null) {
339             throw new ModelException("Missing current SCXMLExecutionContext instance in context under key: "+ getCurrentSCXMLExecutionContextKey());
340         }
341         try {
342             ctx.setLocal(getNamespacesKey(), getNamespaces());
343             Evaluator eval = axctx.getEvaluator();
344 
345             String typeValue = type;
346             if (typeValue == null && typeexpr != null) {
347                 typeValue = (String) getTextContentIfNodeResult(eval.eval(ctx, typeexpr));
348                 if (typeValue == null) {
349                     throw new SCXMLExpressionException("<invoke> for state "+parentState.getId() +
350                             ": type expression \"" + typeexpr + "\" evaluated to null or empty String");
351                 }
352             }
353             if (typeValue == null) {
354                 typeValue = SCXMLExecutionContext.SCXML_INVOKER_TYPE;
355             }
356             Invoker invoker = exctx.newInvoker(typeValue);
357 
358             String invokeId = getId();
359             if (invokeId == null) {
360                 invokeId = parentState.getId() + "." + ctx.get(SCXMLSystemContext.SESSIONID_KEY);
361             }
362             if (getId() == null && getIdlocation() != null) {
363                 eval.evalAssign(ctx, idlocation, invokeId, Evaluator.AssignType.REPLACE_CHILDREN, null);
364             }
365             invoker.setInvokeId(invokeId);
366 
367             String src = getSrc();
368             if (src == null && getSrcexpr() != null) {
369                 src = (String) getTextContentIfNodeResult(eval.eval(ctx, getSrcexpr()));
370             }
371             if (src != null) {
372                 PathResolver pr = getPathResolver();
373                 if (pr != null) {
374                     src = getPathResolver().resolvePath(src);
375                 }
376             }
377             Node srcNode = null;
378             if (src == null && getContent() != null) {
379                 Object contentValue;
380                 if (content.getExpr() != null) {
381                     contentValue = eval.eval(ctx, content.getExpr());
382                 } else {
383                     contentValue = content.getBody();
384                 }
385                 if (contentValue instanceof Node) {
386                     srcNode = ((Node)contentValue).cloneNode(true);
387                 }
388                 else if (contentValue != null) {
389                     src = String.valueOf(contentValue);
390                 }
391             }
392             if (src == null && srcNode == null) {
393                 throw new SCXMLExpressionException("<invoke> for state "+parentState.getId() +
394                         ": no src and no content defined");
395             }
396             Map<String, Object> payloadDataMap = new HashMap<String, Object>();
397             addNamelistDataToPayload(axctx, payloadDataMap);
398             addParamsToPayload(axctx, payloadDataMap);
399             invoker.setParentSCXMLExecutor(exctx.getSCXMLExecutor());
400             if (src != null) {
401                 invoker.invoke(src, payloadDataMap);
402             }
403             
404             exctx.registerInvoker(this, invoker);
405         }
406         catch (InvokerException e) {
407             axctx.getErrorReporter().onError(ErrorConstants.EXECUTION_ERROR, e.getMessage(), this);
408             axctx.getInternalIOProcessor().addEvent(new TriggerEvent(TriggerEvent.ERROR_EXECUTION, TriggerEvent.ERROR_EVENT));
409         }
410         catch (SCXMLExpressionException e) {
411             axctx.getInternalIOProcessor().addEvent(new TriggerEvent(TriggerEvent.ERROR_EXECUTION, TriggerEvent.ERROR_EVENT));
412             axctx.getErrorReporter().onError(ErrorConstants.EXPRESSION_ERROR, e.getMessage(), this);
413         }
414         finally {
415             ctx.setLocal(getNamespacesKey(), null);
416         }
417     }
418 }