Esempio n. 1
0
 @Override
 public Object getDefaultValue(Class<?> hint) {
   if (hint == ScriptRuntime.FunctionClass) return this;
   Object rval;
   Class<?> type;
   try {
     rval = field.get(javaObject);
     type = field.getType();
   } catch (IllegalAccessException accEx) {
     throw Context.reportRuntimeError1("msg.java.internal.private", field.getName());
   }
   Context cx = Context.getContext();
   rval = cx.getWrapFactory().wrap(cx, this, rval, type);
   if (rval instanceof Scriptable) {
     rval = ((Scriptable) rval).getDefaultValue(hint);
   }
   return rval;
 }
Esempio n. 2
0
 private static Object doCall(
     Context cx,
     Scriptable scope,
     Scriptable thisObj,
     Function f,
     Object[] args,
     long argsToWrap) {
   // Wrap the rest of objects
   for (int i = 0; i != args.length; ++i) {
     if (0 != (argsToWrap & (1 << i))) {
       Object arg = args[i];
       if (!(arg instanceof Scriptable)) {
         args[i] = cx.getWrapFactory().wrap(cx, scope, arg, null);
       }
     }
   }
   return f.call(cx, scope, thisObj, args);
 }
Esempio n. 3
0
 Object get(Scriptable scope, String name, Object javaObject, boolean isStatic) {
   Map<String, Object> ht = isStatic ? staticMembers : members;
   Object member = ht.get(name);
   if (!isStatic && member == null) {
     // Try to get static member from instance (LC3)
     member = staticMembers.get(name);
   }
   if (member == null) {
     member =
         this.getExplicitFunction(
             scope, name,
             javaObject, isStatic);
     if (member == null) return Scriptable.NOT_FOUND;
   }
   if (member instanceof Scriptable) {
     return member;
   }
   Context cx = Context.getContext();
   Object rval;
   Class<?> type;
   try {
     if (member instanceof BeanProperty) {
       BeanProperty bp = (BeanProperty) member;
       if (bp.getter == null) return Scriptable.NOT_FOUND;
       rval = bp.getter.invoke(javaObject, Context.emptyArgs);
       type = bp.getter.method().getReturnType();
     } else {
       Field field = (Field) member;
       rval = field.get(isStatic ? null : javaObject);
       type = field.getType();
     }
   } catch (Exception ex) {
     throw Context.throwAsScriptRuntimeEx(ex);
   }
   // Need to wrap the object before we return it.
   scope = ScriptableObject.getTopLevelScope(scope);
   return cx.getWrapFactory().wrap(cx, scope, rval, type);
 }
  @Override
  public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
    // Find a method that matches the types given.
    if (methods.length == 0) {
      throw new RuntimeException("No methods defined for call");
    }

    int index = findFunction(cx, methods, args);
    if (index < 0) {
      Class<?> c = methods[0].method().getDeclaringClass();
      String sig = c.getName() + '.' + getFunctionName() + '(' + scriptSignature(args) + ')';
      throw Context.reportRuntimeError1("msg.java.no_such_method", sig);
    }

    MemberBox meth = methods[index];
    Class<?>[] argTypes = meth.argTypes;

    if (meth.vararg) {
      // marshall the explicit parameters
      Object[] newArgs = new Object[argTypes.length];
      for (int i = 0; i < argTypes.length - 1; i++) {
        newArgs[i] = Context.jsToJava(args[i], argTypes[i]);
      }

      Object varArgs;

      // Handle special situation where a single variable parameter
      // is given and it is a Java or ECMA array or is null.
      if (args.length == argTypes.length
          && (args[args.length - 1] == null
              || args[args.length - 1] instanceof NativeArray
              || args[args.length - 1] instanceof NativeJavaArray)) {
        // convert the ECMA array into a native array
        varArgs = Context.jsToJava(args[args.length - 1], argTypes[argTypes.length - 1]);
      } else {
        // marshall the variable parameters
        Class<?> componentType = argTypes[argTypes.length - 1].getComponentType();
        varArgs = Array.newInstance(componentType, args.length - argTypes.length + 1);
        for (int i = 0; i < Array.getLength(varArgs); i++) {
          Object value = Context.jsToJava(args[argTypes.length - 1 + i], componentType);
          Array.set(varArgs, i, value);
        }
      }

      // add varargs
      newArgs[argTypes.length - 1] = varArgs;
      // replace the original args with the new one
      args = newArgs;
    } else {
      // First, we marshall the args.
      Object[] origArgs = args;
      for (int i = 0; i < args.length; i++) {
        Object arg = args[i];
        Object coerced = Context.jsToJava(arg, argTypes[i]);
        if (coerced != arg) {
          if (origArgs == args) {
            args = args.clone();
          }
          args[i] = coerced;
        }
      }
    }
    Object javaObject;
    if (meth.isStatic()) {
      javaObject = null; // don't need an object
    } else {
      Scriptable o = thisObj;
      Class<?> c = meth.getDeclaringClass();
      for (; ; ) {
        if (o == null) {
          throw Context.reportRuntimeError3(
              "msg.nonjava.method",
              getFunctionName(),
              ScriptRuntime.toString(thisObj),
              c.getName());
        }
        if (o instanceof Wrapper) {
          javaObject = ((Wrapper) o).unwrap();
          if (c.isInstance(javaObject)) {
            break;
          }
        }
        o = o.getPrototype();
      }
    }
    if (debug) {
      printDebug("Calling ", meth, args);
    }

    Object retval = meth.invoke(javaObject, args);
    Class<?> staticType = meth.method().getReturnType();

    if (debug) {
      Class<?> actualType = (retval == null) ? null : retval.getClass();
      System.err.println(
          " ----- Returned " + retval + " actual = " + actualType + " expect = " + staticType);
    }

    Object wrapped =
        cx.getWrapFactory()
            .wrap(
                cx, scope,
                retval, staticType);
    if (debug) {
      Class<?> actualType = (wrapped == null) ? null : wrapped.getClass();
      System.err.println(" ----- Wrapped as " + wrapped + " class = " + actualType);
    }

    if (wrapped == null && staticType == Void.TYPE) {
      wrapped = Undefined.instance;
    }
    return wrapped;
  }
