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

com.google.gwt.i18n.client.Messages Maven / Gradle / Ivy

There is a newer version: 2.10.0
Show newest version
/*
 * Copyright 2008 Google Inc.
 * 
 * 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 com.google.gwt.i18n.client;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 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 com.google.gwt.i18n.client.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 = "com.google.gwt.i18n.rebind.format.PropertiesFormat")
 * @DefaultLocale("en_US")
 * public interface MyMessages extends Messages {
 *   @Key("1234")
 *   @DefaultText("This is a plain string.")
 *   String oneTwoThreeFour();
 *   
 *   @DefaultText("You have {0} widgets")
 *   @PluralText({"one", "You have one widget")
 *   String widgetCount(@PluralCount int count);
 *   
 *   @DefaultText("No reference to the argument")
 *   String optionalArg(@Optional String ignored);
 *   
 *   @DefaultText("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 * com.google.gwt.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 {@link com.google.gwt.core.client.GWT#create(Class)}. */ 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. *

*/ Class value() default 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, or a primitive * numeric 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 { } }