Skip to content

Commit a7ef34f

Browse files
committed
1 parent 968c8fa commit a7ef34f

File tree

5 files changed

+472
-0
lines changed

5 files changed

+472
-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 Jython 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.jython;
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.python.core.PyStringMap;
44+
import org.python.util.PythonInterpreter;
45+
46+
/**
47+
* A {@link Bindings} wrapper around Jython's local variables.
48+
*
49+
* @author Johannes Schindelin
50+
*/
51+
public class JythonBindings implements Bindings {
52+
53+
protected final PythonInterpreter interpreter;
54+
55+
public JythonBindings(final PythonInterpreter interpreter) {
56+
this.interpreter = interpreter;
57+
}
58+
59+
@Override
60+
public int size() {
61+
return interpreter.getLocals().__len__();
62+
}
63+
64+
@Override
65+
public boolean isEmpty() {
66+
return size() == 0;
67+
}
68+
69+
@Override
70+
public boolean containsKey(Object key) {
71+
return get(key) != null;
72+
}
73+
74+
@Override
75+
public boolean containsValue(Object value) {
76+
for (final Object value2 : values()) {
77+
if (value.equals(value2)) return true;
78+
}
79+
return false;
80+
}
81+
82+
@Override
83+
public Object get(Object key) {
84+
try {
85+
return interpreter.get((String)key);
86+
} catch (Error e) {
87+
return null;
88+
}
89+
}
90+
91+
@Override
92+
public Object put(String key, Object value) {
93+
final Object result = get(key);
94+
try {
95+
interpreter.set(key, value);
96+
} catch (Error e) {
97+
// ignore
98+
}
99+
return result;
100+
}
101+
102+
@Override
103+
public Object remove(Object key) {
104+
final Object result = get(key);
105+
if (result != null) interpreter.getLocals().__delitem__((String)key);
106+
return result;
107+
}
108+
109+
@Override
110+
public void putAll(Map<? extends String, ? extends Object> toMerge) {
111+
for (final Entry<? extends String, ? extends Object> entry : toMerge.entrySet()) {
112+
put(entry.getKey(), entry.getValue());
113+
}
114+
}
115+
116+
private PyStringMap dict() {
117+
return (PyStringMap)interpreter.getLocals();
118+
}
119+
120+
@Override
121+
public void clear() {
122+
dict().clear();
123+
}
124+
125+
@Override
126+
public Set<String> keySet() {
127+
final Set<String> result = new HashSet<String>();
128+
for (final Object name : dict().keys()) {
129+
result.add(name.toString());
130+
}
131+
return result;
132+
}
133+
134+
@Override
135+
public Collection<Object> values() {
136+
final List<Object> result = new ArrayList<Object>();
137+
for (final Object name : dict().keys()) 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 Object name : dict().keys()) {
149+
result.add(new Entry<String, Object>() {
150+
151+
@Override
152+
public String getKey() {
153+
return name.toString();
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: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* #%L
3+
* JSR-223-compliant Jython 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.jython;
33+
34+
import java.io.Reader;
35+
import java.io.Writer;
36+
37+
import javax.script.ScriptContext;
38+
import javax.script.ScriptEngine;
39+
import javax.script.ScriptException;
40+
41+
import org.python.core.Py;
42+
import org.python.util.PythonInterpreter;
43+
import org.scijava.script.AbstractScriptEngine;
44+
45+
/**
46+
* A Python interpreter based on Jython.
47+
*
48+
* @author Johannes Schindelin
49+
*/
50+
public class JythonScriptEngine extends AbstractScriptEngine
51+
{
52+
53+
protected final PythonInterpreter interpreter;
54+
55+
public JythonScriptEngine() {
56+
interpreter = new PythonInterpreter();
57+
engineScopeBindings = new JythonBindings(interpreter);
58+
}
59+
60+
@Override
61+
public Object eval(final String script) throws ScriptException {
62+
setup();
63+
try {
64+
return interpreter.eval(script);
65+
}
66+
catch (final Exception e) {
67+
throw new ScriptException(e);
68+
}
69+
}
70+
71+
@Override
72+
public Object eval(final Reader reader) throws ScriptException {
73+
setup();
74+
try {
75+
final String filename = getString(ScriptEngine.FILENAME);
76+
return Py.runCode(interpreter.compile(reader, filename), null, interpreter.getLocals());
77+
}
78+
catch (final Exception e) {
79+
throw new ScriptException(e);
80+
}
81+
}
82+
83+
protected void setup() {
84+
final ScriptContext context = getContext();
85+
final Reader reader = context.getReader();
86+
if (reader != null) {
87+
interpreter.setIn(reader);
88+
}
89+
final Writer writer = context.getWriter();
90+
if (writer != null) {
91+
interpreter.setOut(writer);
92+
}
93+
final Writer errorWriter = context.getErrorWriter();
94+
if (errorWriter != null) {
95+
interpreter.setErr(errorWriter);
96+
}
97+
}
98+
99+
private String getString(final String key) {
100+
Object result = get(key);
101+
return result == null ? null : result.toString();
102+
}
103+
}
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 Jython 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.jython;
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 Jython interpreter to ImageJ's scripting interfaces.
42+
*
43+
* @author Johannes Schindelin
44+
* @see ScriptEngine
45+
*/
46+
@Plugin(type = ScriptLanguage.class)
47+
public class JythonScriptLanguage extends AdaptedScriptLanguage {
48+
49+
public JythonScriptLanguage() {
50+
super("jython");
51+
}
52+
53+
@Override
54+
public String getLanguageName() {
55+
// NB: Must override, or else the name is "python" in small case.
56+
return "Python";
57+
}
58+
59+
@Override
60+
public ScriptEngine getScriptEngine() {
61+
// TODO: Consider adapting the wrapped ScriptEngineFactory's ScriptEngine.
62+
return new JythonScriptEngine();
63+
}
64+
65+
}

0 commit comments

Comments
 (0)