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(); } }
@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; } } }
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)); } } }
@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); } }
private static Object invoke(String m, Object... args) throws Throwable { try { return Java.invokeChildOrStatic(Extension.class, m, args); } catch (InvocationTargetException e) { throw e.getTargetException(); } }
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; }
/** * 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(); }
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)); } } }
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; }
/** * @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}; }
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(); }
@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(); }
/** * 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); } }
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(); } } }