Beispiel #1
0
 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));
     }
   }
 }
Beispiel #2
0
  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));
      }
    }
  }
Beispiel #3
0
  /**
   * 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);
    }
  }
Beispiel #4
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) {
        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();
      }
    }
  }