Ejemplo n.º 1
0
  /**
   * Gets the specified method from a query module.
   *
   * @param mod query module object
   * @param path path of the module
   * @param name method name
   * @param arity number of arguments
   * @param qc query context
   * @param ii input info
   * @return method if found, {@code null} otherwise
   * @throws QueryException query exception
   */
  private static Method getModMethod(
      final Object mod,
      final String path,
      final String name,
      final long arity,
      final QueryContext qc,
      final InputInfo ii)
      throws QueryException {

    // find method with identical name and arity
    Method meth = null;
    for (final Method m : mod.getClass().getMethods()) {
      if (m.getName().equals(name) && m.getParameterTypes().length == arity) {
        if (meth != null) throw JAVAAMBIG_X.get(ii, "Q{" + path + '}' + name + '#' + arity);
        meth = m;
      }
    }
    if (meth == null) throw FUNCJAVA_X.get(ii, path + ':' + name);

    // check if user has sufficient permissions to call the function
    Perm perm = Perm.ADMIN;
    final QueryModule.Requires req = meth.getAnnotation(QueryModule.Requires.class);
    if (req != null) perm = Perm.get(req.value().name());
    if (!qc.context.user.has(perm)) return null;

    // Add module locks to QueryContext.
    final QueryModule.Lock lock = meth.getAnnotation(QueryModule.Lock.class);
    if (lock != null) {
      for (final String read : lock.read()) qc.readLocks.add(DBLocking.MODULE_PREFIX + read);
      for (final String write : lock.write()) qc.writeLocks.add(DBLocking.MODULE_PREFIX + write);
    }

    return meth;
  }
Ejemplo n.º 2
0
  /**
   * Returns a new Java function instance.
   *
   * @param name function name
   * @param args arguments
   * @param qc query context
   * @param sc static context
   * @param ii input info
   * @return Java function or {@code null}
   * @throws QueryException query exception
   */
  static JavaMapping get(
      final QNm name,
      final Expr[] args,
      final QueryContext qc,
      final StaticContext sc,
      final InputInfo ii)
      throws QueryException {

    final byte[] uri = name.uri();
    // check if URI starts with "java:" prefix (if yes, module must be Java code)
    final boolean java = startsWith(uri, JAVAPREF);

    // rewrite function name: convert dashes to upper-case initials
    final String local = camelCase(string(name.local()));

    // check imported Java modules
    final String path = camelCase(toPath(java ? substring(uri, JAVAPREF.length) : uri));

    final ModuleLoader modules = qc.resources.modules();
    final Object jm = modules.findImport(path);
    if (jm != null) {
      final Method meth = getModMethod(jm, path, local, args.length, qc, ii);
      if (meth != null) return new JavaModuleFunc(sc, ii, jm, meth, args);
    }

    // only allowed with administrator permissions
    if (!qc.context.user.has(Perm.ADMIN)) return null;

    // check addressed class
    try {
      return new JavaFunc(sc, ii, modules.findClass(path), local, args);
    } catch (final ClassNotFoundException ex) {
      // only throw exception if "java:" prefix was explicitly specified
      if (java) throw FUNCJAVA_X.get(ii, path);
    } catch (final Throwable th) {
      throw JAVAINIT_X.get(ii, th);
    }

    // no function found
    return null;
  }