/*
ESXX - The friendly ECMAscript/XML Application Server
Copyright (C) 2007-2015 Martin Blom <martin@blom.org>
This program is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.esxx.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptRuntime;
public class KeyValueWrapper {
@SuppressWarnings({"unchecked"})
public KeyValueWrapper(Object obj) {
if (obj instanceof Scriptable) {
js = (Scriptable) obj;
size = -1;
}
else if (obj instanceof Map) {
map = (Map<Object, Object>) obj;
size = -1;
}
else if (obj instanceof Iterable) {
Collection<Object> coll;
if (obj instanceof Collection) {
coll = (Collection<Object>) obj;
}
else {
coll = new ArrayList<Object>();
for (Object o : (Iterable) obj) {
coll.add(o);
}
}
array = coll.toArray();
size = array.length;
}
else {
throw new IllegalArgumentException("Unable to wrap class " + obj.getClass().getSimpleName());
}
}
public int size() {
return size != -1 ? size : getKeys().size();
}
public Collection<Object> getKeys() {
if (keys == null) {
if (js != null) {
keys = Arrays.asList(js.getIds());
}
else if (map != null) {
keys = map.keySet();
}
else if (array != null) {
keys = new ArrayList<Object>(size);
for (int i = 0; i < size; ++i) {
keys.add(new Integer(i));
}
}
else {
throw new IllegalStateException("No object!");
}
}
return keys;
}
public Collection<Object> getValues(Context cx) {
if (values == null) {
if (js != null) {
values = new ArrayList<Object>(getKeys().size());
for (Object key : getKeys()) {
values.add(ScriptRuntime.getObjectElem(js, key, cx));
}
}
else if (map != null) {
values = map.values();
}
else if (array != null) {
values = Arrays.asList(array);
}
else {
throw new IllegalStateException("No object!");
}
}
return values;
}
public Object getValue(Context cx, Object key) {
if (js != null) {
return ScriptRuntime.getObjectElem(js, key, cx);
}
else if (map != null) {
if (map.containsKey(key)) {
return map.get(key);
}
else {
return Context.getUndefinedValue();
}
}
else if (array != null) {
try {
return array[((Number) key).intValue()];
}
catch (Exception ignored) {
return Context.getUndefinedValue();
}
}
else {
throw new IllegalStateException("No object!");
}
}
private int size;
private Collection<Object> keys;
private Collection<Object> values;
private Scriptable js;
private Map<Object, Object> map;
private Object[] array;
}