/** * Invoke instance or class method with arguments. If this method <code>object</code> argument is a {@link Class} * delegate {@link #invoke(Object, Class, String, Object...)} with first argument set to null; otherwise * <code>object</code> is passed as first argument and its class the second. * * @param object object instance or class, * @param methodName method name, * @param arguments variable number of arguments. * @param <T> returned value type. * @return value returned by method or null. * @throws NoSuchBeingException if method is not found. * @throws Exception if invocation fail for whatever reason including method internals. */ public static <T> T invoke(Object object, String methodName, Object... arguments) throws Exception { Params.notNull(object, "Object"); Params.notNullOrEmpty(methodName, "Method name"); if(object instanceof Class<?>) { return invoke(null, (Class<?>)object, methodName, arguments); } else { return invoke(object, object.getClass(), methodName, arguments); } }
@Override public EList call(String elementMethodName, Object... args) { for (int i = 0; i < size(); ++i) { Element element = item(i); try { Classes.invoke(element, elementMethodName, args); } catch (Throwable e) { throw new BugError(e); } } return this; }
/** * Invoke setter method on given object instance. Setter name has format as accepted by * {@link Strings#getMethodAccessor(String, String)} and value string is converted to method parameter type using * {@link Converter} facility. For this reason set parameter type should have a converter registered. * <p> * This method has no means to determine method using {@link Class#getMethod(String, Class...)} because parameter * value is always string and setter parameter type is unknown. For this reason this method uses * {@link #findMethod(Class, String)}. Note that find method searches for named method on object super hierarchy too. * * @param object object instance, * @param name setter name, method name only without <code>set</code> prefix, dashed case accepted, * @param value value to set, string value that is converted to setter method parameter type. * @throws NoSuchMethodException if setter not found. * @throws Exception if invocation fail for whatever reason including method logic. */ public static void invokeSetter(Object object, String name, String value) throws NoSuchMethodException, Exception { String setterName = Strings.getMethodAccessor("set", name); Class<?> clazz = object.getClass(); Method method = findMethod(clazz, setterName); Class<?>[] parameterTypes = method.getParameterTypes(); if(parameterTypes.length != 1) { throw new NoSuchMethodException(String.format("%s#%s", clazz.getName(), setterName)); } invoke(object, method, ConverterRegistry.getConverter().asObject((String)value, parameterTypes[0])); }
/** * Close given <code>closeable</code> if not null but ignoring IO exception generated by failing close operation. * Please note that this helper method does not throw {@link IOException} if close operation fails but still record * the event to error logger. * * @param closeable closeable to close. */ public static void close(Closeable closeable) { if(closeable == null) { return; } try { closeable.close(); } catch(IOException e) { log.error(e); } catch(IncompatibleClassChangeError error) { log.debug("Closeable interface not implemented. Invoke close method directly on instance |%s|.", closeable.getClass()); try { Classes.invoke(closeable, "close"); } catch(Throwable throwable) { log.error(throwable); } } }
/** * Variant for {@link #invokeSetter(Object, String, String)} but no exception if setter not found. * * @param object object instance, * @param name setter name, * @param value value to set. * @throws Exception if invocation fail for whatever reason including method logic. */ public static void invokeOptionalSetter(Object object, String name, String value) throws Exception { String setterName = Strings.getMethodAccessor("set", name); Class<?> clazz = object.getClass(); Method method = null; try { method = findMethod(clazz, setterName); } catch(NoSuchMethodException e) { log.debug("Setter |%s| not found in class |%s| or its super hierarchy.", setterName, clazz); return; } Class<?>[] parameterTypes = method.getParameterTypes(); if(parameterTypes.length != 1) { log.debug("Setter |%s#%s(%s)| with invalid parameters number.", method.getDeclaringClass(), method.getName(), Strings.join(parameterTypes, ',')); return; } invoke(object, method, ConverterRegistry.getConverter().asObject((String)value, parameterTypes[0])); }