Skip to content
This repository was archived by the owner on Feb 4, 2022. It is now read-only.

Commit fe851f5

Browse files
committed
Make the kernel polyglot and sinc bindings between engine.
1 parent dee8a6b commit fe851f5

2 files changed

Lines changed: 85 additions & 28 deletions

File tree

src/main/java/org/scijava/jupyter/kernel/evaluator/ScijavaEvaluator.java

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import java.util.HashMap;
2626
import java.util.List;
2727
import java.util.Map;
28+
import javax.script.Bindings;
29+
import javax.script.ScriptContext;
2830
import javax.script.ScriptEngine;
2931

3032
import org.scijava.Context;
@@ -40,6 +42,8 @@
4042
*/
4143
public class ScijavaEvaluator implements Evaluator {
4244

45+
private static final String DEFAULT_LANGUAGE = "groovy";
46+
4347
@Parameter
4448
private LogService log;
4549

@@ -52,8 +56,9 @@ public class ScijavaEvaluator implements Evaluator {
5256
@Parameter
5357
Context context;
5458

55-
private Map<String, ScriptEngine> scriptEngines;
56-
private Map<String, ScriptLanguage> scriptLanguages;
59+
private final Map<String, ScriptEngine> scriptEngines;
60+
private final Map<String, ScriptLanguage> scriptLanguages;
61+
private String languageName;
5762

5863
protected String shellId;
5964
protected String sessionId;
@@ -66,6 +71,8 @@ public ScijavaEvaluator(Context context, String shellId, String sessionId, Strin
6671

6772
this.scriptEngines = new HashMap<>();
6873
this.scriptLanguages = new HashMap<>();
74+
75+
this.languageName = DEFAULT_LANGUAGE;
6976
}
7077

7178
@Override
@@ -97,14 +104,10 @@ public void startWorker() {
97104
@Override
98105
public void evaluate(SimpleEvaluationObject seo, String code) {
99106

100-
String languageName = "groovy";
101-
this.addLanguage(languageName);
107+
code = this.setLanguage(code);
102108

103-
Worker worker = new Worker(this.context,
104-
this.scriptEngines.get(languageName),
105-
this.scriptLanguages.get(languageName));
106-
107-
worker.setup(seo, code);
109+
Worker worker = new Worker(this.context, this.scriptEngines, this.scriptLanguages);
110+
worker.setup(seo, code, this.languageName);
108111
this.threadService.queue(worker);
109112
}
110113

@@ -123,14 +126,50 @@ private void addLanguage(String languageName) {
123126
}
124127

125128
if (!this.scriptLanguages.keySet().contains(languageName)) {
126-
this.scriptLanguages.put(languageName, scriptService.getLanguageByName(languageName));
127-
}
128-
129-
if (!this.scriptEngines.keySet().contains(languageName)) {
130-
this.scriptEngines.put(languageName, this.scriptLanguages.get(languageName).getScriptEngine());
129+
130+
Bindings bindings = null;
131+
if (!this.scriptEngines.isEmpty()) {
132+
String firstLanguage = this.scriptEngines.keySet().iterator().next();
133+
bindings = this.scriptEngines.get(firstLanguage).getBindings(ScriptContext.ENGINE_SCOPE);
134+
}
135+
136+
log.info("Script Language for '" + languageName + "' found.");
137+
ScriptLanguage scriptLanguage = scriptService.getLanguageByName(languageName);
138+
this.scriptLanguages.put(languageName, scriptLanguage);
139+
140+
ScriptEngine engine = this.scriptLanguages.get(languageName).getScriptEngine();
141+
this.scriptEngines.put(languageName, engine);
142+
143+
// Not implemented yet
144+
//engine.setBindings(this.bindings, ScriptContext.ENGINE_SCOPE);
145+
if (bindings != null) {
146+
this.initBindings(bindings, engine, scriptLanguage);
147+
}
148+
131149
}
132150

133151
log.debug("Script Language found for '" + languageName + "'");
134152
}
135153

154+
private String setLanguage(String code) {
155+
if (code.startsWith("#!")) {
156+
this.languageName = code.substring(2, code.indexOf(System.getProperty("line.separator"))).trim();
157+
158+
// Return the code string without the first line
159+
code = code.substring(code.indexOf(System.getProperty("line.separator")) + 1);
160+
}
161+
162+
this.addLanguage(this.languageName);
163+
return code;
164+
}
165+
166+
private void initBindings(Bindings bindings, ScriptEngine scriptEngine, ScriptLanguage scriptLanguage) {
167+
168+
Bindings currentBindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
169+
bindings.keySet().forEach((String key) -> {
170+
currentBindings.put(key, scriptLanguage.decode(bindings.get(key)));
171+
});
172+
173+
}
174+
136175
}

src/main/java/org/scijava/jupyter/kernel/evaluator/Worker.java

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
import java.io.StringReader;
2121
import java.lang.reflect.InvocationTargetException;
2222
import java.util.List;
23+
import java.util.Map;
24+
import javax.script.Bindings;
25+
import javax.script.ScriptContext;
2326
import javax.script.ScriptEngine;
2427
import org.scijava.Context;
2528
import org.scijava.convert.ConvertService;
@@ -56,51 +59,55 @@ public class Worker implements Runnable {
5659
@Parameter
5760
private ConvertService convertService;
5861

59-
ScriptLanguage scriptLanguage;
60-
ScriptEngine engine;
62+
private final Map<String, ScriptEngine> scriptEngines;
63+
private final Map<String, ScriptLanguage> scriptLanguages;
64+
private String languageName;
6165

6266
SimpleEvaluationObject seo = null;
6367
String code = null;
6468

65-
Worker(Context context, ScriptEngine engine, ScriptLanguage scriptLanguage) {
69+
Worker(Context context, Map<String, ScriptEngine> scriptEngines, Map<String, ScriptLanguage> scriptLanguages) {
6670
context.inject(this);
67-
this.engine = engine;
68-
this.scriptLanguage = scriptLanguage;
71+
this.scriptEngines = scriptEngines;
72+
this.scriptLanguages = scriptLanguages;
6973
}
7074

71-
public void setup(SimpleEvaluationObject seo, String code) {
75+
public void setup(SimpleEvaluationObject seo, String code, String languageName) {
7276
this.seo = seo;
7377
this.code = code;
78+
this.languageName = languageName;
7479
}
7580

7681
@Override
7782
public void run() {
7883

79-
final Reader input = new StringReader(this.code);
84+
ScriptLanguage scriptLanguage = this.scriptLanguages.get(this.languageName);
85+
ScriptEngine scriptEngine = this.scriptEngines.get(this.languageName);
8086

87+
final Reader input = new StringReader(this.code);
8188
ScriptInfo info = new ScriptInfo(context, "dummy.py", input);
82-
8389
this.seo.setOutputHandler();
8490

8591
try {
8692

8793
ScriptModule module = info.createModule();
8894
context.inject(module);
89-
module.setLanguage(this.scriptLanguage);
95+
module.setLanguage(scriptLanguage);
9096

9197
// Populate input annotation parameters
9298
this.preProcess(module);
9399
for (final ModuleItem<?> item : info.inputs()) {
94100
final String name = item.getName();
95-
engine.put(name, module.getInput(name));
101+
scriptEngine.put(name, module.getInput(name));
96102
}
97103

98104
// Execute the code
99105
Object returnValue = null;
100106
try {
101-
returnValue = engine.eval(info.getReader());
102-
returnValue = this.scriptLanguage.decode(returnValue);
107+
returnValue = scriptEngine.eval(info.getReader());
108+
returnValue = scriptLanguage.decode(returnValue);
103109
this.seo.finished(returnValue);
110+
this.syncBindings(this.languageName, scriptEngine, scriptLanguage);
104111
} catch (Throwable e) {
105112

106113
if (e instanceof InvocationTargetException) {
@@ -122,7 +129,7 @@ public void run() {
122129
// NB: This is the special implicit return value output!
123130
value = returnValue;
124131
} else {
125-
value = engine.get(name);
132+
value = scriptEngine.get(name);
126133
}
127134
final Object decoded = scriptLanguage.decode(value);
128135
final Object typed = convertService.convert(decoded, item.getType());
@@ -136,7 +143,6 @@ public void run() {
136143

137144
this.seo.clrOutputHandler();
138145
this.seo.executeCodeCallback();
139-
140146
}
141147

142148
public ModulePreprocessor preProcess(ScriptModule module) {
@@ -165,4 +171,16 @@ public void postProcess(ScriptModule module) {
165171
}
166172
}
167173

174+
private void syncBindings(String languageName, ScriptEngine scriptEngine, ScriptLanguage scriptLanguage) {
175+
176+
Bindings currentBindings = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
177+
this.scriptEngines.forEach((String name, ScriptEngine engine) -> {
178+
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
179+
currentBindings.keySet().forEach((String key) -> {
180+
bindings.put(key, scriptLanguage.decode(currentBindings.get(key)));
181+
});
182+
});
183+
184+
}
185+
168186
}

0 commit comments

Comments
 (0)