| /* | |
| * Copyright 2007 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 | |
| * constant values supplied from properties files. Using | |
| * <code>GWT.create(<i>class</i>)</code> to "instantiate" an interface that | |
| * extends <code>Constants</code> returns an instance of an automatically | |
| * generated subclass that is implemented using values from a property file | |
| * selected based on locale. | |
| * | |
| * <p> | |
| * Locale is specified at run time using a meta tag or query string as described | |
| * for {@link com.google.gwt.i18n.client.Localizable}. | |
| * </p> | |
| * | |
| * <h3>Extending <code>Constants</code></h3> | |
| * To use <code>Constants</code>, begin by defining an interface that extends | |
| * it. Each interface method is referred to as a <i>constant accessor</i>, and | |
| * its corresponding localized value 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}. Also, the default value can be specified in an annotation | |
| * rather than a default properties file (and some key generators may require the value | |
| * to be given in the source file via annotations). For example, | |
| * | |
| * {@example com.google.gwt.examples.i18n.NumberFormatConstants} | |
| * | |
| * expects to find properties named <code>decimalSeparator</code> and | |
| * <code>thousandsSeparator</code> in an associated properties file. For | |
| * example, the following properties would be used for a German locale: | |
| * | |
| * {@gwt.include com/google/gwt/examples/i18n/NumberFormatConstants_de_DE.properties} | |
| * | |
| * <p> | |
| * The following example demonstrates how to use constant accessors defined in | |
| * the interface above: | |
| * | |
| * {@example com.google.gwt.examples.i18n.NumberFormatConstantsExample#useNumberFormatConstants()} | |
| * </p> | |
| * | |
| * <p> | |
| * Here is the same example using annotations to store the default values: | |
| * | |
| * {@example com.google.gwt.examples.i18n.NumberFormatConstantsAnnot} | |
| * </p> | |
| * | |
| * <p> | |
| * It is also possible to change the property name bound to a constant accessor | |
| * using the {@code @Key} annotation. For example, | |
| * {@example com.google.gwt.examples.i18n.NumberFormatConstantsWithAltKey} | |
| * | |
| * would match the names of the following properties: | |
| * | |
| * {@gwt.include com/google/gwt/examples/i18n/NumberFormatConstantsWithAltKey_en.properties} | |
| * </p> | |
| * | |
| * <h3>Defining Constant Accessors</h3> | |
| * Constant accessors must be of the form | |
| * | |
| * <pre>T methodName()</pre> | |
| * | |
| * where <code>T</code> is one of the return types in the following table: | |
| * | |
| * <table> | |
| * <tr> | |
| * <th><nobr>If the return type is...   </nobr></th> | |
| * <th>The property value is interpreted as...</th> | |
| * <th>Annotation to use for default value</th> | |
| * </tr> | |
| * | |
| * <tr> | |
| * <td><code>String</code></td> | |
| * <td>A plain string value</td> | |
| * <td>{@code @DefaultStringValue}</td> | |
| * </tr> | |
| * | |
| * <tr> | |
| * <td><code>String[]</code></td> | |
| * <td>A comma-separated array of strings; use '<code>\\,</code>' to escape | |
| * commas</td> | |
| * <td>{@code @DefaultStringArrayValue}</td> | |
| * </tr> | |
| * | |
| * <tr> | |
| * <td><code>int</code></td> | |
| * <td>An <code>int</code> value, checked during compilation</td> | |
| * <td>{@code @DefaultIntValue}</td> | |
| * </tr> | |
| * | |
| * <tr> | |
| * <td><code>float</code></td> | |
| * <td>A <code>float</code> value, checked during compilation</td> | |
| * <td>{@code @DefaultFloatValue}</td> | |
| * </tr> | |
| * | |
| * <tr> | |
| * <td><code>double</code></td> | |
| * <td>A <code>double</code> value, checked during compilation</td> | |
| * <td>{@code @DefaultDoubleValue}</td> | |
| * </tr> | |
| * | |
| * <tr> | |
| * <td><code>boolean</code></td> | |
| * <td>A <code>boolean</code> value ("true" or "false"), checked during | |
| * compilation</td> | |
| * <td>{@code @DefaultBooleanValue}</td> | |
| * </tr> | |
| * | |
| * <tr> | |
| * <td><code>Map</code></td> | |
| * <td>A comma-separated list of property names, each of which is a key into a | |
| * generated map; the value mapped to given key is the value of the property | |
| * having named by that key</td> | |
| * <td>{@code @DefaultStringMapValue}</td> | |
| * </tr> | |
| * | |
| * </table> | |
| * | |
| * <p> | |
| * As an example of a <code>Map</code>, for the following property file: | |
| * </p> | |
| * | |
| * <pre> | |
| * a = X | |
| * b = Y | |
| * c = Z | |
| * someMap = a, b, c | |
| * </pre> | |
| * | |
| * <p> | |
| * the constant accessor <code>someMap()</code> would return a | |
| * <code>Map</code> that maps <code>"a"</code> onto <code>"X"</code>, | |
| * <code>"b"</code> onto <code>"Y"</code>, and <code>"c"</code> onto | |
| * <code>"Z"</code>. Iterating through this <code>Map</code> will return | |
| * the keys or entries in declaration order. | |
| * </p> | |
| * | |
| * <p>The benefit of using annotations, aside from not having to switch to | |
| * a different file to enter the default values, is that you can make use | |
| * of compile-time constants and not worrying about quoting commas. For example: | |
| * | |
| * {@example com.google.gwt.examples.i18n.AnnotConstants} | |
| * </p> | |
| * | |
| * <h3>Binding to Properties Files</h3> | |
| * If an interface <code>org.example.foo.Intf</code> extends | |
| * <code>Constants</code> and the following code is used to create an object | |
| * from <code>Intf</code> as follows: | |
| * | |
| * <pre class="code">Intf constants = (Intf)GWT.create(Intf.class);</pre> | |
| * | |
| * then <code>constants</code> will be assigned an instance of a generated | |
| * class whose constant accessors are implemented by extracting values from a | |
| * set of matching properties files. Property values are sought using a | |
| * best-match algorithm, and candidate properties files are those which (1) | |
| * reside in the same package as the interface (<code>org/example/foo/</code>), | |
| * (2) have a base filename matching the interface name (<code>Intf</code>), | |
| * and (3) have a suffix that most closely matches the locale. Suffixes are | |
| * matched as follows: | |
| * | |
| * <table> | |
| * | |
| * <tr> | |
| * <th align='left'><nobr>If <code>locale</code> is...  </nobr></th> | |
| * <th align='left'>The properties file that binds to | |
| * <code>org.example.foo.Intf</code> is...</th> | |
| * </tr> | |
| * | |
| * <tr> | |
| * <td><i>unspecified</i></td> | |
| * <td><code>org/example/foo/Intf.properties</code></td> | |
| * </tr> | |
| * | |
| * <tr> | |
| * <td><code>x</code></td> | |
| * <td><code>org/example/foo/Intf_x.properties</code> if it exists and | |
| * defines the property being sought, otherwise treated as if | |
| * <code>locale</code> were <i>unspecified</i></td> | |
| * </tr> | |
| * | |
| * <tr> | |
| * <td><code>x_Y</code></td> | |
| * <td><code>org/example/foo/Intf_x_Y.properties</code> if it exists and | |
| * defines the property being sought, otherwise treated as if | |
| * <code>locale</code> were <code>x</code></td> | |
| * </tr> | |
| * | |
| * </table> where <code>x</code> and <code>Y</code> are language and locale | |
| * codes, as described in the documentation for | |
| * {@link com.google.gwt.i18n.client.Localizable}. Note that default values | |
| * supplied in the source file in annotations take precedence over those in | |
| * the default properties file, if it is also present. | |
| * | |
| * <p> | |
| * Note that the matching algorithm is applied independently for each constant | |
| * accessor. It is therefore possible to create a hierarchy of related | |
| * properties files such that an unlocalized properties file acts as a baseline, | |
| * and locale-specific properties files may redefine a subset of those | |
| * properties, relying on the matching algorithm to prefer localized properties | |
| * while still finding unlocalized properties. | |
| * </p> | |
| * | |
| * <h3>Required Module</h3> | |
| * Modules that use this interface should inherit | |
| * <code>com.google.gwt.i18n.I18N</code>. | |
| * | |
| * {@gwt.include com/google/gwt/examples/i18n/InheritsExample.gwt.xml} | |
| * | |
| * <h3>Note</h3> | |
| * 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 Constants extends LocalizableResource { | |
| /** | |
| * Default boolean value to be used if no translation is found (and also used as the | |
| * source for translation). No quoting (other than normal Java string quoting) | |
| * is done. | |
| */ | |
| @Retention(RetentionPolicy.RUNTIME) | |
| @Target(ElementType.METHOD) | |
| @Documented | |
| public @interface DefaultBooleanValue { | |
| boolean value(); | |
| } | |
| /** | |
| * Default double value to be used if no translation is found (and also used as the | |
| * source for translation). No quoting (other than normal Java string quoting) | |
| * is done. | |
| */ | |
| @Retention(RetentionPolicy.RUNTIME) | |
| @Target(ElementType.METHOD) | |
| @Documented | |
| public @interface DefaultDoubleValue { | |
| double value(); | |
| } | |
| /** | |
| * Default float value to be used if no translation is found (and also used as the | |
| * source for translation). No quoting (other than normal Java string quoting) | |
| * is done. | |
| */ | |
| @Retention(RetentionPolicy.RUNTIME) | |
| @Target(ElementType.METHOD) | |
| @Documented | |
| public @interface DefaultFloatValue { | |
| float value(); | |
| } | |
| /** | |
| * Default integer value to be used if no translation is found (and also used as the | |
| * source for translation). No quoting (other than normal Java string quoting) | |
| * is done. | |
| */ | |
| @Retention(RetentionPolicy.RUNTIME) | |
| @Target(ElementType.METHOD) | |
| @Documented | |
| public @interface DefaultIntValue { | |
| int value(); | |
| } | |
| /** | |
| * Default string array value to be used if no translation is found (and also | |
| * used as the source for translation). No quoting (other than normal Java | |
| * string quoting) is done. | |
| * | |
| * Note that in the corresponding properties/etc file, commas are used to separate | |
| * elements of the array unless they are preceded with a backslash. | |
| */ | |
| @Retention(RetentionPolicy.RUNTIME) | |
| @Target(ElementType.METHOD) | |
| @Documented | |
| public @interface DefaultStringArrayValue { | |
| String[] value(); | |
| } | |
| /** | |
| * Default string map value to be used if no translation is found (and also | |
| * used as the source for translation). No quoting (other than normal Java | |
| * string quoting) is done. The strings for the map are supplied in key/value | |
| * pairs. | |
| * | |
| * Note that in the corresponding properties/etc file, new keys can be supplied | |
| * with the name of the method (or its corresponding key) listing the set of keys | |
| * for the map separated by commas (commas can be part of the keys by preceding | |
| * them with a backslash). In either case, further entries have keys matching | |
| * the key in this map. | |
| */ | |
| @Retention(RetentionPolicy.RUNTIME) | |
| @Target(ElementType.METHOD) | |
| @Documented | |
| public @interface DefaultStringMapValue { | |
| /** | |
| * Must be key-value pairs. | |
| */ | |
| String[] value(); | |
| } | |
| /** | |
| * Default string value to be used if no translation is found (and also used as the | |
| * source for translation). No quoting (other than normal Java string quoting) | |
| * is done. | |
| */ | |
| @Retention(RetentionPolicy.RUNTIME) | |
| @Target(ElementType.METHOD) | |
| @Documented | |
| public @interface DefaultStringValue { | |
| String value(); | |
| } | |
| } |