/* ** ** Copyright 2013, Jules White ** ** */ package org.magnum.soda.android; import java.lang.reflect.Method; import org.magnum.soda.svc.InvocationDispatcher; import org.magnum.soda.svc.InvocationInfo; import android.os.Handler; public class AndroidInvocationDispatcher implements InvocationDispatcher { private class AsyncResultCatcher { private Object result_; private Exception exception_; public synchronized void set(Object rslt) { result_ = rslt; notifyAll(); } public synchronized void setEx(Exception ex) { exception_ = ex; result_ = ex; notifyAll(); } public synchronized Object get() throws Exception { if (result_ == null) { try { wait(); } catch (Exception e) { } } if (exception_ != null) { throw exception_; } return result_; } } private Handler handler_; private boolean alwaysInUi_; public AndroidInvocationDispatcher(Handler handler) { super(); handler_ = handler; } public AndroidInvocationDispatcher(Handler handler, boolean inui) { this(handler); alwaysInUi_ = inui; } @Override public Object dispatch(final InvocationInfo inv, final Object target) throws Exception { Method m = inv.resolve(target.getClass()); if (alwaysInUi_ || m.getAnnotation(SodaInvokeInUi.class) != null) { final AsyncResultCatcher c = new AsyncResultCatcher(); Runnable r = new Runnable() { @Override public void run() { try { Object rslt = InvocationDispatcher.DEFAULT_DISPATCHER .dispatch(inv, target); c.set(rslt); } catch (Exception e) { c.setEx(e); } } }; handler_.post(r); return c.get(); } else { return InvocationDispatcher.DEFAULT_DISPATCHER .dispatch(inv, target); } } }