fix yaml lang support, add multiline scalars and a list method

This commit is contained in:
jascotty2 2019-10-27 15:53:56 -05:00
parent d323358604
commit 44ad32bff0
2 changed files with 92 additions and 41 deletions

View File

@ -184,64 +184,70 @@ public class Locale {
// Write new changes to existing files, if any at all
private static boolean updateFiles(Plugin plugin, InputStream defaultFile, File existingFile, boolean builtin) {
boolean changed = false;
List<String> defaultLines, existingLines;
try (BufferedInputStream defaultIn = new BufferedInputStream(defaultFile);
BufferedInputStream existingIn = new BufferedInputStream(new FileInputStream(existingFile))) {
Charset defaultCharset = TextUtils.detectCharset(defaultIn, StandardCharsets.UTF_8);
Charset existingCharset = TextUtils.detectCharset(existingIn, StandardCharsets.UTF_8);
try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(existingFile, true), existingCharset);
BufferedReader defaultReaderOriginal = new BufferedReader(new InputStreamReader(defaultIn, defaultCharset));
try (BufferedReader defaultReaderOriginal = new BufferedReader(new InputStreamReader(defaultIn, defaultCharset));
BufferedReader existingReaderOriginal = new BufferedReader(new InputStreamReader(existingIn, existingCharset));
BufferedReader defaultReader = translatePropertyToYAML(defaultReaderOriginal, defaultCharset);
BufferedReader existingReader = translatePropertyToYAML(existingReaderOriginal, existingCharset);) {
defaultLines = defaultReader.lines().map(s -> s.replaceAll("[\uFEFF\uFFFE\u200B]", "")).collect(Collectors.toList());
existingLines = existingReader.lines().map(s -> s.replaceAll("[\uFEFF\uFFFE\u200B]", "").split("\\s*=")[0]).collect(Collectors.toList());
for (String defaultValue : defaultLines) {
Config existingLang = new Config(existingFile);
existingLang.load(existingReader);
translateMsgRoot(existingLang, existingFile, existingCharset);
if (defaultValue.isEmpty() || defaultValue.startsWith("#")) {
Config defaultLang = new Config();
String defaultData = defaultReader.lines().map(s -> s.replaceAll("[\uFEFF\uFFFE\u200B]", "")).collect(Collectors.joining("\n"));
defaultLang.loadFromString(defaultData);
translateMsgRoot(defaultLang, defaultData, defaultCharset);
List<String> added = new ArrayList();
for (String defaultValueKey : defaultLang.getKeys(true)) {
Object val = defaultLang.get(defaultValueKey);
if (val instanceof ConfigSection) {
continue;
}
String key = defaultValue.split("\\s*:")[0];
if (!existingLang.contains(defaultValueKey)) {
added.add(defaultValueKey);
existingLang.set(defaultValueKey, val);
}
}
if (!existingLines.contains(key)) {
if (!changed) {
writer.write("\n\n");
// Leave a note alerting the user of the newly added messages.
writer.write("# New messages for " + plugin.getName() + " v" + plugin.getDescription().getVersion() + ".");
// If changes were found outside of the default file leave a note explaining that.
if (!added.isEmpty()) {
if (!builtin) {
writer.write("\n");
writer.write("# These translations were found untranslated, join\n");
writer.write("# our translation Discord https://discord.gg/f7fpZEf\n");
writer.write("# to request an official update!\n");
}
}
writer.write("\n");
// re-encode to target format? (transform down, not up)
// if (defaultCharset != existingCharset) {
// byte[] encoded = defaultValue.getBytes(defaultCharset);
// defaultValue = new String(encoded, 2, encoded.length - 2, existingCharset);
// }
writer.write(defaultValue);
changed = true;
existingLang.setHeader("New messages added for " + plugin.getName() + " v" + plugin.getDescription().getVersion() + ".",
"",
"These translations were found untranslated, join",
"our translation Discord https://discord.gg/f7fpZEf",
"to request an official update!",
"",
added.stream().collect(Collectors.joining("\n"))
);
} else {
existingLang.setHeader("New messages added for " + plugin.getName() + " v" + plugin.getDescription().getVersion() + ".",
"",
added.stream().collect(Collectors.joining("\n"))
);
}
existingLang.setRootNodeSpacing(0);
existingLang.save();
}
return !added.isEmpty();
} catch (InvalidConfigurationException ex) {
plugin.getLogger().log(Level.SEVERE, "Error checking config " + existingFile.getName(), ex);
}
} catch (IOException e) {
return false;
}
return changed;
return false;
}
/**
@ -271,8 +277,11 @@ public class Locale {
Config lang = new Config(file);
lang.load(reader);
translateMsgRoot(lang, file, charset);
// todo: how should string lists be handled?
lang.getValues(true).forEach((k, v) -> nodes.put(k, v.toString()));
// load lists as strings with newlines
lang.getValues(true).forEach((k, v) -> nodes.put(k,
v instanceof List
? (((List) v).stream().map(l -> l.toString()).collect(Collectors.joining("\n")).toString())
: v.toString()));
} catch (IOException e) {
e.printStackTrace();
return false;
@ -296,9 +305,15 @@ public class Locale {
}
}
Matcher matcher;
if ((line = line.trim().replace('\r', ' ')).isEmpty() || line.startsWith("#") /* Comment */
|| !(matcher = OLD_NODE_PATTERN.matcher(line)).find()) {
if ((line = line.replace('\r', ' ')).trim().isEmpty() || line.trim().startsWith("#") /* Comment */
// need to trim the search group because tab characters somehow ended up at the end of lines in a lot of these files
|| !(matcher = OLD_NODE_PATTERN.matcher(line.trim())).find()) {
if (line.startsWith("//")) {
// someone used an improper comment in some files *grumble grumble*
output.append("#").append(line).append("\n");
} else {
output.append(line).append("\n");
}
} else {
output.append(matcher.group(1)).append(": \"").append(matcher.group(2)).append("\"\n");
}
@ -333,6 +348,31 @@ public class Locale {
}
}
protected static void translateMsgRoot(Config lang, String file, Charset charset) throws IOException {
List<String> msgs = lang.getValues(true).entrySet().stream()
.filter(e -> e.getValue() instanceof ConfigSection)
.map(e -> e.getKey())
.collect(Collectors.toList());
if (!msgs.isEmpty()) {
String source[] = file.split("\n");
String line;
for (int lineNumber = 0; lineNumber < source.length; lineNumber++) {
line = source[lineNumber];
if (lineNumber == 0) {
// remove BOM markers, if any
line = line.replaceAll("[\uFEFF\uFFFE\u200B]", "");
}
Matcher matcher;
if (!(line = line.trim()).isEmpty() && !line.startsWith("#")
&& (matcher = OLD_NODE_PATTERN.matcher(line)).find()) {
if (msgs.contains(matcher.group(1))) {
lang.set(matcher.group(1) + ".message", matcher.group(2));
}
}
}
}
}
/**
* Supply the Message object with the plugins prefix.
*

View File

@ -1,6 +1,8 @@
package com.songoda.core.locale;
import com.songoda.core.compatibility.ServerVersion;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@ -126,6 +128,15 @@ public class Message {
return ChatColor.translateAlternateColorCodes('&', this.message);
}
/**
* Get and format the held message
*
* @return the message
*/
public List<String> getMessageLines() {
return Arrays.asList(ChatColor.translateAlternateColorCodes('&', this.message).split("\n|\\|"));
}
/**
* Get the held message
*