|
30 | 30 |
|
31 | 31 | package org.scijava.plugins.scripting.scala; |
32 | 32 |
|
33 | | -import java.io.BufferedReader; |
34 | | -import java.io.PrintWriter; |
35 | | -import java.io.Reader; |
36 | | -import java.io.StringWriter; |
37 | | -import java.io.Writer; |
38 | | -import java.util.Map.Entry; |
| 33 | +import javax.script.ScriptEngine; |
39 | 34 |
|
40 | | -import javax.script.ScriptContext; |
41 | | -import javax.script.ScriptException; |
| 35 | +import org.scijava.script.AdaptedScriptEngine; |
42 | 36 |
|
43 | | -import org.scijava.script.AbstractScriptEngine; |
44 | | - |
45 | | -import scala.collection.immutable.List; |
46 | | -import scala.tools.nsc.Settings; |
47 | 37 | import scala.tools.nsc.interpreter.IMain; |
| 38 | +import scala.tools.nsc.settings.MutableSettings.BooleanSetting; |
48 | 39 |
|
49 | 40 | /** |
50 | | - * A Scala interpreter for ImageJ. |
51 | | - * |
52 | | - * @author Johannes Schindelin |
| 41 | + * An adapter of the Scala script engine. |
| 42 | + * |
| 43 | + * @author Curtis Rueden |
53 | 44 | */ |
54 | | -public class ScalaScriptEngine extends AbstractScriptEngine { |
| 45 | +public class ScalaScriptEngine extends AdaptedScriptEngine { |
55 | 46 |
|
56 | | - { |
57 | | - engineScopeBindings = new ScalaBindings(); |
58 | | - } |
| 47 | + private final IMain engine; |
59 | 48 |
|
60 | | - @Override |
61 | | - public Object eval(final String script) throws ScriptException { |
62 | | - try { |
63 | | - return interpreter().interpret(script); |
64 | | - } |
65 | | - catch (final Exception e) { |
66 | | - throw new ScriptException(e); |
| 49 | + public ScalaScriptEngine(final ScriptEngine engine) { |
| 50 | + super(engine); |
| 51 | + |
| 52 | + if (!(engine instanceof IMain)) { |
| 53 | + throw new IllegalArgumentException(// |
| 54 | + "Not a Scala script engine: " + engine.getClass().getName()); |
67 | 55 | } |
| 56 | + this.engine = (IMain) engine; |
| 57 | + |
| 58 | + enableClassPath(); |
68 | 59 | } |
69 | 60 |
|
| 61 | + // -- ScriptEngine methods -- |
| 62 | + |
70 | 63 | @Override |
71 | | - public Object eval(final Reader reader) throws ScriptException { |
72 | | - try { |
73 | | - final BufferedReader bufferedReader = new BufferedReader(reader); |
74 | | - final StringWriter writer = new StringWriter(); |
75 | | - for (;;) { |
76 | | - final String line = bufferedReader.readLine(); |
77 | | - if (line == null) break; |
78 | | - writer.write(line); |
79 | | - writer.write("\n"); |
80 | | - } |
81 | | - return interpreter().interpret(writer.toString()); |
82 | | - } |
83 | | - catch (final Exception e) { |
84 | | - throw new ScriptException(e); |
85 | | - } |
| 64 | + public void put(final String key, final Object value) { |
| 65 | + // NB: Add a suffix to the key indicating its type. |
| 66 | + // This is necessary in order to properly populate the variable. |
| 67 | + // |
| 68 | + // Thanks to takawitter for this invocation: |
| 69 | + // https://gist.github.com/takawitter/5479445 |
| 70 | + |
| 71 | + engine.put(key + ": " + value.getClass().getName(), value); |
86 | 72 | } |
87 | 73 |
|
88 | | - private IMain interpreter() { |
89 | | - final ScriptContext context = getContext(); |
90 | | - final Writer writer = context.getWriter(); |
| 74 | + // -- Helper methods -- |
91 | 75 |
|
92 | | - final Settings settings = new Settings(); |
93 | | - settings.usejavacp().tryToSet(List.make(1, "true")); |
94 | | - final PrintWriter out = writer == null ? null : |
95 | | - (writer instanceof PrintWriter ? (PrintWriter)writer : new PrintWriter(writer)); |
96 | | - final IMain interpreter = out == null ? new IMain(settings) : new IMain(settings, out); |
| 76 | + private void enableClassPath() { |
| 77 | + // NB: Enable class-path-based processing. |
| 78 | + // |
| 79 | + // Without this, the engine fails with the following error: |
| 80 | + // |
| 81 | + // [init] error: error while loading Object, Missing dependency |
| 82 | + // 'object scala in compiler mirror', required by |
| 83 | + // .../lib/rt.jar(java/lang/Object.class) |
| 84 | + // |
| 85 | + // Failed to initialize compiler: object scala in compiler mirror not found. |
| 86 | + // ** Note that as of 2.8 scala does not assume use of the java classpath. |
| 87 | + // ** For the old behavior pass -usejavacp to scala, or if using a Settings |
| 88 | + // ** object programmatically, settings.usejavacp.value = true. |
| 89 | + // |
| 90 | + // Thanks to takawitter for this invocation: |
| 91 | + // https://gist.github.com/takawitter/5479445 |
97 | 92 |
|
98 | | - for (final Entry<String, Object> entry : engineScopeBindings.entrySet()) { |
99 | | - final String name = entry.getKey(); |
100 | | - final Object value = entry.getValue(); |
101 | | - interpreter.bind(name, value.getClass().getCanonicalName(), value, List.make(0, "")); |
102 | | - } |
103 | | - |
104 | | - return interpreter; |
| 93 | + final BooleanSetting usejavacp = // |
| 94 | + (BooleanSetting) engine.settings().usejavacp(); |
| 95 | + usejavacp.value_$eq(true); |
105 | 96 | } |
| 97 | + |
106 | 98 | } |
0 commit comments