/*
* Scriptographer
*
* This file is part of Scriptographer, a Scripting Plugin for Adobe Illustrator
* http://scriptographer.org/
*
* Copyright (c) 2002-2010, Juerg Lehni
* http://scratchdisk.com/
*
* All rights reserved. See LICENSE file for details.
*
* File created on 19.02.2005.
*/
package com.scratchdisk.script.rhino;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.Wrapper;
import java.util.Map;
/**
* Wrapper class for java.util.Map objects It adds JS object-like properties, so
* it is possible to access lists like this: map["value"], or map[10].
*
* It also defines getIds(), so enumeration is possible too: for (var i in list)
* ... But it does not allow to access by anything else than Integer or String,
* so not the whole functionality Of maps is provided. For Scriptographer it is
* enough, though.
*
* @author lehni
*/
public class MapWrapper extends ScriptableObject implements Wrapper {
private Map map;
public MapWrapper(Scriptable scope, Map map) {
super(scope, ScriptableObject.getObjectPrototype(scope));
this.map = map;
}
public boolean has(String name, Scriptable start) {
if (map != null) {
return map.containsKey(name);
} else {
return super.has(name, start);
}
}
public boolean has(int index, Scriptable start) {
if (map != null) {
return map.containsKey(Integer.toString(index));
} else {
return super.has(index, start);
}
}
public Object get(String name, Scriptable start) {
// Retrieve from map first, then from super, to give entries priority
// over methods and fields.
if (map != null)
return getInternal(name);
else
return super.get(name, start);
}
public Object get(int index, Scriptable start) {
// Retrieve from map first, then from super, to give entries priority over methods and fields.
if (map != null)
return getInternal(Integer.toString(index));
else
return super.get(index, start);
}
private Object getInternal(Object key) {
if (map.containsKey(key)) {
Object value = map.get(key);
return value != null ? Context.javaToJS(value, getParentScope()) : null;
}
return Scriptable.NOT_FOUND;
}
public void put(String name, Scriptable start, Object value) {
if (map != null)
putInternal(name, value);
else
super.put(name, start, value);
}
public void put(int index, Scriptable start, Object value) {
if (map != null)
putInternal(Integer.toString(index), value);
else
super.put(index, start, value);
}
@SuppressWarnings("unchecked")
private void putInternal(Object key, Object value) {
try {
map.put(key, Context.jsToJava(value,
ScriptRuntime.ObjectClass));
} catch (RuntimeException e) {
Context.throwAsScriptRuntimeEx(e);
}
}
public void delete(String name) {
if (map != null) {
try {
map.remove(name);
} catch (RuntimeException e) {
Context.throwAsScriptRuntimeEx(e);
}
} else {
super.delete(name);
}
}
public void delete(int index) {
if (map != null) {
try {
map.remove(new Integer(index));
} catch (RuntimeException e) {
Context.throwAsScriptRuntimeEx(e);
}
} else {
super.delete(index);
}
}
public Object[] getIds() {
if (map != null) {
return map.keySet().toArray();
} else {
return new Object[0];
}
}
public String getClassName() {
// It looks like an Object, inherits from it, so why not pretending to
// be one.
return "Object";
}
public Object unwrap() {
return map;
}
}