Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.mozilla.javascript.NativeJavaMap Maven / Gradle / Ivy
Go to download
Rhino JavaScript runtime jar, excludes tools & JSR-223 Script Engine wrapper.
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.javascript;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* NativeJavaMap
is a wrapper for java objects implementing java.util.Map
*
interface. When {@link Context#FEATURE_ENABLE_JAVA_MAP_ACCESS} is enabled, property based
* access like map[key]
is delegated to {@link Map#get(Object)} or {@link
* Map#put(Object, Object)} operations so that a JavaMap
acts very similar to a
* javascript Object
There is also an iterator to iterate over entries with
* for .. of
.
*
* Limitations: The wrapped map should have String
or Integer
as
* key. Otherwise, property based access may not work properly.
*/
public class NativeJavaMap extends NativeJavaObject {
private static final long serialVersionUID = -3786257752907047381L;
private Map map;
static void init(ScriptableObject scope, boolean sealed) {
NativeJavaMapIterator.init(scope, sealed);
}
@SuppressWarnings("unchecked")
public NativeJavaMap(Scriptable scope, Object map) {
super(scope, map, map.getClass());
assert map instanceof Map;
this.map = (Map) map;
}
@Override
public String getClassName() {
return "JavaMap";
}
@Override
public boolean has(String name, Scriptable start) {
Context cx = Context.getCurrentContext();
if (cx != null && cx.hasFeature(Context.FEATURE_ENABLE_JAVA_MAP_ACCESS)) {
if (map.containsKey(name)) {
return true;
}
}
return super.has(name, start);
}
@Override
public boolean has(int index, Scriptable start) {
Context cx = Context.getCurrentContext();
if (cx != null && cx.hasFeature(Context.FEATURE_ENABLE_JAVA_MAP_ACCESS)) {
if (map.containsKey(Integer.valueOf(index))) {
return true;
}
}
return super.has(index, start);
}
@Override
public boolean has(Symbol key, Scriptable start) {
if (SymbolKey.ITERATOR.equals(key)) {
return true;
}
return false;
}
@Override
public Object get(String name, Scriptable start) {
Context cx = Context.getCurrentContext();
if (cx != null && cx.hasFeature(Context.FEATURE_ENABLE_JAVA_MAP_ACCESS)) {
if (map.containsKey(name)) {
Object obj = map.get(name);
return cx.getWrapFactory().wrap(cx, this, obj, obj == null ? null : obj.getClass());
}
}
return super.get(name, start);
}
@Override
public Object get(int index, Scriptable start) {
Context cx = Context.getCurrentContext();
if (cx != null && cx.hasFeature(Context.FEATURE_ENABLE_JAVA_MAP_ACCESS)) {
if (map.containsKey(Integer.valueOf(index))) {
Object obj = map.get(Integer.valueOf(index));
return cx.getWrapFactory().wrap(cx, this, obj, obj == null ? null : obj.getClass());
}
}
return super.get(index, start);
}
@Override
public Object get(Symbol key, Scriptable start) {
if (SymbolKey.ITERATOR.equals(key)) {
return symbol_iterator;
}
return super.get(key, start);
}
@Override
public void put(String name, Scriptable start, Object value) {
Context cx = Context.getCurrentContext();
if (cx != null && cx.hasFeature(Context.FEATURE_ENABLE_JAVA_MAP_ACCESS)) {
map.put(name, Context.jsToJava(value, Object.class));
} else {
super.put(name, start, value);
}
}
@Override
public void put(int index, Scriptable start, Object value) {
Context cx = Context.getContext();
if (cx != null && cx.hasFeature(Context.FEATURE_ENABLE_JAVA_MAP_ACCESS)) {
map.put(Integer.valueOf(index), Context.jsToJava(value, Object.class));
} else {
super.put(index, start, value);
}
}
@Override
public Object[] getIds() {
Context cx = Context.getCurrentContext();
if (cx != null && cx.hasFeature(Context.FEATURE_ENABLE_JAVA_MAP_ACCESS)) {
List ids = new ArrayList<>(map.size());
for (Object key : map.keySet()) {
if (key instanceof Integer) {
ids.add(key);
} else {
ids.add(ScriptRuntime.toString(key));
}
}
return ids.toArray();
}
return super.getIds();
}
private static Callable symbol_iterator =
(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) -> {
if (!(thisObj instanceof NativeJavaMap)) {
throw ScriptRuntime.typeErrorById("msg.incompat.call", SymbolKey.ITERATOR);
}
return new NativeJavaMapIterator(scope, ((NativeJavaMap) thisObj).map);
};
private static final class NativeJavaMapIterator extends ES6Iterator {
private static final long serialVersionUID = 1L;
private static final String ITERATOR_TAG = "JavaMapIterator";
static void init(ScriptableObject scope, boolean sealed) {
ES6Iterator.init(scope, sealed, new NativeJavaMapIterator(), ITERATOR_TAG);
}
/** Only for constructing the prototype object. */
private NativeJavaMapIterator() {
super();
}
NativeJavaMapIterator(Scriptable scope, Map map) {
super(scope, ITERATOR_TAG);
this.iterator = map.entrySet().iterator();
}
@Override
public String getClassName() {
return "Java Map Iterator";
}
@Override
protected boolean isDone(Context cx, Scriptable scope) {
return !iterator.hasNext();
}
@Override
protected Object nextValue(Context cx, Scriptable scope) {
if (!iterator.hasNext()) {
return cx.newArray(scope, new Object[] {Undefined.instance, Undefined.instance});
}
Map.Entry e = iterator.next();
return cx.newArray(scope, new Object[] {e.getKey(), e.getValue()});
}
@Override
protected String getTag() {
return ITERATOR_TAG;
}
private Iterator> iterator;
}
}