package water.api;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
import water.H2O.H2OCountedCompleter;
import water.H2O;
import water.schemas.HTTP500V1;
import water.schemas.Schema;
import water.util.Log;
public abstract class Handler<H extends Handler<H,S>,S extends Schema<H,S>> extends H2OCountedCompleter {
private long _t_start, _t_stop; // Start/Stop time in ms for the serve() call
/** Default supported versions: Version 2 onwards, not Version 1. Override
* in child handlers to e.g. support V1. */
protected int min_ver() { return 2; }
protected int max_ver() { return Integer.MAX_VALUE; }
/** Dumb Version->Schema mapping */
abstract protected S schema(int version);
// Invoke the handler with parameters. Can throw any exception the called handler can throw.
protected final Schema handle(int version, Method meth, Properties parms) throws Exception {
if( !(min_ver() <= version && version <= max_ver()) ) // Version check!
return new HTTP500V1(new IllegalArgumentException("Version "+version+" is not in range V"+min_ver()+"-V"+max_ver()));
// Make a version-specific Schema; primitive-parse the URL into the Schema,
// fill the Handler from the versioned Schema.
S s = schema(version).fillFrom(parms).fillInto((H)this); // Version-specific Schema
// Run the Handler in the Nano Thread (nano does not grok CPS!)
_t_start = System.currentTimeMillis();
try { meth.invoke(this); }
// Exception throws out of the invoked method turn into InvocationTargetException
// rather uselessly. Peel out the original exception & throw it.
catch( InvocationTargetException ite ) {
Throwable t = ite.getCause();
throw (t instanceof Exception) ? (Exception)t : new RuntimeException(t);
}
_t_stop = System.currentTimeMillis();
// Version-specific unwind from the Handler back into the Schema
return s.fillFrom((H)this);
}
}