@SuppressWarnings("unchecked") public static void resolve(Http.Request request, Http.Response response) { if (!Play.started) { return; } Http.Request.current.set(request); Http.Response.current.set(response); Scope.Params.current.set(request.params); Scope.RenderArgs.current.set(new Scope.RenderArgs()); Scope.RouteArgs.current.set(new Scope.RouteArgs()); Scope.Session.current.set(Scope.Session.restore()); Scope.Flash.current.set(Scope.Flash.restore()); CachedBoundActionMethodArgs.init(); ControllersEnhancer.currentAction.set(new Stack<String>()); if (request.resolved) { return; } // Route and resolve format if not already done if (request.action == null) { Play.pluginCollection.routeRequest(request); Route route = Router.route(request); Play.pluginCollection.onRequestRouting(route); } request.resolveFormat(); // Find the action method try { Method actionMethod = null; Object[] ca = getActionMethod(request.action); actionMethod = (Method) ca[1]; request.controller = ((Class) ca[0]).getName().substring(12).replace("$", ""); request.controllerClass = ((Class) ca[0]); request.actionMethod = actionMethod.getName(); request.action = request.controller + "." + request.actionMethod; request.invokedMethod = actionMethod; if (Logger.isTraceEnabled()) { Logger.trace("------- %s", actionMethod); } request.resolved = true; } catch (ActionNotFoundException e) { Logger.error(e, "%s action not found", e.getAction()); throw new NotFound(String.format("%s action not found", e.getAction())); } }
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)))); // 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(); } } }