Ejemplo n.º 1
0
 @Override
 public Object invokeMethod(String name, Object param) {
     try {
         if (controller == null) {
             controller = Request.current().controller;
         }
         String action = controller + "." + name;
         if (action.endsWith(".call")) {
             action = action.substring(0, action.length() - 5);
         }
         try {
             Map<String, Object> r = new HashMap<String, Object>();
             Method actionMethod = (Method) ActionInvoker.getActionMethod(action)[1];
             String[] names = (String[]) actionMethod.getDeclaringClass().getDeclaredField("$" + actionMethod.getName() + LocalVariablesNamesTracer.computeMethodHash(actionMethod.getParameterTypes())).get(null);
             if (param instanceof Object[]) {
                 // too many parameters versus action, possibly a developer error. we must warn him.
                 if (names.length < ((Object[]) param).length) {
                     throw new NoRouteFoundException(action, null);
                 }
                 for (int i = 0; i < ((Object[]) param).length; i++) {
                     if (((Object[]) param)[i] instanceof Router.ActionDefinition && ((Object[]) param)[i] != null) {
                         Unbinder.unBind(r, ((Object[]) param)[i].toString(), i < names.length ? names[i] : "");
                     } else if (isSimpleParam(actionMethod.getParameterTypes()[i])) {
                         if (((Object[]) param)[i] != null) {
                             Unbinder.unBind(r, ((Object[]) param)[i].toString(), i < names.length ? names[i] : "");
                         }
                     } else {
                         Unbinder.unBind(r, ((Object[]) param)[i], i < names.length ? names[i] : "");
                     }
                 }
             }
             Router.ActionDefinition def = Router.reverse(action, r);
             if (absolute) {
                 def.absolute();
             }
             if (template.template.name.endsWith(".html") || template.template.name.endsWith(".xml")) {
                 def.url = def.url.replace("&", "&amp;");
             }
             return def;
         } catch (ActionNotFoundException e) {
             throw new NoRouteFoundException(action, null);
         }
     } catch (Exception e) {
         if (e instanceof PlayException) {
             throw (PlayException) e;
         }
         throw new UnexpectedException(e);
     }
 }
Ejemplo n.º 2
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();
  }