mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-20 03:35:51 +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);
|
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.");
|
Validate.notNull(biome, "The biome must not be null.");
|
||||||
|
|
||||||
return dataMap.containsKey(biome);
|
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) {
|
public boolean put(@Nonnull Biome biome, @Nonnull T value) {
|
||||||
Validate.notNull(biome, "The biome should not be null.");
|
Validate.notNull(biome, "The biome should not be null.");
|
||||||
Validate.notNull(value, "Values cannot be null.");
|
Validate.notNull(value, "Values cannot be null.");
|
||||||
|
@ -30,6 +30,8 @@ import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
|
|||||||
*
|
*
|
||||||
* @param <T>
|
* @param <T>
|
||||||
* The data type of the resulting {@link BiomeMap}
|
* The data type of the resulting {@link BiomeMap}
|
||||||
|
*
|
||||||
|
* @see BiomeMap
|
||||||
*/
|
*/
|
||||||
class BiomeMapParser<T> {
|
class BiomeMapParser<T> {
|
||||||
|
|
||||||
@ -40,6 +42,24 @@ class BiomeMapParser<T> {
|
|||||||
private final BiomeDataConverter<T> valueConverter;
|
private final BiomeDataConverter<T> valueConverter;
|
||||||
private final Map<Biome, T> map = new EnumMap<>(Biome.class);
|
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
|
@ParametersAreNonnullByDefault
|
||||||
BiomeMapParser(NamespacedKey key, BiomeDataConverter<T> valueConverter) {
|
BiomeMapParser(NamespacedKey key, BiomeDataConverter<T> valueConverter) {
|
||||||
Validate.notNull(key, "The key shall not be null.");
|
Validate.notNull(key, "The key shall not be null.");
|
||||||
@ -49,6 +69,33 @@ class BiomeMapParser<T> {
|
|||||||
this.valueConverter = valueConverter;
|
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 {
|
void read(@Nonnull String json) throws BiomeMapException {
|
||||||
Validate.notNull(json, "The JSON string should not be null!");
|
Validate.notNull(json, "The JSON string should not be null!");
|
||||||
JsonArray root = null;
|
JsonArray root = null;
|
||||||
@ -82,15 +129,23 @@ class BiomeMapParser<T> {
|
|||||||
private void readEntry(@Nonnull JsonObject entry) throws BiomeMapException {
|
private void readEntry(@Nonnull JsonObject entry) throws BiomeMapException {
|
||||||
Validate.notNull(entry, "The JSON entry should not be null!");
|
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)) {
|
if (entry.has(VALUE_KEY)) {
|
||||||
T value = valueConverter.convert(entry.get(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()) {
|
if (entry.has(BIOMES_KEY) && entry.get(BIOMES_KEY).isJsonArray()) {
|
||||||
Set<Biome> biomes = readBiomes(entry.get(BIOMES_KEY).getAsJsonArray());
|
Set<Biome> biomes = readBiomes(entry.get(BIOMES_KEY).getAsJsonArray());
|
||||||
|
|
||||||
|
// Loop through all biome strings in this array
|
||||||
for (Biome biome : biomes) {
|
for (Biome biome : biomes) {
|
||||||
T prev = map.put(biome, value);
|
T prev = map.put(biome, value);
|
||||||
|
|
||||||
|
// Check for duplicates
|
||||||
if (prev != null) {
|
if (prev != null) {
|
||||||
throw new BiomeMapException(key, "Biome '" + biome.getKey() + "' is registered twice");
|
throw new BiomeMapException(key, "Biome '" + biome.getKey() + "' is registered twice");
|
||||||
}
|
}
|
||||||
@ -118,6 +173,11 @@ class BiomeMapParser<T> {
|
|||||||
Biome biome = Biome.valueOf(formattedValue);
|
Biome biome = Biome.valueOf(formattedValue);
|
||||||
biomes.add(biome);
|
biomes.add(biome);
|
||||||
} catch (IllegalArgumentException x) {
|
} catch (IllegalArgumentException x) {
|
||||||
|
// Lenient Parsers will ignore unknown biomes
|
||||||
|
if (isLenient) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
throw new BiomeMapException(key, "The Biome '" + value + "' does not exist!");
|
throw new BiomeMapException(key, "The Biome '" + value + "' does not exist!");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -132,6 +192,14 @@ class BiomeMapParser<T> {
|
|||||||
return biomes;
|
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
|
@Nonnull
|
||||||
BiomeMap<T> buildBiomeMap() {
|
BiomeMap<T> buildBiomeMap() {
|
||||||
BiomeMap<T> biomeMap = new BiomeMap<>(key);
|
BiomeMap<T> biomeMap = new BiomeMap<>(key);
|
||||||
|
@ -74,13 +74,13 @@ class TestBiomeMap {
|
|||||||
Biome biome3 = Biome.DESERT;
|
Biome biome3 = Biome.DESERT;
|
||||||
BiomeMap<Integer> biomes = createBiomeMap(AS_INT, "[{\"value\":1,\"biomes\":[\"" + biome1.getKey() + "\", \"" + biome2.getKey() + "\"]}, {\"value\":2, \"biomes\":[\"" + biome3.getKey() + "\"]}]");
|
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.assertEquals(1, biomes.get(biome1));
|
||||||
|
|
||||||
Assertions.assertTrue(biomes.contains(biome2));
|
Assertions.assertTrue(biomes.containsKey(biome2));
|
||||||
Assertions.assertEquals(1, biomes.get(biome2));
|
Assertions.assertEquals(1, biomes.get(biome2));
|
||||||
|
|
||||||
Assertions.assertTrue(biomes.contains(biome3));
|
Assertions.assertTrue(biomes.containsKey(biome3));
|
||||||
Assertions.assertEquals(2, biomes.get(biome3));
|
Assertions.assertEquals(2, biomes.get(biome3));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,11 +92,11 @@ class TestBiomeMap {
|
|||||||
String value = "Under the sea";
|
String value = "Under the sea";
|
||||||
|
|
||||||
Assertions.assertTrue(biomes.put(biome, value));
|
Assertions.assertTrue(biomes.put(biome, value));
|
||||||
Assertions.assertTrue(biomes.contains(biome));
|
Assertions.assertTrue(biomes.containsKey(biome));
|
||||||
Assertions.assertEquals(value, biomes.get(biome));
|
Assertions.assertEquals(value, biomes.get(biome));
|
||||||
|
|
||||||
Assertions.assertTrue(biomes.remove(biome));
|
Assertions.assertTrue(biomes.remove(biome));
|
||||||
Assertions.assertFalse(biomes.contains(biome));
|
Assertions.assertFalse(biomes.containsKey(biome));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
|
@ -9,6 +9,8 @@ import org.junit.jupiter.api.Assertions;
|
|||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
import org.junit.jupiter.api.DisplayName;
|
import org.junit.jupiter.api.DisplayName;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.ValueSource;
|
||||||
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
|
|
||||||
@ -93,6 +95,37 @@ class TestBiomeMapParser {
|
|||||||
assertMisconfiguration(AS_INT, "[{\"value\": 1, \"biomes\": [\"" + biome.getKey() + "\"]}, {\"value\": 2, \"biomes\": [\"" + biome.getKey() + "\"]}]");
|
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
|
@ParametersAreNonnullByDefault
|
||||||
private <T> void assertMisconfiguration(BiomeDataConverter<T> function, String json) {
|
private <T> void assertMisconfiguration(BiomeDataConverter<T> function, String json) {
|
||||||
BiomeMapParser<T> parser = new BiomeMapParser<>(key, function);
|
BiomeMapParser<T> parser = new BiomeMapParser<>(key, function);
|
||||||
|
Loading…
Reference in New Issue
Block a user