1 /**
2 * This is a simple mechanism to bind Inkscape to Java, and thence
3 * to all of the nice things that can be layered upon that.
4 *
5 * Authors:
6 * Bob Jamison
7 *
8 * Copyright (C) 2007-2008 Bob Jamison
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 3 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
25 package org.inkscape.cmn;
27 import javax.script.*;
28 import java.util.List;
29 import java.io.FileReader;
30 import java.io.PrintStream;
31 import java.io.OutputStream;
32 import java.io.IOException;
33 import javax.swing.JOptionPane;
36 /**
37 * Runs scripts
38 */
39 public class ScriptRunner
40 {
41 /**
42 * Pointer back to the BinderyImpl C++ object that launched me
43 */
44 long backPtr;
46 /**
47 * The script engine manager that we want to use
48 */
49 ScriptEngineManager scriptEngineManager;
52 //########################################################################
53 //# MESSSAGES
54 //########################################################################
55 static void err(String message)
56 {
57 System.err.println("ScriptRunner err:" + message);
58 }
60 static void msg(String message)
61 {
62 System.out.println("ScriptRunner:" + message);
63 }
65 static void trace(String message)
66 {
67 log.println("ScriptRunner:" + message);
68 }
72 //########################################################################
73 //# REDIRECT STDERR / STDOUT
74 //########################################################################
75 /**
76 * Redirect stdout
77 */
78 public native void stdOutWrite(long ptr, int b);
79 class StdOutStream extends OutputStream
80 {
82 public void write(int b)
83 {
84 stdOutWrite(backPtr, b);
85 }
87 }
90 /**
91 * Redirect stderr
92 */
93 public native void stdErrWrite(long ptr, int b);
94 class StdErrStream extends OutputStream
95 {
97 public void write(int b)
98 {
99 stdErrWrite(backPtr, b);
100 }
103 }
105 /**
106 * A logging stream
107 */
108 static PrintStream log;
109 public native void logWrite(long ptr, int b);
110 class LogStream extends OutputStream
111 {
113 public void write(int b)
114 {
115 logWrite(backPtr, b);
116 }
119 }
122 //########################################################################
123 //# RUN
124 //########################################################################
127 /**
128 * Run a script buffer
129 *
130 * @param lang the scripting language to run
131 * @param str the script buffer to execute
132 * @return true if successful, else false
133 */
134 public boolean doRun(String lang, String str)
135 {
136 // create JavaScript engine
137 ScriptEngine engine = scriptEngineManager.getEngineByName(lang);
138 if (engine == null)
139 {
140 err("doRun: cannot find script engine '" + lang + "'");
141 return false;
142 }
143 //execute script from buffer
144 try
145 {
146 engine.eval(str);
147 }
148 catch (javax.script.ScriptException e)
149 {
150 err("Executing script: " + e);
151 e.printStackTrace();
152 }
153 return true;
154 }
156 /**
157 * Run a script buffer
158 *
159 * @param backPtr pointer back to the C context that called this
160 * @param lang the scripting language to run
161 * @param str the script buffer to execute
162 * @return true if successful, else false
163 */
164 public static boolean run(String lang, String str)
165 {
166 //wrap whole thing in try/catch, since this will
167 //likely be called from C
168 try
169 {
170 ScriptRunner runner = getInstance();
171 if (runner == null)
172 {
173 err("ScriptRunner not initialized");
174 return false;
175 }
176 return runner.doRun(lang, str);
177 }
178 catch (Exception e)
179 {
180 err("run :" + e);
181 e.printStackTrace();
182 return false;
183 }
184 }
187 /**
188 * Run a script file
189 *
190 * @param lang the scripting language to run
191 * @param fname the script file to execute
192 * @return true if successful, else false
193 */
194 public boolean doRunFile(String lang, String fname)
195 {
196 // create JavaScript engine
197 ScriptEngine engine = scriptEngineManager.getEngineByName(lang);
198 if (engine == null)
199 {
200 err("doRunFile: cannot find script engine '" + lang + "'");
201 return false;
202 }
203 //try opening file and feeding into engine
204 FileReader in = null;
205 boolean ret = true;
206 try
207 {
208 in = new FileReader(fname);
209 }
210 catch (java.io.IOException e)
211 {
212 err("Executing file: " + e);
213 return false;
214 }
215 try
216 {
217 engine.eval(in);
218 }
219 catch (javax.script.ScriptException e)
220 {
221 err("Executing file: " + e);
222 ret = false;
223 }
224 try
225 {
226 in.close();
227 }
228 catch (java.io.IOException e)
229 {
230 err("Executing file: " + e);
231 return false;
232 }
233 return ret;
234 }
237 /**
238 * Run a script file
239 *
240 * @param backPtr pointer back to the C context that called this
241 * @param lang the scripting language to run
242 * @param fname the script file to execute
243 * @return true if successful, else false
244 */
245 public static boolean runFile(String lang, String fname)
246 {
247 //wrap whole thing in try/catch, since this will
248 //likely be called from C
249 try
250 {
251 ScriptRunner runner = getInstance();
252 if (runner == null)
253 {
254 err("ScriptRunner not initialized");
255 return false;
256 }
257 return runner.doRunFile(lang, fname);
258 }
259 catch (Exception e)
260 {
261 err("run :" + e);
262 return false;
263 }
264 }
268 //########################################################################
269 //# CONSTRUCTOR
270 //########################################################################
274 private static ScriptRunner _instance = null;
275 public static ScriptRunner getInstance()
276 {
277 return _instance;
278 }
280 private void listFactories()
281 {
282 List<ScriptEngineFactory> factories =
283 scriptEngineManager.getEngineFactories();
284 for (ScriptEngineFactory factory: factories)
285 {
286 log.println("ScriptEngineFactory Info");
287 String engName = factory.getEngineName();
288 String engVersion = factory.getEngineVersion();
289 String langName = factory.getLanguageName();
290 String langVersion = factory.getLanguageVersion();
291 log.printf("\tScript Engine: %s (%s)\n",
292 engName, engVersion);
293 List<String> engNames = factory.getNames();
294 for(String name: engNames)
295 {
296 log.printf("\tEngine Alias: %s\n", name);
297 }
298 log.printf("\tLanguage: %s (%s)\n",
299 langName, langVersion);
300 }
301 }
305 /**
306 * Constructor
307 * @param backPtr pointer back to the C context that called this
308 */
309 public ScriptRunner(long backPtr)
310 {
311 /**
312 * Set up the output, error, and logging stream
313 */
314 System.setOut(new PrintStream(new StdOutStream()));
315 System.setErr(new PrintStream(new StdErrStream()));
316 log = new PrintStream(new LogStream());
318 //Point back to C++ object
319 this.backPtr = backPtr;
321 //Start up the factory
322 scriptEngineManager = new ScriptEngineManager();
323 listFactories();
324 _instance = this;
325 }
328 static
329 {
331 }
333 }
334 //########################################################################
335 //# E N D O F F I L E
336 //########################################################################