Skip to content

Commit f5a5e6a

Browse files
authored
Enhance nullability annotations and documentation in LocalizedText (#6149)
1 parent f0466c1 commit f5a5e6a

1 file changed

Lines changed: 50 additions & 6 deletions

File tree

HMCLCore/src/main/java/org/jackhuang/hmcl/util/i18n/LocalizedText.java

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,60 @@
2323
import com.google.gson.stream.JsonReader;
2424
import com.google.gson.stream.JsonToken;
2525
import com.google.gson.stream.JsonWriter;
26-
import org.jetbrains.annotations.NotNull;
26+
import org.jackhuang.hmcl.util.gson.JsonSerializable;
27+
import org.jetbrains.annotations.NotNullByDefault;
2728
import org.jetbrains.annotations.Nullable;
2829

2930
import java.io.IOException;
3031
import java.util.*;
3132

33+
/// Represents text that may either be locale-independent or stored as values keyed by language tags.
34+
///
35+
/// The JSON representation accepts either a string or an object. A string is treated as the same text for every
36+
/// locale, while an object maps language keys, such as `en`, `zh-Hans`, or `default`, to localized text values.
37+
///
38+
/// @author Glavo
39+
@NotNullByDefault
3240
@JsonAdapter(LocalizedText.Adapter.class)
41+
@JsonSerializable
3342
public final class LocalizedText {
43+
/// Locale-independent text used when this instance is not backed by localized values.
3444
private final @Nullable String value;
45+
46+
/// Text values keyed by language keys generated by [LocaleUtils#toLanguageKey(Locale)].
3547
private final @Nullable Map<String, String> localizedValues;
3648

37-
public LocalizedText(String value) {
49+
/// Creates a locale-independent text value.
50+
///
51+
/// When `value` is `null`, [#getText(List)] returns `null` for every candidate locale.
52+
///
53+
/// @param value the text value, or `null` if the text is absent
54+
public LocalizedText(@Nullable String value) {
3855
this.value = value;
3956
this.localizedValues = null;
4057
}
4158

42-
public LocalizedText(@NotNull Map<String, String> localizedValues) {
59+
/// Creates a localized text value backed by language-key mappings.
60+
///
61+
/// The map is stored directly and is not copied. Later changes to `localizedValues` are visible through this
62+
/// instance.
63+
///
64+
/// @param localizedValues text values keyed by language keys generated by [LocaleUtils#toLanguageKey(Locale)]
65+
/// @throws NullPointerException if `localizedValues` is `null`
66+
public LocalizedText(Map<String, String> localizedValues) {
4367
this.value = null;
4468
this.localizedValues = Objects.requireNonNull(localizedValues);
4569
}
4670

47-
public String getText(@NotNull List<Locale> candidates) {
71+
/// Returns the best matching text for the given candidate locales.
72+
///
73+
/// If this instance stores localized values, the candidates are checked in iteration order after conversion with
74+
/// [LocaleUtils#toLanguageKey(Locale)]. The first matching value is returned, or `null` if no candidate matches.
75+
/// If this instance stores locale-independent text, the stored value is returned without checking `candidates`.
76+
///
77+
/// @param candidates candidate locales ordered from most preferred to least preferred
78+
/// @return the matched text, the locale-independent text, or `null` if no text is available
79+
public @Nullable String getText(List<Locale> candidates) {
4880
if (localizedValues != null) {
4981
for (Locale locale : candidates) {
5082
String value = localizedValues.get(LocaleUtils.toLanguageKey(locale));
@@ -56,10 +88,17 @@ public String getText(@NotNull List<Locale> candidates) {
5688
return value;
5789
}
5890

91+
/// Gson adapter for the compact localized text JSON representation.
5992
static final class Adapter extends TypeAdapter<LocalizedText> {
6093

94+
/// Reads a localized text value from `null`, a JSON string, or a JSON object.
95+
///
96+
/// @param jsonReader the reader positioned at the next localized text value
97+
/// @return the parsed localized text, or `null` if the next JSON token is `null`
98+
/// @throws IOException if reading from `jsonReader` fails
99+
/// @throws JsonSyntaxException if the next token is neither `null`, a string, nor an object
61100
@Override
62-
public LocalizedText read(JsonReader jsonReader) throws IOException {
101+
public @Nullable LocalizedText read(JsonReader jsonReader) throws IOException {
63102
JsonToken nextToken = jsonReader.peek();
64103
if (nextToken == JsonToken.NULL) {
65104
return null;
@@ -83,8 +122,13 @@ public LocalizedText read(JsonReader jsonReader) throws IOException {
83122
}
84123
}
85124

125+
/// Writes a localized text value as `null`, a JSON string, or a JSON object.
126+
///
127+
/// @param jsonWriter the writer that receives the JSON representation
128+
/// @param localizedText the localized text to write, or `null` to write a JSON `null`
129+
/// @throws IOException if writing to `jsonWriter` fails
86130
@Override
87-
public void write(JsonWriter jsonWriter, LocalizedText localizedText) throws IOException {
131+
public void write(JsonWriter jsonWriter, @Nullable LocalizedText localizedText) throws IOException {
88132
if (localizedText == null) {
89133
jsonWriter.nullValue();
90134
} else if (localizedText.localizedValues != null) {

0 commit comments

Comments
 (0)