views:

403

answers:

2

Is it possible, with resource bundles and MessageFormat to have the following result?

  • when I call getBundle("message.07", "test") to get "Group test"
  • when I call getBundle("message.07", null) to get "No group selected"

Every example I found on the Internet is with planets, with files on the disk and so on.

I only need to check if one parameter is null (or doesn't exist) in the resource bundle's properties file. I hope to find a special format for the null parameter something like {0,choice,null#No group selected|notnull#Group {0}}.

The method I use to get the bundles is:

public String getBundle(String key, Object... params) {
  try {
    String message = resourceBundle.getString(key);
    if (params.length == 0) {
      return message;
    } else {
      return MessageFormat.format(message, params);
    }
  } catch (Exception e) {
    return "???";
  }
}

I also call this method for other bundles, like

  • getBundle("message.08", 1, 2) => "Page 1 of 2" (always parameters, no need to check for null)
  • getBundle("message.09") => "Open file" (no parameters, no need to check for null)

What should I write in my .properties file for message.07 to have the result described?
What I have now is:

message.07=Group {0} 
message.08=Page {0} of {1}    # message with parameters where I always send them
message.09=Open file          # message without parameters
A: 

Your .properties file,

message.07=Group {0} 
message.08=Page {0} of {1}
message.09=Open file
message.null = No group selected

And then you need to change your code to put an explicit check params for null. And if null then you can do something like resourceBundle.getString(NULL_MSG). Where NULL_MSG will be this,

private static final String NULL_MSG = "message.null";

So, now your original method would become something like this.

public String getBundle(String key, Object... params) {
  String message = null;
  try {
    if (params == null) {
      message = resourceBundle.getString(NULL_MSG);
    } else {
      message = MessageFormat.format(resourceBundle.getString(key), params);
    }
  } catch (Exception e) {
    e.printStackTrace();
  }
  return message;
}

Calling my method like below,

getBundle("message.07", "test") // returning 'Group test'
getBundle("message.07", null) // returning 'No group selected'
getBundle("message.08", 1, 2) // returning 'Page 1 of 2'
getBundle("message.08", null) // returning 'No group selected'
getBundle("message.09", new Object[0]) // returning 'Open file'
getBundle("message.09", null) // returning 'No group selected'

Now tell me where is the problem?

Adeel Ansari
I would like not to change that method, because it is used everywhere in my code and it should work with the rest of the messages (where the parameters are numbers, strings...) where I don't need to check for `null`. Also it is possible to have more cases like this (more messages with null testing)
True Soft
It wouldn't break the code anywhere, just change the internal behaviour. The parameters are not changed, neither the return type. I don't see any problem.
Adeel Ansari
Maybe you wanted to say `message.07.null`, and I should add a supplimentary key for each message that accepts null for parameters. I was hoping to find a special format like `{0,choice,1#one|2#two}` for the `null` parameter.
True Soft
You don't need the supplementary key for each and every message. Just make a generic for `null`. That will suffice, AFAICS. Moreover, check my edits.
Adeel Ansari
I added more details to my question. For example, with your changes, the call `getBundle("message.09")` would not give the expected result.
True Soft
Do you have an overloaded method which just take one argument? Moreover, in this case, my method will give you the result, "Open file". What else you are expecting?
Adeel Ansari
I don't have an overloaded method with one argument, because: the `getBundle` method has varargs, and when `params` is a zero-length array, I will have something exactly like a method with one argument. That's why I check it with `if (params.length == 0) {`.
True Soft
You must understand that calling MessageFormat.format(message, params) with null param, or zero length param, will not do anything to your message. It will just return you the message as it is. And thats what you are doing after checking for length.
Adeel Ansari
@Oscar, I don't understand what is your comment got to do with my question.
True Soft
@True Soft: Sorry about that. Never mind.. erh.. wrong number :)
OscarRyz
+1  A: 

I'll recommend not trying to change the bundle functionality (even if you have a getBundle method encapsulating it).

Simply do in your code:

getBundle(param == null? "message.07.null": "message.07", param)

Or make another method:

getBundleOrNull("message.07", param, "message.07.null")

that does

public String getBundleOrNull(String key, value, nullKey) {
   return getBundle(value == null? nullKey: key: value);
}
helios
Thank you for your answer. I will choose to make something that is a combination of your answer and Vinegear's, and it's hard to select an accepted answer. I'll vote your answer, anyway.
True Soft
Thanks. Good luck!
helios