KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > genimen > djeneric > tools > scriptengine > core > nodes > ScriptNode


1 /*
2  * Copyright (c) 2001-2005 by Genimen BV (www.genimen.com) All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, is permitted provided that the following conditions are met: -
6  * Redistributions of source code must retain the above copyright notice, this
7  * list of conditions and the following disclaimer. - Redistributions in binary
8  * form must reproduce the above copyright notice, this list of conditions and
9  * the following disclaimer in the documentation and/or other materials
10  * provided with the distribution. - All advertising materials mentioning
11  * features or use of this software must display the following acknowledgment:
12  * "This product includes Djeneric." - Products derived from this software may
13  * not be called "Djeneric" nor may "Djeneric" appear in their names without
14  * prior written permission of Genimen BV. - Redistributions of any form
15  * whatsoever must retain the following acknowledgment: "This product includes
16  * Djeneric."
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL GENIMEN BV, DJENERIC.ORG, OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */

30 package com.genimen.djeneric.tools.scriptengine.core.nodes;
31
32 import java.util.ArrayList JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.Iterator JavaDoc;
35
36 import com.genimen.djeneric.language.Messages;
37 import com.genimen.djeneric.repository.DjSession;
38 import com.genimen.djeneric.repository.exceptions.DjenericException;
39 import com.genimen.djeneric.tools.scriptengine.core.DjScriptParserEngine;
40 import com.genimen.djeneric.tools.scriptengine.core.ScriptRunnerContainer;
41 import com.genimen.djeneric.tools.scriptengine.core.SimpleNode;
42 import com.genimen.djeneric.tools.scriptengine.core.util.DjScriptCompileTimeScope;
43 import com.genimen.djeneric.tools.scriptengine.core.util.DjScriptExecutionException;
44 import com.genimen.djeneric.tools.scriptengine.core.util.DjScriptExecutionTimeScope;
45 import com.genimen.djeneric.tools.scriptengine.core.util.Variable;
46
47 public class ScriptNode extends SimpleNode
48 {
49
50   public static final String JavaDoc EVENT_VARIABLE_NAME = "$event";
51   private String JavaDoc _scriptName = null;
52   private String JavaDoc _title = null;
53   DjScriptExecutionTimeScope _executionContext = null;
54   DjSession _session = null;
55   private HashMap JavaDoc _externalGlobals = new HashMap JavaDoc();
56
57   public ScriptNode(int i)
58   {
59     super(i);
60   }
61
62   public ScriptNode(DjScriptParserEngine p, int i)
63   {
64     super(p, i);
65   }
66
67   public void setExternalGlobal(String JavaDoc name, Object JavaDoc value)
68   {
69     _externalGlobals.put(name, new Variable(name, value));
70   }
71
72   public void setExternalGlobal(String JavaDoc name, Object JavaDoc value, String JavaDoc typeName)
73   {
74     _externalGlobals.put(name, new Variable(name, value, typeName));
75   }
76
77   public void setParameter(String JavaDoc name, Object JavaDoc value) throws DjenericException
78   {
79     if (_executionContext == null) throw new DjenericException(
80         "ExecutionContext not initialized. Call initializeNow() first");
81     _executionContext.setParameter(name, value);
82   }
83
84   public void setParameter(String JavaDoc name, Object JavaDoc value, String JavaDoc typeName) throws DjenericException
85   {
86     if (_executionContext == null) throw new DjenericException(
87         "ExecutionContext not initialized. Call initializeNow() first");
88     _executionContext.setParameter(name, value);
89   }
90
91   public String JavaDoc getNodeTitle()
92   {
93     return getScriptName();
94   }
95
96   public String JavaDoc getScriptName()
97   {
98     return _scriptName;
99   }
100
101   public void setScriptName(String JavaDoc scriptName)
102   {
103     _scriptName = scriptName;
104   }
105
106   public String JavaDoc getName()
107   {
108     return "script";
109   }
110
111   public String JavaDoc toString()
112   {
113     return "script name = " + _scriptName + ", title = " + _title;
114   }
115
116   public String JavaDoc getTitle()
117   {
118     if (_title == null) return _scriptName;
119     return _title;
120   }
121
122   public void setTitle(String JavaDoc string)
123   {
124     _title = string.substring(1, string.length() - 1);
125   }
126
127   protected boolean isBuiltInEvent(String JavaDoc eventName)
128   {
129     return eventName.endsWith("validate") || eventName.endsWith("close");
130   }
131
132   public void validateScript(DjScriptCompileTimeScope ctxt) throws DjScriptExecutionException
133   {
134     declareGlobalsFromConstructor(ctxt);
135     HashMap JavaDoc eventsDefsByEventName = new HashMap JavaDoc();
136
137     ArrayList JavaDoc eventMappings = new ArrayList JavaDoc();
138     collectNodes(EventMappingNode.class, eventMappings);
139
140     ArrayList JavaDoc eventDefinitions = new ArrayList JavaDoc();
141     collectNodes(EventDefinitionNode.class, eventDefinitions);
142
143     for (int i = 0; i < eventDefinitions.size(); i++)
144     {
145       EventDefinitionNode event = (EventDefinitionNode) eventDefinitions.get(i);
146       eventsDefsByEventName.put(event.getEventNameIncludingAction(), event);
147
148       String JavaDoc[] actionNames = ctxt.getController().getActionsForEvent(event.getEventName());
149       if (actionNames.length == 0)
150       {
151         throw new DjScriptExecutionException(Messages.getString("ScriptNode.Event", event.getEventName()), event);
152       }
153     }
154
155     for (int i = 0; i < eventMappings.size(); i++)
156     {
157       EventMappingNode map = (EventMappingNode) eventMappings.get(i);
158
159       ArrayList JavaDoc actions = map.getActions();
160       for (int a = 0; a < actions.size(); a++)
161       {
162         String JavaDoc actionName = actions.get(a).toString();
163
164         /** ************* VALIDATE THE ACTION NAME OF A MAPPING: ************* */
165         ctxt.getAction(actionName, map);
166
167         /** ************* VALIDATE THAT AN EVENT THAT IS MAPPED IS FIRED BY AN ACTION: ************* */
168         String JavaDoc eventName = map.getPath();
169
170         if (eventName.indexOf('*') == -1 && !isBuiltInEvent(eventName))
171         {
172           if (eventsDefsByEventName.get(eventName) == null)
173           {
174             // throw new ScriptExecutionException("Event " + eventName + " is never fired in this script", map);
175
}
176         }
177       }
178     }
179
180     super.validateScript(ctxt);
181   }
182
183   public void declareGlobalsFromConstructor(DjScriptCompileTimeScope ctxt) throws DjScriptExecutionException
184   {
185     ConstructorNode constructor = (ConstructorNode) getChild(ConstructorNode.class);
186     if (constructor != null)
187     {
188       constructor.declareGlobals(ctxt);
189     }
190   }
191
192   private void initExecutionContext(ScriptRunnerContainer container, boolean executeConstructor)
193       throws DjScriptExecutionException
194   {
195     ConstructorNode constructor = (ConstructorNode) getChild(ConstructorNode.class);
196     ControllerNode controller = (ControllerNode) getChild(ControllerNode.class);
197     ActionNode[] actions = (ActionNode[]) getChildren(ActionNode.class).toArray(new ActionNode[0]);
198
199     try
200     {
201       _executionContext = new DjScriptExecutionTimeScope(this, container.getPersistenceManager(), _session);
202     }
203     catch (DjenericException e)
204     {
205       throw new DjScriptExecutionException(e, this);
206     }
207     _executionContext.setContainer(container);
208     _executionContext.setController(controller);
209     _executionContext.setActions(actions);
210     _executionContext.getVariableStack().push(EVENT_VARIABLE_NAME, "<none>");
211
212     setGlobalVariables();
213
214     if (executeConstructor && constructor != null) constructor.execute(_executionContext);
215
216     validateScript(_executionContext);
217
218   }
219
220   private void setGlobalVariables()
221   {
222     Iterator JavaDoc it = _externalGlobals.keySet().iterator();
223     while (it.hasNext())
224     {
225       String JavaDoc name = it.next().toString();
226       _executionContext.pushVariable((Variable) _externalGlobals.get(name));
227     }
228   }
229
230   public void validate(ScriptRunnerContainer container) throws DjScriptExecutionException
231   {
232     try
233     {
234       // the following call will also validate the script:
235
initExecutionContext(container, false);
236     }
237     finally
238     {
239       terminate();
240     }
241   }
242
243   public void setSession(DjSession sessionToUse) throws DjScriptExecutionException
244   {
245     if (_executionContext != null) throw new DjScriptExecutionException(Messages
246         .getString("ScriptNode.CanNotSetSession"));
247     _session = sessionToUse;
248   }
249
250   public void execute(ScriptRunnerContainer container) throws DjScriptExecutionException
251   {
252     ActionListNode scriptline = (ActionListNode) getChild(ActionListNode.class);
253
254     initExecutionContext(container, true);
255
256     String JavaDoc firstActionName = scriptline.getFirstActionName();
257
258     if (firstActionName == null) return;
259
260     ActionNode firstAction = _executionContext.getAction(firstActionName, scriptline);
261
262     firstAction.execute(_executionContext);
263   }
264
265   public void terminate()
266   {
267     // If the session was not explicitly set we will handle closing it
268
if (_executionContext != null && _session == null) _executionContext.getSession().close();
269   }
270
271   public void initializeNow(ScriptRunnerContainer container) throws DjScriptExecutionException
272   {
273     initExecutionContext(container, true);
274   }
275
276   public void executeAction(ScriptRunnerContainer container, String JavaDoc actionName) throws DjScriptExecutionException
277   {
278     if (_executionContext == null)
279     {
280       initExecutionContext(container, true);
281     }
282     ActionNode someAction = _executionContext.getAction(actionName, this);
283     someAction.execute(_executionContext);
284   }
285
286   public boolean handleEvent(ScriptRunnerContainer container, String JavaDoc eventName) throws DjScriptExecutionException
287   {
288     boolean modelMightHaveChanged = false;
289     if (_executionContext == null)
290     {
291       initExecutionContext(container, true);
292       modelMightHaveChanged = true;
293     }
294     else setGlobalVariables();
295
296     ControllerNode controller = _executionContext.getController();
297     if (controller == null) throw new DjScriptExecutionException(Messages.getString("ScriptNode.NoController"), this);
298
299     String JavaDoc[] actionNames = controller.getActionsForEvent(eventName);
300
301     Variable event = _executionContext.lookupVariable(EVENT_VARIABLE_NAME);
302     if (event != null) event.assign(eventName, this);
303
304     // if (actionNames.length == 0)
305
// {
306
// throw new ScriptExecutionException("Event " + eventName + " not defined", this);
307
// }
308
for (int i = 0; i < actionNames.length; i++)
309     {
310       ActionNode action = _executionContext.getAction(actionNames[i], this);
311       action.execute(_executionContext);
312       modelMightHaveChanged = true;
313     }
314     return modelMightHaveChanged;
315   }
316 }
Popular Tags