예제 #1
0
  @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()));
    }
  }
예제 #2
0
  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();
      }
    }
  }