org.gwtproject.i18n.client.Constants Maven / Gradle / Ivy
/*
* 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 constant values
* supplied from properties files. Using GWT.create(class)
to "instantiate" an
* interface that extends Constants
returns an instance of an automatically generated
* subclass that is implemented using values from a property file selected based on locale.
*
* Locale is specified at run time using a meta tag or query string as described for {@link
* org.gwtproject.i18n.shared.Localizable}.
*
*
Extending Constants
*
* To use Constants
, begin by defining an interface that extends it. Each interface
* method is referred to as a constant accessor, 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 decimalSeparator
and thousandsSeparator
*
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}
*
*
The following example demonstrates how to use constant accessors defined in the interface
* above:
*
*
{@example
* com.google.gwt.examples.i18n.NumberFormatConstantsExample#useNumberFormatConstants()}
*
*
Here is the same example using annotations to store the default values:
*
*
{@example com.google.gwt.examples.i18n.NumberFormatConstantsAnnot}
*
*
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}
*
*
Defining Constant Accessors
*
* Constant accessors must be of the form
*
* T methodName()
*
* where T
is one of the return types in the following table:
*
*
*
* If the return type is...
* The property value is interpreted as...
* Annotation to use for default value
*
*
*
* String
* A plain string value
* {@code @DefaultStringValue}
*
*
*
* String[]
* A comma-separated array of strings; use '\\,
' to escape
* commas
* {@code @DefaultStringArrayValue}
*
*
*
* int
* An int
value, checked during compilation
* {@code @DefaultIntValue}
*
*
*
* float
* A float
value, checked during compilation
* {@code @DefaultFloatValue}
*
*
*
* double
* A double
value, checked during compilation
* {@code @DefaultDoubleValue}
*
*
*
* boolean
* A boolean
value ("true" or "false"), checked during
* compilation
* {@code @DefaultBooleanValue}
*
*
*
* Map
* 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
* {@code @DefaultStringMapValue}
*
*
*
*
* As an example of a Map
, for the following property file:
*
*
* a = X
* b = Y
* c = Z
* someMap = a, b, c
*
*
* the constant accessor someMap()
would return a Map
that maps
* "a"
onto "X"
, "b"
onto "Y"
, and "c"
* onto "Z"
. Iterating through this Map
will return the keys or entries in
* declaration order.
*
*
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}
*
*
Binding to Properties Files
*
* If an interface org.example.foo.Intf
extends Constants
and the
* following code is used to create an object from Intf
as follows:
*
* Intf constants = (Intf)GWT.create(Intf.class);
*
* then constants
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 (org/example/foo/
), (2) have a base
* filename matching the interface name (Intf
), and (3) have a suffix that most closely
* matches the locale. Suffixes are matched as follows:
*
*
*
*
* If locale
is...
* The properties file that binds to
* org.example.foo.Intf
is...
*
*
*
* unspecified
* org/example/foo/Intf.properties
*
*
*
* x
* org/example/foo/Intf_x.properties
if it exists and
* defines the property being sought, otherwise treated as if
* locale
were unspecified
*
*
*
* x_Y
* org/example/foo/Intf_x_Y.properties
if it exists and
* defines the property being sought, otherwise treated as if
* locale
were x
*
*
*
*
* where x
and Y
are language and locale codes, as described in the
* documentation for {@link org.gwtproject.i18n.shared.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.
*
* 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.
*
*
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 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();
}
}