Class PropertyFileUtil

java.lang.Object
jp.ecuacion.lib.core.util.PropertyFileUtil

public class PropertyFileUtil extends Object
Provides utility methods to read *.properties files.

It has following features added to ResourceBundle class packaged in JRE.

  1. To read multiple kinds of *.properties files
  2. To read all the *.properties files in ecuacion modules and multiple modules of an app
  3. To remove default locale from candidate locales
  4. To avoid throwing an exception exen if a message key does not exist
  5. To use "default" value by putting ".default" postfix to the key
  6. To have the override function by java launch parameter (-D) or System.setProperty(...)
  7. To resolve property keys in the obtained value
  8. To resolve property keys in arguments
  9. To resolve EL expression

1. To read multiple kinds of *.properties files

It treats *.properties files below.
Localized ones take Locale as an argument, and parameterized ones does String[] or Arg[]. (Details for Arg are in section 8.)

kinds of *.properties files
file name method to obtain values from files localized parameterized description
application[_xxx].properties getApplication(...)
Treats app settings
messages[_xxx].properties getMessage(...)
☑️ ☑️ Treats localized messages
strings[_xxx].properties getString(...)
☑️ Treats non-localized messages
item_names[_xxx].properties getItemName(...)
☑️ Treats enum item names
enum_names[_xxx].properties getEnumName(...)
☑️ Treats enum value names
ValidationMessages[_xxx].properties getValidationMessage(...)
☑️ Treats jakarta validation messages, but it's never called from apps. It's used only from ecuacion-modules. No item names in them.
ValidationMessagesWithItemNames[_xxx].properties getValidationMessageWithItemName(...)
☑️ Treats jakarta validation messages, but it's never called from apps. It's used only from ecuacion-modules. Item names in them.
ValidationMessagesPatternDescriptions[_xxx].properties getValidationMessagePatternDescription(...)
☑️ Treats pattern expressing localized strings used for jakarta validation messages, but it's never called from apps. It's used only from ecuacion-modules.

2. To read all the *.properties files in ecuacion modules and multiple modules of an app

When we talk about messages[_xxx].properties, this class reads ones in ecuacion modules (like messages_lib_core.properties in ecuacion-lib-core), and ones in your apps.
In ecuacion modules an app is assumed to divided into some modules (=usually called "projects" in IDE), which are base, core, web (or none), batch.

If the name of your app is sample-app, module names would be :
sample-app-base : messages_base.properties
sample-app-core : messages_core.properties
sample-app-web : messages.properties
sample-app-batch: messages.properties

PropertyFileUtil.getMessage(...) will read all the properties above.
Duplicated definition detectable. (causes exception)

And of course you can use localized files like messages_core_ja.properties for localized files (see the table above) because this class uses ResourceBundle inside to read them.


3. To remove default locale from candidate locales

Java Standard ResourceBundle uses default locale (which is obtained by Locale.getDefault()) when the property file of specified locale is not found.
The default locale is usually equal to the locale of the OS (of the server usually in web application environment), which means the result depends on the machine the program is executed on.

To avoid that situation deault locale is removed from candidate locales with this class.

Note that it uses default locale when you don't specify locale to get a string from localized *.properties files.


4. To avoid throwing an exception exen if a message key does not exist

Since application.properties has settings, exception should be thrown when a required key does not exist.
On the other hand, since messages.properties has messages only and even if it's shown on the screen, it's weird but not very fatal, and furthermore it's better when developing because developers can see clearly which messages are not defined (System error screen has no concrete information), so exception should not be thrown and just show the message key with [ ].

This feature offers shown key on screen with non-application properties.


5. To use "default" value by putting ".default" postfix to the key

It's kind of troublesome that you have to create *.properties for pre-defined keys in ecuacion-modules.
But on the other hand, it's better for app developers to be able to change it when it has to be. So the keys in *.properties files contained in ecuacion modules have ".default" postfix and those can be overrided in app modules by defining the key in app *.properties files without ".default".

6. To Have the override function by java launch parameter (-D) or System.setProperty(...)

