コード例 #1
0
 public static <T> T invoke(String m, Object... args) throws Throwable {
   Class claseDelMetodoALlamar = null;
   List<Class> classes = Play.classloader.getAssignableClasses(JustificacionFapController.class);
   if (classes.size() != 0) {
     claseDelMetodoALlamar = classes.get(0);
   } else {
     return (T) Java.invokeStatic(JustificacionFapController.class, m, args);
   }
   try {
     return (T) Java.invokeStaticOrParent(claseDelMetodoALlamar, m, args);
   } catch (InvocationTargetException e) {
     throw e.getTargetException();
   }
 }
コード例 #2
0
ファイル: GroovyTemplate.java プロジェクト: jpbriend/play
 @SuppressWarnings("unchecked")
 void directLoad(byte[] code) throws Exception {
     TClassLoader tClassLoader = new TClassLoader();
     String[] lines = new String(code, "utf-8").split("\n");
     this.linesMatrix = (HashMap<Integer, Integer>) Java.deserialize(Codec.decodeBASE64(lines[1]));
     this.doBodyLines = (HashSet<Integer>) Java.deserialize(Codec.decodeBASE64(lines[3]));
     for (int i = 4; i < lines.length; i = i + 2) {
         String className = lines[i];
         byte[] byteCode = Codec.decodeBASE64(lines[i + 1]);
         Class c = tClassLoader.defineTemplate(className, byteCode);
         if (compiledTemplate == null) {
             compiledTemplate = c;
         }
     }
 }
コード例 #3
0
ファイル: ActionInvoker.java プロジェクト: branaway/play
 private static void handleAfters(Http.Request request) throws Exception {
   List<Method> afters =
       Java.findAllAnnotatedMethods(Controller.getControllerClass(), After.class);
   ControllerInstrumentation.stopActionCall();
   for (Method after : afters) {
     String[] unless = after.getAnnotation(After.class).unless();
     String[] only = after.getAnnotation(After.class).only();
     boolean skip = false;
     for (String un : only) {
       if (!un.contains(".")) {
         un = after.getDeclaringClass().getName().substring(12) + "." + un;
       }
       if (un.equals(request.action)) {
         skip = false;
         break;
       } else {
         skip = true;
       }
     }
     for (String un : unless) {
       if (!un.contains(".")) {
         un = after.getDeclaringClass().getName().substring(12) + "." + un;
       }
       if (un.equals(request.action)) {
         skip = true;
         break;
       }
     }
     if (!skip) {
       after.setAccessible(true);
       inferResult(invokeControllerMethod(after));
     }
   }
 }
コード例 #4
0
 @Override
 public void beforeActionInvocation(Method actionMethod) {
   try {
     Validation.current.set(restore());
     boolean verify = false;
     for (Annotation[] annotations : actionMethod.getParameterAnnotations()) {
       if (annotations.length > 0) {
         verify = true;
         break;
       }
     }
     if (!verify) {
       return;
     }
     List<ConstraintViolation> violations = new Validator().validateAction(actionMethod);
     ArrayList<Error> errors = new ArrayList<Error>();
     String[] paramNames = Java.parameterNames(actionMethod);
     for (ConstraintViolation violation : violations) {
       errors.add(
           new Error(
               paramNames[((MethodParameterContext) violation.getContext()).getParameterIndex()],
               violation.getMessage(),
               violation.getMessageVariables() == null
                   ? new String[0]
                   : violation.getMessageVariables().values().toArray(new String[0])));
     }
     Validation.current.get().errors.addAll(errors);
   } catch (Exception e) {
     throw new UnexpectedException(e);
   }
 }
コード例 #5
0
ファイル: Admin.java プロジェクト: codeborne/play-cms
 private static Object invoke(String m, Object... args) throws Throwable {
   try {
     return Java.invokeChildOrStatic(Extension.class, m, args);
   } catch (InvocationTargetException e) {
     throw e.getTargetException();
   }
 }
