/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.script.js.engine; import java.util.ArrayList; import javax.script.Bindings; import javax.script.ScriptContext; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; public class EngineScope implements Scriptable { private ScriptContext context; private Scriptable prototype; private Scriptable parent; public EngineScope(ScriptContext context) { this.context = context; } @Override public String getClassName() { return "Engine"; } @Override public synchronized Object get(String name, Scriptable start) { Object value; synchronized (context) { int scope = context.getAttributesScope(name); if (scope != -1) { value = context.getAttribute(name, scope); } else { value = NOT_FOUND; } } return value; } @Override public synchronized Object get(int index, Scriptable start) { return get(String.valueOf(index), start); } @Override public synchronized boolean has(String name, Scriptable start) { boolean has; synchronized (context) { has = context.getAttributesScope(name) != -1; } return has; } @Override public synchronized boolean has(int index, Scriptable start) { return has(String.valueOf(index), start); } @Override public synchronized void put(String name, Scriptable start, Object value) { if (start == this) { synchronized (context) { int scope = context.getAttributesScope(name); if (scope == -1) { scope = ScriptContext.ENGINE_SCOPE; } context.setAttribute(name, value, scope); } } else { start.put(name, this, value); } } @Override public synchronized void put(int index, Scriptable start, Object value) { put(String.valueOf(index), start, value); } @Override public synchronized void delete(String name) { synchronized (context) { int scope = context.getAttributesScope(name); if (scope != -1) { context.removeAttribute(name, scope); } } } @Override public synchronized void delete(int index) { delete(String.valueOf(index)); } @Override public Scriptable getPrototype() { return prototype; } @Override public void setPrototype(Scriptable prototype) { this.prototype = prototype; } @Override public Scriptable getParentScope() { return parent; } @Override public void setParentScope(Scriptable parent) { this.parent = parent; } @Override public Object[] getIds() { ArrayList<String> list = new ArrayList<String>(); synchronized (context) { for (int scope : context.getScopes()) { Bindings bindings = context.getBindings(scope); if (bindings != null) { list.ensureCapacity(bindings.size()); for (String key : bindings.keySet()) { list.add(key); } } } } return list.toArray(new String[list.size()]); } @Override public Object getDefaultValue(Class<?> hint) { return ScriptableObject.getDefaultValue(this, hint); } @Override public boolean hasInstance(Scriptable instance) { Scriptable proto = instance.getPrototype(); boolean has = false; while (proto != null) { if (proto.equals(this)) { has = true; break; } proto = proto.getPrototype(); } return has; } }