Skip to content

Commit 954ea6e

Browse files
committed
Full support for multi-file and multi-lanuages with overrides and bundled supports
1 parent 94bd283 commit 954ea6e

File tree

5 files changed

+81
-66
lines changed

5 files changed

+81
-66
lines changed

crowdin.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
files:
2-
- source: /src/main/resources/lang-original/*.json
2+
- source: /src/main/resources/bundled/*.json
33
translation: /src/main/resources/lang/%locale%/%original_file_name%

pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@
314314
<excludes>
315315
<exclude>src/main/resources/bin</exclude>
316316
<exclude>src/main/resources/lang</exclude>
317-
<exclude>src/main/resources/lang-original</exclude>
317+
<exclude>src/main/resources/bundled</exclude>
318318
</excludes>
319319
</resource>
320320
<resource>
@@ -328,9 +328,9 @@
328328
<directory>src/main/resources/lang</directory>
329329
</resource>
330330
<resource>
331-
<targetPath>lang-original</targetPath>
331+
<targetPath>bundled</targetPath>
332332
<filtering>false</filtering>
333-
<directory>src/main/resources/lang-original</directory>
333+
<directory>src/main/resources/bundled</directory>
334334
</resource>
335335
</resources>
336336
</build>

src/main/java/org/maxgamer/quickshop/util/MsgUtil.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ public static void loadI18nFile() throws InvalidConfigurationException {
227227
// String buildInMessageFilePath = "lang/" + languageCode + "/messages.json";
228228
// if (plugin.getResource(buildInMessageFilePath) == null) {
229229
// //Use default
230-
// buildInMessageFilePath = "lang-original/messages.json";
230+
// buildInMessageFilePath = "bundled/messages.json";
231231
// }
232232
// if (!extractedMessageFile.exists()) {
233233
// try {
@@ -280,7 +280,7 @@ public static void loadI18nFile() throws InvalidConfigurationException {
280280
// Util.debugLog("Cannot load default built-in language file: " + ioException.getMessage());
281281
// }
282282
// builtInLang = HumanReadableJsonConfiguration.loadConfiguration(buildInLangFile);
283-
// try (InputStreamReader inputStreamReader = new InputStreamReader(Objects.requireNonNull(plugin.getResource("lang-original/messages.json")))) {
283+
// try (InputStreamReader inputStreamReader = new InputStreamReader(Objects.requireNonNull(plugin.getResource("bundled/messages.json")))) {
284284
// builtInOriginalLang = HumanReadableJsonConfiguration.loadConfiguration(inputStreamReader);
285285
// } catch (IOException | NullPointerException exception) {
286286
// plugin.getLogger().log(Level.WARNING, "Cannot to load built-in original messages, some phrases may missing when upgrading", exception);

src/main/java/org/maxgamer/quickshop/util/language/text/TextManager.java

Lines changed: 75 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,19 @@
2525
import java.util.*;
2626
import java.util.logging.Level;
2727

28+
/**
29+
* QuickShop universal text manager
30+
* With multi-files and multi-languages support
31+
*/
2832
public class TextManager {
2933
private final QuickShop plugin;
3034
private final Distribution distribution;
3135
// <File <Locale, Section>>
3236
private final Map<String, Map<String, JsonConfiguration>> locale2ContentMapping = new HashMap<>();
3337
private final static String languageFileCrowdin = "/master/src/main/resources/lang/%locale%/messages.json";
3438
public List<PostProcessor> postProcessors = new ArrayList<>();
39+
// <File, Section>
40+
private final Map<String, JsonConfiguration> bundledMapping = new HashMap<>();
3541
private JsonConfiguration bundledLang = new JsonConfiguration();
3642

3743
public TextManager(QuickShop plugin) {
@@ -40,69 +46,78 @@ public TextManager(QuickShop plugin) {
4046
load();
4147
}
4248

49+
/**
50+
* Generate and returns the override files storage folder for specific file
51+
*
52+
* @param distributionPath The file name or path on distribution platform
53+
* @return The storage folder
54+
*/
4355
@NotNull
44-
private File getOverrideFilesFolder(@NotNull String crowdinPath) {
45-
File file = new File(crowdinPath);
46-
File folder = new File(new File(plugin.getDataFolder(), "overrides"), file.getName() + ".overrides");
56+
private File getOverrideFilesFolder(@NotNull String distributionPath) {
57+
File folder = new File(new File(plugin.getDataFolder(), "overrides"), getFileNameFromFullPath(distributionPath) + ".overrides");
4758
folder.mkdirs();
4859
return folder;
4960
}
5061

62+
private String getFileNameFromFullPath(@NotNull String path) {
63+
return new File(path).getName();
64+
}
65+
5166
public void load() {
5267
plugin.getLogger().info("Checking for translation updates...");
5368
locale2ContentMapping.clear();
5469
postProcessors.clear();
5570
// Load mapping
56-
//for (String availableFile : distribution.getAvailableFiles()) {
57-
try {
58-
bundledLang.loadFromString(new String(IOUtils.toByteArray(new InputStreamReader(plugin.getResource("lang-original/messages.json")), StandardCharsets.UTF_8)));
59-
} catch (IOException | InvalidConfigurationException ex) {
60-
bundledLang = new JsonConfiguration();
61-
plugin.getLogger().log(Level.SEVERE, "Cannot load bundled language file from Jar, some strings may missing!", ex);
62-
}
71+
72+
6373
// init file mapping
6474
locale2ContentMapping.computeIfAbsent(languageFileCrowdin, e -> new HashMap<>());
6575
// Multi File and Multi-Language loader
6676

67-
68-
distribution.getAvailableLanguages().parallelStream().forEach(crowdinCode -> distribution.getAvailableFiles().parallelStream().forEach(crowdinFile -> {
77+
distribution.getAvailableFiles().parallelStream().forEach(crowdinFile -> {
78+
JsonConfiguration bundledLang = new JsonConfiguration();
6979
try {
70-
// load OTA text from Crowdin
71-
72-
String minecraftCode = crowdinCode.toLowerCase(Locale.ROOT).replace("-", "_");
73-
74-
Util.debugLog("Loading translation for locale: " + crowdinCode + " (" + minecraftCode + ")");
75-
JsonConfiguration configuration = new JsonConfiguration();
80+
bundledLang.loadFromString(new String(IOUtils.toByteArray(new InputStreamReader(plugin.getResource("bundled/" + getFileNameFromFullPath(crowdinFile))), StandardCharsets.UTF_8)));
81+
} catch (IOException | InvalidConfigurationException ex) {
82+
bundledLang = new JsonConfiguration();
83+
plugin.getLogger().log(Level.SEVERE, "Cannot load bundled file " + crowdinFile + " from Jar, some strings may missing!", ex);
84+
}
85+
bundledMapping.put(crowdinFile, bundledLang);
86+
distribution.getAvailableLanguages().parallelStream().forEach(crowdinCode -> {
7687
try {
77-
configuration.loadFromString(distribution.getFile(crowdinFile, crowdinCode));
78-
} catch (InvalidConfigurationException exception) {
79-
configuration.loadFromString(distribution.getFile(crowdinFile, crowdinCode, true));
80-
}
81-
// load override text (allow user modification the translation)
82-
JsonConfiguration override = new JsonConfiguration();
83-
File localOverrideFile = new File(getOverrideFilesFolder(crowdinFile), minecraftCode + ".json");
84-
if (!localOverrideFile.exists()) {
85-
localOverrideFile.getParentFile().mkdirs();
86-
localOverrideFile.createNewFile();
88+
// load OTA text from Crowdin
89+
String minecraftCode = crowdinCode.toLowerCase(Locale.ROOT).replace("-", "_");
90+
Util.debugLog("Loading translation for locale: " + crowdinCode + " (" + minecraftCode + ")");
91+
JsonConfiguration configuration = new JsonConfiguration();
92+
try {
93+
configuration.loadFromString(distribution.getFile(crowdinFile, crowdinCode));
94+
} catch (InvalidConfigurationException exception) {
95+
configuration.loadFromString(distribution.getFile(crowdinFile, crowdinCode, true));
96+
}
97+
// load override text (allow user modification the translation)
98+
JsonConfiguration override = new JsonConfiguration();
99+
File localOverrideFile = new File(getOverrideFilesFolder(crowdinFile), minecraftCode + ".json");
100+
if (!localOverrideFile.exists()) {
101+
localOverrideFile.getParentFile().mkdirs();
102+
localOverrideFile.createNewFile();
103+
}
104+
override.loadFromString(Util.readToString(localOverrideFile));
105+
for (String key : override.getKeys(true)) {
106+
if (key.equals("language-version") || key.equals("config-version") || key.equals("version"))
107+
continue;
108+
configuration.set(key, override.get(key));
109+
}
110+
locale2ContentMapping.get(languageFileCrowdin).computeIfAbsent(minecraftCode, e -> configuration);
111+
} catch (CrowdinOTA.OTAException e) {
112+
plugin.getLogger().warning("Couldn't update the translation for locale " + crowdinCode + " because it not configured, please report to QuickShop");
113+
} catch (IOException e) {
114+
plugin.getLogger().log(Level.WARNING, "Couldn't update the translation for locale " + crowdinCode + " please check your network connection.", e);
115+
} catch (Exception e) {
116+
plugin.getLogger().log(Level.WARNING, "Couldn't update the translation for locale " + crowdinCode + ".", e);
87117
}
88-
override.loadFromString(Util.readToString(localOverrideFile));
89-
for (String key : override.getKeys(true)) {
90-
if (key.equals("language-version") || key.equals("config-version") || key.equals("version"))
91-
continue;
92-
configuration.set(key, override.get(key));
93-
}
94-
locale2ContentMapping.get(languageFileCrowdin).computeIfAbsent(minecraftCode, e -> configuration);
95-
Util.debugLog("Locale " + crowdinFile);
96-
if (configuration.getInt("language-version") < bundledLang.getInt("language-version"))
97-
Util.debugLog("Locale " + crowdinCode + " file version is outdated, some string will fallback to English.");
98-
} catch (CrowdinOTA.OTAException e) {
99-
plugin.getLogger().warning("Couldn't update the translation for locale " + crowdinCode + " because it not configured, please report to QuickShop");
100-
} catch (IOException e) {
101-
plugin.getLogger().log(Level.WARNING, "Couldn't update the translation for locale " + crowdinCode + " please check your network connection.", e);
102-
} catch (Exception e) {
103-
plugin.getLogger().log(Level.WARNING, "Couldn't update the translation for locale " + crowdinCode + ".", e);
104-
}
105-
}));
118+
});
119+
});
120+
106121

107122

108123
// for (String availableLanguage : distribution.getAvailableLanguages()) {
@@ -114,27 +129,27 @@ public void load() {
114129
}
115130

116131
public Text of(@NotNull String path, String... args) {
117-
return new Text(this, (CommandSender) null, locale2ContentMapping.get(languageFileCrowdin), path, args);
132+
return new Text(this, (CommandSender) null, languageFileCrowdin, path, args);
118133
}
119134

120135
public Text of(@Nullable CommandSender sender, @NotNull String path, String... args) {
121-
return new Text(this, sender, locale2ContentMapping.get(languageFileCrowdin), path, args);
136+
return new Text(this, sender, languageFileCrowdin, path, args);
122137
}
123138

124139
public Text of(@Nullable UUID sender, @NotNull String path, String... args) {
125-
return new Text(this, sender, locale2ContentMapping.get(languageFileCrowdin), path, args);
140+
return new Text(this, sender, languageFileCrowdin, path, args);
126141
}
127142

128143
public TextList ofList(@NotNull String path, String... args) {
129-
return new TextList(this, (CommandSender) null, locale2ContentMapping.get(languageFileCrowdin), path, args);
144+
return new TextList(this, (CommandSender) null, languageFileCrowdin, path, args);
130145
}
131146

132147
public TextList ofList(@Nullable UUID sender, @NotNull String path, String... args) {
133-
return new TextList(this, sender, locale2ContentMapping.get(languageFileCrowdin), path, args);
148+
return new TextList(this, sender, languageFileCrowdin, path, args);
134149
}
135150

136151
public TextList ofList(@Nullable CommandSender sender, @NotNull String path, String... args) {
137-
return new TextList(this, sender, locale2ContentMapping.get(languageFileCrowdin), path, args);
152+
return new TextList(this, sender, languageFileCrowdin, path, args);
138153
}
139154

140155
public static class TextList {
@@ -145,23 +160,23 @@ public static class TextList {
145160
private final CommandSender sender;
146161
private final String[] args;
147162

148-
private TextList(TextManager manager, CommandSender sender, Map<String, JsonConfiguration> mapping, String path, String... args) {
163+
private TextList(TextManager manager, CommandSender sender, String file, String path, String... args) {
149164
this.plugin = manager.plugin;
150165
this.manager = manager;
151166
this.sender = sender;
152-
this.mapping = mapping;
167+
this.mapping = manager.locale2ContentMapping.get(file);
153168
this.path = path;
154169
this.args = args;
155170
}
156171

157-
private TextList(TextManager manager, UUID sender, Map<String, JsonConfiguration> mapping, String path, String... args) {
172+
private TextList(TextManager manager, UUID sender, String file, String path, String... args) {
158173
this.plugin = manager.plugin;
159174
this.manager = manager;
160175
if (sender != null)
161176
this.sender = Bukkit.getPlayer(sender);
162177
else
163178
this.sender = null;
164-
this.mapping = mapping;
179+
this.mapping = manager.locale2ContentMapping.get(file);
165180
this.path = path;
166181
this.args = args;
167182
}
@@ -229,23 +244,23 @@ public static class Text {
229244
private final CommandSender sender;
230245
private final String[] args;
231246

232-
private Text(TextManager manager, CommandSender sender, Map<String, JsonConfiguration> mapping, String path, String... args) {
247+
private Text(TextManager manager, CommandSender sender, String file, String path, String... args) {
233248
this.plugin = manager.plugin;
234249
this.manager = manager;
235250
this.sender = sender;
236-
this.mapping = mapping;
251+
this.mapping = manager.locale2ContentMapping.get(file);
237252
this.path = path;
238253
this.args = args;
239254
}
240255

241-
private Text(TextManager manager, UUID sender, Map<String, JsonConfiguration> mapping, String path, String... args) {
256+
private Text(TextManager manager, UUID sender, String file, String path, String... args) {
242257
this.plugin = manager.plugin;
243258
this.manager = manager;
244259
if (sender != null)
245260
this.sender = Bukkit.getPlayer(sender);
246261
else
247262
this.sender = null;
248-
this.mapping = mapping;
263+
this.mapping = manager.locale2ContentMapping.get(file);
249264
this.path = path;
250265
this.args = args;
251266
}
File renamed without changes.

0 commit comments

Comments
 (0)