コード例 #6
0
ファイル: ActionInvoker.java プロジェクト: branaway/play
  public static Object[] getActionMethodArgs(Method method, Object o) throws Exception {
    String[] paramsNames = Java.parameterNames(method);
    if (paramsNames == null && method.getParameterTypes().length > 0) {
      throw new UnexpectedException("Parameter names not found for method " + method);
    }

    // Check if we have already performed the bind operation
    Object[] rArgs = CachedBoundActionMethodArgs.current().retrieveActionMethodArgs(method);
    if (rArgs != null) {
      // We have already performed the binding-operation for this method
      // in this request.
      return rArgs;
    }

    rArgs = new Object[method.getParameterTypes().length];
    for (int i = 0; i < method.getParameterTypes().length; i++) {

      Class<?> type = method.getParameterTypes()[i];
      Map<String, String[]> params = new HashMap<String, String[]>();

      // In case of simple params, we don't want to parse the body.
      if (type.equals(String.class) || Number.class.isAssignableFrom(type) || type.isPrimitive()) {
        params.put(paramsNames[i], Scope.Params.current().getAll(paramsNames[i]));
      } else {
        params.putAll(Scope.Params.current().all());
      }
      Logger.trace(
          "getActionMethodArgs name ["
              + paramsNames[i]
              + "] annotation ["
              + Utils.join(method.getParameterAnnotations()[i], " ")
              + "]");

      RootParamNode root = ParamNode.convert(params);
      rArgs[i] =
          Binder.bind(
              root,
              paramsNames[i],
              method.getParameterTypes()[i],
              method.getGenericParameterTypes()[i],
              method.getParameterAnnotations()[i],
              new Binder.MethodAndParamInfo(o, method, i + 1));
    }

    CachedBoundActionMethodArgs.current().storeActionMethodArgs(method, rArgs);
    return rArgs;
  }