Esempio n. 5
0
  /**
   * Performs conversions on argument types if needed and invokes the underlying Java method or
   * constructor.
   *
   * <p>Implements Function.call.
   *
   * @see gov.nbcs.rp.common.js.javascript.Function#call( Context, Scriptable, Scriptable, Object[])
   */
  public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
    Object result;
    boolean checkMethodResult = false;

    if (parmsLength < 0) {
      if (parmsLength == VARARGS_METHOD) {
        Object[] invokeArgs = {cx, thisObj, args, this};
        result = member.invoke(null, invokeArgs);
        checkMethodResult = true;
      } else {
        boolean inNewExpr = (thisObj == null);
        Boolean b = inNewExpr ? Boolean.TRUE : Boolean.FALSE;
        Object[] invokeArgs = {cx, args, this, b};
        result =
            (member.isCtor()) ? member.newInstance(invokeArgs) : member.invoke(null, invokeArgs);
      }

    } else {
      if (!isStatic) {
        Class clazz = member.getDeclaringClass();
        if (!clazz.isInstance(thisObj)) {
          boolean compatible = false;
          if (thisObj == scope) {
            Scriptable parentScope = getParentScope();
            if (scope != parentScope) {
              // Call with dynamic scope for standalone function,
              // use parentScope as thisObj
              compatible = clazz.isInstance(parentScope);
              if (compatible) {
                thisObj = parentScope;
              }
            }
          }
          if (!compatible) {
            // Couldn't find an object to call this on.
            throw ScriptRuntime.typeError1("msg.incompat.call", functionName);
          }
        }
      }

      Object[] invokeArgs;
      if (parmsLength == args.length) {
        // Do not allocate new argument array if java arguments are
        // the same as the original js ones.
        invokeArgs = args;
        for (int i = 0; i != parmsLength; ++i) {
          Object arg = args[i];
          Object converted = convertArg(cx, scope, arg, typeTags[i]);
          if (arg != converted) {
            if (invokeArgs == args) {
              invokeArgs = (Object[]) args.clone();
            }
            invokeArgs[i] = converted;
          }
        }
      } else if (parmsLength == 0) {
        invokeArgs = ScriptRuntime.emptyArgs;
      } else {
        invokeArgs = new Object[parmsLength];
        for (int i = 0; i != parmsLength; ++i) {
          Object arg = (i < args.length) ? args[i] : Undefined.instance;
          invokeArgs[i] = convertArg(cx, scope, arg, typeTags[i]);
        }
      }

      if (member.isMethod()) {
        result = member.invoke(thisObj, invokeArgs);
        checkMethodResult = true;
      } else {
        result = member.newInstance(invokeArgs);
      }
    }

    if (checkMethodResult) {
      if (hasVoidReturn) {
        result = Undefined.instance;
      } else if (returnTypeTag == JAVA_UNSUPPORTED_TYPE) {
        result = cx.getWrapFactory().wrap(cx, scope, result, null);
      }
      // XXX: the code assumes that if returnTypeTag == JAVA_OBJECT_TYPE
      // then the Java method did a proper job of converting the
      // result to JS primitive or Scriptable to avoid
      // potentially costly Context.javaToJS call.
    }

    return result;
  }
  /**
   * @deprecated Use {@link Context#getWrapFactory()} together with calling {@link
   *     WrapFactory#wrap(Context, Scriptable, Object, Class)}
   */
  public static Object wrap(Scriptable scope, Object obj, Class<?> staticType) {

    Context cx = Context.getContext();
    return cx.getWrapFactory().wrap(cx, scope, obj, staticType);
  }