Skip to content

Commit

Permalink
HV-1748 Generalize the ability to define the supported locales
Browse files Browse the repository at this point in the history
While not used to initialize the resource bundles, it can be used for
advanced locale resolution via Locale.LanguageRange.
  • Loading branch information
gsmet committed Jan 15, 2020
1 parent 2c43b79 commit c4dfc46
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 110 deletions.
Expand Up @@ -7,6 +7,8 @@
package org.hibernate.validator;

import java.time.Duration;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;

Expand Down Expand Up @@ -372,6 +374,34 @@ public interface BaseHibernateValidatorConfiguration<S extends BaseHibernateVali
@Incubating
S propertyNodeNameProvider(PropertyNodeNameProvider propertyNodeNameProvider);

/**
* Allows setting the list of the locales supported by this ValidatorFactory.
* <p>
* Can be used for advanced locale resolution and/or to force the initialization of the resource bundles at
* bootstrap.
* <p>
* If not set, defaults to a singleton containing {@link Locale#getDefault()}.
*
* @since 6.1.1
*/
@Incubating
S locales(Set<Locale> locales);

/**
* Allows setting the list of the locales supported by this ValidatorFactory.
* <p>
* Can be used for advanced locale resolution and/or to force the initialization of the resource bundles at
* bootstrap.
* <p>
* If not set, defaults to a singleton containing {@link Locale#getDefault()}.
*
* @since 6.1.1
*/
@Incubating
default S locales(Locale... locales) {
return locales( new HashSet<>( Arrays.asList( locales ) ) );
}

/**
* Allows setting the default locale used to interpolate the constraint violation messages.
* <p>
Expand Down
Expand Up @@ -25,7 +25,11 @@ public interface PredefinedScopeHibernateValidatorConfiguration extends BaseHibe
@Incubating
PredefinedScopeHibernateValidatorConfiguration initializeBeanMetaData(Set<Class<?>> beanClassesToInitialize);

/**
* @deprecated Planned for removal, use {@link BaseHibernateValidatorConfiguration#locales(Set)} instead.
*/
@Incubating
@Deprecated
PredefinedScopeHibernateValidatorConfiguration initializeLocales(Set<Locale> locales);

