Class MessageFormatter


  • @Deprecated
    public class MessageFormatter
    extends java.lang.Object
    Deprecated.
    This API is for technology preview only.

    Overview of MessageFormatter

    In ICU4J, the MessageFormatter class is the next iteration of MessageFormat. This new version will build on the lessons learned from using MessageFormat for 25 years in various environments, when used directly or as a base for other public APIs.

    The effort to design a succesor to MessageFormat will result in a specification referred to as MessageFormat 2.0. The reasoning for this effort is shared in the “Why MessageFormat needs a successor” document.

    MessageFormat 2.0 will be more modular and easier to port and backport. It will also provide extension points via interfaces to allow users to supply new formatters and selectors without having to modify the specification. ICU will eventually include support for new formatters, such as intervals, relative time, lists, measurement units, personal names, and more, as well as the ability for users to supply their own custom implementations. These will potentially support use cases like grammatical gender, inflection, markup regimes (such as those require for text-to-speech), and other complex message management needs.

    The MessageFormat Working Group, which develops the new data model, semantics, and syntax, is hosted on GitHub. The current specification for the syntax and data model can be found here.

    This technical preview implements enough functions for MessageFormatter to be useful in many situations, but the final set of functions and the parameters accepted by those functions is not yet finalized.

    Examples

    Basic usage

     import static org.junit.Assert.assertEquals;
     import java.util.Date;
     import java.util.HashMap;
     import java.util.Locale;
     import java.util.Map;
    
     import com.ibm.icu.message2.MessageFormatter;
    
     @Test
     public void testMf2() {
         final Locale enGb = Locale.forLanguageTag("en-GB");
         Map arguments = new HashMap<>();
         arguments.put("name", "John");
         arguments.put("exp", new Date(1679971371000L));  // March 27, 2023, 7:42:51 PM
    
         MessageFormatter mf2 = MessageFormatter.builder()
             .setPattern("{Hello {$name}, your card expires on {$exp :datetime skeleton=yMMMdE}!}")
             .setLocale(enGb)
             .build();
    
         assertEquals(
             "Hello John, your card expires on Mon, 27 Mar 2023!",
             mf2.formatToString(arguments));
     }
     

    Placeholder examples

    Code to set runtime value for placeholder Examples of placeholder in message pattern
    arguments.put("name", "John") &#125;$name&#126;
    arguments.put("exp", new Date(…)) &#125;$exp :datetime skeleton=yMMMdE&#126;
    &#125;$exp :datetime datestyle=full&#126;
    arguments.put("val", 3.141592653) &#125;$val&#126;
    &#125;$val :number skeleton=(.####)&#126;
    No argument for fixed values known at build time &#125;(123456789.531) :number&#126;

    Plural selection message

     @Test
     public void testMf2Selection() {
        final String message = "match {$count :plural}\n"
                + " when one {You have one notification.}\n"
                + " when * {You have {$count} notifications.}\n";
        final Locale enGb = Locale.forLanguageTag("en-GB");
        Map arguments = new HashMap<>();
    
        MessageFormatter mf2 = MessageFormatter.builder()
            .setPattern(message)
            .setLocale(enGb)
            .build();
    
        arguments.put("count", 1);
        assertEquals(
            "You have one notification.",
            mf2.formatToString(arguments));
    
        arguments.put("count", 42);
        assertEquals(
            "You have 42 notifications.",
            mf2.formatToString(arguments));
     }
     

    Built-in formatter functions

    The tech preview implementation comes with formatters for numbers (number), date / time (datetime), plural selectors (plural and selectordinal), and general selector (select), very similar to what MessageFormat offers.

    The ICU test code covers most features, and has examples of how to make custom placeholder formatters; you can look for classes that implement com.ibm.icu.message2.FormatterFactory (they are named Custom*Test.java).

    Functions currently implemented

    These are the functions interpreted right now:

    datetime Similar to MessageFormat's date and time.
    datestyle and timestyle
    Similar to argStyle : short | medium | long | full.
    Same values are accepted, but we can use both in one placeholder, for example {$due :datetime datestyle=full timestyle=long}.
    pattern
    Similar to argStyle = argStyleText.
    This is bad i18n practice, and will probably be dropped.
    This is included just to support migration to MessageFormat 2.
    skeleton
    Same as argStyle = argSkeletonText.
    These are the date/time skeletons as supported by SimpleDateFormat.
    number Similar to MessageFormat's number.
    skeleton
    These are the number skeletons as supported by NumberFormatter.
    minimumFractionDigits
    Only implemented to be able to pass the unit tests from the ECMA tech preview implementation, which prefers options bags to skeletons.
    TBD if the final function will support skeletons, option backs, or both.
    offset
    Used to support plural with an offset.
    identityReturns the direct string value of the argument (calling toString()).
    plural Similar to MessageFormat's plural.
    skeleton
    These are the number skeletons as supported by NumberFormatter.
    Can also be indirect, from a local variable of type number (recommended).
    offset
    Used to support plural with an offset.
    Can also be indirect, from a local variable of type number (recommended).
    selectordinal Similar to MessageFormat's selectordinal.
    For now it accepts the same parameters as plural, although there is no use case for them.
    TBD if this will be merged into plural (with some kind option) or not.
    selectLiteral match, same as MessageFormat's select.
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      static class  MessageFormatter.Builder
      Deprecated.
      This API is for technology preview only.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods Deprecated Methods 
      Modifier and Type Method Description
      static MessageFormatter.Builder builder()
      Deprecated.
      This API is for technology preview only.
      FormattedMessage format​(java.util.Map<java.lang.String,​java.lang.Object> arguments)
      Deprecated.
      This API is for technology preview only.
      java.lang.String formatToString​(java.util.Map<java.lang.String,​java.lang.Object> arguments)
      Deprecated.
      This API is for technology preview only.
      Mf2DataModel getDataModel()
      Deprecated.
      This API is for technology preview only.
      java.util.Locale getLocale()
      Deprecated.
      This API is for technology preview only.
      java.lang.String getPattern()
      Deprecated.
      This API is for technology preview only.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • builder

        @Deprecated
        public static MessageFormatter.Builder builder()
        Deprecated.
        This API is for technology preview only.
        Creates a builder.
        Returns:
        the Builder.
      • getLocale

        @Deprecated
        public java.util.Locale getLocale()
        Deprecated.
        This API is for technology preview only.
        Get the locale to use for all the formatting and selections in the current MessageFormatter.
        Returns:
        the locale.
      • getPattern

        @Deprecated
        public java.lang.String getPattern()
        Deprecated.
        This API is for technology preview only.
        Get the pattern (the serialized message in MessageFormat 2 syntax) of the current MessageFormatter.

        If the MessageFormatter was created from an Mf2DataModel the this string is generated from that model.

        Returns:
        the pattern.
      • getDataModel

        @Deprecated
        public Mf2DataModel getDataModel()
        Deprecated.
        This API is for technology preview only.
        Give public access to the message data model.

        This data model is similar to the functionality we have today in MessagePatternUtil maybe even a bit more higher level.

        We can also imagine a model where one parses the string syntax, takes the data model, modifies it, and then uses that modified model to create a MessageFormatter.

        Returns:
        the data model.
      • formatToString

        @Deprecated
        public java.lang.String formatToString​(java.util.Map<java.lang.String,​java.lang.Object> arguments)
        Deprecated.
        This API is for technology preview only.
        Formats a map of objects by iterating over the MessageFormat's pattern, with the plain text “as is” and the arguments replaced by the formatted objects.
        Parameters:
        arguments - a map of objects to be formatted and substituted.
        Returns:
        the string representing the message with parameters replaced.
        Throws:
        java.lang.IllegalArgumentException - when something goes wrong (for example wrong argument type, or null arguments, etc.)
      • format

        @Deprecated
        public FormattedMessage format​(java.util.Map<java.lang.String,​java.lang.Object> arguments)
        Deprecated.
        This API is for technology preview only.
        Not yet implemented: formats a map of objects by iterating over the MessageFormat's pattern, with the plain text “as is” and the arguments replaced by the formatted objects.
        Parameters:
        arguments - a map of objects to be formatted and substituted.
        Returns:
        the FormattedMessage class representing the message with parameters replaced.