Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I used named parameters in a messages.properties file?

Is there any way to have message.properties records as follows

message.myMessage=This message is for ${name} in ${location}

as opposed to

message.myMessage = This message is for {0} in {1}

When I am creating the messages, I don't neccessarily know the order / how many parameters are needed, but I am able just pass in several properties by name, and just the correct ones would be used.

like image 295
questioner Avatar asked Apr 08 '11 19:04

questioner


5 Answers

After facing the very same question and poking in source code I found a "loop-hole" that makes it possible in a very easy way:

message.myMessage = This message is for {0,,name} in {1,,location}

This approach doesn't eliminate usage of numbers. The reason to use it is to give hints to translation folks.

like image 99
Yuriy Zubarev Avatar answered Nov 14 '22 20:11

Yuriy Zubarev


I am afraid not, parameters are an Object array so there is no way to define names for them. If you always passes in the array of parameter in the same order though you could use them like this:

message.myMessage = This message is for {0} in {1}
message.myNameMessage = This message is for {0}
message.myLocationMessage = This message is for people in {1}
message.myAlternateMessage = The message params are location: {1}; name: {0}
like image 13
krock Avatar answered Nov 14 '22 22:11

krock


Take a look at ICU4J

It allows for something like this:

message.myMessage=This message is for {name} in {location}.

And it is way more powerful than the simple replacements suggested, because can do locale aware formatting of the parameters (ie: "Subscription expires on: {expirationDate, date, long})

http://icu-project.org/apiref/icu4j/com/ibm/icu/text/MessageFormat.html

like image 11
Mihai Nita Avatar answered Nov 14 '22 22:11

Mihai Nita


Unfortunately the MessageFormat API does not support named parameters, only argument-index:

Patterns and Their Interpretation

MessageFormat uses patterns of the following form:

MessageFormatPattern:
     String
     MessageFormatPattern FormatElement String

FormatElement:
     { ArgumentIndex }
     { ArgumentIndex , FormatType }
     { ArgumentIndex , FormatType , FormatStyle }
like image 7
matt b Avatar answered Nov 14 '22 20:11

matt b


Everything is possible for those who try... I never heard about something like that for Java, but you can write it by yourself.

Please take a look at this example:

public String format(String message, String... arguments) {
    for (String argument : arguments) {
        String[] keyValue = argument.split("=");
        if (keyValue.length != 2)
            throw new IllegalArgumentException("Incorrect argument: " + argument);
        String placeholder = "${" + keyValue[0] + "}";
        if (!message.contains(placeholder))
            throw new IllegalArgumentException(keyValue[0] + " does not exists.");
        while (message.contains(placeholder))
            message = message.replace(placeholder, keyValue[1]);
    }

    return message;
}

It is not ideal, as you actually would call it with hardcoded string (which is generally bad idea) and you would be forced to use Strings only, but it can be done. The only question is if it is practical.

like image 7
Paweł Dyda Avatar answered Nov 14 '22 20:11

Paweł Dyda