From 7854a8a6151eaa963dcdc98c0f75af1ee4cb4f59 Mon Sep 17 00:00:00 2001 From: tchristofferson Date: Mon, 30 Dec 2024 21:01:11 -0600 Subject: [PATCH 1/2] Fix internal utf8 issue. Spigot 1.8 wasn't writing as utf8. Updated Mockito dependency --- pom.xml | 4 +- .../configupdater/ConfigUpdater.java | 38 ++++++++++++------- .../configupdater/ConfigUpdaterTest.java | 15 ++++---- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/pom.xml b/pom.xml index 00ad9a6..fca68c7 100644 --- a/pom.xml +++ b/pom.xml @@ -79,8 +79,8 @@ org.mockito - mockito-all - 1.10.19 + mockito-core + 5.14.2 test diff --git a/src/main/java/com/tchristofferson/configupdater/ConfigUpdater.java b/src/main/java/com/tchristofferson/configupdater/ConfigUpdater.java index 734c1f8..75f094c 100644 --- a/src/main/java/com/tchristofferson/configupdater/ConfigUpdater.java +++ b/src/main/java/com/tchristofferson/configupdater/ConfigUpdater.java @@ -9,8 +9,10 @@ import org.bukkit.plugin.Plugin; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.representer.Representer; import java.io.*; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; @@ -20,6 +22,7 @@ public class ConfigUpdater { //Used for separating keys in the keyBuilder inside parseComments method private static final char SEPARATOR = '.'; + private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; /** * Update the YAML file inside the plugin folder, only if it does not match the file from the JAR. @@ -50,8 +53,8 @@ public static void update(Plugin plugin, String resourceName, File toUpdate, Str public static void update(Plugin plugin, String resourceName, File toUpdate, List ignoredSections) throws IOException { Preconditions.checkArgument(toUpdate.exists(), "The toUpdate file doesn't exist!"); - FileConfiguration defaultConfig = YamlConfiguration.loadConfiguration(new InputStreamReader(plugin.getResource(resourceName), StandardCharsets.UTF_8)); - FileConfiguration currentConfig = YamlConfiguration.loadConfiguration(Files.newBufferedReader(toUpdate.toPath(), StandardCharsets.UTF_8)); + FileConfiguration defaultConfig = YamlConfiguration.loadConfiguration(new InputStreamReader(plugin.getResource(resourceName), DEFAULT_CHARSET)); + FileConfiguration currentConfig = YamlConfiguration.loadConfiguration(Files.newBufferedReader(toUpdate.toPath(), DEFAULT_CHARSET)); Map comments = parseComments(plugin, resourceName, defaultConfig); Map ignoredSectionsValues = parseIgnoredSections(toUpdate, comments, ignoredSections == null ? Collections.emptyList() : ignoredSections); // will write updated config file "contents" to a string @@ -60,8 +63,8 @@ public static void update(Plugin plugin, String resourceName, File toUpdate, Lis String value = writer.toString(); // config contents Path toUpdatePath = toUpdate.toPath(); - if (!value.equals(new String(Files.readAllBytes(toUpdatePath), StandardCharsets.UTF_8))) { // if updated contents are not the same as current file contents, update - Files.write(toUpdatePath, value.getBytes(StandardCharsets.UTF_8)); + if (!value.equals(new String(Files.readAllBytes(toUpdatePath), DEFAULT_CHARSET))) { // if updated contents are not the same as current file contents, update + Files.write(toUpdatePath, value.getBytes(DEFAULT_CHARSET)); } } @@ -76,8 +79,8 @@ public static void update(Plugin plugin, String resourceName, File toUpdate, Lis * @throws IOException if an I/O error occurs while writing the data to the BufferedWriter. */ private static void write(FileConfiguration defaultConfig, FileConfiguration currentConfig, BufferedWriter writer, Map comments, Map ignoredSectionsValues) throws IOException { - //Used for converting objects to yaml, then cleared - FileConfiguration parserConfig = new YamlConfiguration(); + //Used for converting objects to yaml + Yaml yaml = getYamlWriter(); for (String fullKey : defaultConfig.getKeys(true)) { String indents = KeyUtils.getIndents(fullKey, SEPARATOR); @@ -100,7 +103,7 @@ private static void write(FileConfiguration defaultConfig, FileConfiguration cur writeConfigurationSection(writer, indents, trailingKey, (ConfigurationSection) currentValue); continue; } - writeYamlValue(parserConfig, writer, indents, trailingKey, currentValue); + writeYamlValue(yaml, writer, indents, trailingKey, currentValue); } String danglingComments = comments.get(null); @@ -123,7 +126,7 @@ private static void write(FileConfiguration defaultConfig, FileConfiguration cur private static Map parseComments(Plugin plugin, String resourceName, FileConfiguration defaultConfig) throws IOException { //keys are in order List keys = new ArrayList<>(defaultConfig.getKeys(true)); - BufferedReader reader = new BufferedReader(new InputStreamReader(plugin.getResource(resourceName), StandardCharsets.UTF_8)); + BufferedReader reader = new BufferedReader(new InputStreamReader(plugin.getResource(resourceName), DEFAULT_CHARSET)); Map comments = new LinkedHashMap<>(); StringBuilder commentBuilder = new StringBuilder(); KeyBuilder keyBuilder = new KeyBuilder(defaultConfig, SEPARATOR); @@ -196,7 +199,7 @@ private static Map parseIgnoredSections(File toUpdate, Map root = (Map) yaml.load(new FileReader(toUpdate)); + Map root = (Map) yaml.load(new InputStreamReader(new FileInputStream(toUpdate), DEFAULT_CHARSET)); ignoredSections.forEach(section -> { String[] split = section.split("[" + SEPARATOR + "]"); String key = split[split.length - 1]; @@ -410,19 +413,18 @@ private static Object getKeyAsObject(String key, Map sectionCont /** * Writes the current value with the provided trailing key to the provided writer. * - * @param parserConfig The parser configuration to use for writing the YAML value. + * @param yamlWriter The {@link Yaml} object used for converting to yaml * @param bufferedWriter The writer to write the value to. * @param indents The string representation of the indentation. * @param trailingKey The trailing key for the YAML value. * @param currentValue The current value to write as YAML. * @throws IOException If an I/O error occurs while writing the YAML value. */ - private static void writeYamlValue(final FileConfiguration parserConfig, final BufferedWriter bufferedWriter, final String indents, final String trailingKey, final Object currentValue) throws IOException { - parserConfig.set(trailingKey, currentValue); - String yaml = parserConfig.saveToString(); + private static void writeYamlValue(final Yaml yamlWriter, final BufferedWriter bufferedWriter, final String indents, final String trailingKey, final Object currentValue) throws IOException { + Map map = Collections.singletonMap(trailingKey, currentValue); + String yaml = yamlWriter.dump(map); yaml = yaml.substring(0, yaml.length() - 1).replace("\n", "\n" + indents); final String toWrite = indents + yaml + "\n"; - parserConfig.set(trailingKey, null); bufferedWriter.write(toWrite); } @@ -466,4 +468,12 @@ private static void writeConfigurationSection(final BufferedWriter bufferedWrite bufferedWriter.write(" {}\n"); } } + + private static Yaml getYamlWriter() { + DumperOptions dumperOptions = new DumperOptions(); + dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + dumperOptions.setAllowUnicode(true); + + return new Yaml(dumperOptions); + } } diff --git a/src/test/java/com/tchristofferson/configupdater/ConfigUpdaterTest.java b/src/test/java/com/tchristofferson/configupdater/ConfigUpdaterTest.java index 6512453..9c2ebda 100644 --- a/src/test/java/com/tchristofferson/configupdater/ConfigUpdaterTest.java +++ b/src/test/java/com/tchristofferson/configupdater/ConfigUpdaterTest.java @@ -11,9 +11,7 @@ import org.junit.Test; import org.mockito.stubbing.Answer; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.StandardCharsets; @@ -24,10 +22,11 @@ import java.util.List; import static org.junit.Assert.*; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +//JUnit tests should be run with -Dfile.encoding=GBK to make sure UTF8 is used everywhere public class ConfigUpdaterTest { private static final String FILE_NAME = "config.yml"; @@ -69,7 +68,7 @@ public void testUpdateMethodToCheckIfFilesAreSameAfter() throws IOException, URI public void testUpdateMethodToMakeSureIgnoredSectionsAreHandledCorrectly() throws IOException, InvalidConfigurationException { File toUpdate = new File(FILE_NAME); - FileConfiguration config = YamlConfiguration.loadConfiguration(toUpdate); + FileConfiguration config = YamlConfiguration.loadConfiguration(new BufferedReader(new InputStreamReader(Files.newInputStream(toUpdate.toPath()), StandardCharsets.UTF_8))); config.set("a-section-with-ignored-sections.sub-ignored.ignored.value3", 3); config.set("a-section-with-ignored-sections.sub-ignored.ignored2.value", 1); @@ -141,8 +140,10 @@ public void testIgnoredSectionKeysAreStillValidAfterUpdate() throws IOException } private void saveDefaultConfig(File toUpdate) throws IOException, URISyntaxException { - FileConfiguration configuration = YamlConfiguration.loadConfiguration(Files.newBufferedReader(getResourcePath(), StandardCharsets.UTF_8)); - configuration.save(toUpdate); + byte[] bytes = Files.readAllBytes(getResourcePath()); + BufferedWriter writer = Files.newBufferedWriter(toUpdate.toPath(), StandardCharsets.UTF_8); + writer.write(new String(bytes, StandardCharsets.UTF_8)); + writer.close(); } private Path getResourcePath() throws URISyntaxException { From 6c5e298d4a3ba56939822a6ee86f4ad94dff393b Mon Sep 17 00:00:00 2001 From: tchristofferson Date: Mon, 30 Dec 2024 21:05:31 -0600 Subject: [PATCH 2/2] Update maven.yml Use JDK 21 --- .github/workflows/maven.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index a41b7dd..9f65157 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -20,10 +20,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up JDK 8 + - name: Set up JDK 21 uses: actions/setup-java@v3 with: - java-version: '8' + java-version: '21' distribution: 'temurin' cache: maven