Skip to content

Commit

Permalink
Fallback Locale other than the system Locale through setDefaultLocale
Browse files Browse the repository at this point in the history
Closes gh-23977
  • Loading branch information
jhoeller committed Nov 13, 2019
1 parent f4c847b commit f61d728
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 5 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,6 +17,7 @@
package org.springframework.context.support;

import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Set;

import org.springframework.lang.Nullable;
Expand All @@ -43,6 +44,9 @@ public abstract class AbstractResourceBasedMessageSource extends AbstractMessage

private boolean fallbackToSystemLocale = true;

@Nullable
private Locale defaultLocale;

private long cacheMillis = -1;


Expand Down Expand Up @@ -143,6 +147,7 @@ protected String getDefaultEncoding() {
* {@code java.util.ResourceBundle}. However, this is often not desirable
* in an application server environment, where the system Locale is not relevant
* to the application at all: set this flag to "false" in such a scenario.
* @see #setDefaultLocale
*/
public void setFallbackToSystemLocale(boolean fallbackToSystemLocale) {
this.fallbackToSystemLocale = fallbackToSystemLocale;
Expand All @@ -152,11 +157,46 @@ public void setFallbackToSystemLocale(boolean fallbackToSystemLocale) {
* Return whether to fall back to the system Locale if no files for a specific
* Locale have been found.
* @since 4.3
* @deprecated as of 5.2.2, in favor of {@link #getDefaultLocale()}
*/
@Deprecated
protected boolean isFallbackToSystemLocale() {
return this.fallbackToSystemLocale;
}

/**
* Specify a default Locale to fall back to, as an alternative to falling back
* to the system Locale.
* <p>Default is to fall back to the system Locale. You may override this with
* a locally specified default Locale here, or enforce no fallback locale at all
* through disabling {@link #setFallbackToSystemLocale "fallbackToSystemLocale"}.
* @since 5.2.2
* @see #setFallbackToSystemLocale
* @see #getDefaultLocale()
*/
public void setDefaultLocale(@Nullable Locale defaultLocale) {
this.defaultLocale = defaultLocale;
}

/**
* Determine a default Locale to fall back to: either a locally specified default
* Locale or the system Locale, or {@code null} for no fallback locale at all.
* @since 5.2.2
* @see #setDefaultLocale
* @see #setFallbackToSystemLocale
* @see Locale#getDefault()
*/
@Nullable
protected Locale getDefaultLocale() {
if (this.defaultLocale != null) {
return this.defaultLocale;
}
if (this.fallbackToSystemLocale) {
return Locale.getDefault();
}
return null;
}

/**
* Set the number of seconds to cache loaded properties files.
* <ul>
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -237,6 +237,7 @@ protected PropertiesHolder getMergedProperties(Locale locale) {
if (mergedHolder != null) {
return mergedHolder;
}

Properties mergedProps = newProperties();
long latestTimestamp = -1;
String[] basenames = StringUtils.toStringArray(getBasenameSet());
Expand All @@ -253,6 +254,7 @@ protected PropertiesHolder getMergedProperties(Locale locale) {
}
}
}

mergedHolder = new PropertiesHolder(mergedProps, latestTimestamp);
PropertiesHolder existing = this.cachedMergedProperties.putIfAbsent(locale, mergedHolder);
if (existing != null) {
Expand All @@ -279,18 +281,26 @@ protected List<String> calculateAllFilenames(String basename, Locale locale) {
return filenames;
}
}

// Filenames for given Locale
List<String> filenames = new ArrayList<>(7);
filenames.addAll(calculateFilenamesForLocale(basename, locale));
if (isFallbackToSystemLocale() && !locale.equals(Locale.getDefault())) {
List<String> fallbackFilenames = calculateFilenamesForLocale(basename, Locale.getDefault());

// Filenames for default Locale, if any
Locale defaultLocale = getDefaultLocale();
if (defaultLocale != null && !defaultLocale.equals(locale)) {
List<String> fallbackFilenames = calculateFilenamesForLocale(basename, defaultLocale);
for (String fallbackFilename : fallbackFilenames) {
if (!filenames.contains(fallbackFilename)) {
// Entry for fallback locale that isn't already in filenames list.
filenames.add(fallbackFilename);
}
}
}

// Filename for default bundle file
filenames.add(basename);

if (localeMap == null) {
localeMap = new ConcurrentHashMap<>();
Map<Locale, List<String>> existing = this.cachedFilenames.putIfAbsent(basename, localeMap);
Expand Down
Expand Up @@ -461,7 +461,8 @@ public ResourceBundle newBundle(String baseName, Locale locale, String format, C
@Override
@Nullable
public Locale getFallbackLocale(String baseName, Locale locale) {
return (isFallbackToSystemLocale() ? super.getFallbackLocale(baseName, locale) : null);
Locale defaultLocale = getDefaultLocale();
return (defaultLocale != null && !defaultLocale.equals(locale) ? defaultLocale : null);
}

@Override
Expand Down

0 comments on commit f61d728

Please sign in to comment.