All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.gwtproject.i18n.client.Messages Maven / Gradle / Ivy

There is a newer version: 1.0.139
Show newest version
/*
 * Copyright © 2018 The GWT Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.gwtproject.i18n.client;

import java.lang.annotation.*;

/**
 * A tag interface that facilitates locale-sensitive, compile-time binding of messages supplied from
 * various sources.Using GWT.create(class) to "instantiate" an interface that
 * extends Messages returns an instance of an automatically generated subclass that is
 * implemented using message templates selected based on locale. Message templates are based on a
 * subset of the format used by 
 * MessageFormat. Note in particular that single quotes are used to quote other
 * characters, and should be doubled for a literal single quote.
 *
 * 

Locale is specified at run time using a meta tag or query string as described for {@link * org.gwtproject.i18n.shared.Localizable}. * *

Extending Messages

* * To use Messages, begin by defining an interface that extends it. Each interface * method is referred to as a message accessor, and its corresponding message template is * loaded based on the key for that method. The default key is simply the unqualified name of the * method, but can be specified directly with an {@code @Key} annotation or a different generation * method using {@code @GenerateKeys}. Additionally, if plural forms are used on a given method the * plural form is added as a suffix to the key, such as widgets[one] for the singular * version of the widgets message. The resulting key is used to find translated * versions of the message from any supported input file, such as Java properties files. For * example, * *

{@example com.google.gwt.examples.i18n.GameStatusMessages} * *

expects to find properties named turnsLeft and currentScore in an * associated properties file, formatted as message templates taking two arguments and one argument, * respectively. For example, the following properties would correctly bind to the * GameStatusMessages interface: * *

{@gwt.include com/google/gwt/examples/i18n/GameStatusMessages.properties} * *

The following example demonstrates how to use constant accessors defined in the interface * above: * *

{@example com.google.gwt.examples.i18n.GameStatusMessagesExample#beginNewGameRound(String)} * *

The following example shows how to use annotations to store the default strings in the source * file itself, rather than needing a properties file (you still need properties files for the * translated strings): * *

{@example com.google.gwt.examples.i18n.GameStatusMessagesAnnot} * *

In this example, calling msg.turnsLeft("John", 13) would return the string * "Turns left for player 'John': 13". * *

Defining Message Accessors

* * Message accessors must be of the form * *
String methodName(optional-params)
* * and parameters may be of any type. Arguments are converted into strings at runtime using Java * string concatenation syntax (the '+' operator), which uniformly handles primitives, null * , and invoking toString() to format objects. * *

Compile-time checks are performed to ensure that the number of placeholders in a message * template (e.g. {0}) matches the number of parameters supplied. * *

Integral arguments may be used to select the proper plural form to use for different locales. * To do this, mark the particular argument with {@code @PluralCount} (a plural rule may be * specified with {@code @PluralCount} if necessary, but you will almost never need to do this). The * actual plural forms for the default locale can be supplied in a {@code @PluralText} annotation on * the method, such as @PluralText({"one", "You have one widget"}), or they can be * supplied in the properties file as {@code methodkey[one]=You have one widget}. Note that * non-default plural forms are not inherited between locales, because the different locales may * have different plural rules (especially {@code default} and anything else and those which use * different scripts such as {@code sr_Cyrl} and {@code sr_Latn} [one of which would likely be the * default], but also subtle cases like {@code pt} and {@code pt_BR}). * *

Additionally, individual arguments can be marked as optional (ie, GWT will not give an error * if a particular translation does not reference the argument) with the {@code @Optional} * annotation, and an example may be supplied to the translator with the {@code @Example(String)} * annotation. * *

Complete Annotations Example

* * In addition to the default properties file, default text and additional metadata may be stored in * the source file itself using annotations. A complete example of using annotations in this way is: *
 * @Generate(format = "org.gwtproject.i18n.rebind.format.PropertiesFormat")
 * @DefaultLocale("en_US")
 * public interface MyMessages extends Messages {
 *   @Key("1234")
 *   @DefaultMessage("This is a plain string.")
 *   String oneTwoThreeFour();
 *
 *   @DefaultMessage("You have {0} widgets")
 *   @PluralText({"one", "You have one widget")
 *   String widgetCount(@PluralCount int count);
 *
 *   @DefaultMessage("No reference to the argument")
 *   String optionalArg(@Optional String ignored);
 *
 *   @DefaultMessage("Your cart total is {0,number,currency}")
 *   @Description("The total value of the items in the shopping cart in local currency")
 *   String totalAmount(@Example("$5.00") double amount);
 *
 *   @Meaning("the color")
 *   @DefaultMessage("orange")
 *   String orangeColor();
 *
 *   @Meaning("the fruit")
 *   @DefaultMessage("orange")
 *   String orangeFruit();
 * }
 * 
* *

Binding to Properties Files

* * Interfaces extending Messages are bound to resource files using the same algorithm * as interfaces extending Constants. See the documentation for {@link Constants} for a * description of the algorithm. * *

Required Module

* * Modules that use this interface should inherit org.gwtproject.i18n.I18N. * *

{@gwt.include com/google/gwt/examples/i18n/InheritsExample.gwt.xml} * *

Note

* * You should not directly implement this interface or interfaces derived from it since an * implementation is generated automatically when message interfaces are created using. */ public interface Messages extends LocalizableResource { /** * Provides alternate forms of a message, such as are needed when plural forms are used or a * placeholder has known gender. The selection of which form to use is based on the value of the * arguments marked PluralCount and/or Select. * *

Example:

   *   @DefaultMessage("You have {0} widgets.")
   *   @AlternateMessage({"one", "You have one widget.")
   *   String example(@PluralCount int count);
   * 
* *

If multiple {@link PluralCount} or {@link Select} parameters are supplied, the forms for * each, in the order they appear in the parameter list, are supplied separated by a vertical bar * ("|"). Example:

   *   @DefaultMessage("You have {0} messages and {1} notifications.")
   *   @AlternateMessage({
   *       "=0|=0", "You have no messages or notifications."
   *       "=0|one", "You have a notification."
   *       "one|=0", "You have a message."
   *       "one|one", "You have one message and one notification."
   *       "other|one", "You have {0} messages and one notification."
   *       "one|other", "You have one message and {1} notifications."
   *   })
   *   String messages(@PluralCount int msgCount,
   *       @PluralCount int notifyCount);
   * 
Note that the number of permutations can grow quickly, and that the default * message is used when every {@link PluralCount} or {@link Select} would use the "other" value. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Documented public @interface AlternateMessage { /** * An array of pairs of strings containing the strings for different forms. * * Each pair is the name of a form followed by the string in the source * locale for that form. Each form name is the name of a plural form if * {@link PluralCount} is used, or the matching value if {@link Select} is * used. An example for a locale that has "none", "one", and "other" plural * forms: * *
     * @DefaultMessage("{0} widgets")
     * @AlternateMessage({"none", "No widgets", "one", "One widget"})
     * 
* * Note that the plural form "other" gets the translation specified in * {@code @DefaultMessage}, as does any {@code @Select} value not * listed. * * If more than one way of selecting a translation exists, they will be * combined, separated with {@code |}, in the order they are supplied as * arguments in the method. For example: *
     *   @DefaultMessage("{0} gave away their {2} widgets")
     *   @AlternateMesssage({
     *     "MALE|other", "{0} gave away his {2} widgets",
     *     "FEMALE|other", "{0} gave away her {2} widgets",
     *     "MALE|one", "{0} gave away his widget",
     *     "FEMALE|one", "{0} gave away her widget",
     *     "other|one", "{0} gave away their widget",
     *   })
     *   String giveAway(String name, @Select Gender gender,
     *       @PluralCount int count);
     * 
*/ String[] value(); } /** * Default text to be used if no translation is found (and also used as the source for * translation). Format should be that expected by {@link java.text.MessageFormat}. * *

Example:

   *   @DefaultMessage("Don''t panic - you have {0} widgets left")
   *   String example(int count)
   * 
*/ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Documented public @interface DefaultMessage { String value(); } /** * An example of the annotated parameter to assist translators. * *

Example:

   *   String example(@Example("/etc/passwd") String fileName)
   * 
*/ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface Example { String value(); } /** * Ignored except on parameters also tagged with {@link PluralCount}, and provides an offset to be * subtracted from the value before a plural rule is chosen or the value is formatted. Note that * "=n" forms are evaluated before this offset is applied. * *

Example:

   *   @PluralText({"=0", "No one has recommended this movie",
   *     "=1", "{0} has recommended this movie",
   *     "=2", "{0} and {1} have recommended this movie",
   *     "one", "{0}, {1} and one other have recommended this movie"})
   *   @DefaultMessage("{0}, {1} and {2,number} others have recommended this movie")
   *   String recommenders(@Optional String rec1, @Optional String rec2,
   *     @PluralCount @Offset(2) int count);
   * 
would result in
   * recommenders("John", null, 1) => "John has..."
   * recommenders("John", "Jane", 3) => "John, Jane, and one other..."
   * recommenders("John", "Jane", 1402) => "John, Jane, and 1,400 others..."
   * 
*/ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface Offset { int value(); } /** * Indicates the specified parameter is optional and need not appear in a particular translation * of this message. * *

Example:

   *   String example(@Optional int count)
   * 
*/ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface Optional {} /** * Provides multiple plural forms based on a count. The selection of which plural form is * performed by a PluralRule implementation. * *

This annotation is applied to a single parameter of a Messages subinterface and indicates * that parameter is to be used to choose the proper plural form of the message. The parameter * chosen must be of type short or int. * *

Optionally, a class literal referring to a PluralRule implementation can be supplied as the * argument if the standard implementation is insufficient. * *

Example:

   *   @DefaultMessage("You have {0} widgets.")
   *   @AlternateMessage({"one", "You have one widget."})
   *   String example(@PluralCount int count)
   * 
*/ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface PluralCount { /** * The PluralRule implementation to use for this message. If not specified, the GWT-supplied one * is used instead, which should cover most use cases. * *

{@code PluralRule.class} is used as a default value here, which will be replaced during * code generation with the default implementation. */ // http://bugs.sun.com/view_bug.do?bug_id=6512707 Class value() default org.gwtproject.i18n.client.PluralRule.class; } /** * Provides multiple plural forms based on a count. The selection of which plural form to use is * based on the value of the argument marked PluralCount, which may also specify an alternate * plural rule to use. * *

Example:

   *   @DefaultMessage("You have {0} widgets.")
   *   @PluralText({"one", "You have one widget.")
   *   String example(@PluralCount int count)
   * 
* * @deprecated use {@link AlternateMessage} instead */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Documented @Deprecated public @interface PluralText { /** * An array of pairs of strings containing the strings for different plural * forms. * * Each pair is the name of the plural form (as returned by * PluralForm.toString) followed by the string for that plural form. An * example for a locale that has "none", "one", and "other" plural forms: * *
     * @DefaultMessage("{0} widgets")
     * @PluralText({"none", "No widgets", "one", "One widget"})
     * 
* * "other" must not be included in this array as it will map to the * DefaultMessage value. */ String[] value(); } /** * Provides multiple forms based on a dynamic parameter. * *

This annotation is applied to a single parameter of a Messages subinterface and indicates * that parameter is to be used to choose the proper form of the message. The parameter chosen * must be of type Enum, String, boolean, or a primitive integral type. This is frequently used to * get proper gender for translations to languages where surrounding words depend on the gender of * a person or noun. This also marks the parameter as {@link Optional}. * *

Example:

   *   @DefaultMessage("{0} likes their widgets.")
   *   @AlternateMessage({
   *       "FEMALE", "{0} likes her widgets.",
   *       "MALE", "{0} likes his widgets.",
   *   })
   *   String example(String name, @Select Gender gender)
   * 
*/ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface Select {} }