package iiuf.util; import java.util.Vector; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import iiuf.log.Log; /** An async invocation queue. (c) 2000, 2001, IIUF, DIUF<p> @author $Author: ohitz $ @version $Name: $ $Revision: 1.1 $ */ public class AsyncInvocation extends Queue { public static class Result { private boolean valid; private Object result; private Throwable exception; public boolean isValid() { return valid; } public synchronized Object get() { if(valid) return result; else { try{wait();} catch(InterruptedException e) {Util.printStackTrace(e);} } return result; } public synchronized void set(Object result_) { result = result_; valid = true; notify(); } public synchronized void setException(Throwable exception_) { exception = exception_; valid = true; notify(); } } public static class Invocation { public Method method; public Object object; public Object[] args; public Result result = new Result(); Invocation(Method method, Object object) { this(method, object, null); } Invocation(Method method_, Object object_, Object[] args_) { method = method_; object = object_; args = args_; } Invocation create(Object arg) { return new Invocation(method, object, new Object[] {arg}); } Invocation create(Object[] args) { return new Invocation(method, object, args); } void invoke() { try{result.set(method.invoke(object, args));} catch(IllegalAccessException e) { if(!((object.getClass().getModifiers() & Modifier.PUBLIC) == Modifier.PUBLIC)) Log.error("Class of target object must be public."); Util.printStackTrace(e); result.setException(e); } catch(IllegalArgumentException e) { Util.printStackTrace(e); result.setException(e); } catch(InvocationTargetException e) { result.setException(e.getTargetException()); } } } private Vector asyncAccels = new Vector(); public void addAsyncAccelerator(AsyncAccelerator accel) { asyncAccels.add(accel); } public AsyncInvocation(String name) { super(name, Thread.MIN_PRIORITY); } private String argStr(Object[] args) { if(args.length == 0) return ""; String result = args[0].toString(); for(int i = 1; i < args.length; i++) result += "," + args[i].toString(); return result; } protected boolean handle(Object o) { Invocation i = (Invocation)o; // Log.debug("invoking " + i.method + "(" + argStr(i.args) + ") on " + i.object); for(int j = 0; j < asyncAccels.size(); j++) { ((AsyncAccelerator)asyncAccels.elementAt(j)).handle(i, i.result); if(i.result.isValid()) return true; } i.invoke(); return true; } public Result invoke(Object object, String method, Class argType, Object arg) { return invoke(object, method, new Class[] {argType}, new Object[] {arg}); } public Result invoke(Object object, String method, Class[] argTypes, Object[] args) { try{ Invocation i = new Invocation(object.getClass().getMethod(method, argTypes), object, args); Result result = i.result; put(i); return result; } catch(Exception e) {Util.printStackTrace(e);} return null; } } /* $Log: AsyncInvocation.java,v $ Revision 1.1 2002/07/11 12:00:11 ohitz Initial checkin Revision 1.2 2001/01/04 16:28:40 schubige Header update for 2001 and DIUF Revision 1.1 2000/11/09 07:53:09 schubige early checkin for DCJava */