src.org.python.jsr223.PyScriptEngineScope Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython-standalone Show documentation
Show all versions of jython-standalone Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
package org.python.jsr223;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import org.python.core.Py;
import org.python.core.PyDictionary;
import org.python.core.PyIterator;
import org.python.core.PyList;
import org.python.core.PyObject;
import org.python.core.PyString;
import org.python.core.PyType;
import org.python.core.Visitproc;
import org.python.core.Untraversable;
import org.python.expose.ExposedType;
import org.python.expose.ExposedGet;
import org.python.expose.ExposedMethod;
/**
* JSR 223 does not map well to Jython's concept of "locals" and "globals".
* Instead, SimpleScriptContext provides ENGINE_SCOPE and GLOBAL_SCOPE, each
* with its own bindings. We adapt this multi-scope object for use as both
* a local and global dictionary.
*/
@Untraversable
@ExposedType(name = "scope", isBaseType = false)
public final class PyScriptEngineScope extends PyObject {
public static final PyType TYPE = PyType.fromClass(PyScriptEngineScope.class);
private final ScriptContext context;
private final ScriptEngine engine;
PyScriptEngineScope(ScriptEngine engine, ScriptContext context) {
this.context = context;
this.engine = engine;
}
@ExposedGet(name = "context")
public PyObject pyGetContext() {
return Py.java2py(context);
}
@ExposedGet(name = "engine")
public PyObject pyGetEngine() {
return Py.java2py(engine);
}
@ExposedMethod
public PyObject scope_keys() {
PyList members = new PyList();
List scopes = context.getScopes();
for (int scope : scopes) {
Bindings bindings = context.getBindings(scope);
if (bindings == null)
continue;
for (String key : bindings.keySet())
members.append(new PyString(key));
}
members.sort();
return members;
}
// satisfy mapping and lookup
@ExposedMethod
@Override
public PyObject __getitem__(PyObject key) {
return __finditem__(key);
}
// satisfy iterable
@ExposedMethod
@Override
public PyObject __iter__() {
return new ScopeIterator(this);
}
@ExposedMethod(defaults = "Py.None")
final PyObject scope_get(PyObject keyObj, PyObject defaultObj) {
String key = keyObj.asString();
int scope = context.getAttributesScope(key);
return scope == -1 ? defaultObj : Py.java2py(context.getAttribute(key, scope));
}
@ExposedMethod
final boolean scope_has_key(PyObject key) {
return context.getAttributesScope(key.asString()) != -1;
}
@Override
public boolean __contains__(PyObject obj) {
return scope___contains__(obj);
}
@ExposedMethod
final boolean scope___contains__(PyObject obj) {
return scope_has_key(obj);
}
@ExposedMethod(defaults = "Py.None")
final PyObject scope_setdefault(PyObject keyObj, PyObject failObj) {
PyObject result;
String key = keyObj.asString();
int scope = context.getAttributesScope(key);
if (scope == -1) {
scope = ScriptContext.ENGINE_SCOPE;
context.setAttribute(key,
failObj instanceof PyType
? failObj : failObj.__tojava__(Object.class),
scope);
result = failObj;
} else {
result = Py.java2py(context.getAttribute(key, scope));
}
return result;
}
@Override
public String toString() {
return getDictionary().toString();
}
@Override
public PyObject __finditem__(PyObject key) {
return __finditem__(key.asString());
}
@Override
public PyObject __finditem__(String key) {
int scope = context.getAttributesScope(key);
if (scope == -1)
return null;
return Py.java2py(context.getAttribute(key, scope));
}
@ExposedMethod
@Override
public void __setitem__(PyObject key, PyObject value) {
__setitem__(key.asString(), value);
}
@Override
public void __setitem__(String key, PyObject value) {
int scope = context.getAttributesScope(key);
if (scope == -1)
scope = ScriptContext.ENGINE_SCOPE;
context.setAttribute(key,
value instanceof PyType ? value : value.__tojava__(Object.class),
scope);
}
@ExposedMethod
@Override
public void __delitem__(PyObject key) {
__delitem__(key.asString());
}
@Override
public void __delitem__(String key) {
int scope = context.getAttributesScope(key);
if (scope == -1)
throw Py.KeyError(key);
context.removeAttribute(key, scope);
}
private Map getMap() {
ScopeIterator iterator = new ScopeIterator(this);
Map map = new HashMap(iterator.size());
PyObject key = iterator.__iternext__();
while (key != null) {
map.put(key, __finditem__(key));
key = iterator.__iternext__();
}
return map;
}
private PyDictionary getDictionary() {
return new PyDictionary(getMap());
}
public class ScopeIterator extends PyIterator {
private int _index;
private int _size;
private PyObject _keys;
ScopeIterator(PyScriptEngineScope scope) {
_keys = scope.scope_keys();
_size = _keys.__len__();
_index = -1;
}
public int size() {
return _size;
}
@Override
public PyObject __iternext__() {
PyObject result = null;
_index++;
if (_index < size()) {
result = _keys.__getitem__(_index);
}
return result;
}
/* Traverseproc implementation */
@Override
public int traverse(Visitproc visit, Object arg) {
int retVal = super.traverse(visit, arg);
if (retVal != 0) {
return retVal;
}
return _keys != null ? visit.visit(_keys, arg) : 0;
}
@Override
public boolean refersDirectlyTo(PyObject ob) {
return ob != null && (ob == _keys || super.refersDirectlyTo(ob));
}
}
}