You can override values with those settings. (It's implemented for application.properties)

7. To resolve property keys in the obtained value

You can put a property key into a property value.
For example, you can define keys and values like this in messages.properties. By executing PropertyFileUtil.getMessage("message") you'll get "a-b-c".

    message=a-${+messages:message_test1}-c
    message_test1=b

Recursive resolution is also supported so you can even define like the one below.
By executing PropertyFileUtil.getMessage("message") you'll get "a-b-c-d-e-f-g".

    message=a-${+messages:message_test1}-c-${+messages:message_test2}-g
    message_test1=b
    message_test2=d-${messages:message_test3}-f
    message_test3=e

Examples above uses {+messages:...} but you can also use other file kinds like {+application:...}, {+item_names:...} and {+enum_names:...}.

Recursive resolution is supported, but multiple layer of key is not supported. (which does not seem to be needed)

    message=a-${+messages:${+messages:message_prefix}_test1}-c
    message_prefix=message
    message_test1=b

8. To resolve property keys in arguments

Sometimes you want to put not a static string, but a dynamic one, and maybe localized one as a parameter of messages.properties or strings.properties.

You can realize it by Arg instead of String as a parameter class.


9. To resolve EL expression

EL expression is supported. (Since jakarta validation does.)
You can define it like this.

math.addition=1 + 1 = ${1 + 1}.

Miscellaneous

  • messages[_xxx].properties, enum_names[_xxx].properties, fiels_names[_xxx].properties need to have default locale file (like messages.properties. This is the rule of the library.
    It leads the conclusion that hasXxx(...) (like hasMsg(...)) doesn't need to have locale argument. (default locale used)
  • Method Details

    • getApplication

      @Nonnull public static String getApplication(@RequireNonnull String key)
      Returns the value in application_xxx.properties.
      Parameters:
      key - the key of the property
      Returns:
      the value of the property
    • hasApplication

      public static boolean hasApplication(@RequireNonnull String key)
      Returns the existence of the key in application_xxx.properties.
      Parameters:
      key - the key of the property
      Returns:
      boolean value that shows whether properties has the key
    • getApplicationOrElse

      @Nullable public static String getApplicationOrElse(@RequireNonnull String key, String defaultValue)
      Returns the value in application_xxx.properties if it exists. Returns given default value if not.
      Parameters:
      key - the key of the property
      defaultValue - default value
      Returns:
      the value of the property
    • getMessage

      @Nonnull public static String getMessage(@RequireNonnull String key, @RequireNonnull String... args)
      Returns the value of default locale in messages_xxx.properties.
      Parameters:
      key - the key of the property
      args - message arguments
      Returns:
      the value (message) of the property key (message ID)
    • getMessage

      @Nonnull public static String getMessage(@Nullable Locale locale, @RequireNonnull String key, @RequireNonnull String... args)
      Returns the localized value in messages_xxx.properties.
      Parameters:
      locale - locale, may be null which means no Locale specified.
      key - the key of the property
      args - message arguments
      Returns:
      the value (message) of the property key (message ID)
    • getMessage

      @Nonnull public static String getMessage(@RequireNonnull String key, @RequireNonnull PropertyFileUtil.Arg[] args)
      Returns the value of default locale in messages_xxx.properties.
      Parameters:
      key - the key of the property
      args - message arguments, which can be message ID. The data type is Arg[], not Arg... because if Arg causes an error when you call getMsg(key) since the second parameter is unclear (String... or Arg....
      Returns:
      the value (message) of the property key (message ID)
    • getMessage

      @Nonnull public static String getMessage(@Nullable Locale locale, @RequireNonnull String key, @RequireNonnull PropertyFileUtil.Arg[] args)
      Returns the localized value in messages_xxx.properties.
      Parameters:
      locale - locale, may be null which means no Locale specified.
      key - the key of the property
      args - message arguments, which can be message ID. The data type is Arg[], not Arg... because if Arg causes an error when you call getMsg(key) since the second parameter is unclear (String... or Arg....
      Returns:
      the message corresponding to the message ID
    • hasMessage

      public static boolean hasMessage(@RequireNonnull String key)
      Returns the existence of the key in messages_xxx.properties.
      Parameters:
      key - the key of the property
      Returns:
      boolean value that shows whether properties has the key (message ID)
    • getMessageWithItemName

      @Nonnull public static String getMessageWithItemName(@RequireNonnull String key, @RequireNonnull String... args)
      Returns the value of default locale in messagesWithItemNames_xxx.properties.
      Parameters:
      key - the key of the property
      args - message arguments
      Returns:
      the value (message) of the property key (message ID)
    • getMessageWithItemName

      @Nonnull public static String getMessageWithItemName(@Nullable Locale locale, @RequireNonnull String key, @RequireNonnull String... args)
      Returns the localized value in messagesWithItemNames_xxx.properties.
      Parameters:
      locale - locale, may be null which means no Locale specified.
      key - the key of the property
      args - message arguments
      Returns:
      the value (message) of the property key (message ID)
    • getMessageWithItemName

      @Nonnull public static String getMessageWithItemName(@RequireNonnull String key, @RequireNonnull PropertyFileUtil.Arg[] args)
      Returns the value of default locale in messagesWithItemNames_xxx.properties.
      Parameters:
      key - the key of the property
      args - message arguments, which can be message ID. The data type is Arg[], not Arg... because if Arg causes an error when you call getMsg(key) since the second parameter is unclear (String... or Arg....
      Returns:
      the value (message) of the property key (message ID)
    • getMessageWithItemName

      @Nonnull public static String getMessageWithItemName(@Nullable Locale locale, @RequireNonnull String key, @RequireNonnull PropertyFileUtil.Arg[] args)
      Returns the localized value in messagesWithItemNames_xxx.properties.
      Parameters:
      locale - locale, may be null which means no Locale specified.
      key - the key of the property
      args - message arguments, which can be message ID. The data type is Arg[], not Arg... because if Arg causes an error when you call getMsg(key) since the second parameter is unclear (String... or Arg....
      Returns:
      the message corresponding to the message ID
    • hasMessageWithItemName

      public static boolean hasMessageWithItemName(@RequireNonnull String key)
      Returns the existence of the key in messagesWithItemNames_xxx.properties.
      Parameters:
      key - the key of the property
      Returns:
      boolean value that shows whether properties has the key (message ID)
    • getString

      @Nonnull public static String getString(@RequireNonnull String key, @RequireNonnull String... args)
      Returns the value in string_xxx.properties.
      Parameters:
      key - the key of the property
      args - message arguments
      Returns:
      the value (message) of the property key (message ID)
    • getString

      @Nonnull public static String getString(@RequireNonnull String key, @RequireNonnull PropertyFileUtil.Arg[] args)
      Returns the value in string_xxx.properties.
      Parameters:
      key - the key of the property
      args - message arguments, which can be message ID. The data type is Arg[], not Arg... because if Arg causes an error when you call getMsg(key) since the second parameter is unclear (String... or Arg....
      Returns:
      the value (message) of the property key (message ID)
    • hasString

      public static boolean hasString(@RequireNonnull String key)
      Returns the existence of the key in strings_xxx.properties.
      Parameters:
      key - the key of the property
      Returns:
      boolean value that shows whether properties has the key
    • getItemName

      @Nonnull public static String getItemName(@RequireNonnull String key)
      Returns the item name of default locale in item_names_xxx.properties.
      Parameters:
      key - the key of the property
      Returns:
      the value of the property
    • getItemName

      @Nonnull public static String getItemName(@Nullable Locale locale, @RequireNonnull String key)
      Returns the localized item name in item_names_xxx.properties.
      Parameters:
      locale - locale, may be null which is treated as Locale.getDefault().
      key - the key of the property
      Returns:
      the value of the property
    • hasItemName

      public static boolean hasItemName(@RequireNonnull String key)
      Returns the existence of the key in item_names_xxx.properties.
      Parameters:
      key - the key of the property
      Returns:
      boolean value that shows whether properties has the key
    • getEnumName

      @Nonnull public static String getEnumName(@RequireNonnull String key)
      Returns the enum name of default locale in enum_names_xxx.properties.
      Parameters:
      key - the key of the property
      Returns:
      the value of the property
    • getEnumName

      @Nonnull public static String getEnumName(@Nullable Locale locale, @RequireNonnull String key)
      Returns the localized enum name in enum_names_xxx.properties.
      Parameters:
      locale - locale, may be null which is treated as Locale.getDefault().
      key - the key of the property
      Returns:
      the value of the property
    • hasEnumName

      public static boolean hasEnumName(@RequireNonnull String key)
      Returns the existence of the key in enam_names_xxx.properties.
      Parameters:
      key - the key of the property
      Returns:
      boolean value that shows whether properties has the key
    • getValidationMessage

      @Nonnull public static String getValidationMessage(@RequireNonnull String key, Map<String,Object> argMap)
      Returns the property value of default locale in ValidationMessages[_locale].properties.

      Usually ValidationMessages[_locale].properties file satisfies validation message's requirement. But when you want to show error messages on the top message space and

      Parameters:
      key - the key of the property
      argMap - argMap
      Returns:
      the value of the property
    • getValidationMessage

      @Nonnull public static String getValidationMessage(@Nullable Locale locale, @RequireNonnull String key, @Nullable Map<String,Object> argMap)
      Returns the localized enum name in ValidationMessages[_locale].properties.
      Parameters:
      locale - locale, may be null which is treated as Locale.getDefault().
      key - the key of the property
      Returns:
      the value of the property
    • getValidationMessageWithItemName

      @Nonnull public static String getValidationMessageWithItemName(@RequireNonnull String key, @Nullable Map<String,Object> argMap)
      Returns the property value of default locale in ValidationMessagesWithItemNames_xxx.properties.

      Usually ValidationMessages[_locale].properties file satisfies validation message's requirement. But when you want to show error messages on the top message space and

      Parameters:
      key - the key of the property
      argMap - argMap
      Returns:
      the value of the property
    • getValidationMessageWithItemName

      @Nonnull public static String getValidationMessageWithItemName(@Nullable Locale locale, @RequireNonnull String key, @Nullable Map<String,Object> argMap)
      Returns the localized enum name in enum_names_xxx.properties.
      Parameters:
      locale - locale, may be null which is treated as Locale.getDefault().
      key - the key of the property
      Returns:
      the value of the property
    • getValidationMessagePatternDescription

      @Nonnull public static String getValidationMessagePatternDescription(@RequireNonnull String key)
      Returns the property value of default locale in ValidationMessages[_locale].properties.

      Usually ValidationMessages[_locale].properties file satisfies validation message's requirement. But when you want to show error messages on the top message space and

      Parameters:
      key - the key of the property
      Returns:
      the value of the property
    • getValidationMessagePatternDescription

      @Nonnull public static String getValidationMessagePatternDescription(@Nullable Locale locale, @RequireNonnull String key)
      Returns the localized enum name in ValidationMessages[_locale].properties.
      Parameters:
      locale - locale, may be null which is treated as Locale.getDefault().
      key - the key of the property
      Returns:
      the value of the property
    • get

      @Nonnull public static String get(@RequireNonnull String propertyUtilFileKind, @RequireNonnull String key)
      Returns the property value of default locale.
      Parameters:
      propertyUtilFileKind - String value of PropertyUtilFileKind (application, messages, ...)
      key - the key of the property
      Returns:
      the value of the property
    • get

      @Nonnull public static String get(@RequireNonnull String propertyUtilFileKind, @Nullable Locale locale, @RequireNonnull String key)
      Returns the localized property value.
      Parameters:
      propertyUtilFileKind - String value of PropertyUtilFileKind (application, messages, ...)
      locale - locale, may be null which is treated as Locale.getDefault().
      key - the key of the property
      Returns:
      the value of the property
    • has

      public static boolean has(@RequireNonnull String propertyUtilFileKind, @RequireNonnull String key)
      Returns the existence of the key.
      Parameters:
      propertyUtilFileKind - String value of PropertyUtilFileKind (application, messages, ...)
      key - the key of the property
      Returns:
      the value of the property
    • addResourceBundlePostfix

      public static void addResourceBundlePostfix(@RequireNonnull String postfix)
      Adds postfix dinamically.

      If you add test for example, messages_test[_lang].properties, application_test[_lang].properties, ... are searched.

      In java 9 module system environment, you also need to Service Provider Interface(SPI) defined in `ecuacion-lib-core`.

      Parameters:
      postfix - postfix
    • getStringFromArg

      @Nonnull public static String getStringFromArg(@Nullable Locale locale, @RequireNonnull PropertyFileUtil.Arg arg)
      Obtains string from Arg.
      Parameters:
      locale - locale, may be null which means no Locale specified.
      arg - message arguments, which can be message ID.
      Returns:
      the message corresponding to the message ID or the string set to Arg.