/** * Copyright (c) 2012-2016 André Bargull * Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms. * * <https://github.com/anba/es6draft> */ package com.github.anba.es6draft.scripting; import static com.github.anba.es6draft.scripting.TypeConverter.fromJava; import static com.github.anba.es6draft.scripting.TypeConverter.toJava; import java.util.AbstractMap.SimpleImmutableEntry; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.script.Bindings; import com.github.anba.es6draft.runtime.GlobalEnvironmentRecord; import com.github.anba.es6draft.runtime.Realm; /** * Concrete implementation of the {@link Bindings} interface. */ // TODO: Handle ScriptException when calling globalEnvRec methods? final class GlobalBindings implements Bindings { private final Realm realm; private final GlobalEnvironmentRecord globalEnvRec; public GlobalBindings(Realm realm) { this.realm = realm; this.globalEnvRec = realm.getGlobalEnv().getEnvRec(); } /** * Converts <var>key</var> to a binding name. * * @param key * the key * @return the binding name * @throws ClassCastException * if <var>key</var> is not a {@link String} * @throws NullPointerException * if <var>key</var> is {@code null} * @throws IllegalArgumentException * if <var>key</var> is the empty string */ private static String toBindingName(Object key) { String name = (String) key; if (name.isEmpty()) { throw new IllegalArgumentException(); } return name; } private Object getOrNull(String name) { return containsKey(name) ? get(name) : null; } /** * Returns the realm object this {@link Bindings} instance is bound to. * * @return the realm object */ Realm getRealm() { return realm; } @Override public Object put(String key, Object value) { String name = toBindingName(key); Object oldValue = getOrNull(name); globalEnvRec.setMutableBinding(name, fromJava(value), false); return oldValue; } @Override public void putAll(Map<? extends String, ? extends Object> toMerge) { for (Map.Entry<? extends String, ? extends Object> entry : toMerge.entrySet()) { put(entry.getKey(), entry.getValue()); } } @Override public boolean containsKey(Object key) { String name = toBindingName(key); return globalEnvRec.hasBinding(name); } @Override public Object get(Object key) { String name = toBindingName(key); Object value = globalEnvRec.getBindingValue(name, false); return toJava(value); } @Override public Object remove(Object key) { String name = toBindingName(key); Object oldValue = getOrNull(name); globalEnvRec.deleteBinding(name); return oldValue; } @Override public Set<String> keySet() { return Collections.unmodifiableSet(globalEnvRec.bindingNames()); } @Override public int size() { return keySet().size(); } @Override public boolean isEmpty() { return size() == 0; } @Override public boolean containsValue(Object value) { return values().contains(value); } @Override public void clear() { for (String key : keySet()) { remove(key); } } @Override public Collection<Object> values() { ArrayList<Object> values = new ArrayList<>(); for (String key : keySet()) { values.add(get(key)); } return Collections.unmodifiableList(values); } @Override public Set<Map.Entry<String, Object>> entrySet() { HashSet<Map.Entry<String, Object>> entries = new HashSet<>(); for (String key : keySet()) { entries.add(new SimpleImmutableEntry<>(key, get(key))); } return Collections.unmodifiableSet(entries); } }