Пример #1
0
  /**
   * 对Scriptable对象转换成相应的Java对象
   *
   * <p>如果对象类型是数组,按下标数组和关联数组两种情况分别转换为Array和Map; 否则转换为对应的Java对象,或者是一个包含此对象所有属性的Map
   *
   * @param scriptObj 需要转换的Scriptable对象
   * @param context 上下文
   * @return return 转换后的Java对象
   */
  @SuppressWarnings({"rawtypes", "unchecked"})
  private static Object scriptableToJava(ScriptableObject scriptObj, Context context)
      throws IllegalAccessException, NoSuchFieldException {
    // Array & Arguments
    if (ScriptRuntime.isArrayObject(scriptObj)) {
      final Object[] arrayElements = (Object[]) context.getElements(scriptObj);
      // If scriptObj is a associative arry, arrayElements.length will
      // always 0
      // So if scriptObj is empty or index array, return true, else return
      // false
      if (scriptObj.getIds().length == 0 || arrayElements.length == scriptObj.getIds().length) {
        for (int i = 0; i < arrayElements.length; i++) {
          arrayElements[i] = jsToJava(arrayElements[i], context);
        }
        return arrayElements;
      } else {
        final Object[] ids = scriptObj.getIds();

        final HashMap map = new HashMap();
        for (int i = 0; i < ids.length; i++) {
          final String key = ids[i].toString();
          Object value = scriptObj.get(key, scriptObj);
          // if value is UniqueTag, means index is numeric,
          // should get its value by index
          if (value.getClass().equals(UniqueTag.class)) {
            value = scriptObj.get(Integer.parseInt(key), scriptObj);
          }
          map.put(ids[i], jsToJava(value, context));
        }
        return map;
      }
    } else {
      final String jsClassName = scriptObj.getClassName();
      // If jsClassName is 'Object', means scriptObj could't directly
      // convert to a normal java object, in this case we
      // return a map contains all properties in this scriptable object.
      if ("Object".equals(jsClassName)) {
        final Object[] ids = scriptObj.getIds();
        final HashMap map = new HashMap();
        for (int i = 0; i < ids.length; i++) {
          final String key = ids[i].toString();
          final Object value = scriptObj.get(key, scriptObj);
          map.put(key, jsToJava(value, context));
        }
        return map;
      }
      // If jsClassName is 'Funtion' & instanceof NativeFunction,
      // means scriptObj is a function defined in script,
      // in this case we return a String present source of this function
      else if ("Function".equals(jsClassName) && scriptObj instanceof NativeFunction) {
        final NativeFunction func = (NativeFunction) scriptObj;
        return Decompiler.decompile(
            func.getEncodedSource(), Decompiler.TO_SOURCE_FLAG, new UintMap());
      }
      // Else, we can covert it to a desired java object by
      // Context.jsToJava()
      else {
        final Class clazz =
            (Class) ScriptRuntime.class.getDeclaredField(jsClassName + "Class").get(scriptObj);
        return Context.jsToJava(scriptObj, clazz);
      }
    }
  }