mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-19 19:25:48 +00:00
Added lenient parsing and more documentation
This commit is contained in:
parent
db5e4ffa2e
commit
5ba049d29c
@ -77,12 +77,28 @@ public class BiomeMap<T> implements Keyed {
|
||||
return dataMap.getOrDefault(biome, defaultValue);
|
||||
}
|
||||
|
||||
public boolean contains(@Nonnull Biome biome) {
|
||||
public boolean containsKey(@Nonnull Biome biome) {
|
||||
Validate.notNull(biome, "The biome must not be null.");
|
||||
|
||||
return dataMap.containsKey(biome);
|
||||
}
|
||||
|
||||
public boolean containsValue(@Nonnull T value) {
|
||||
Validate.notNull(value, "The value must not be null.");
|
||||
|
||||
return dataMap.containsValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns whether this {@link BiomeMap} is empty.
|
||||
* An empty {@link BiomeMap} contains no biomes or values.
|
||||
*
|
||||
* @return Whether this {@link BiomeMap} is empty.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return dataMap.isEmpty();
|
||||
}
|
||||
|
||||
public boolean put(@Nonnull Biome biome, @Nonnull T value) {
|
||||
Validate.notNull(biome, "The biome should not be null.");
|
||||
Validate.notNull(value, "Values cannot be null.");
|
||||
|
@ -30,6 +30,8 @@ import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
|
||||
*
|
||||
* @param <T>
|
||||
* The data type of the resulting {@link BiomeMap}
|
||||
*
|
||||
* @see BiomeMap
|
||||
*/
|
||||
class BiomeMapParser<T> {
|
||||
|
||||
@ -40,6 +42,24 @@ class BiomeMapParser<T> {
|
||||
private final BiomeDataConverter<T> valueConverter;
|
||||
private final Map<Biome, T> map = new EnumMap<>(Biome.class);
|
||||
|
||||
/**
|
||||
* This flag specifies whether the parsing is "lenient" or not.
|
||||
* A lenient parser will not throw a {@link BiomeMapException} if the {@link Biome}
|
||||
* could not be found.
|
||||
* The default value is false.
|
||||
*/
|
||||
private boolean isLenient = false;
|
||||
|
||||
/**
|
||||
* This constructs a new {@link BiomeMapParser}.
|
||||
* <p>
|
||||
* To parse data, use the {@link #read(JsonArray)} or {@link #read(String)} method.
|
||||
*
|
||||
* @param key
|
||||
* The {@link NamespacedKey} for the resulting {@link BiomeMap}
|
||||
* @param valueConverter
|
||||
* A function to convert {@link JsonElement}s into your desired data type
|
||||
*/
|
||||
@ParametersAreNonnullByDefault
|
||||
BiomeMapParser(NamespacedKey key, BiomeDataConverter<T> valueConverter) {
|
||||
Validate.notNull(key, "The key shall not be null.");
|
||||
@ -49,6 +69,33 @@ class BiomeMapParser<T> {
|
||||
this.valueConverter = valueConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the "lenient" flag for this parser.
|
||||
* <p>
|
||||
* A lenient parser will not throw a {@link BiomeMapException} if the {@link Biome}
|
||||
* could not be found.
|
||||
* The default value is false.
|
||||
*
|
||||
* @param isLenient
|
||||
* Whether this parser should be lenient or not.
|
||||
*/
|
||||
void setLenient(boolean isLenient) {
|
||||
this.isLenient = isLenient;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns whether this parser is flagged as "lenient".
|
||||
* <p>
|
||||
* A lenient parser will not throw a {@link BiomeMapException} if the {@link Biome}
|
||||
* could not be found.
|
||||
* The default value is false.
|
||||
*
|
||||
* @return Whether this parser is lenient or not.
|
||||
*/
|
||||
boolean isLenient() {
|
||||
return isLenient;
|
||||
}
|
||||
|
||||
void read(@Nonnull String json) throws BiomeMapException {
|
||||
Validate.notNull(json, "The JSON string should not be null!");
|
||||
JsonArray root = null;
|
||||
@ -82,15 +129,23 @@ class BiomeMapParser<T> {
|
||||
private void readEntry(@Nonnull JsonObject entry) throws BiomeMapException {
|
||||
Validate.notNull(entry, "The JSON entry should not be null!");
|
||||
|
||||
/*
|
||||
* Check if the entry has a "value" element.
|
||||
* The data type is irrelevant here, any JsonElement is supported (in theory).
|
||||
* If you write a converter for it, you can also serialize complex objects this way.
|
||||
*/
|
||||
if (entry.has(VALUE_KEY)) {
|
||||
T value = valueConverter.convert(entry.get(VALUE_KEY));
|
||||
|
||||
// Check if the entry has a "biomes" element of type JsonArray.
|
||||
if (entry.has(BIOMES_KEY) && entry.get(BIOMES_KEY).isJsonArray()) {
|
||||
Set<Biome> biomes = readBiomes(entry.get(BIOMES_KEY).getAsJsonArray());
|
||||
|
||||
// Loop through all biome strings in this array
|
||||
for (Biome biome : biomes) {
|
||||
T prev = map.put(biome, value);
|
||||
|
||||
// Check for duplicates
|
||||
if (prev != null) {
|
||||
throw new BiomeMapException(key, "Biome '" + biome.getKey() + "' is registered twice");
|
||||
}
|
||||
@ -118,6 +173,11 @@ class BiomeMapParser<T> {
|
||||
Biome biome = Biome.valueOf(formattedValue);
|
||||
biomes.add(biome);
|
||||
} catch (IllegalArgumentException x) {
|
||||
// Lenient Parsers will ignore unknown biomes
|
||||
if (isLenient) {
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new BiomeMapException(key, "The Biome '" + value + "' does not exist!");
|
||||
}
|
||||
} else {
|
||||
@ -132,6 +192,14 @@ class BiomeMapParser<T> {
|
||||
return biomes;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method builds a {@link BiomeMap} based on the parsed data.
|
||||
* <p>
|
||||
* Make sure to parse data via {@link #read(JsonArray)} or {@link #read(String)}
|
||||
* before calling this method! Otherwise the resulting {@link BiomeMap} will be empty.
|
||||
*
|
||||
* @return The resulting {@link BiomeMap}
|
||||
*/
|
||||
@Nonnull
|
||||
BiomeMap<T> buildBiomeMap() {
|
||||
BiomeMap<T> biomeMap = new BiomeMap<>(key);
|
||||
|
@ -74,13 +74,13 @@ class TestBiomeMap {
|
||||
Biome biome3 = Biome.DESERT;
|
||||
BiomeMap<Integer> biomes = createBiomeMap(AS_INT, "[{\"value\":1,\"biomes\":[\"" + biome1.getKey() + "\", \"" + biome2.getKey() + "\"]}, {\"value\":2, \"biomes\":[\"" + biome3.getKey() + "\"]}]");
|
||||
|
||||
Assertions.assertTrue(biomes.contains(biome1));
|
||||
Assertions.assertTrue(biomes.containsKey(biome1));
|
||||
Assertions.assertEquals(1, biomes.get(biome1));
|
||||
|
||||
Assertions.assertTrue(biomes.contains(biome2));
|
||||
Assertions.assertTrue(biomes.containsKey(biome2));
|
||||
Assertions.assertEquals(1, biomes.get(biome2));
|
||||
|
||||
Assertions.assertTrue(biomes.contains(biome3));
|
||||
Assertions.assertTrue(biomes.containsKey(biome3));
|
||||
Assertions.assertEquals(2, biomes.get(biome3));
|
||||
}
|
||||
|
||||
@ -92,11 +92,11 @@ class TestBiomeMap {
|
||||
String value = "Under the sea";
|
||||
|
||||
Assertions.assertTrue(biomes.put(biome, value));
|
||||
Assertions.assertTrue(biomes.contains(biome));
|
||||
Assertions.assertTrue(biomes.containsKey(biome));
|
||||
Assertions.assertEquals(value, biomes.get(biome));
|
||||
|
||||
Assertions.assertTrue(biomes.remove(biome));
|
||||
Assertions.assertFalse(biomes.contains(biome));
|
||||
Assertions.assertFalse(biomes.containsKey(biome));
|
||||
}
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
|
@ -9,6 +9,8 @@ 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 org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
@ -93,6 +95,37 @@ class TestBiomeMapParser {
|
||||
assertMisconfiguration(AS_INT, "[{\"value\": 1, \"biomes\": [\"" + biome.getKey() + "\"]}, {\"value\": 2, \"biomes\": [\"" + biome.getKey() + "\"]}]");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Test BiomeMapParser being not lenient by default")
|
||||
void testParserNotLenientByDefault() {
|
||||
BiomeMapParser<Integer> parser = new BiomeMapParser<>(key, AS_INT);
|
||||
|
||||
// Test default value
|
||||
Assertions.assertFalse(parser.isLenient());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(booleans = { true, false })
|
||||
@DisplayName("Test lenient parser")
|
||||
void testLenientParsing(boolean isLenient) {
|
||||
BiomeMapParser<Integer> parser = new BiomeMapParser<>(key, AS_INT);
|
||||
|
||||
parser.setLenient(isLenient);
|
||||
Assertions.assertEquals(isLenient, parser.isLenient());
|
||||
|
||||
/*
|
||||
* I picked a random String here.
|
||||
* If this biome will exist in Minecraft one day... then you saw it here first, folks ;D
|
||||
*/
|
||||
String json = "[{\"value\": 2048, \"biomes\": [\"minecraft:thebusybiscuits_wonderland\"]}]";
|
||||
|
||||
if (isLenient) {
|
||||
Assertions.assertDoesNotThrow(() -> parser.read(json));
|
||||
} else {
|
||||
Assertions.assertThrows(BiomeMapException.class, () -> parser.read(json));
|
||||
}
|
||||
}
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
private <T> void assertMisconfiguration(BiomeDataConverter<T> function, String json) {
|
||||
BiomeMapParser<T> parser = new BiomeMapParser<>(key, function);
|
||||
|
Loading…
Reference in New Issue
Block a user