package com.ui4j.webkit;
import static java.lang.Integer.parseInt;
import static java.lang.String.valueOf;
import static java.util.Collections.emptyMap;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.ui4j.spi.JavaScriptEngine;
import netscape.javascript.JSObject;
public class WebKitMapper {
public WebKitMapper(JavaScriptEngine engine) {
engine.executeScript(
"Object.prototype.__ui4j_keys = function() { return Object.keys(this); };" +
"Object.prototype.__ui4j_isArray = function() { return Array.isArray(this); };");
}
public Map<String, Object> toJava(JSObject object) {
if (object == null) {
return emptyMap();
}
Map<String, Object> map = new LinkedHashMap<>();
JSObject keys = (JSObject) object.call("__ui4j_keys");
int length = parseInt(valueOf(keys.getMember("length")));
for (int i = 0; i < length; i++) {
String key = (String) keys.getSlot(i);
Object value = object.getMember(key);
value = toJava(value);
if (!(value instanceof JSObject)) {
map.put(key, value);
} else {
JSObject jsObject = (JSObject) value;
boolean isArray = (Boolean) jsObject.call("__ui4j_isArray");
if (isArray) {
List<Object> list = new ArrayList<>();
int arrayLength = parseInt(valueOf(jsObject.getMember("length")));
for (int j = 0; j < arrayLength; j++) {
Object slot = jsObject.getSlot(j);
slot = toJava(slot);
if (!(slot instanceof JSObject)) {
list.add(slot);
} else {
list.add(toJava((JSObject) slot));
}
}
map.put(key, list);
} else {
map.put(key, toJava(jsObject));
}
}
}
return map;
}
protected Object toJava(Object value) {
if (value instanceof Integer) {
return (Integer) value;
} else if (value instanceof Double) {
return (Double) value;
} else if (value instanceof Boolean) {
return (Boolean) value;
}
return value;
}
}