1 18 package org.apache.batik.script.rhino; 19 20 import java.io.IOException ; 21 import java.io.Reader ; 22 import java.io.StringReader ; 23 import java.io.Writer ; 24 import java.lang.reflect.Method ; 25 import java.net.URL ; 26 import java.security.AccessControlContext ; 27 import java.security.AccessController ; 28 import java.security.PrivilegedAction ; 29 import java.util.Iterator ; 30 import java.util.LinkedList ; 31 import java.util.Locale ; 32 import java.util.Map ; 33 import java.util.HashMap ; 34 35 import org.apache.batik.bridge.InterruptedBridgeException; 36 import org.apache.batik.script.Interpreter; 37 import org.apache.batik.script.InterpreterException; 38 import org.apache.batik.script.Window; 39 import org.mozilla.javascript.Context; 40 import org.mozilla.javascript.Function; 41 import org.mozilla.javascript.JavaScriptException; 42 import org.mozilla.javascript.NativeJavaPackage; 43 import org.mozilla.javascript.PropertyException; 44 import org.mozilla.javascript.Script; 45 import org.mozilla.javascript.Scriptable; 46 import org.mozilla.javascript.ScriptableObject; 47 import org.mozilla.javascript.SecurityController; 48 import org.mozilla.javascript.WrapFactory; 49 import org.mozilla.javascript.WrappedException; 50 import org.w3c.dom.events.EventTarget ; 51 52 58 public class RhinoInterpreter implements Interpreter { 59 private static String [] TO_BE_IMPORTED = { 60 "java.lang", 61 "org.w3c.dom", 62 "org.w3c.dom.css", 63 "org.w3c.dom.events", 64 "org.w3c.dom.smil", 65 "org.w3c.dom.stylesheets", 66 "org.w3c.dom.svg", 67 "org.w3c.dom.views" 68 }; 69 70 73 protected Window window; 74 75 public Window getWindow() { 76 return window; 77 } 78 79 80 private static class Entry { 81 String str; 82 Script script; 83 Entry(String str, Script script) { 84 this.str = str; 85 this.script = script; 86 } 87 } 88 89 92 private static final int MAX_CACHED_SCRIPTS = 32; 93 94 97 public static final String SOURCE_NAME_SVG = "<SVG>"; 98 99 102 public static final String BIND_NAME_WINDOW = "window"; 103 104 private ScriptableObject globalObject = null; 105 private LinkedList compiledScripts = new LinkedList (); 106 private WrapFactory wrapFactory = 107 new BatikWrapFactory(this); 108 109 114 protected RhinoClassLoader rhinoClassLoader; 115 116 121 private SecurityController securityController 122 = new BatikSecurityController(); 123 124 132 public RhinoInterpreter(URL documentURL) { 133 try { 134 rhinoClassLoader = new RhinoClassLoader 135 (documentURL, getClass().getClassLoader()); 136 } catch (SecurityException se) { 137 rhinoClassLoader = null; 138 } 139 Context ctx = enterContext(); 141 try { 142 try { 143 Scriptable scriptable = ctx.initStandardObjects(null, false); 144 ScriptableObject.defineClass(scriptable, WindowWrapper.class); 145 } catch (Exception e) { 146 } 148 WindowWrapper wWrapper = new WindowWrapper(ctx); 154 globalObject = wWrapper; 155 NativeJavaPackage[] p= new NativeJavaPackage[TO_BE_IMPORTED.length]; 157 for (int i = 0; i < TO_BE_IMPORTED.length; i++) { 158 p[i] = new NativeJavaPackage(TO_BE_IMPORTED[i], rhinoClassLoader); 159 } try { 160 ScriptableObject.callMethod(globalObject, "importPackage", p); 161 } catch (JavaScriptException e) { 162 } 165 } finally { 166 Context.exit(); 167 } 168 } 169 170 174 public AccessControlContext getAccessControlContext(){ 175 return rhinoClassLoader.getAccessControlContext(); 176 } 177 178 182 public Context enterContext(){ 183 Context ctx = Context.getCurrentContext(); 184 if (ctx == null) { 185 ctx = new ExtendedContext(); 186 ctx.setWrapFactory(wrapFactory); 187 ctx.setSecurityController(securityController); 188 ctx.setClassShutter(new RhinoClassShutter()); 189 190 if (rhinoClassLoader == null) { 192 ctx.setOptimizationLevel(-1); 193 ctx.setCachingEnabled(false); 194 } 195 } 196 ctx = Context.enter(ctx); 197 198 return ctx; 199 } 200 201 205 protected ScriptableObject getGlobalObject() { 206 return globalObject; 207 } 208 209 211 217 public Object evaluate(Reader scriptreader) 218 throws InterpreterException, IOException { 219 return evaluate(scriptreader, SOURCE_NAME_SVG); 220 } 221 222 230 public Object evaluate(Reader scriptreader, String description) 231 throws InterpreterException, IOException { 232 233 Object rv = null; 234 final Context ctx = enterContext(); 235 try { 236 rv = ctx.evaluateReader(globalObject, 237 scriptreader, 238 description, 239 1, rhinoClassLoader); 240 } catch (JavaScriptException e) { 241 if (e.getValue() instanceof Exception ) { 243 Exception ex = (Exception )e.getValue(); 244 throw new InterpreterException(ex, ex.getMessage(), -1, -1); 245 } else 246 throw new InterpreterException(e, e.getMessage(), -1, -1); 247 } catch (WrappedException we) { 248 Throwable w = we.getWrappedException(); 250 if (w instanceof Exception ) 251 throw 252 new InterpreterException((Exception )we.getWrappedException(), 253 we.getWrappedException().getMessage(), 254 -1, -1); 255 else 256 throw new InterpreterException(we.getWrappedException().getMessage(), -1, -1); 257 } catch (InterruptedBridgeException ibe) { 258 throw ibe; 260 } catch (RuntimeException re) { 261 throw new InterpreterException(re, re.getMessage(), -1, -1); 263 } finally { 264 Context.exit(); 265 } 266 return rv; 267 } 268 269 278 public Object evaluate(final String scriptstr) 279 throws InterpreterException { 280 Object rv = null; 281 final Context ctx = enterContext(); 282 try { 283 Script script = null; 284 Entry et = null; 285 Iterator it = compiledScripts.iterator(); 286 while (it.hasNext()) { 289 if ((et = (Entry)(it.next())).str.equals(scriptstr)) { 290 script = et.script; 294 it.remove(); 295 break; 296 } 297 } 298 299 if (script == null) { 300 304 script = (Script)AccessController.doPrivileged 305 (new PrivilegedAction () { 306 public Object run() { 307 try { 308 return ctx.compileReader 309 (globalObject, 310 new StringReader (scriptstr), 311 SOURCE_NAME_SVG, 312 1, rhinoClassLoader); 313 } catch (IOException io) { 314 throw new Error (); 316 } 317 } 318 }); 319 320 if (compiledScripts.size()+1 > MAX_CACHED_SCRIPTS) { 321 compiledScripts.removeFirst(); 325 } 326 compiledScripts.addLast(new Entry(scriptstr, script)); 328 } else { 329 compiledScripts.addLast(et); 332 } 333 334 try { 335 rv = script.exec(ctx, globalObject); 336 } catch (JavaScriptException e) { 337 if (e.getValue() instanceof Exception ) { 339 Exception ex = (Exception )e.getValue(); 340 throw new InterpreterException(ex, ex.getMessage(), -1,-1); 341 } else 342 throw new InterpreterException(e, e.getMessage(), -1, -1); 343 } catch (WrappedException we) { 344 throw 346 new InterpreterException 347 ((Exception )we.getWrappedException(), 348 we.getWrappedException().getMessage(), -1, -1); 349 } catch (RuntimeException re) { 350 throw new InterpreterException(re, re.getMessage(), -1, -1); 352 } 353 354 } finally { 355 Context.exit(); 356 } 357 return rv; 358 } 359 360 364 public void dispose() { 365 if (rhinoClassLoader != null) { 366 Context.setCachingEnabled(false); 367 Context.setCachingEnabled(true); 368 } 369 } 370 371 377 public void bindObject(String name, Object object) { 378 enterContext(); 379 try { 380 if (name.equals(BIND_NAME_WINDOW) && object instanceof Window) { 381 window = (Window)object; 382 object = globalObject; 383 } 384 try { 385 Scriptable jsObject; 386 jsObject = Context.toObject(object, globalObject); 387 objects.put(name, jsObject); 388 if (ScriptableObject.getProperty(globalObject, name) == 389 ScriptableObject.NOT_FOUND) 390 globalObject.defineProperty 391 (name, new RhinoGetDelegate(name), 392 rhinoGetter, null, ScriptableObject.READONLY); 393 } catch (PropertyException pe) { 394 pe.printStackTrace(); 395 } 396 } finally { 397 Context.exit(); 398 } 399 } 400 404 Map objects = new HashMap (4); 405 406 413 public static class RhinoGetDelegate { 414 String name; 415 RhinoGetDelegate(String name) { 416 this.name = name; 417 } 418 public Object get(ScriptableObject so) { 419 Context ctx = Context.getCurrentContext(); 420 if (ctx == null ) return null; 421 return ((ExtendedContext)ctx).getInterpreter().objects.get(name); 422 } 423 } 424 static Method rhinoGetter; 427 static { 428 try { 429 Class [] getterArgs = { ScriptableObject.class }; 430 rhinoGetter = RhinoGetDelegate.class.getDeclaredMethod 431 ("get", getterArgs); 432 } catch (NoSuchMethodException nsm) { } 433 } 434 435 436 439 void callHandler(Function handler, 440 Object arg) 441 throws JavaScriptException { 442 Context ctx = enterContext(); 443 try { 444 arg = Context.toObject(arg, globalObject); 445 Object [] args = {arg}; 446 handler.call(ctx, globalObject, globalObject, args); 447 } finally { 448 Context.exit(); 449 } 450 } 451 452 455 void callMethod(ScriptableObject obj, 456 String methodName, 457 ArgumentsBuilder ab) 458 throws JavaScriptException { 459 enterContext(); 460 try { 461 ScriptableObject.callMethod(obj, methodName, ab.buildArguments()); 462 } finally { 463 Context.exit(); 464 } 465 } 466 467 470 void callHandler(Function handler, 471 Object [] args) 472 throws JavaScriptException { 473 Context ctx = enterContext(); 474 try { 475 handler.call(ctx, globalObject, globalObject, args); 476 } finally { 477 Context.exit(); 478 } 479 } 480 481 484 void callHandler(Function handler, ArgumentsBuilder ab) 485 throws JavaScriptException { 486 Context ctx = enterContext(); 487 try { 488 Object [] args = ab.buildArguments(); 489 handler.call(ctx, handler.getParentScope(), globalObject, args ); 490 } finally { 491 Context.exit(); 492 } 493 } 494 495 498 public interface ArgumentsBuilder { 499 Object [] buildArguments(); 500 } 501 502 505 Scriptable buildEventTargetWrapper(EventTarget obj) { 506 return new EventTargetWrapper(globalObject, obj); 507 } 508 509 514 public void setOut(Writer out) { 515 } 517 518 520 524 public Locale getLocale() { 525 return null; 527 } 528 529 535 public void setLocale(Locale locale) { 536 } 538 539 549 public String formatMessage(String key, Object [] args) { 550 return null; 551 } 552 553 public class ExtendedContext extends Context { 554 public ExtendedContext() { 555 super(); 556 } 557 558 public RhinoInterpreter getInterpreter() { 559 return RhinoInterpreter.this; 560 } 561 562 public Window getWindow() { 563 return RhinoInterpreter.this.getWindow(); 564 } 565 566 public ScriptableObject getGlobalObject() { 567 return RhinoInterpreter.this.getGlobalObject(); 568 } 569 } 570 } 571 | Popular Tags |