}
}
public static void invoke(Http.Request request, Http.Response response) {
Monitor monitor = null;
try {
resolve(request, response);
Method actionMethod = request.invokedMethod;
// 1. Prepare request params
Scope.Params.current().__mergeWith(request.routeArgs);
// add parameters from the URI query string
String encoding = Http.Request.current().encoding;
Scope.Params.current()._mergeWith(UrlEncodedParser.parseQueryString(new ByteArrayInputStream(request.querystring.getBytes(encoding))));
Lang.resolvefrom(request);
// 2. Easy debugging ...
if (Play.mode == Play.Mode.DEV) {
Controller.class.getDeclaredField("params").set(null, Scope.Params.current());
Controller.class.getDeclaredField("request").set(null, Http.Request.current());
Controller.class.getDeclaredField("response").set(null, Http.Response.current());
Controller.class.getDeclaredField("session").set(null, Scope.Session.current());
Controller.class.getDeclaredField("flash").set(null, Scope.Flash.current());
Controller.class.getDeclaredField("renderArgs").set(null, Scope.RenderArgs.current());
Controller.class.getDeclaredField("routeArgs").set(null, Scope.RouteArgs.current());
Controller.class.getDeclaredField("validation").set(null, Validation.current());
}
ControllerInstrumentation.stopActionCall();
Play.pluginCollection.beforeActionInvocation(actionMethod);
// Monitoring
monitor = MonitorFactory.start(request.action + "()");
// 3. Invoke the action
try {
// @Before
handleBefores(request);
// Action
Result actionResult = null;
String cacheKey = null;
// Check the cache (only for GET or HEAD)
if ((request.method.equals("GET") || request.method.equals("HEAD")) && actionMethod.isAnnotationPresent(CacheFor.class)) {
cacheKey = actionMethod.getAnnotation(CacheFor.class).id();
if ("".equals(cacheKey)) {
cacheKey = "urlcache:" + request.url + request.querystring;
}
actionResult = (Result) play.cache.Cache.get(cacheKey);
}
if (actionResult == null) {
ControllerInstrumentation.initActionCall();
try {
inferResult(invokeControllerMethod(actionMethod));
} catch (InvocationTargetException ex) {
// It's a Result ? (expected)
if (ex.getTargetException() instanceof Result) {
actionResult = (Result) ex.getTargetException();
// Cache it if needed
if (cacheKey != null) {
play.cache.Cache.set(cacheKey, actionResult, actionMethod.getAnnotation(CacheFor.class).value());
}
} else {
// @Catch
Object[] args = new Object[]{ex.getTargetException()};
List<Method> catches = Java.findAllAnnotatedMethods(Controller.getControllerClass(), Catch.class);
Collections.sort(catches, new Comparator<Method>() {
public int compare(Method m1, Method m2) {
Catch catch1 = m1.getAnnotation(Catch.class);
Catch catch2 = m2.getAnnotation(Catch.class);
return catch1.priority() - catch2.priority();
}
});
ControllerInstrumentation.stopActionCall();
for (Method mCatch : catches) {
Class[] exceptions = mCatch.getAnnotation(Catch.class).value();
if (exceptions.length == 0) {
exceptions = new Class[]{Exception.class};
}
for (Class exception : exceptions) {
if (exception.isInstance(args[0])) {
mCatch.setAccessible(true);
inferResult(invokeControllerMethod(mCatch, args));
break;
}
}
}
throw ex;
}
}
}
// @After
handleAfters(request);
monitor.stop();
monitor = null;
// OK, re-throw the original action result
if (actionResult != null) {
throw actionResult;
}
throw new NoResult();
} catch (IllegalAccessException ex) {
throw ex;
} catch (IllegalArgumentException ex) {
throw ex;
} catch (InvocationTargetException ex) {
// It's a Result ? (expected)
if (ex.getTargetException() instanceof Result) {
throw (Result) ex.getTargetException();
}
// Re-throw the enclosed exception
if (ex.getTargetException() instanceof PlayException) {
throw (PlayException) ex.getTargetException();
}
StackTraceElement element = PlayException.getInterestingStrackTraceElement(ex.getTargetException());
if (element != null) {
throw new JavaExecutionException(Play.classes.getApplicationClass(element.getClassName()), element.getLineNumber(), ex.getTargetException());
}
throw new JavaExecutionException(Http.Request.current().action, ex);
}
} catch (Result result) {
Play.pluginCollection.onActionInvocationResult(result);
// OK there is a result to apply
// Save session & flash scope now
Scope.Session.current().save();
Scope.Flash.current().save();
result.apply(request, response);
Play.pluginCollection.afterActionInvocation();
// @Finally
handleFinallies(request, null);
} catch (PlayException e) {
handleFinallies(request, e);
throw e;
} catch (Throwable e) {
handleFinallies(request, e);
throw new UnexpectedException(e);
} finally {
if (monitor != null) {
monitor.stop();
}
}
}