1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.scripting.component;
12
13 import org.mule.MuleServer;
14 import org.mule.DefaultMuleEventContext;
15 import org.mule.transport.NullPayload;
16 import org.mule.api.MuleEvent;
17 import org.mule.api.lifecycle.Initialisable;
18 import org.mule.api.lifecycle.InitialisationException;
19 import org.mule.api.transformer.TransformerException;
20 import org.mule.api.transport.MessageAdapter;
21 import org.mule.config.i18n.CoreMessages;
22 import org.mule.config.i18n.MessageFactory;
23 import org.mule.util.CollectionUtils;
24 import org.mule.util.IOUtils;
25 import org.mule.util.StringUtils;
26
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.InputStreamReader;
30 import java.io.Reader;
31 import java.io.StringReader;
32 import java.util.Iterator;
33 import java.util.Map;
34 import java.util.Properties;
35
36 import javax.script.Bindings;
37 import javax.script.Compilable;
38 import javax.script.CompiledScript;
39 import javax.script.ScriptEngine;
40 import javax.script.ScriptEngineManager;
41 import javax.script.ScriptException;
42
43 import org.apache.commons.logging.Log;
44 import org.apache.commons.logging.LogFactory;
45
46
47
48
49
50 public class Scriptable implements Initialisable
51 {
52
53 private String scriptText;
54
55
56 private String scriptFile;
57
58
59 private Properties properties;
60
61
62 private String scriptEngineName;
63
64
65
66
67
68
69 private CompiledScript compiledScript;
70
71 private ScriptEngine scriptEngine;
72 private ScriptEngineManager scriptEngineManager;
73
74 protected transient Log logger = LogFactory.getLog(getClass());
75
76 public void initialise() throws InitialisationException
77 {
78 scriptEngineManager = new ScriptEngineManager();
79
80
81 if (scriptEngineName != null)
82 {
83 scriptEngine = createScriptEngineByName(scriptEngineName);
84 if (scriptEngine == null)
85 {
86 throw new InitialisationException(MessageFactory.createStaticMessage("Scripting engine '" + scriptEngineName + "' not found. Available engines are: " + listAvailableEngines()), this);
87 }
88 }
89
90 else if (scriptFile != null)
91 {
92 int i = scriptFile.lastIndexOf(".");
93 if (i > -1)
94 {
95 logger.info("Script Engine name not set. Guessing by file extension.");
96 String ext = scriptFile.substring(i + 1);
97 scriptEngine = createScriptEngineByExtension(ext);
98 if (scriptEngine == null)
99 {
100 throw new InitialisationException(MessageFactory.createStaticMessage("File extension '" + ext + "' does not map to a scripting engine. Available engines are: " + listAvailableEngines()), this);
101 }
102 else
103 {
104 setScriptEngineName(scriptEngine.getFactory().getEngineName());
105 }
106 }
107 }
108
109 Reader script;
110
111 if (StringUtils.isNotBlank(scriptText))
112 {
113 script = new StringReader(scriptText);
114 }
115
116 else if (scriptFile != null)
117 {
118 InputStream is;
119 try
120 {
121 is = IOUtils.getResourceAsStream(scriptFile, getClass());
122 }
123 catch (IOException e)
124 {
125 throw new InitialisationException(CoreMessages.cannotLoadFromClasspath(scriptFile), e, this);
126 }
127 if (is == null)
128 {
129 throw new InitialisationException(CoreMessages.cannotLoadFromClasspath(scriptFile), this);
130 }
131 script = new InputStreamReader(is);
132 }
133 else
134 {
135 throw new InitialisationException(CoreMessages.propertiesNotSet("scriptText, scriptFile"), this);
136 }
137
138
139 if (scriptEngine instanceof Compilable)
140 {
141 try
142 {
143 compiledScript = ((Compilable) scriptEngine).compile(script);
144 }
145 catch (ScriptException e)
146 {
147 throw new InitialisationException(e, this);
148 }
149 }
150
151
152 }
153
154 public void populateDefaultBindings(Bindings bindings)
155 {
156 if (properties != null)
157 {
158 bindings.putAll((Map) properties);
159 }
160 bindings.put("log", logger);
161
162
163 bindings.put("result", NullPayload.getInstance());
164 bindings.put("muleContext", MuleServer.getMuleContext());
165 }
166
167 public void populateBindings(Bindings bindings, Object payload)
168 {
169 populateDefaultBindings(bindings);
170 bindings.put("payload", payload);
171
172
173 bindings.put("src", payload);
174 }
175
176 public void populateBindings(Bindings bindings, MessageAdapter message)
177 {
178 populateDefaultBindings(bindings);
179 bindings.put("message", message);
180
181
182 bindings.put("payload", message.getPayload());
183
184 bindings.put("src", message.getPayload());
185
186
187 String propertyName;
188 for (Iterator iterator = message.getPropertyNames().iterator(); iterator.hasNext();)
189 {
190 propertyName = (String)iterator.next();
191 bindings.put(propertyName, message.getProperty(propertyName));
192 }
193 }
194
195 public void populateBindings(Bindings bindings, MuleEvent event)
196 {
197 populateBindings(bindings, event.getMessage());
198 bindings.put("originalPayload", event.getMessage().getPayload());
199
200 try
201 {
202 bindings.put("payload", event.transformMessage());
203 }
204 catch (TransformerException e)
205 {
206 logger.warn(e);
207 }
208
209 bindings.put("eventContext", new DefaultMuleEventContext(event));
210 bindings.put("id", event.getId());
211 bindings.put("service", event.getService());
212 }
213
214 public Object runScript(Bindings bindings) throws ScriptException
215 {
216 Object result;
217 if (compiledScript != null)
218 {
219 result = compiledScript.eval(bindings);
220 }
221 else
222 {
223 result = scriptEngine.eval(scriptText, bindings);
224 }
225
226
227
228 if (result == null)
229 {
230 result = bindings.get("result");
231 }
232 return result;
233 }
234
235 protected ScriptEngine createScriptEngineByName(String name)
236 {
237 return scriptEngineManager.getEngineByName(name);
238 }
239
240 protected ScriptEngine createScriptEngineByExtension(String ext)
241 {
242 return scriptEngineManager.getEngineByExtension(ext);
243 }
244
245 protected String listAvailableEngines()
246 {
247 return CollectionUtils.toString(scriptEngineManager.getEngineFactories(), false);
248 }
249
250
251
252
253
254 public String getScriptText()
255 {
256 return scriptText;
257 }
258
259 public void setScriptText(String scriptText)
260 {
261 this.scriptText = scriptText;
262 }
263
264 public String getScriptFile()
265 {
266 return scriptFile;
267 }
268
269 public void setScriptFile(String scriptFile)
270 {
271 this.scriptFile = scriptFile;
272 }
273
274 public void setScriptEngineName(String scriptEngineName)
275 {
276 this.scriptEngineName = scriptEngineName;
277 }
278
279 public String getScriptEngineName()
280 {
281 return scriptEngineName;
282 }
283
284 public Properties getProperties()
285 {
286 return properties;
287 }
288
289 public void setProperties(Properties properties)
290 {
291 this.properties = properties;
292 }
293
294 public ScriptEngine getScriptEngine()
295 {
296 return scriptEngine;
297 }
298
299 protected void setScriptEngine(ScriptEngine scriptEngine)
300 {
301 this.scriptEngine = scriptEngine;
302 }
303
304 protected CompiledScript getCompiledScript()
305 {
306 return compiledScript;
307 }
308
309 protected void setCompiledScript(CompiledScript compiledScript)
310 {
311 this.compiledScript = compiledScript;
312 }
313 }