/* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: Redistributions of source code * must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. Neither the name of the Sun Microsystems nor the names of * is contributors may be used to endorse or promote products derived from this software * without specific prior written permission. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package com.l2jserver.script.jython; import java.util.List; import javax.script.Bindings; import javax.script.ScriptContext; import javax.script.ScriptEngine; import org.python.core.Py; import org.python.core.PyClass; import org.python.core.PyList; import org.python.core.PyObject; import org.python.core.PyString; /** * @author A. Sundararajan */ public final class JythonScope extends PyObject { private static final long serialVersionUID = 1L; private final ScriptContext ctx; JythonScope(ScriptEngine engine, ScriptContext ctx) { this.ctx = ctx; // global module's name is expected to be 'main' __setitem__("__name__", new PyString("main")); // JSR-223 requirement: context is exposed as variable __setitem__("context", Py.java2py(ctx)); // expose current engine as another top-level variable __setitem__("engine", Py.java2py(engine)); } @Override public synchronized PyObject invoke(String name) { if (name.equals("keys")) { // special case for "keys" so that dir() will // work for the global "module" PyList keys = new PyList(); synchronized (ctx) { List<Integer> scopes = ctx.getScopes(); for (int scope : scopes) { Bindings b = ctx.getBindings(scope); if (b != null) { for (String key : b.keySet()) { keys.append(new PyString(key)); } } } } return keys; } else { return super.invoke(name); } } @Override public PyObject __findattr__(String key) { return __finditem__(key); } @Override public synchronized PyObject __finditem__(String key) { synchronized (ctx) { int scope = ctx.getAttributesScope(key); if (scope == -1) { return null; } Object value = ctx.getAttribute(key, scope); return JythonScriptEngine.java2py(value); } } @Override public void __setattr__(String key, PyObject value) { __setitem__(key, value); } @Override public synchronized void __setitem__(String key, PyObject value) { synchronized (ctx) { int scope = ctx.getAttributesScope(key); if (scope == -1) { scope = ScriptContext.ENGINE_SCOPE; } Object obj = value; if (!(obj instanceof PyClass)) { obj = JythonScriptEngine.py2java(value); } ctx.setAttribute(key, obj, scope); } } @Override public void __delattr__(String key) { __delitem__(key); } @Override public synchronized void __delitem__(String key) { synchronized (ctx) { int scope = ctx.getAttributesScope(key); if (scope != -1) { ctx.removeAttribute(key, scope); } } } @Override public String toString() { return "<global scope at " + hashCode() + ">"; } }