private boolean invokeMethod(String line, PrintWriter out, Method method, String[] fields) throws IllegalAccessException, InvocationTargetException { ArrayList<Object> methodArguments = new ArrayList<Object>(); Class<?>[] parameterTypes = method.getParameterTypes(); if (parameterTypes.length == 2 && parameterTypes[0] == PrintWriter.class && parameterTypes[1] == String.class) { // FIXME: there must be a better way to say "I want to parse the line myself." methodArguments.add(out); methodArguments.add(line); } else { int nextField = 1; for (Class<?> parameterType : parameterTypes) { if (parameterType == PrintWriter.class) { methodArguments.add(out); } else if (parameterType == String.class) { methodArguments.add(fields[nextField++]); } // FIXME: support other common types. "int" seems a likely first candidate. } } method.invoke(handler, methodArguments.toArray()); return true; }
/** * 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; }