示例#1
1
  static JavaMembers lookupClass(
      Scriptable scope, Class<?> dynamicType, Class<?> staticType, boolean includeProtected) {
    JavaMembers members;
    ClassCache cache = ClassCache.get(scope);
    Map<Class<?>, JavaMembers> ct = cache.getClassCacheMap();

    Class<?> cl = dynamicType;
    for (; ; ) {
      members = ct.get(cl);
      if (members != null) {
        if (cl != dynamicType) {
          // member lookup for the original class failed because of
          // missing privileges, cache the result so we don't try
          // again
          ct.put(dynamicType, members);
        }
        return members;
      }
      try {
        members = new JavaMembers(cache.getAssociatedScope(), cl, includeProtected);
        break;
      } catch (SecurityException e) {
        // Reflection may fail for objects that are in a restricted
        // access package (e.g. sun.*). If we get a security
        // exception, try again with the static type if it is interface.
        // Otherwise, try superclass
        if (staticType != null && staticType.isInterface()) {
          cl = staticType;
          staticType = null; // try staticType only once
        } else {
          Class<?> parent = cl.getSuperclass();
          if (parent == null) {
            if (cl.isInterface()) {
              // last resort after failed staticType interface
              parent = ScriptRuntime.ObjectClass;
            } else {
              throw e;
            }
          }
          cl = parent;
        }
      }
    }

    if (cache.isCachingEnabled()) {
      ct.put(cl, members);
      if (cl != dynamicType) {
        // member lookup for the original class failed because of
        // missing privileges, cache the result so we don't try again
        ct.put(dynamicType, members);
      }
    }
    return members;
  }
示例#2
0
  /**
   * Make glue object implementing interface cl that will call the supplied JS function when called.
   * Only interfaces were all methods have the same signature is supported.
   *
   * @return The glue object or null if <tt>cl</tt> is not interface or has methods with different
   *     signatures.
   */
  static Object create(Context cx, Class<?> cl, Callable function) {
    if (!cl.isInterface()) throw new IllegalArgumentException();

    Scriptable topScope = ScriptRuntime.getTopCallScope(cx);
    ClassCache cache = ClassCache.get(topScope);
    InterfaceAdapter adapter;
    adapter = (InterfaceAdapter) cache.getInterfaceAdapter(cl);
    ContextFactory cf = cx.getFactory();
    if (adapter == null) {
      Method[] methods = cl.getMethods();
      if (methods.length == 0) {
        throw Context.reportRuntimeError2(
            "msg.no.empty.interface.conversion", String.valueOf(function), cl.getClass().getName());
      }
      boolean canCallFunction = false;
      canCallFunctionChecks:
      {
        Class<?>[] argTypes = methods[0].getParameterTypes();
        // check that the rest of methods has the same signature
        for (int i = 1; i != methods.length; ++i) {
          Class<?>[] types2 = methods[i].getParameterTypes();
          if (types2.length != argTypes.length) {
            break canCallFunctionChecks;
          }
          for (int j = 0; j != argTypes.length; ++j) {
            if (types2[j] != argTypes[j]) {
              break canCallFunctionChecks;
            }
          }
        }
        canCallFunction = true;
      }
      if (!canCallFunction) {
        throw Context.reportRuntimeError2(
            "msg.no.function.interface.conversion",
            String.valueOf(function),
            cl.getClass().getName());
      }
      adapter = new InterfaceAdapter(cf, cl);
      cache.cacheInterfaceAdapter(cl, adapter);
    }
    return VMBridge.instance.newInterfaceProxy(
        adapter.proxyHelper, cf, adapter, function, topScope);
  }
示例#3
0
  private static Class<?> getAdapterClass(
      Scriptable scope, Class<?> superClass, Class<?>[] interfaces, Scriptable obj) {
    ClassCache cache = ClassCache.get(scope);
    Map<JavaAdapterSignature, Class<?>> generated = cache.getInterfaceAdapterCacheMap();

    ObjToIntMap names = getObjectFunctionNames(obj);
    JavaAdapterSignature sig;
    sig = new JavaAdapterSignature(superClass, interfaces, names);
    Class<?> adapterClass = generated.get(sig);
    if (adapterClass == null) {
      String adapterName = "adapter" + cache.newClassSerialNumber();
      byte[] code = createAdapterCode(names, adapterName, superClass, interfaces, null);

      adapterClass = loadAdapterClass(adapterName, code);
      if (cache.isCachingEnabled()) {
        generated.put(sig, adapterClass);
      }
    }
    return adapterClass;
  }