Example #1
0
 private Object translateMsgArg(
     List<Object> arguments, MessagesApi messagesApi, play.i18n.Lang lang) {
   if (arguments != null) {
     return arguments
         .stream()
         .map(
             arg -> {
               if (arg instanceof String) {
                 return messagesApi.get(lang, (String) arg);
               }
               if (arg instanceof List) {
                 return ((List<?>) arg)
                     .stream()
                     .map(key -> messagesApi.get(lang, (String) key))
                     .collect(Collectors.toList());
               }
               return arg;
             })
         .collect(Collectors.toList());
   } else {
     return null;
   }
 }
Example #2
0
 /** Returns the form errors serialized as Json using the given Lang. */
 public com.fasterxml.jackson.databind.JsonNode errorsAsJson(play.i18n.Lang lang) {
   Map<String, List<String>> allMessages = new HashMap<>();
   for (String key : errors.keySet()) {
     List<ValidationError> errs = errors.get(key);
     if (errs != null && !errs.isEmpty()) {
       List<String> messages = new ArrayList<String>();
       for (ValidationError error : errs) {
         if (messagesApi != null && lang != null) {
           messages.add(
               messagesApi.get(
                   lang, error.messages(), translateMsgArg(error.arguments(), messagesApi, lang)));
         } else {
           messages.add(error.message());
         }
       }
       allMessages.put(key, messages);
     }
   }
   return play.libs.Json.toJson(allMessages);
 }
Example #3
0
  /**
   * Binds data to this form - that is, handles form submission.
   *
   * @param data data to submit
   * @return a copy of this form filled with the new data
   */
  @SuppressWarnings("unchecked")
  public Form<T> bind(Map<String, String> data, String... allowedFields) {

    DataBinder dataBinder;
    Map<String, String> objectData = data;
    if (rootName == null) {
      dataBinder = new DataBinder(blankInstance());
    } else {
      dataBinder = new DataBinder(blankInstance(), rootName);
      objectData = new HashMap<>();
      for (String key : data.keySet()) {
        if (key.startsWith(rootName + ".")) {
          objectData.put(key.substring(rootName.length() + 1), data.get(key));
        }
      }
    }
    if (allowedFields.length > 0) {
      dataBinder.setAllowedFields(allowedFields);
    }
    SpringValidatorAdapter validator =
        new SpringValidatorAdapter(play.data.validation.Validation.getValidator());
    dataBinder.setValidator(validator);
    dataBinder.setConversionService(formatters.conversion);
    dataBinder.setAutoGrowNestedPaths(true);
    final Map<String, String> objectDataFinal = objectData;
    withRequestLocale(
        () -> {
          dataBinder.bind(new MutablePropertyValues(objectDataFinal));
          return null;
        });
    Set<ConstraintViolation<Object>> validationErrors;
    if (groups != null) {
      validationErrors = validator.validate(dataBinder.getTarget(), groups);
    } else {
      validationErrors = validator.validate(dataBinder.getTarget());
    }

    BindingResult result = dataBinder.getBindingResult();

    for (ConstraintViolation<Object> violation : validationErrors) {
      String field = violation.getPropertyPath().toString();
      FieldError fieldError = result.getFieldError(field);
      if (fieldError == null || !fieldError.isBindingFailure()) {
        try {
          result.rejectValue(
              field,
              violation.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName(),
              getArgumentsForConstraint(
                  result.getObjectName(), field, violation.getConstraintDescriptor()),
              getMessageForConstraintViolation(violation));
        } catch (NotReadablePropertyException ex) {
          throw new IllegalStateException(
              "JSR-303 validated property '"
                  + field
                  + "' does not have a corresponding accessor for data binding - "
                  + "check your DataBinder's configuration (bean property versus direct field access)",
              ex);
        }
      }
    }

    if (result.hasErrors() || result.getGlobalErrorCount() > 0) {
      Map<String, List<ValidationError>> errors = new HashMap<>();
      for (FieldError error : result.getFieldErrors()) {
        String key = error.getObjectName() + "." + error.getField();
        if (key.startsWith("target.") && rootName == null) {
          key = key.substring(7);
        }
        if (!errors.containsKey(key)) {
          errors.put(key, new ArrayList<>());
        }

        ValidationError validationError;
        if (error.isBindingFailure()) {
          ImmutableList.Builder<String> builder = ImmutableList.builder();
          Optional<Messages> msgs =
              Optional.of(Http.Context.current.get()).map(c -> messagesApi.preferred(c.request()));
          for (String code : error.getCodes()) {
            code = code.replace("typeMismatch", "error.invalid");
            if (!msgs.isPresent() || msgs.get().isDefinedAt(code)) {
              builder.add(code);
            }
          }
          validationError =
              new ValidationError(
                  key, builder.build().reverse(), convertErrorArguments(error.getArguments()));
        } else {
          validationError =
              new ValidationError(
                  key, error.getDefaultMessage(), convertErrorArguments(error.getArguments()));
        }
        errors.get(key).add(validationError);
      }

      List<ValidationError> globalErrors = new ArrayList<>();

      for (ObjectError error : result.getGlobalErrors()) {
        globalErrors.add(
            new ValidationError(
                "", error.getDefaultMessage(), convertErrorArguments(error.getArguments())));
      }

      if (!globalErrors.isEmpty()) {
        errors.put("", globalErrors);
      }

      return new Form(
          rootName, backedType, data, errors, Optional.empty(), groups, messagesApi, formatters);
    } else {
      Object globalError = null;
      if (result.getTarget() != null) {
        try {
          java.lang.reflect.Method v = result.getTarget().getClass().getMethod("validate");
          globalError = v.invoke(result.getTarget());
        } catch (NoSuchMethodException e) {
          // do nothing
        } catch (Throwable e) {
          throw new RuntimeException(e);
        }
      }
      if (globalError != null) {
        Map<String, List<ValidationError>> errors = new HashMap<>();
        if (globalError instanceof String) {
          errors.put("", new ArrayList<>());
          errors.get("").add(new ValidationError("", (String) globalError, new ArrayList()));
        } else if (globalError instanceof List) {
          for (ValidationError error : (List<ValidationError>) globalError) {
            List<ValidationError> errorsForKey = errors.get(error.key());
            if (errorsForKey == null) {
              errors.put(error.key(), errorsForKey = new ArrayList<>());
            }
            errorsForKey.add(error);
          }
        } else if (globalError instanceof Map) {
          errors = (Map<String, List<ValidationError>>) globalError;
        }
        return new Form(
            rootName, backedType, data, errors, Optional.empty(), groups, messagesApi, formatters);
      }
      return new Form(
          rootName,
          backedType,
          new HashMap<>(data),
          new HashMap<>(errors),
          Optional.ofNullable((T) result.getTarget()),
          groups,
          messagesApi,
          formatters);
    }
  }