org.omnifaces.validator.JsfLabelMessageInterpolator Maven / Gradle / Ivy
/*
* Copyright 2020 OmniFaces
*
* 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
*
* https://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.omnifaces.validator;
import static javax.validation.Validation.byDefaultProvider;
import static org.omnifaces.util.Components.getCurrentComponent;
import static org.omnifaces.util.Components.getLabel;
import static org.omnifaces.util.Faces.getLocale;
import static org.omnifaces.util.Faces.hasContext;
import java.util.Locale;
import javax.validation.MessageInterpolator;
/**
*
* Unlike native JSF validation error messages, in a bean validation message by default the label of the component where
* a validation constraint violation originated from can not be displayed in the middle of a message. Using the
* javax.faces.validator.BeanValidator.MESSAGE
bundle key such label can be put in front or behind the
* message, but that's it. With this {@link JsfLabelMessageInterpolator} a label can appear in the middle of a message,
* by using the special placeholder {jsf.label}
in bean validation messages.
*
* Note that Bean Validation is not only called from within JSF, and as such JSF might not be available. If JSF
* is not available occurrences of {jsf.label}
will be replaced by an empty string. The user should take
* care that messages are compatible with both situations if needed.
*
* This message interpolator is not needed for putting a component label before or after a bean
* validation message. That functionality is already provided by JSF itself via the
* javax.faces.validator.BeanValidator.MESSAGE
key in any resource bundle known to JSF.
*
*
Installation
*
* Create a /META-INF/validation.xml
file in WAR with the following contents:
*
*
* <?xml version="1.0" encoding="UTF-8"?>
* <validation-config
* xmlns="http://jboss.org/xml/ns/javax/validation/configuration"
* xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
* xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/configuration validation-configuration-1.0.xsd"
* >
* <message-interpolator>org.omnifaces.validator.JsfLabelMessageInterpolator</message-interpolator>
* </validation-config>
*
*
* Usage
* As an example, the customization of @Size
in ValidationMessages.properties
:
*
* javax.validation.constraints.Size.message = The size of {jsf.label} must be between {min} and {max} characters
*
*
* @author Arjan Tijms
* @since 1.5
*/
public class JsfLabelMessageInterpolator implements MessageInterpolator {
private final MessageInterpolator wrapped;
public JsfLabelMessageInterpolator() {
wrapped = byDefaultProvider().configure().getDefaultMessageInterpolator();
}
@Override
public String interpolate(String messageTemplate, Context context) {
return interpolate(messageTemplate, context, hasContext() ? getLocale() : Locale.getDefault());
}
@Override
public String interpolate(String messageTemplate, Context context, Locale locale) {
String message = wrapped.interpolate(messageTemplate, context, locale);
if (message.contains("{jsf.label}")) {
String label = "";
if (hasContext()) {
label = getLabel(getCurrentComponent());
}
message = message.replace("{jsf.label}", label);
}
return message;
}
}