Open KotlinFactory opened 1 year ago
I'm going to look on what other places we need to handle bundles.
With providing some common class user can use, ParserMessage
and TemplateExecutor
are one internal examples where i18n is needed.
Getting started with boot is super easy as you just create messages.properties
, messages_en.properties
, etc. For library code few questions remains:
I would suggest defining 2 properties that can be set in the project that uses the spring-shell library, e.g.
When creating the message source all message files are combined. As the first hit wins, the custom files should be added first, so one can overwrite the texts of the spring shell. A constructor for a class could look like this (not tested if addBasenames works if no basenames have been set before and parameters may not be null):
public SpringShellMessages(final String language, final String[] clientLocalization) {
final var messageSource = new ResourceBundleMessageSource();
messageSource.setDefaultEncoding("UTF-8");
if (clientLocalization.length > 0) {
messageSource.setBasenames(clientLocalization);
}
messageSource.addBasenames("localization/message");
final Locale loc = Locale.forLanguageTag(language);
accessor = new MessageSourceAccessor(messageSource, loc.getLanguage().isEmpty() ? Locale.ENGLISH : loc);
}
You can now use the accessor to lookup the message codes: accessor.getMessage(code); accessor.getMessage(code, defaultMessage); accessor.getMessage(code, args); // with arguments to fill in for parameters in the message
spring-shell would put message_en.properties, etc in its /src/main/resources/localization. A project using the library can define one or multiple basenames as well (other than message) and put its files in its own resources dir. String literals will be put in the message file with a code that is used to lookup the string. To determine if a set command or parameter description should be treated as a literal or as a lookup code, one can either lookup the string and if it is not found use it as default or define a marker prefix for lookup codes.
So here are some examples on how we archived localization in our internal fork. It was still using the old SpringShell 2.x version.
We started by creating a wrapper that contains all SpringShell messages.
This is then used in the StandardMethodTargetRegistrar
And finally to determine the group and the description in the register method in the StandardMethodTargetRegistrar
We also replaced the String literals in the SpringShell using the
SpringShellMessages
class