package org.qrone.r7.script;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.mozilla.javascript.NativeArray;
import org.mozilla.javascript.NativeJavaObject;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.Wrapper;
public class Scriptables {
public static Map asMap(Object obj){
if(obj instanceof Scriptable){
if( obj instanceof Wrapper){
Object unwrapped = ((Wrapper)obj).unwrap();
if(unwrapped instanceof Map)
return (Map)unwrapped;
}
return asMap((Scriptable)obj);
}else if(obj instanceof Map){
return (Map)obj;
}
throw new IllegalArgumentException();
}
public static Map asMap(Scriptable s){
Map m = null;
if(s.get("window", s).equals(s)){
Scriptable scope = s.getPrototype();
s.setPrototype(null);
s.delete("window");
m = asMap(s, new HashSet());
s.setPrototype(scope);
s.put("window", s, s);
}else{
Scriptable scope = s.getPrototype();
s.setPrototype(null);
m = asMap(s, new HashSet());
s.setPrototype(scope);
}
return m;
}
public static Map asMap(Scriptable s, Set r){
Map m = new HashMap();
Object[] ids = s.getIds();
for (int i = 0; i < ids.length; i++) {
Object k = ids[i];
if(k instanceof String && !k.equals("prototype") && !k.equals("parentScope")){
Object v = s.get(((String)k), s);
m.put(k, asJava(v, r));
}else if (k instanceof Number){
Object v = s.get(((Number)k).intValue(), s);
m.put(k, asJava(v, r));
}
}
return m;
}
public static List asList(NativeArray s, Set r){
long len = s.getLength();
List list = new ArrayList();
for (int i = 0; i < len; i++) {
list.add(i, asJava(s.get(i, s), r));
}
return list;
}
private static Object asJava(Object o, Set r){
if(o == null)
return null;
if(r.contains(o)){
return null;
}
r.add(o);
if(o instanceof NativeArray){
return asList((NativeArray)o, r);
}else if(o instanceof NativeJavaObject){
return asJava(((NativeJavaObject)o).unwrap(),r);
}else if(o instanceof Scriptable){
return asMap((Scriptable)o, r);
}else{
if(o.getClass().getName().startsWith("org.qrone")){
return o.getClass().getName();
}
return o;
}
}
}