Message formatting

This example will show how to format a message with java's MessageFormat. MessageFormat provides a way to concatenate messages by accepting a set of objects, formats them, and then inserts the strings into the pattern specified. As noted in the java docs the MessageFormat class doesn't handle locale specifics so if it is required you must provide it with the pattern and sub formats.

w/o MessageFormat

Without MessageFormat you are handling the message, formats and variables to be inserted which is a form of string concatenation.

@Test
public void format_message_with_out_messageformatter_java() {
    String value1 = "Your account balance was ";
    String value2 = "2,500 ";
    String value3 = "on ";
    String value4 = "5/15/2013";

    String output = value1 + value2 + value3 + value4;

    assertEquals("Your account balance was 2,500 on 5/15/2013", output);
}

MessageFormat

In this snippet we will call MessageFormat.format which accepts a format and an array of arguments. Both arguments in the object array are pre formatted, first is a number with a comma and second is a date in MM/dd/yyyy format.

@Test
public void format_message_with_messageformatter() {

    Object[] accountValues = { "2,500", "5/15/2013" };
    String output = MessageFormat.format("Your account balance was {0} on {1}", accountValues);

    assertEquals("Your account balance was 2,500 on 5/15/2013", output);
}

MessageFormat multiple records

To format multiple messages we will first create a multidimensional array containing two objects to be injected into the message. Next we will define a MessageFormat with the necessary placeholders and then loop over statementValues. The formatter.format produces a String which we will collect into an ArrayList. This is different than the snippet above as we instantiate the MessageFormat object to be called multiple times.

@Test
public void messageformatter_mutliple_records() {

    Object[][] statementValues = { { "2,500", "5/15/2013" },
            { "2,200", "6/15/2013" } };

    MessageFormat formatter = new MessageFormat("Your account balance was {0} on {1}");

    List<String> statementOutput = new ArrayList<String>();
    for (Object[] monthlyStatements : statementValues) {
        statementOutput.add(formatter.format(monthlyStatements));
    }

    assertTrue(statementOutput.size() == 2);
    assertEquals("Your account balance was 2,500 on 5/15/2013", statementOutput.get(0));
    assertEquals("Your account balance was 2,200 on 6/15/2013",statementOutput.get(1));
}

MessageFormat format & style

In both of the snippets above the values were pre formatted. This will show how you can define the MessageFormat and a pattern to be used to format the given arguments. The first argument will format the number as currency while the second will format the java.util.Date object in MM/dd/yyyy format. A side note, we are using Joda Time to create statementDate.

@Test
public void messageformatter_with_format_type_and_style() {

    DateTime statementDate = new DateTime(2013, 5, 15, 0, 0, 0, 0);
    double satementBalance = 2500;

    Object[] statementValues = { satementBalance, statementDate.toDate() };

    String output = MessageFormat.format("Your account balance was {0, number, currency} "
            + "on {1, date, MM/dd/yyyy}", statementValues);

    assertEquals("Your account balance was $2,500.00 on  05/15/2013", output);
}

MessageFormat w/ choice

This snippet will show how to provide flexibility when the values of the objects are not present. Breaking down the pattern, the first parameter will format the date in MM/dd/yyyy format and the second will have a choice. If the value is specified in the given arguments then a it will be formatted as currency, if a values isn't present a predefined message will be presented.

@Test
public void messageformatter_with_choice() {

    String pattern = "Your statement on {0, date, MM/dd/yyyy} "
            + "{1,choice,0#is not available|1#is {1, number, currency}}";

    MessageFormat statementFormat = new MessageFormat(pattern);

    DateTime statementDate1 = new DateTime(2013, 5, 15, 0, 0, 0, 0);

    Object[] statement1 = {statementDate1.toDate(), 23444};
    assertEquals("Your statement on  05/15/2013 is $23,444.00",
            statementFormat.format(statement1));

    DateTime statementDate2 = new DateTime(2013, 6, 15, 0, 0, 0, 0);
    Object[] statement2 = {statementDate2.toDate(), 0};
    assertEquals("Your statement on  06/15/2013 is not available",
            statementFormat.format(statement2));
}