MessageSourceProperties.java
/*
* Copyright 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.
* 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.bremersee.context;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import javax.validation.constraints.NotNull;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.bremersee.common.model.JavaLocale;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
/**
* The message source properties.
*
* @author Christian Bremer
*/
@ConfigurationProperties("bremersee.messages")
@Getter
@Setter
@ToString
@EqualsAndHashCode
@Validated
public class MessageSourceProperties {
/**
* Set whether to always apply the {@code MessageFormat} rules, parsing even messages without arguments.
*
* <p>Default is "false": Messages without arguments are by default
* returned as-is, without parsing them through MessageFormat. Set this to "true" to enforce MessageFormat for all
* messages, expecting all message texts to be written with MessageFormat escaping.
*
* <p>For example, MessageFormat expects a single quote to be escaped
* as "''". If your message texts are all written with such escaping, even when not defining argument placeholders,
* you need to set this flag to "true". Else, only message texts with actual arguments are supposed to be written with
* MessageFormat escaping.
*
* @see java.text.MessageFormat
*/
private boolean alwaysUseMessageFormat = false; // from MessageSourceSupport
/**
* Set whether to use the message code as default message instead of throwing a NoSuchMessageException. Useful for
* development and debugging. Default is "false".
*/
private boolean useCodeAsDefaultMessage = false; // from AbstractMessageSource
/**
* Set an list of basenames, each following the basic ResourceBundle convention of not specifying file extension or
* language codes. The resource location format is up to the specific {@code MessageSource} implementation.
*
* <p>Regular and XMl properties files are supported: e.g. "messages" will find
* a "messages.properties", "messages_en.properties" etc arrangement as well as "messages.xml", "messages_en.xml"
* etc.
*
* <p>The associated resource bundles will be checked sequentially when resolving
* a message code. Note that message definitions in a <i>previous</i> resource bundle will override ones in a later
* bundle, due to the sequential lookup.
*/
private List<String> baseNames = new ArrayList<>(); // from AbstractResourceBasedMessageSource
/**
* Set the number of seconds to cache loaded properties files.
* <ul>
* <li>Default is "-1", indicating to cache forever (just like
* {@code java.util.ResourceBundle}).
* <li>A positive number will cache loaded properties files for the given
* number of seconds. This is essentially the interval between refresh checks.
* Note that a refresh attempt will first check the last-modified timestamp
* of the file before actually reloading it; so if files don't change, this
* interval can be set rather low, as refresh attempts will not actually reload.
* <li>A value of "0" will check the last-modified timestamp of the file on
* every message access. <b>Do not use this in a production environment!</b>
* </ul>
*/
private int cacheSeconds = -1; // from AbstractResourceBasedMessageSource
/**
* Set the default charset to use for parsing properties files. Used if no file-specific charset is specified for a
* file.
*
* <p>The effective default is the {@code java.util.Properties}
* default encoding: ISO-8859-1. A {@code null} value indicates the platform default encoding.
*
* <p>Only applies to classic properties files, not to XML files.
*/
private String defaultEncoding = StandardCharsets.UTF_8.name(); // from AbstractResourceBasedM.
/**
* Set whether to fall back to the system Locale if no files for a specific Locale have been found. Default is "true";
* if this is turned off, the only fallback will be the default file (e.g. "messages.properties" for basename
* "messages").
*
* <p>Falling back to the system Locale is the default behavior of
* {@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.
*/
private boolean fallbackToSystemLocale = true;
/**
* 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.
*/
private String defaultLocale = "de-DE";
/**
* Specify a default time zone to fall back to.
*/
private String defaultTimeZone = "Europe/Berlin";
/**
* Specifies whether the resource bundles are reloadable or not.
*/
private boolean useReloadableMessageSource = false;
/**
* Specify whether to allow for concurrent refresh behavior, i.e. one thread locked in a refresh attempt for a
* specific cached properties file whereas other threads keep returning the old properties for the time being, until
* the refresh attempt has completed.
*
* <p>Default is "true": this behavior is new as of Spring Framework 4.1,
* minimizing contention between threads. If you prefer the old behavior, i.e. to fully block on refresh, switch this
* flag to "false".
*/
private boolean concurrentRefresh = true; // ReloadableResourceBundleMessageSource
/**
* Set per-file charsets to use for parsing properties files.
*
* <p>Only applies to classic properties files, not to XML files.
*/
private Map<String, String> fileEncodings = new HashMap<>(); // ReloadableResourceBundleMessageS.
/**
* Default locale.
*
* @return the locale
*/
@NotNull
public Locale defaultLocale() {
return StringUtils.hasText(getDefaultLocale())
? JavaLocale.fromValue(getDefaultLocale()).toLocale(Locale.getDefault())
: Locale.getDefault();
}
/**
* Default time zone.
*
* @return the time zone
*/
@NotNull
public TimeZone defaultTimeZone() {
return StringUtils.hasText(getDefaultTimeZone())
? TimeZone.getTimeZone(getDefaultTimeZone())
: TimeZone.getDefault();
}
}