コード例 #7
0
  /**
   * Parses the playframework action expressions. The string inside "()" is evaluated by OGNL in the
   * current context.
   *
   * @param arguments
   * @param attributeValue e.g. "Application.show(obj.id)"
   * @return parsed action path
   */
  @SuppressWarnings("unchecked")
  static String toActionString(final Arguments arguments, String attributeValue) {
    Matcher matcher = PARAM_PATTERN.matcher(attributeValue);
    if (!matcher.matches()) {
      return Router.reverse(attributeValue).toString();
    }

    String exp = matcher.group(1);
    if (StringUtils.isBlank(exp)) {
      return Router.reverse(attributeValue).toString();
    }

    Object obj =
        PlayOgnlVariableExpressionEvaluator.INSTANCE.evaluate(
            arguments.getConfiguration(), arguments, exp, false);
    if (obj instanceof Map) {
      return Router.reverse(attributeValue, (Map<String, Object>) obj).toString();
    }

    List<?> list = obj instanceof List ? (List<?>) obj : Arrays.asList(obj);

    Map<String, Object> paramMap = new HashMap<String, Object>();

    String extracted = StringUtils.substringBefore(attributeValue, "(");
    if (!extracted.contains(".")) {
      extracted = Request.current().controller + "." + extracted;
    }
    Object[] actionMethods = ActionInvoker.getActionMethod(extracted);
    String[] paramNames = null;
    try {
      paramNames = Java.parameterNames((Method) actionMethods[1]);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    if (paramNames.length < list.size()) {
      Logger.warn("param length unmatched. %s", Arrays.toString(paramNames));
      throw new ActionNotFoundException(attributeValue, null);
    }

    for (int i = 0; i < list.size(); i++) {
      paramMap.put(paramNames[i], list.get(i));
    }

    return Router.reverse(extracted, paramMap).toString();
  }
コード例 #8
0
ファイル: ActionInvoker.java プロジェクト: jkot/play
  private static void handleBefores(Http.Request request) throws Exception {
    List<Method> befores =
        Java.findAllAnnotatedMethods(Controller.getControllerClass(), Before.class);
    Collections.sort(
        befores,
        new Comparator<Method>() {

          public int compare(Method m1, Method m2) {
            Before before1 = m1.getAnnotation(Before.class);
            Before before2 = m2.getAnnotation(Before.class);
            return before1.priority() - before2.priority();
          }
        });
    ControllerInstrumentation.stopActionCall();
    for (Method before : befores) {
      String[] unless = before.getAnnotation(Before.class).unless();
      String[] only = before.getAnnotation(Before.class).only();
      boolean skip = false;
      for (String un : only) {
        if (!un.contains(".")) {
          un = before.getDeclaringClass().getName().substring(12).replace("$", "") + "." + un;
        }
        if (un.equals(request.action)) {
          skip = false;
          break;
        } else {
          skip = true;
        }
      }
      for (String un : unless) {
        if (!un.contains(".")) {
          un = before.getDeclaringClass().getName().substring(12).replace("$", "") + "." + un;
        }
        if (un.equals(request.action)) {
          skip = true;
          break;
        }
      }
      if (!skip) {
        before.setAccessible(true);
        inferResult(invokeControllerMethod(before));
      }
    }
  }
コード例 #9
0
ファイル: CRUD.java プロジェクト: playframework/play1
 public static ObjectType get(Class<? extends Controller> controllerClass) {
   Class<? extends Model> entityClass = getEntityClassForController(controllerClass);
   if (entityClass == null || !Model.class.isAssignableFrom(entityClass)) {
     return null;
   }
   ObjectType type;
   try {
     type =
         (ObjectType)
             Java.invokeStaticOrParent(controllerClass, "createObjectType", entityClass);
   } catch (Exception e) {
     Logger.error(e, "Couldn't create an ObjectType. Use default one.");
     type = new ObjectType(entityClass);
   }
   type.name = controllerClass.getSimpleName().replace("$", "");
   type.controllerName = controllerClass.getSimpleName().toLowerCase().replace("$", "");
   type.controllerClass = controllerClass;
   return type;
 }
コード例 #10
0
ファイル: ActionInvoker.java プロジェクト: branaway/play
 /**
  * @author Bing Ran ([email protected])
  * @param fullAction
  * @return the controller class and the action method, in the format of [<class<?>>, Method]
  */
 public static Object[] getActionMethod(String fullAction) {
   Method actionMethod = null;
   Class controllerClass = null;
   try {
     if (!fullAction.startsWith("controllers.")) {
       fullAction = "controllers." + fullAction;
     }
     String controller = fullAction.substring(0, fullAction.lastIndexOf("."));
     String action = fullAction.substring(fullAction.lastIndexOf(".") + 1);
     controllerClass = Play.classloader.getClassIgnoreCase(controller);
     if (controllerClass == null) {
       throw new ActionNotFoundException(
           fullAction, new Exception("Controller " + controller + " not found"));
     }
     if (!ControllerSupport.class.isAssignableFrom(controllerClass)) {
       // Try the scala way
       controllerClass = Play.classloader.getClassIgnoreCase(controller + "$");
       if (!ControllerSupport.class.isAssignableFrom(controllerClass)) {
         throw new ActionNotFoundException(
             fullAction,
             new Exception("class " + controller + " does not extend play.mvc.Controller"));
       }
     }
     actionMethod = Java.findActionMethod(action, controllerClass);
     if (actionMethod == null) {
       throw new ActionNotFoundException(
           fullAction,
           new Exception(
               "No method public static void " + action + "() was found in class " + controller));
     }
   } catch (PlayException e) {
     throw e;
   } catch (Exception e) {
     throw new ActionNotFoundException(fullAction, e);
   }
   return new Object[] {controllerClass, actionMethod};
 }
コード例 #11
0
ファイル: GroovyTemplate.java プロジェクト: jpbriend/play
    public void compile() {
        if (compiledTemplate == null) {
            try {
                long start = System.currentTimeMillis();

                TClassLoader tClassLoader = new TClassLoader();

                // Let's compile the groovy source
                final List<GroovyClass> groovyClassesForThisTemplate = new ArrayList<GroovyClass>();
                // ~~~ Please !
                CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
                compilerConfiguration.setSourceEncoding("utf-8"); // ouf
                CompilationUnit compilationUnit = new CompilationUnit(compilerConfiguration);
                compilationUnit.addSource(new SourceUnit(name, compiledSource, compilerConfiguration, tClassLoader, compilationUnit.getErrorCollector()));
                Field phasesF = compilationUnit.getClass().getDeclaredField("phaseOperations");
                phasesF.setAccessible(true);
                LinkedList[] phases = (LinkedList[]) phasesF.get(compilationUnit);
                LinkedList<GroovyClassOperation> output = new LinkedList<GroovyClassOperation>();
                phases[Phases.OUTPUT] = output;
                output.add(new GroovyClassOperation() {
                    public void call(GroovyClass gclass) {
                        groovyClassesForThisTemplate.add(gclass);
                    }
                });
                compilationUnit.compile();
                // ouf 

                // Define script classes
                StringBuilder sb = new StringBuilder();
                sb.append("LINESMATRIX" + "\n");
                sb.append(Codec.encodeBASE64(Java.serialize(linesMatrix)).replaceAll("\\s", ""));
                sb.append("\n");
                sb.append("DOBODYLINES" + "\n");
                sb.append(Codec.encodeBASE64(Java.serialize(doBodyLines)).replaceAll("\\s", ""));
                sb.append("\n");
                for (GroovyClass gclass : groovyClassesForThisTemplate) {
                    tClassLoader.defineTemplate(gclass.getName(), gclass.getBytes());
                    sb.append(gclass.getName() + "\n");
                    sb.append(Codec.encodeBASE64(gclass.getBytes()).replaceAll("\\s", ""));
                    sb.append("\n");
                }
                // Cache
                BytecodeCache.cacheBytecode(sb.toString().getBytes("utf-8"), name, source);
                compiledTemplate = tClassLoader.loadClass(groovyClassesForThisTemplate.get(0).getName());
                if (System.getProperty("precompile") != null) {
                    try {
                        // emit bytecode to standard class layout as well
                        File f = Play.getFile("precompiled/templates/" + name.replaceAll("\\{(.*)\\}", "from_$1").replace(":", "_").replace("..", "parent"));
                        f.getParentFile().mkdirs();
                        FileOutputStream fos = new FileOutputStream(f);
                        fos.write(sb.toString().getBytes("utf-8"));
                        fos.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                Logger.trace("%sms to compile template %s to %d classes", System.currentTimeMillis() - start, name, groovyClassesForThisTemplate.size());

            } catch (MultipleCompilationErrorsException e) {
                if (e.getErrorCollector().getLastError() != null) {
                    SyntaxErrorMessage errorMessage = (SyntaxErrorMessage) e.getErrorCollector().getLastError();
                    SyntaxException syntaxException = errorMessage.getCause();
                    Integer line = this.linesMatrix.get(syntaxException.getLine());
                    if (line == null) {
                        line = 0;
                    }
                    String message = syntaxException.getMessage();
                    if (message.indexOf("@") > 0) {
                        message = message.substring(0, message.lastIndexOf("@"));
                    }
                    throw new TemplateCompilationException(this, line, message);
                }
                throw new UnexpectedException(e);
            } catch (Exception e) {
                throw new UnexpectedException(e);
            }
        }
        compiledTemplateName = compiledTemplate.getName();
    }
コード例 #12
0
ファイル: JobsPlugin.java プロジェクト: hopcroft/databus
  @Override
  public String getStatus() {
    StringWriter sw = new StringWriter();
    PrintWriter out = new PrintWriter(sw);
    if (executor == null) {
      out.println("Jobs execution pool:");
      out.println("~~~~~~~~~~~~~~~~~~~");
      out.println("(not yet started)");
      return sw.toString();
    }
    out.println("Jobs execution pool:");
    out.println("~~~~~~~~~~~~~~~~~~~");
    out.println("Pool size: " + executor.getPoolSize());
    out.println("Active count: " + executor.getActiveCount());
    out.println("Scheduled task count: " + executor.getTaskCount());
    out.println("Queue size: " + executor.getQueue().size());
    SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
    if (!scheduledJobs.isEmpty()) {
      out.println();
      out.println("Scheduled jobs (" + scheduledJobs.size() + "):");
      out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~");
      for (Job job : scheduledJobs) {
        out.print(job.getClass().getName());
        if (job.getClass().isAnnotationPresent(OnApplicationStart.class)) {
          OnApplicationStart appStartAnnotation =
              job.getClass().getAnnotation(OnApplicationStart.class);
          out.print(
              " run at application start" + (appStartAnnotation.async() ? " (async)" : "") + ".");
        }

        if (job.getClass().isAnnotationPresent(On.class)) {

          String cron = job.getClass().getAnnotation(On.class).value();
          if (cron != null && cron.startsWith("cron.")) {
            cron = Play.configuration.getProperty(cron);
          }
          out.print(" run with cron expression " + cron + ".");
        }
        if (job.getClass().isAnnotationPresent(Every.class)) {
          out.print(" run every " + job.getClass().getAnnotation(Every.class).value() + ".");
        }
        if (job.lastRun > 0) {
          out.print(" (last run at " + df.format(new Date(job.lastRun)));
          if (job.wasError) {
            out.print(" with error)");
          } else {
            out.print(")");
          }
        } else {
          out.print(" (has never run)");
        }
        out.println();
      }
    }
    if (!executor.getQueue().isEmpty()) {
      out.println();
      out.println("Waiting jobs:");
      out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~");
      for (Object o : executor.getQueue()) {
        ScheduledFuture task = (ScheduledFuture) o;
        out.println(
            Java.extractUnderlyingCallable((FutureTask) task)
                + " will run in "
                + task.getDelay(TimeUnit.SECONDS)
                + " seconds");
      }
    }
    return sw.toString();
  }
コード例 #13
0
ファイル: ActionInvoker.java プロジェクト: branaway/play
  /**
   * Checks and calla all methods in controller annotated with @Finally. The caughtException-value
   * is sent as argument to @Finally-method if method has one argument which is Throwable
   *
   * @param request
   * @param caughtException If @Finally-methods are called after an error, this variable holds the
   *     caught error
   * @throws PlayException
   */
  static void handleFinallies(Http.Request request, Throwable caughtException)
      throws PlayException {

    if (Controller.getControllerClass() == null) {
      // skip it
      return;
    }

    try {
      List<Method> allFinally =
          Java.findAllAnnotatedMethods(Controller.getControllerClass(), Finally.class);
      ControllerInstrumentation.stopActionCall();
      for (Method aFinally : allFinally) {
        String[] unless = aFinally.getAnnotation(Finally.class).unless();
        String[] only = aFinally.getAnnotation(Finally.class).only();
        boolean skip = false;
        for (String un : only) {
          if (!un.contains(".")) {
            un = aFinally.getDeclaringClass().getName().substring(12) + "." + un;
          }
          if (un.equals(request.action)) {
            skip = false;
            break;
          } else {
            skip = true;
          }
        }
        for (String un : unless) {
          if (!un.contains(".")) {
            un = aFinally.getDeclaringClass().getName().substring(12) + "." + un;
          }
          if (un.equals(request.action)) {
            skip = true;
            break;
          }
        }
        if (!skip) {
          aFinally.setAccessible(true);

          // check if method accepts Throwable as only parameter
          Class[] parameterTypes = aFinally.getParameterTypes();
          if (parameterTypes.length == 1 && parameterTypes[0] == Throwable.class) {
            // invoking @Finally method with caughtException as
            // parameter
            invokeControllerMethod(aFinally, new Object[] {caughtException});
          } else {
            // invoce @Finally-method the regular way without
            // caughtException
            invokeControllerMethod(aFinally, null);
          }
        }
      }
    } catch (InvocationTargetException ex) {
      StackTraceElement element =
          PlayException.getInterestingStackTraceElement(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 (Exception e) {
      throw new UnexpectedException("Exception while doing @Finally", e);
    }
  }
コード例 #14
0
ファイル: ActionInvoker.java プロジェクト: branaway/play
  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) {
        Class<Controller> cclass = Controller.class;
        cclass.getDeclaredField("params").set(null, Scope.Params.current());
        cclass.getDeclaredField("request").set(null, Http.Request.current());
        cclass.getDeclaredField("response").set(null, Http.Response.current());
        cclass.getDeclaredField("session").set(null, Scope.Session.current());
        cclass.getDeclaredField("flash").set(null, Scope.Flash.current());
        cclass.getDeclaredField("renderArgs").set(null, Scope.RenderArgs.current());
        cclass.getDeclaredField("routeArgs").set(null, Scope.RouteArgs.current());
        cclass.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 (Result result) {
            actionResult = result;
            // Cache it if needed
            if (cacheKey != null) {
              play.cache.Cache.set(
                  cacheKey, actionResult, actionMethod.getAnnotation(CacheFor.class).value());
            }
          } 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);
              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.getInterestingStackTraceElement(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 {
      Play.pluginCollection.onActionInvocationFinally();

      if (monitor != null) {
        monitor.stop();
      }
    }
  }