Skip to content

Commit e89c7ae

Browse files
committed
1 parent 263395c commit e89c7ae

File tree

5 files changed

+480
-0
lines changed

5 files changed

+480
-0
lines changed

LICENSE.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
Copyright (c) 2008 - 2014, Board of Regents of the University of
2+
Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
3+
Institute of Molecular Cell Biology and Genetics.
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without modification,
7+
are permitted provided that the following conditions are met:
8+
9+
1. Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26+
POSSIBILITY OF SUCH DAMAGE.
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/*
2+
* #%L
3+
* JSR-223-compliant JRuby scripting language plugin.
4+
* %%
5+
* Copyright (C) 2008 - 2014 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.plugins.scripting.jruby;
33+
34+
import java.util.ArrayList;
35+
import java.util.Collection;
36+
import java.util.HashSet;
37+
import java.util.List;
38+
import java.util.Map;
39+
import java.util.Set;
40+
41+
import javax.script.Bindings;
42+
43+
import org.jruby.Ruby;
44+
import org.jruby.exceptions.RaiseException;
45+
import org.jruby.internal.runtime.GlobalVariables;
46+
import org.jruby.javasupport.JavaUtil;
47+
48+
/**
49+
* A {@link Bindings} wrapper around JRuby's local variables.
50+
*
51+
* @author Johannes Schindelin
52+
*/
53+
public class JRubyBindings implements Bindings {
54+
55+
private Ruby interpreter;
56+
57+
public JRubyBindings(final Ruby interpreter) {
58+
this.interpreter = interpreter;
59+
}
60+
61+
@Override
62+
public int size() {
63+
return interpreter.getGlobalVariables().getNames().size();
64+
}
65+
66+
@Override
67+
public boolean isEmpty() {
68+
return size() == 0;
69+
}
70+
71+
@Override
72+
public boolean containsKey(Object key) {
73+
return get(key) != null;
74+
}
75+
76+
@Override
77+
public boolean containsValue(Object value) {
78+
for (final Object value2 : values()) {
79+
if (value.equals(value2)) return true;
80+
}
81+
return false;
82+
}
83+
84+
@Override
85+
public Object get(Object key) {
86+
try {
87+
return interpreter.getGlobalVariables().get((String)key);
88+
} catch (Error e) {
89+
return null;
90+
}
91+
}
92+
93+
@Override
94+
public Object put(String key, Object value) {
95+
final Object result = get(key);
96+
try {
97+
interpreter.getGlobalVariables().set(key, JavaUtil.convertJavaToRuby(interpreter, value));
98+
} catch (Error e) {
99+
// ignore
100+
}
101+
return result;
102+
}
103+
104+
@Override
105+
public Object remove(Object key) {
106+
final Object result = get(key);
107+
if (result != null) interpreter.getGlobalVariables().clear((String)key);
108+
return result;
109+
}
110+
111+
@Override
112+
public void putAll(Map<? extends String, ? extends Object> toMerge) {
113+
for (final Entry<? extends String, ? extends Object> entry : toMerge.entrySet()) {
114+
put(entry.getKey(), entry.getValue());
115+
}
116+
}
117+
118+
@Override
119+
public void clear() {
120+
final GlobalVariables vars = interpreter.getGlobalVariables();
121+
for (final String name : new ArrayList<String>(vars.getNames())) try {
122+
if (!name.startsWith("$") || (name.length() > 1 && "=<.-".contains(name.substring(1, 2)))) continue;
123+
vars.clear(name);
124+
} catch (final RaiseException e) {
125+
// ignore
126+
}
127+
}
128+
129+
@Override
130+
public Set<String> keySet() {
131+
return new HashSet<String>(interpreter.getGlobalVariables().getNames());
132+
}
133+
134+
@Override
135+
public Collection<Object> values() {
136+
final List<Object> result = new ArrayList<Object>();
137+
for (final Object name : interpreter.getGlobalVariables().getNames()) try {
138+
result.add(get(name));
139+
} catch (Error exc) {
140+
// ignore for now
141+
}
142+
return result;
143+
}
144+
145+
@Override
146+
public Set<Entry<String, Object>> entrySet() {
147+
final Set<Entry<String, Object>> result = new HashSet<Entry<String, Object>>();
148+
for (final String name : interpreter.getGlobalVariables().getNames()) {
149+
result.add(new Entry<String, Object>() {
150+
151+
@Override
152+
public String getKey() {
153+
return name;
154+
}
155+
156+
@Override
157+
public Object getValue() {
158+
return get(name);
159+
}
160+
161+
@Override
162+
public Object setValue(Object value) {
163+
throw new UnsupportedOperationException();
164+
}
165+
});
166+
}
167+
return result;
168+
}
169+
170+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* #%L
3+
* JSR-223-compliant JRuby scripting language plugin.
4+
* %%
5+
* Copyright (C) 2008 - 2014 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.plugins.scripting.jruby;
33+
34+
import java.io.PrintStream;
35+
import java.io.Reader;
36+
import java.io.Writer;
37+
38+
import javax.script.ScriptContext;
39+
import javax.script.ScriptEngine;
40+
import javax.script.ScriptException;
41+
42+
import org.jruby.Ruby;
43+
import org.jruby.RubyInstanceConfig;
44+
import org.jruby.embed.io.ReaderInputStream;
45+
import org.jruby.embed.io.WriterOutputStream;
46+
import org.scijava.script.AbstractScriptEngine;
47+
48+
/**
49+
* A Ruby interpreter based on JRuby.
50+
*
51+
* @author Johannes Schindelin
52+
*/
53+
public class JRubyScriptEngine extends AbstractScriptEngine
54+
{
55+
private Ruby interpreter;
56+
57+
public JRubyScriptEngine() {
58+
interpreter = Ruby.newInstance();
59+
engineScopeBindings = new JRubyBindings(interpreter);
60+
}
61+
62+
@Override
63+
public Object eval(final String script) throws ScriptException {
64+
setup();
65+
try {
66+
return interpreter.evalScriptlet(script);
67+
}
68+
catch (final Exception e) {
69+
throw new ScriptException(e);
70+
}
71+
}
72+
73+
@Override
74+
public Object eval(final Reader reader) throws ScriptException {
75+
setup();
76+
try {
77+
final String filename = getString(ScriptEngine.FILENAME);
78+
interpreter.runFromMain(new ReaderInputStream(reader), filename == null ? "*none*" : filename);
79+
return this;
80+
}
81+
catch (final Exception e) {
82+
throw new ScriptException(e);
83+
}
84+
}
85+
86+
protected void setup() {
87+
final RubyInstanceConfig config = interpreter.getInstanceConfig();
88+
final ScriptContext context = getContext();
89+
final Reader reader = context.getReader();
90+
if (reader != null) {
91+
config.setInput(new ReaderInputStream(reader));
92+
}
93+
final Writer writer = context.getWriter();
94+
if (writer != null) {
95+
config.setOutput(new PrintStream(new WriterOutputStream(writer)));
96+
}
97+
final Writer errorWriter = context.getErrorWriter();
98+
if (errorWriter != null) {
99+
config.setError(new PrintStream(new WriterOutputStream(errorWriter)));
100+
}
101+
}
102+
103+
private String getString(final String key) {
104+
Object result = get(key);
105+
return result == null ? null : result.toString();
106+
}
107+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* #%L
3+
* JSR-223-compliant JRuby scripting language plugin.
4+
* %%
5+
* Copyright (C) 2008 - 2014 Board of Regents of the University of
6+
* Wisconsin-Madison, Broad Institute of MIT and Harvard, and Max Planck
7+
* Institute of Molecular Cell Biology and Genetics.
8+
* %%
9+
* Redistribution and use in source and binary forms, with or without
10+
* modification, are permitted provided that the following conditions are met:
11+
*
12+
* 1. Redistributions of source code must retain the above copyright notice,
13+
* this list of conditions and the following disclaimer.
14+
* 2. Redistributions in binary form must reproduce the above copyright notice,
15+
* this list of conditions and the following disclaimer in the documentation
16+
* and/or other materials provided with the distribution.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
* POSSIBILITY OF SUCH DAMAGE.
29+
* #L%
30+
*/
31+
32+
package org.scijava.plugins.scripting.jruby;
33+
34+
import javax.script.ScriptEngine;
35+
36+
import org.scijava.plugin.Plugin;
37+
import org.scijava.script.AdaptedScriptLanguage;
38+
import org.scijava.script.ScriptLanguage;
39+
40+
/**
41+
* An adapter of the JRuby interpreter to ImageJ's scripting interfaces.
42+
*
43+
* @author Johannes Schindelin
44+
* @see ScriptEngine
45+
*/
46+
@Plugin(type = ScriptLanguage.class)
47+
public class JRubyScriptLanguage extends AdaptedScriptLanguage {
48+
49+
public JRubyScriptLanguage() {
50+
super("jruby");
51+
}
52+
53+
@Override
54+
public String getLanguageName() {
55+
// NB: Must override, or else the name is "ruby" in small case.
56+
return "Ruby";
57+
}
58+
59+
@Override
60+
public ScriptEngine getScriptEngine() {
61+
// TODO: Consider adapting the wrapped ScriptEngineFactory's ScriptEngine.
62+
return new JRubyScriptEngine();
63+
}
64+
65+
}

0 commit comments

Comments
 (0)