/* GENERATED SOURCE. DO NOT MODIFY. */ // © 2022 and later: Unicode, Inc. and others. // License & terms of use: https://www.unicode.org/copyright.html package android.icu.message2; import java.util.Locale; import java.util.Map; /** *
In ICU4J, the {@code MessageFormatter} class is the next iteration of {@link android.icu.text.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 {@code 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 {@code MessageFormatter} to be useful in many situations, * but the final set of functions and the parameters accepted by those functions is not yet finalized.
* ** ** import static org.junit.Assert.assertEquals; * import java.util.Date; * import java.util.HashMap; * import java.util.Locale; * import java.util.Map; * * import android.icu.message2.MessageFormatter; * * @Test * public void test() { * final Locale enGb = Locale.forLanguageTag("en-GB"); * Maparguments = new HashMap<>(); * arguments.put("name", "John"); * arguments.put("exp", new Date(2023 - 1900, 2, 27, 19, 42, 51)); // March 27, 2023, 7:42:51 PM * * MessageFormatter mf2 = MessageFormatter.builder() * .setPattern("Hello {$name}, your card expires on {$exp :datetime year=numeric month=short day=numeric weekday=short}!") * .setLocale(enGb) * .build(); * * assertEquals( * "Hello John, your card expires on Mon, 27 Mar 2023!", * mf2.formatToString(arguments)); * } *
Code to set runtime value for placeholder | *Examples of placeholder in message pattern | *
---|---|
arguments.put("name", "John") |
* {$name} |
*
arguments.put("exp", new Date(…)) |
* {$exp :datetime skeleton=year=numeric month=short day=numeric weekday=short} * {$exp :datetime dateStyle=full} |
*
arguments.put("val", 3.141592653) |
* {$val} {$val :number minimumFractionDigits=5} |
*
No argument for fixed values known at build time | *{|123456789.531| :number} |
*
* ** @Test * public void testSelection() { * final String message = ".match {$count :number}\n" * + " 1 {{You have one notification.}}\n" * + " * {{You have {$count} notifications.}}\n"; * final Locale enGb = Locale.forLanguageTag("en-GB"); * Maparguments = 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)); * } *
The tech preview implementation comes with formatters for numbers ({@code :number}), * date / time ({@code :datetime}, {@code :date}, {@code :time}), * plural selectors ({@code :number} with options for {@code plural} and {@code ordinal} selection), * and general selector ({@code :string}), * very similar to what {@code 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 {@code android.icu.message2.FormatterFactory} * (they are named {@code Custom*Test.java}).
* *The complete list of valid options for each function, and how they infulence the results, can be found at * here.
* * @deprecated This API is for technology preview only. * @hide Only a subset of ICU is exposed in Android * @hide draft / provisional / internal are hidden on Android */ @Deprecated public class MessageFormatter { private final Locale locale; private final String pattern; private final MFFunctionRegistry functionRegistry; private final MFDataModel.Message dataModel; private final MFDataModelFormatter modelFormatter; private MessageFormatter(Builder builder) { this.locale = builder.locale; this.functionRegistry = builder.functionRegistry; if ((builder.pattern == null && builder.dataModel == null) || (builder.pattern != null && builder.dataModel != null)) { throw new IllegalArgumentException( "You need to set either a pattern, or a dataModel, but not both."); } if (builder.dataModel != null) { this.dataModel = builder.dataModel; // this.pattern = MFSerializer.dataModelToString(this.dataModel); this.pattern = MFSerializer.dataModelToString(dataModel); } else { this.pattern = builder.pattern; try { this.dataModel = MFParser.parse(pattern); } catch (MFParseException pe) { throw new IllegalArgumentException("" + "Parse error:\n" + "Message: <<" + pattern + ">>\n" + "Error: " + pe.getMessage() + "\n"); } } modelFormatter = new MFDataModelFormatter(dataModel, locale, functionRegistry); } /** * Creates a builder. * * @return the Builder. * * @deprecated This API is for technology preview only. * @hide draft / provisional / internal are hidden on Android */ @Deprecated public static Builder builder() { return new Builder(); } /** * Get the locale to use for all the formatting and selections in * the current {@code MessageFormatter}. * * @return the locale. * * @deprecated This API is for technology preview only. * @hide draft / provisional / internal are hidden on Android */ @Deprecated public Locale getLocale() { return locale; } /** * Get the pattern (the serialized message in MessageFormat 2 syntax) of * the current {@code MessageFormatter}. * *
If the {@code MessageFormatter} was created from an {@link MFDataModel} * the this string is generated from that model.
* * @return the pattern. * * @deprecated This API is for technology preview only. * @hide draft / provisional / internal are hidden on Android */ @Deprecated public String getPattern() { return pattern; } /** * Give public access to the message data model. * *This data model is similar to the functionality we have today * in {@link android.icu.text.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 {@code MessageFormatter}.
* * @return the data model. * * @deprecated This API is for technology preview only. * @hide draft / provisional / internal are hidden on Android */ @Deprecated public MFDataModel.Message getDataModel() { return dataModel; } /** * 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. * * @param arguments a map of objects to be formatted and substituted. * @return the string representing the message with parameters replaced. * * @throws IllegalArgumentException when something goes wrong * (for example wrong argument type, or null arguments, etc.) * * @deprecated This API is for technology preview only. * @hide draft / provisional / internal are hidden on Android */ @Deprecated public String formatToString(MapThere is no need to do this in order to use standard functions
* (for example date / time / number formatting, plural / ordinal / literal selection).
* The exact set of standard functions, with the types they format and the options
* they accept is still TBD.