Skip to content

Instantly share code, notes, and snippets.

@martinus
Created April 17, 2009 14:04
Show Gist options
  • Save martinus/97038 to your computer and use it in GitHub Desktop.
Save martinus/97038 to your computer and use it in GitHub Desktop.
package com.ankerl.stuff;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* Calls multiple methods with a single interface.
*
* @author Martin Ankerl (martin.ankerl@gmail.com)
* @param <X>
* Return type.
*/
public class MethodsToProc<X> implements Iterable<MethodsToProc.Proc<X>> {
/**
* Contains all the wrapped methods.
*/
private final Collection<Proc<X>> mCallers;
/**
* The callable interface used for each method that should be called.
*/
public static class Proc<Output> {
private final Method mM;
private final Object mO;
public Proc(final Object o, final Method m) {
mO = o;
mM = m;
}
@SuppressWarnings("unchecked")
public Output call() {
try {
return (Output) mM.invoke(mO, new Object[] {});
} catch (final IllegalArgumentException e) {
throw new Exception(e);
} catch (final IllegalAccessException e) {
throw new Exception(e);
} catch (final InvocationTargetException e) {
throw new Exception(e);
}
}
/**
* Gets the method that will be invoked.
*
* @return
*/
public Method getMethod() {
return mM;
}
}
/**
* Thrown when invocation fails for any reason.
*/
@SuppressWarnings("serial")
public static class Exception extends RuntimeException {
public Exception(final Throwable t) {
super(t);
}
}
/**
* Warps all methods that have the @Callable exception into a Caller, which
* can be called later.
*
* @param o
* The object to wrap.
* @param returnType
* The return type.
*/
public MethodsToProc(final Object o) {
mCallers = new ArrayList<Proc<X>>();
for (final Method m : o.getClass().getMethods()) {
if (m.getAnnotation(Callable.class) != null) {
mCallers.add(new Proc<X>(o, m));
}
}
}
/**
* Creates a new iterable callable for each method with the @Callable
* annotation.
*
* @param <X>
* The return type of the callable.
* @param o
* The object to wrap.
* @param returnType
* The return class.
* @return
*/
public static <X> MethodsToProc<X> create(final Object o) {
return new MethodsToProc<X>(o);
}
@Override
public Iterator<Proc<X>> iterator() {
return mCallers.iterator();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment