From db5e4ffa2e0fad6e7c4a0ba6dfac86971b4fd4a2 Mon Sep 17 00:00:00 2001 From: TheBusyBiscuit Date: Wed, 8 Dec 2021 20:25:04 +0100 Subject: [PATCH] Refactoring and documentation --- .../utils/biomes/BiomeDataConverter.java | 46 +++++++ .../slimefun4/utils/biomes/BiomeMap.java | 39 +++++- .../utils/biomes/BiomeMapParser.java | 15 ++- .../slimefun4/utils/biomes/TestBiomeMap.java | 115 ++++++++++++++++++ .../utils/biomes/TestBiomeMapParser.java | 69 +---------- 5 files changed, 211 insertions(+), 73 deletions(-) create mode 100644 src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeDataConverter.java create mode 100644 src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMap.java diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeDataConverter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeDataConverter.java new file mode 100644 index 000000000..2a6a42eb9 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeDataConverter.java @@ -0,0 +1,46 @@ +package io.github.thebusybiscuit.slimefun4.utils.biomes; + +import javax.annotation.Nonnull; + +import com.google.gson.JsonElement; + +/** + * A simple functional interface for converting a {@link JsonElement} into the desired data type + * needed for your {@link BiomeMap}. + * + * @author TheBusyBiscuit + * + * @param + * Your target data type + * + * @see BiomeMap + */ +@FunctionalInterface +public interface BiomeDataConverter { + + /** + * Override this method and provide a way to convert a {@link JsonElement} into your + * desired data type. + *

+ * For primitive data values, you you can also just use the following method references: + * + *

    + *
  • JsonElement::getAsString
  • + *
  • JsonElement::getAsInt
  • + *
  • JsonElement::getAsDouble
  • + *
  • JsonElement::getAsFloat
  • + *
  • JsonElement::getAsLong
  • + *
  • JsonElement::getAsBoolean
  • + *
+ * + * or similar. + * + * @param jsonElement + * The {@link JsonElement} to convert + * + * @return Your desired data type. + */ + @Nonnull + T convert(@Nonnull JsonElement jsonElement); + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMap.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMap.java index 4c7413ea9..12c65b40a 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMap.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMap.java @@ -6,7 +6,6 @@ import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.EnumMap; import java.util.Map; -import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Nonnull; @@ -21,13 +20,44 @@ import org.bukkit.block.Biome; import com.google.gson.JsonElement; import io.github.thebusybiscuit.slimefun4.api.exceptions.BiomeMapException; +import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; +/** + * {@link BiomeMap}s are used to map data values to {@link Biome} constants. + *

+ * We heavily utilise this method of data mapping for {@link GEOResource}s, especially + * when supporting multiple versions of Minecraft. This way, we can have different {@link BiomeMap}s + * for different versions of Minecraft, incase {@link Biome} names change inbetween versions. + *

+ * The data type can be any type of {@link Object}. + * The most common type is {@link Integer}, if you are using complex objects and try to read + * your {@link BiomeMap} from a {@link JsonElement}, make sure to provide an adequate + * {@link BiomeDataConverter} to convert the raw json data. + * + * @author TheBusyBiscuit + * + * @param + * The stored data type + */ public class BiomeMap implements Keyed { + /** + * Our internal {@link EnumMap} holding all the data. + */ private final Map dataMap = new EnumMap<>(Biome.class); + + /** + * The {@link NamespacedKey} to identify this {@link BiomeMap}. + */ private final NamespacedKey namespacedKey; + /** + * This constructs a new {@link BiomeMap} with the given {@link NamespacedKey}. + * + * @param namespacedKey + * The {@link NamespacedKey} for this {@link BiomeMap} + */ @ParametersAreNonnullByDefault public BiomeMap(NamespacedKey namespacedKey) { Validate.notNull(namespacedKey, "The key must not be null."); @@ -86,13 +116,16 @@ public class BiomeMap implements Keyed { return namespacedKey; } + /** + * {@inheritDoc} + */ @Override public String toString() { return "BiomeMap " + dataMap.toString(); } @ParametersAreNonnullByDefault - public static @Nonnull BiomeMap fromJson(NamespacedKey key, String json, Function valueConverter) throws BiomeMapException { + public static @Nonnull BiomeMap fromJson(NamespacedKey key, String json, BiomeDataConverter valueConverter) throws BiomeMapException { // All parameters are validated by the Parser. BiomeMapParser parser = new BiomeMapParser<>(key, valueConverter); parser.read(json); @@ -100,7 +133,7 @@ public class BiomeMap implements Keyed { } @ParametersAreNonnullByDefault - public static @Nonnull BiomeMap fromResource(NamespacedKey key, String path, Function valueConverter) throws BiomeMapException { + public static @Nonnull BiomeMap fromResource(NamespacedKey key, String path, BiomeDataConverter valueConverter) throws BiomeMapException { Validate.notNull(key, "The key shall not be null."); Validate.notNull(path, "The path should not be null!"); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMapParser.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMapParser.java index 93a2ab87e..0838d2bcb 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMapParser.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMapParser.java @@ -5,7 +5,6 @@ import java.util.EnumSet; import java.util.Locale; import java.util.Map; import java.util.Set; -import java.util.function.Function; import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; @@ -24,17 +23,25 @@ import io.github.bakedlibs.dough.common.CommonPatterns; import io.github.thebusybiscuit.slimefun4.api.exceptions.BiomeMapException; import io.github.thebusybiscuit.slimefun4.utils.PatternUtils; +/** + * The {@link BiomeMapParser} allows you to parse json data into a {@link BiomeMap}. + * + * @author TheBusyBiscuit + * + * @param + * The data type of the resulting {@link BiomeMap} + */ class BiomeMapParser { private static final String VALUE_KEY = "value"; private static final String BIOMES_KEY = "biomes"; private final NamespacedKey key; - private final Function valueConverter; + private final BiomeDataConverter valueConverter; private final Map map = new EnumMap<>(Biome.class); @ParametersAreNonnullByDefault - BiomeMapParser(NamespacedKey key, Function valueConverter) { + BiomeMapParser(NamespacedKey key, BiomeDataConverter valueConverter) { Validate.notNull(key, "The key shall not be null."); Validate.notNull(valueConverter, "You must provide a Function to convert raw json values to your desired data type."); @@ -76,7 +83,7 @@ class BiomeMapParser { Validate.notNull(entry, "The JSON entry should not be null!"); if (entry.has(VALUE_KEY)) { - T value = valueConverter.apply(entry.get(VALUE_KEY)); + T value = valueConverter.convert(entry.get(VALUE_KEY)); if (entry.has(BIOMES_KEY) && entry.get(BIOMES_KEY).isJsonArray()) { Set biomes = readBiomes(entry.get(BIOMES_KEY).getAsJsonArray()); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMap.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMap.java new file mode 100644 index 000000000..3cde1bfdc --- /dev/null +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMap.java @@ -0,0 +1,115 @@ +package io.github.thebusybiscuit.slimefun4.utils.biomes; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +import org.bukkit.NamespacedKey; +import org.bukkit.block.Biome; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import com.google.gson.JsonElement; + +import io.github.thebusybiscuit.slimefun4.api.exceptions.BiomeMapException; +import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; + +import be.seeseemelk.mockbukkit.MockBukkit; + +class TestBiomeMap { + + private static final BiomeDataConverter AS_STRING = JsonElement::getAsString; + private static final BiomeDataConverter AS_INT = JsonElement::getAsInt; + + private static Slimefun plugin; + private static NamespacedKey key; + + @BeforeAll + public static void load() { + MockBukkit.mock(); + plugin = MockBukkit.load(Slimefun.class); + key = new NamespacedKey(plugin, "test"); + } + + @AfterAll + public static void unload() { + MockBukkit.unmock(); + } + + @Test + @DisplayName("Test BiomeMap#getKey") + void testKeyed() { + BiomeMap biomes = new BiomeMap<>(key); + Assertions.assertEquals(key, biomes.getKey()); + } + + @Test + @DisplayName("Test BiomeMap#toString") + void testToString() { + BiomeMap biomes = new BiomeMap<>(key); + Assertions.assertTrue(biomes.toString().startsWith("BiomeMap")); + } + + @Test + @DisplayName("Test different value converters") + void testValueConversion() { + Biome biome = Biome.OCEAN; + + String stringValue = "hello world"; + BiomeMap stringMap = createBiomeMap(AS_STRING, "[{\"value\": \"" + stringValue + "\", \"biomes\": [\"" + biome.getKey() + "\"]}]"); + Assertions.assertEquals(stringValue, stringMap.get(biome)); + + int intValue = 1024; + BiomeMap intMap = createBiomeMap(AS_INT, "[{\"value\": \"" + intValue + "\", \"biomes\": [\"" + biome.getKey() + "\"]}]"); + Assertions.assertEquals(intValue, intMap.get(biome)); + } + + @Test + @DisplayName("Test working BiomeMap from JSON") + void testBiomeMapFromJson() { + Biome biome1 = Biome.JUNGLE; + Biome biome2 = Biome.OCEAN; + Biome biome3 = Biome.DESERT; + BiomeMap biomes = createBiomeMap(AS_INT, "[{\"value\":1,\"biomes\":[\"" + biome1.getKey() + "\", \"" + biome2.getKey() + "\"]}, {\"value\":2, \"biomes\":[\"" + biome3.getKey() + "\"]}]"); + + Assertions.assertTrue(biomes.contains(biome1)); + Assertions.assertEquals(1, biomes.get(biome1)); + + Assertions.assertTrue(biomes.contains(biome2)); + Assertions.assertEquals(1, biomes.get(biome2)); + + Assertions.assertTrue(biomes.contains(biome3)); + Assertions.assertEquals(2, biomes.get(biome3)); + } + + @Test + @DisplayName("Test working BiomeMap manually") + void testManualBiomeMap() { + BiomeMap biomes = new BiomeMap<>(key); + Biome biome = Biome.OCEAN; + String value = "Under the sea"; + + Assertions.assertTrue(biomes.put(biome, value)); + Assertions.assertTrue(biomes.contains(biome)); + Assertions.assertEquals(value, biomes.get(biome)); + + Assertions.assertTrue(biomes.remove(biome)); + Assertions.assertFalse(biomes.contains(biome)); + } + + @ParametersAreNonnullByDefault + private @Nonnull BiomeMap createBiomeMap(BiomeDataConverter function, String json) { + BiomeMapParser parser = new BiomeMapParser<>(key, function); + + try { + parser.read(json); + } catch (BiomeMapException e) { + Assertions.fail(e); + } + + return parser.buildBiomeMap(); + } + +} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapParser.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapParser.java index 71d9dd235..70a8040ab 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapParser.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/biomes/TestBiomeMapParser.java @@ -1,8 +1,5 @@ package io.github.thebusybiscuit.slimefun4.utils.biomes; -import java.util.function.Function; - -import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; import org.bukkit.NamespacedKey; @@ -22,8 +19,8 @@ import be.seeseemelk.mockbukkit.MockBukkit; class TestBiomeMapParser { - private static final Function AS_STRING = JsonElement::getAsString; - private static final Function AS_INT = JsonElement::getAsInt; + private static final BiomeDataConverter AS_STRING = JsonElement::getAsString; + private static final BiomeDataConverter AS_INT = JsonElement::getAsInt; private static Slimefun plugin; private static NamespacedKey key; @@ -96,68 +93,8 @@ class TestBiomeMapParser { assertMisconfiguration(AS_INT, "[{\"value\": 1, \"biomes\": [\"" + biome.getKey() + "\"]}, {\"value\": 2, \"biomes\": [\"" + biome.getKey() + "\"]}]"); } - @Test - @DisplayName("Test different value converters") - void testValueConversion() { - Biome biome = Biome.OCEAN; - - String stringValue = "hello world"; - BiomeMap stringMap = createBiomeMap(AS_STRING, "[{\"value\": \"" + stringValue + "\", \"biomes\": [\"" + biome.getKey() + "\"]}]"); - Assertions.assertEquals(stringValue, stringMap.get(biome)); - - int intValue = 1024; - BiomeMap intMap = createBiomeMap(AS_INT, "[{\"value\": \"" + intValue + "\", \"biomes\": [\"" + biome.getKey() + "\"]}]"); - Assertions.assertEquals(intValue, intMap.get(biome)); - } - - @Test - @DisplayName("Test working BiomeMap from JSON") - void testBiomeMapFromJson() { - Biome biome1 = Biome.JUNGLE; - Biome biome2 = Biome.OCEAN; - Biome biome3 = Biome.DESERT; - BiomeMap biomes = createBiomeMap(AS_INT, "[{\"value\":1,\"biomes\":[\"" + biome1.getKey() + "\", \"" + biome2.getKey() + "\"]}, {\"value\":2, \"biomes\":[\"" + biome3.getKey() + "\"]}]"); - - Assertions.assertTrue(biomes.contains(biome1)); - Assertions.assertEquals(1, biomes.get(biome1)); - - Assertions.assertTrue(biomes.contains(biome2)); - Assertions.assertEquals(1, biomes.get(biome2)); - - Assertions.assertTrue(biomes.contains(biome3)); - Assertions.assertEquals(2, biomes.get(biome3)); - } - - @Test - @DisplayName("Test working BiomeMap manually") - void testManualBiomeMap() { - BiomeMap biomes = new BiomeMap<>(key); - Biome biome = Biome.OCEAN; - String value = "Under the sea"; - - Assertions.assertTrue(biomes.put(biome, value)); - Assertions.assertTrue(biomes.contains(biome)); - Assertions.assertEquals(value, biomes.get(biome)); - - Assertions.assertTrue(biomes.remove(biome)); - Assertions.assertFalse(biomes.contains(biome)); - } - @ParametersAreNonnullByDefault - private @Nonnull BiomeMap createBiomeMap(Function function, String json) { - BiomeMapParser parser = new BiomeMapParser<>(key, function); - - try { - parser.read(json); - } catch (BiomeMapException e) { - Assertions.fail(e); - } - - return parser.buildBiomeMap(); - } - - @ParametersAreNonnullByDefault - private void assertMisconfiguration(Function function, String json) { + private void assertMisconfiguration(BiomeDataConverter function, String json) { BiomeMapParser parser = new BiomeMapParser<>(key, function); Assertions.assertThrows(BiomeMapException.class, () -> parser.read(json)); }