@Incubating
Expand Down
Expand Up @@ -46,6 +46,7 @@
import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager;
import org.hibernate.validator.internal.properties.DefaultGetterPropertySelectionStrategy;
import org.hibernate.validator.internal.properties.javabean.JavaBeanHelper;
import org.hibernate.validator.internal.util.CollectionHelper;
import org.hibernate.validator.internal.util.Contracts;
import org.hibernate.validator.internal.util.Version;
import org.hibernate.validator.internal.util.logging.Log;
Expand All @@ -71,6 +72,7 @@
* @author Gunnar Morling
* @author Kevin Pollet &lt;kevin.pollet@serli.com&gt; (C) 2011 SERLI
* @author Chris Beckey &lt;cbeckey@paypal.com&gt;
* @author Guillaume Smet
*/
public abstract class AbstractConfigurationImpl<T extends BaseHibernateValidatorConfiguration<T>>
implements BaseHibernateValidatorConfiguration<T>, ConfigurationState {
Expand Down Expand Up @@ -113,6 +115,7 @@ public abstract class AbstractConfigurationImpl<T extends BaseHibernateValidator
private Duration temporalValidationTolerance;
private Object constraintValidatorPayload;
private GetterPropertySelectionStrategy getterPropertySelectionStrategy;
private Set<Locale> locales = Collections.emptySet();
private Locale defaultLocale = Locale.getDefault();
private LocaleResolver localeResolver;

Expand Down Expand Up @@ -338,6 +341,14 @@ public T getterPropertySelectionStrategy(GetterPropertySelectionStrategy getterP
return thisAsT();
}

@Override
public T locales(Set<Locale> locales) {
Contracts.assertNotNull( defaultLocale, MESSAGES.parameterMustNotBeNull( "locales" ) );

this.locales = locales;
return thisAsT();
}

@Override
public T defaultLocale(Locale defaultLocale) {
Contracts.assertNotNull( defaultLocale, MESSAGES.parameterMustNotBeNull( "defaultLocale" ) );
Expand Down Expand Up @@ -543,8 +554,9 @@ public ClassLoader getExternalClassLoader() {
@Override
public final MessageInterpolator getDefaultMessageInterpolator() {
if ( defaultMessageInterpolator == null ) {
defaultMessageInterpolator = new ResourceBundleMessageInterpolator( getDefaultResourceBundleLocator(), getAllLocalesToInitialize(),
defaultLocale, ValidatorFactoryConfigurationHelper.determineLocaleResolver( this, this.getProperties(), externalClassLoader ) );
defaultMessageInterpolator = new ResourceBundleMessageInterpolator( getDefaultResourceBundleLocator(), getAllSupportedLocales(),
defaultLocale, ValidatorFactoryConfigurationHelper.determineLocaleResolver( this, this.getProperties(), externalClassLoader ),
preloadResourceBundles() );
}

return defaultMessageInterpolator;
Expand All @@ -564,7 +576,7 @@ public final ConstraintValidatorFactory getDefaultConstraintValidatorFactory() {
public final ResourceBundleLocator getDefaultResourceBundleLocator() {
if ( defaultResourceBundleLocator == null ) {
defaultResourceBundleLocator = new PlatformResourceBundleLocator(
ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES, getAllLocalesToInitialize() );
ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES, preloadResourceBundles(), getAllSupportedLocales() );
}

return defaultResourceBundleLocator;
Expand Down Expand Up @@ -714,12 +726,14 @@ private MessageInterpolator getDefaultMessageInterpolatorConfiguredWithClassLoad
if ( externalClassLoader != null ) {
PlatformResourceBundleLocator userResourceBundleLocator = new PlatformResourceBundleLocator(
ResourceBundleMessageInterpolator.USER_VALIDATION_MESSAGES,
getAllLocalesToInitialize(),
preloadResourceBundles(),
getAllSupportedLocales(),
externalClassLoader
);
PlatformResourceBundleLocator contributorResourceBundleLocator = new PlatformResourceBundleLocator(
ResourceBundleMessageInterpolator.CONTRIBUTOR_VALIDATION_MESSAGES,
getAllLocalesToInitialize(),
preloadResourceBundles(),
getAllSupportedLocales(),
externalClassLoader,
true
);
Expand All @@ -733,9 +747,10 @@ private MessageInterpolator getDefaultMessageInterpolatorConfiguredWithClassLoad
return new ResourceBundleMessageInterpolator(
userResourceBundleLocator,
contributorResourceBundleLocator,
getAllLocalesToInitialize(),
getAllSupportedLocales(),
defaultLocale,
ValidatorFactoryConfigurationHelper.determineLocaleResolver( this, this.getProperties(), externalClassLoader )
ValidatorFactoryConfigurationHelper.determineLocaleResolver( this, this.getProperties(), externalClassLoader ),
preloadResourceBundles()
);
}
finally {
Expand All @@ -747,15 +762,22 @@ private MessageInterpolator getDefaultMessageInterpolatorConfiguredWithClassLoad
}
}

protected final Locale getDefaultLocale() {
return defaultLocale;
}
private Set<Locale> getAllSupportedLocales() {
if ( locales.isEmpty() ) {
return Collections.singleton( defaultLocale );
}
if ( locales.contains( defaultLocale ) ) {
return locales;
}

protected Set<Locale> getAllLocalesToInitialize() {
// By default, we return an empty set meaning that we will dynamically initialize the locales.
return Collections.emptySet();
Set<Locale> allLocales = CollectionHelper.newHashSet( locales.size() + 1 );
allLocales.addAll( locales );
allLocales.add( defaultLocale );
return allLocales;
}

protected abstract boolean preloadResourceBundles();

@SuppressWarnings("unchecked")
protected T thisAsT() {
return (T) this;
Expand Down
Expand Up @@ -20,6 +20,7 @@
* @author Gunnar Morling
* @author Kevin Pollet &lt;kevin.pollet@serli.com&gt; (C) 2011 SERLI
* @author Chris Beckey &lt;cbeckey@paypal.com&gt;
* @author Guillaume Smet
*/
public class ConfigurationImpl extends AbstractConfigurationImpl<HibernateValidatorConfiguration> implements HibernateValidatorConfiguration, ConfigurationState {

Expand All @@ -30,4 +31,9 @@ public ConfigurationImpl(BootstrapState state) {
public ConfigurationImpl(ValidationProvider<?> provider) {
super( provider );
}

@Override
protected boolean preloadResourceBundles() {
return false;
}
}
Expand Up @@ -8,7 +8,6 @@

import static org.hibernate.validator.internal.util.logging.Messages.MESSAGES;

import java.util.Collections;
import java.util.Locale;
import java.util.Set;

Expand All @@ -31,13 +30,6 @@ public class PredefinedScopeConfigurationImpl extends AbstractConfigurationImpl<

private BeanMetaDataClassNormalizer beanMetaDataClassNormalizer;

/**
* Locales to initialize eagerly.
* <p>
* We will always include the default locale in the final list.
*/
private Set<Locale> localesToInitialize = Collections.emptySet();

public PredefinedScopeConfigurationImpl(BootstrapState state) {
super( state );
}
Expand All @@ -59,7 +51,7 @@ public Set<Class<?>> getBeanClassesToInitialize() {
@Override
public PredefinedScopeHibernateValidatorConfiguration initializeLocales(Set<Locale> localesToInitialize) {
Contracts.assertNotNull( localesToInitialize, MESSAGES.parameterMustNotBeNull( "localesToInitialize" ) );
this.localesToInitialize = localesToInitialize;
locales( localesToInitialize );
return thisAsT();
}

Expand All @@ -74,14 +66,7 @@ public BeanMetaDataClassNormalizer getBeanMetaDataClassNormalizer() {
}

@Override
protected Set<Locale> getAllLocalesToInitialize() {
if ( localesToInitialize.isEmpty() ) {
return Collections.singleton( getDefaultLocale() );
}

Set<Locale> allLocales = CollectionHelper.newHashSet( localesToInitialize.size() + 1 );
allLocales.addAll( localesToInitialize );
allLocales.add( getDefaultLocale() );
return Collections.unmodifiableSet( allLocales );
protected boolean preloadResourceBundles() {
return true;
}
}

0 comments on commit c4dfc46

Please sign in to comment.