1 30 package com.genimen.djeneric.tools.scriptengine.core.nodes; 31 32 import java.util.ArrayList ; 33 import java.util.HashMap ; 34 import java.util.Iterator ; 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 EVENT_VARIABLE_NAME = "$event"; 51 private String _scriptName = null; 52 private String _title = null; 53 DjScriptExecutionTimeScope _executionContext = null; 54 DjSession _session = null; 55 private HashMap _externalGlobals = new HashMap (); 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 name, Object value) 68 { 69 _externalGlobals.put(name, new Variable(name, value)); 70 } 71 72 public void setExternalGlobal(String name, Object value, String typeName) 73 { 74 _externalGlobals.put(name, new Variable(name, value, typeName)); 75 } 76 77 public void setParameter(String name, Object 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 name, Object value, String 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 getNodeTitle() 92 { 93 return getScriptName(); 94 } 95 96 public String getScriptName() 97 { 98 return _scriptName; 99 } 100 101 public void setScriptName(String scriptName) 102 { 103 _scriptName = scriptName; 104 } 105 106 public String getName() 107 { 108 return "script"; 109 } 110 111 public String toString() 112 { 113 return "script name = " + _scriptName + ", title = " + _title; 114 } 115 116 public String getTitle() 117 { 118 if (_title == null) return _scriptName; 119 return _title; 120 } 121 122 public void setTitle(String string) 123 { 124 _title = string.substring(1, string.length() - 1); 125 } 126 127 protected boolean isBuiltInEvent(String 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 eventsDefsByEventName = new HashMap (); 136 137 ArrayList eventMappings = new ArrayList (); 138 collectNodes(EventMappingNode.class, eventMappings); 139 140 ArrayList eventDefinitions = new ArrayList (); 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 [] 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 actions = map.getActions(); 160 for (int a = 0; a < actions.size(); a++) 161 { 162 String actionName = actions.get(a).toString(); 163 164 165 ctxt.getAction(actionName, map); 166 167 168 String eventName = map.getPath(); 169 170 if (eventName.indexOf('*') == -1 && !isBuiltInEvent(eventName)) 171 { 172 if (eventsDefsByEventName.get(eventName) == null) 173 { 174 } 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 it = _externalGlobals.keySet().iterator(); 223 while (it.hasNext()) 224 { 225 String 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 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 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 (_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 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 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 [] actionNames = controller.getActionsForEvent(eventName); 300 301 Variable event = _executionContext.lookupVariable(EVENT_VARIABLE_NAME); 302 if (event != null) event.assign(eventName, this); 303 304 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 |