org.thymeleaf.spring4.util.FieldUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of thymeleaf-spring4 Show documentation
Show all versions of thymeleaf-spring4 Show documentation
XML/XHTML/HTML5 template engine for Java
/*
* =============================================================================
*
* Copyright (c) 2011-2014, The THYMELEAF team (http://www.thymeleaf.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* =============================================================================
*/
package org.thymeleaf.spring4.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.NotReadablePropertyException;
import org.springframework.util.StringUtils;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.servlet.support.BindStatus;
import org.springframework.web.servlet.support.RequestContext;
import org.thymeleaf.context.IExpressionContext;
import org.thymeleaf.exceptions.TemplateProcessingException;
import org.thymeleaf.spring4.naming.SpringContextVariableNames;
import org.thymeleaf.standard.expression.IStandardExpression;
import org.thymeleaf.standard.expression.IStandardExpressionParser;
import org.thymeleaf.standard.expression.SelectionVariableExpression;
import org.thymeleaf.standard.expression.StandardExpressions;
import org.thymeleaf.standard.expression.VariableExpression;
import org.thymeleaf.util.Validate;
/**
*
* Static utility class containing methods for dealing with form fields in Spring-enabled environments.
*
*
* Note a class with this name existed since 1.0, but it was completely reimplemented
* in Thymeleaf 3.0
*
*
* @author Daniel Fernández
* @author Tobias Gafner
*
* @since 3.0.0
*
*/
public final class FieldUtils {
public static final String ALL_FIELDS = "*";
public static final String GLOBAL_EXPRESSION = "global";
public static final String ALL_EXPRESSION = "all";
public static boolean hasErrors(final IExpressionContext context, final String field) {
return checkErrors(context, convertToFieldExpression(field));
}
public static boolean hasAnyErrors(final IExpressionContext context) {
return checkErrors(context, ALL_EXPRESSION);
}
public static boolean hasGlobalErrors(final IExpressionContext context) {
return checkErrors(context, GLOBAL_EXPRESSION);
}
public static List errors(final IExpressionContext context, final String field) {
return computeErrors(context, convertToFieldExpression(field));
}
public static List errors(final IExpressionContext context) {
return computeErrors(context, ALL_EXPRESSION);
}
public static List globalErrors(final IExpressionContext context) {
return computeErrors(context, GLOBAL_EXPRESSION);
}
private static List computeErrors(final IExpressionContext context, final String fieldExpression) {
final BindStatus bindStatus = FieldUtils.getBindStatus(context, fieldExpression);
if (bindStatus == null) {
return Collections.EMPTY_LIST;
}
final String[] errorMessages = bindStatus.getErrorMessages();
if (errorMessages == null || errorMessages.length == 0) {
// If we don't need a new object, we avoid creating it
return Collections.EMPTY_LIST;
}
return Arrays.asList(errorMessages);
}
public static List detailedErrors(final IExpressionContext context) {
return computeDetailedErrors(context, ALL_EXPRESSION);
}
public static List detailedErrors(final IExpressionContext context, final String field) {
return computeDetailedErrors(context, convertToFieldExpression(field));
}
public static List globalDetailedErrors(final IExpressionContext context) {
return computeDetailedErrors(context, GLOBAL_EXPRESSION);
}
private static List computeDetailedErrors(
final IExpressionContext context, final String fieldExpression) {
final BindStatus bindStatus =
FieldUtils.getBindStatus(context, fieldExpression);
if (bindStatus == null) {
return Collections.EMPTY_LIST;
}
final Errors errors = bindStatus.getErrors();
if (errors == null) {
return Collections.EMPTY_LIST;
}
final RequestContext requestContext =
(RequestContext) context.getVariable(SpringContextVariableNames.SPRING_REQUEST_CONTEXT);
if (requestContext == null) {
return Collections.EMPTY_LIST;
}
// We will try to avoid creating the List if we don't need it
List errorObjects = null;
final String bindExpression = bindStatus.getExpression();
if (bindExpression == null || ALL_EXPRESSION.equals(bindExpression) || ALL_FIELDS.equals(bindExpression)) {
final List globalErrors = errors.getGlobalErrors();
for (final ObjectError globalError : globalErrors) {
final String message = requestContext.getMessage(globalError, false);
final DetailedError errorObject =
new DetailedError(globalError.getCode(), globalError.getArguments(), message);
if (errorObjects == null) {
errorObjects = new ArrayList(errors.getErrorCount() + 2);
}
errorObjects.add(errorObject);
}
}
if (bindExpression != null) {
final List fieldErrors = errors.getFieldErrors(bindStatus.getExpression());
for (final FieldError fieldError : fieldErrors) {
final String message = requestContext.getMessage(fieldError, false);
final DetailedError errorObject =
new DetailedError(fieldError.getField(), fieldError.getCode(), fieldError.getArguments(), message);
if (errorObjects == null) {
errorObjects = new ArrayList(errors.getErrorCount() + 2);
}
errorObjects.add(errorObject);
}
}
if (errorObjects == null) {
return Collections.EMPTY_LIST;
}
return errorObjects;
}
public static String idFromName(final String fieldName) {
return StringUtils.deleteAny(fieldName, "[]");
}
private static String convertToFieldExpression(final String field) {
if (field == null) {
return null;
}
final String trimmedField = field.trim();
if (trimmedField.length() == 0) {
return null;
}
final char firstc = trimmedField.charAt(0);
if (firstc == '*' || firstc == '$') {
return field;
}
return "*{" + field + "}";
}
private static boolean checkErrors(
final IExpressionContext context, final String expression) {
final BindStatus bindStatus = FieldUtils.getBindStatus(context, expression);
if (bindStatus == null) {
throw new TemplateProcessingException(
"Could not bind form errors using expression \"" + expression + "\". Please check this " +
"expression is being executed inside the adequate context (e.g. a