From e00a9c301abeedbfbfbdd90de43cfe3348e4a7c5 Mon Sep 17 00:00:00 2001 From: portlek Date: Fri, 13 Dec 2019 12:32:11 +0300 Subject: [PATCH] Improvement for IFile class Former-commit-id: c3b2b924c5e72624cbe35cdf422eeb29136cd533 --- pom.xml | 4 - .../maxgamer/quickshop/File/FileEnvelope.java | 142 +++++++++- .../org/maxgamer/quickshop/File/IFile.java | 189 ++++++++++++- .../quickshop/Util/Location/LocationOf.java | 39 +++ .../quickshop/Util/Location/StringOf.java | 51 ++++ .../org/maxgamer/quickshop/Util/Util.java | 14 + .../quickshop/File/FileEnvelopeTest.java | 257 ++++++++++++++++++ .../maxgamer/quickshop/File/JSONFileTest.java | 46 ---- .../maxgamer/quickshop/File/YAMLFileTest.java | 48 ---- 9 files changed, 690 insertions(+), 100 deletions(-) create mode 100644 src/main/java/org/maxgamer/quickshop/Util/Location/LocationOf.java create mode 100644 src/main/java/org/maxgamer/quickshop/Util/Location/StringOf.java create mode 100644 src/test/java/org/maxgamer/quickshop/File/FileEnvelopeTest.java delete mode 100644 src/test/java/org/maxgamer/quickshop/File/JSONFileTest.java delete mode 100644 src/test/java/org/maxgamer/quickshop/File/YAMLFileTest.java diff --git a/pom.xml b/pom.xml index 93352f6c5..c26752ede 100644 --- a/pom.xml +++ b/pom.xml @@ -287,10 +287,6 @@ bukkit org.bukkit - - commons-io - commons-io - diff --git a/src/main/java/org/maxgamer/quickshop/File/FileEnvelope.java b/src/main/java/org/maxgamer/quickshop/File/FileEnvelope.java index 0960ffc1f..7697c828f 100644 --- a/src/main/java/org/maxgamer/quickshop/File/FileEnvelope.java +++ b/src/main/java/org/maxgamer/quickshop/File/FileEnvelope.java @@ -1,15 +1,24 @@ package org.maxgamer.quickshop.File; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.maxgamer.quickshop.Mock.MckFileConfiguration; import org.maxgamer.quickshop.Util.Copied; +import org.maxgamer.quickshop.Util.Location.LocationOf; +import org.maxgamer.quickshop.Util.Location.StringOf; +import org.maxgamer.quickshop.Util.Util; import java.io.File; import java.io.InputStream; +import java.util.List; import java.util.Objects; +import java.util.Optional; public abstract class FileEnvelope implements IFile { @@ -79,7 +88,7 @@ public abstract class FileEnvelope implements IFile { fileConfiguration.save(file); } catch (Exception exception) { - throw new RuntimeException(exception); + throw new IllegalStateException(exception); } } @@ -89,9 +98,140 @@ public abstract class FileEnvelope implements IFile { return fileConfiguration.get(path); } + @NotNull + @Override + public Object get(@NotNull String path, @NotNull Object fallback) { + final Object object = fileConfiguration.get(path, fallback); + + if (object == null) { + return fallback; + } + + return object; + } + + @NotNull + @Override + @SuppressWarnings("unchecked") + public T getOrSet(@NotNull String path, @NotNull T fallback) { + final T object = (T) fileConfiguration.get(path, null); + + if (object != null) { + return object; + } + + set(path, fallback); + + return fallback; + } + + @NotNull + @Override + public Location getLocation(@NotNull String path) { + return new LocationOf( + getString(path).orElse("") + ).value(); + } + + @Override + public void setLocation(@NotNull String path, @NotNull Location location) { + set( + path, + new StringOf(location).asString() + ); + } + + @NotNull + @Override + public ItemStack getCustomItemStack(@NotNull String path) { + try { + return Util.deserialize(path); + } catch (Exception exception) { + return new ItemStack(Material.AIR); + } + } + + @Override + public void setCustomItemStack(@NotNull String path, @NotNull ItemStack itemStack) { + fileConfiguration.set(path, Util.serialize(itemStack)); + } + + @NotNull + @Override + public Optional getString(@NotNull String path) { + return Optional.ofNullable(fileConfiguration.getString(path)); + } + @Override public void set(@NotNull String path, @NotNull Object object) { fileConfiguration.set(path, object); + save(); + } + + @NotNull + @Override + public List getStringList(@NotNull String path) { + return fileConfiguration.getStringList(path); + } + + @Override + public int getInt(@NotNull String path) { + return fileConfiguration.getInt(path); + } + + @Override + public double getDouble(@NotNull String path) { + return fileConfiguration.getDouble(path); + } + + @Override + public long getLong(@NotNull String path) { + return fileConfiguration.getLong(path); + } + + @Override + public byte getByte(@NotNull String path) { + return (byte) fileConfiguration.getInt(path); + } + + @Override + public short getShort(@NotNull String path) { + return (short) fileConfiguration.getInt(path); + } + + @Override + public boolean getBoolean(@NotNull String path) { + return fileConfiguration.getBoolean(path); + } + + @NotNull + @Override + public ConfigurationSection createSection(@NotNull String path) { + final ConfigurationSection configurationSection = fileConfiguration.createSection(path); + + save(); + + return configurationSection; + } + + @NotNull + @Override + public ConfigurationSection getSection(@NotNull String path) { + final ConfigurationSection configurationSection = fileConfiguration.getConfigurationSection(path); + + return configurationSection == null ? new MckFileConfiguration() : configurationSection; + } + + @NotNull + @Override + public ConfigurationSection getOrCreateSection(@NotNull String path) { + ConfigurationSection section = getSection(path); + + if (section instanceof MckFileConfiguration) { + section = createSection(path); + } + + return section; } } diff --git a/src/main/java/org/maxgamer/quickshop/File/IFile.java b/src/main/java/org/maxgamer/quickshop/File/IFile.java index e30ee6a08..b2e429952 100644 --- a/src/main/java/org/maxgamer/quickshop/File/IFile.java +++ b/src/main/java/org/maxgamer/quickshop/File/IFile.java @@ -1,24 +1,211 @@ package org.maxgamer.quickshop.File; +import org.bukkit.Location; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.InputStream; +import java.util.List; +import java.util.Optional; public interface IFile { + /** + * Creates yml file on the path + */ void create(); @NotNull InputStream getInputStream(); + /** + * Reloads file + */ void reload(); + /** + * Saves file + */ void save(); + /** + * Gets the object + * + * @param path object path to get + * @return if path does not exist returns null + */ @Nullable Object get(@NotNull String path); - void set(@NotNull String path, @NotNull Object object); + /** + * Gets the object with fallback + * + * @param path object path to get + * @param fallback fallback object to get if path does not exist + * @return if path does not exist returns fallback object else the path object + */ + @NotNull + Object get(@NotNull String path, @NotNull Object fallback); + + /** + * Gets or sets the object + * + * @param path object path to get + * @param fallback fallback object to get if path does not exist + * @param object type + * @return if path does not exist returns and set the path with fallback object + */ + @NotNull + T getOrSet(@NotNull final String path, @NotNull T fallback); + + /** + * Gets location + * + * @param path location path to get + * @return {@link Location} + */ + @NotNull + Location getLocation(@NotNull final String path); + + /** + * Sets location into the path + * + * @param path location path to set + * @param location {@link Location} + */ + void setLocation(@NotNull final String path, @NotNull final Location location); + + /** + * Pattern: + * + * path: + * (material): 'DIAMOND' + * [amount]: 1 + * [data]: 0 + * [display-name]: 'Diamond Sword' + * [enchants]: + * DAMAGE_ALL: 10 + * FIRE_ASPECT: 2 + * [lore]: + * - 'Lore 1' + * - 'Lore 2' + * + * @param path itemstack path to get + * @return {@link ItemStack} + */ + @NotNull + ItemStack getCustomItemStack(@NotNull final String path); + + /** + * Sets custom itemstack to path + * + * @param path itemstack path to set + * @param itemStack {@link ItemStack} + */ + void setCustomItemStack(@NotNull final String path, @NotNull final ItemStack itemStack); + + /** + * Gets string + * + * @param path string path to get + * @return {@link String} + */ + @NotNull + Optional getString(@NotNull final String path); + + /** + * Sets object to path + * + * @param path object path to set + * @param object {@link Object} + */ + void set(@NotNull final String path, @NotNull final Object object); + + /** + * Gets string list + * + * @param path string list path to get + * @return string list + */ + @NotNull + List getStringList(@NotNull final String path); + + /** + * Gets int + * + * @param path integer path to get + * @return {@link Integer} + */ + int getInt(@NotNull final String path); + + /** + * Gets double + * + * @param path double path to get + * @return {@link Double} + */ + double getDouble(@NotNull final String path); + + /** + * Gets long + * + * @param path long path to get + * @return {@link Integer} + */ + long getLong(@NotNull String path); + + /** + * Gets byte + * + * @param path byte path to get + * @return {@link Byte} + */ + byte getByte(@NotNull final String path); + + /** + * Gets short + * + * @param path short path to get + * @return {@link Short} + */ + short getShort(@NotNull String path); + + /** + * Gets boolean + * + * @param path boolean path to get + * @return {@link Boolean} + */ + boolean getBoolean(@NotNull final String path); + + /** + * Creates configuration section into path + * + * @param path configuration section path to create + * @return {@link ConfigurationSection} + */ + @NotNull + ConfigurationSection createSection(@NotNull String path); + + /** + * Gets configuration section from path + * + * @param path configurations section path to get + * @return if there isn't section returns {@link MckFileConfiguration} + */ + @NotNull + ConfigurationSection getSection(@NotNull final String path); + + /** + * Gets configuration section from path + * if there is no section It will create + * + * @param path configurations section path to get + * @return {@link ConfigurationSection} + */ + @NotNull + ConfigurationSection getOrCreateSection(@NotNull final String path); } diff --git a/src/main/java/org/maxgamer/quickshop/Util/Location/LocationOf.java b/src/main/java/org/maxgamer/quickshop/Util/Location/LocationOf.java new file mode 100644 index 000000000..a36158683 --- /dev/null +++ b/src/main/java/org/maxgamer/quickshop/Util/Location/LocationOf.java @@ -0,0 +1,39 @@ +package org.maxgamer.quickshop.Util.Location; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.jetbrains.annotations.NotNull; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public final class LocationOf { + + @NotNull + private static final Pattern PATTERN = + Pattern.compile("((?[^:/]+)[:/])?(?[\\-0-9.]+),(?[\\-0-9.]+),(?[\\-0-9.]+)(:(?[\\-0-9.]+):(?[\\-0-9.]+))?"); + + @NotNull + private final String text; + + public LocationOf(@NotNull String text) { + this.text = text; + } + + @NotNull + public Location value() { + final Matcher match = PATTERN.matcher(text.replaceAll("_", "\\.")); + + if (match.matches()) + return new Location( + Bukkit.getWorld(match.group("world")), + Double.parseDouble(match.group("x")), + Double.parseDouble(match.group("y")), + Double.parseDouble(match.group("z")), + match.group("yaw") != null ? Float.parseFloat(match.group("yaw")) : 0F, + match.group("pitch") != null ? Float.parseFloat(match.group("pitch")) : 0F + ); + + throw new IllegalStateException("Location string has wrong style!"); + } +} diff --git a/src/main/java/org/maxgamer/quickshop/Util/Location/StringOf.java b/src/main/java/org/maxgamer/quickshop/Util/Location/StringOf.java new file mode 100644 index 000000000..8800a1b07 --- /dev/null +++ b/src/main/java/org/maxgamer/quickshop/Util/Location/StringOf.java @@ -0,0 +1,51 @@ +package org.maxgamer.quickshop.Util.Location; + +import org.bukkit.Location; +import org.bukkit.World; +import org.jetbrains.annotations.NotNull; + +import java.util.Locale; + +public final class StringOf { + + @NotNull + private final Location location; + + @NotNull + private final World world; + + public StringOf(@NotNull Location location) { + if (location.getWorld() == null) { + throw new IllegalStateException("World of the location cannot be null!"); + } + + this.location = location; + this.world = location.getWorld(); + } + + @NotNull + public String asString() { + String s = world.getName() + ":"; + + s += String.format( + Locale.ENGLISH, + "%.2f,%.2f,%.2f", + location.getX(), location.getY(), location.getZ() + ); + + if (location.getYaw() != 0f || location.getPitch() != 0f) { + s += String.format( + Locale.ENGLISH, + ":%.2f:%.2f", + location.getYaw(), location.getPitch() + ); + } + return s; + } + + @NotNull + public String asKey() { + return asString().replaceAll(":", "/").replaceAll("\\.", "_"); + } + +} diff --git a/src/main/java/org/maxgamer/quickshop/Util/Util.java b/src/main/java/org/maxgamer/quickshop/Util/Util.java index 61a39ade0..983936bc4 100644 --- a/src/main/java/org/maxgamer/quickshop/Util/Util.java +++ b/src/main/java/org/maxgamer/quickshop/Util/Util.java @@ -990,6 +990,20 @@ public class Util { return text; } + /** + * Parse colors for the List. + * + * @param list the list + * @return parsed list + */ + public static List parseColours(@NotNull List list) { + final List newList = new ArrayList<>(); + + list.forEach(s -> newList.add(parseColours(s))); + + return newList; + } + /** * Converts a name like IRON_INGOT into Iron Ingot to improve readability * diff --git a/src/test/java/org/maxgamer/quickshop/File/FileEnvelopeTest.java b/src/test/java/org/maxgamer/quickshop/File/FileEnvelopeTest.java new file mode 100644 index 000000000..bc321e6ca --- /dev/null +++ b/src/test/java/org/maxgamer/quickshop/File/FileEnvelopeTest.java @@ -0,0 +1,257 @@ +package org.maxgamer.quickshop.File; + +import be.seeseemelk.mockbukkit.MockBukkit; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.inventory.ItemStack; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.maxgamer.quickshop.Mock.MckFileConfiguration; +import org.maxgamer.quickshop.QuickShopTest; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.*; + +public class FileEnvelopeTest { + + private final List test = new ArrayList<>(); + private QuickShopTest plugin; + private IFile json; + private IFile yaml; + + @BeforeEach + void start() { + MockBukkit.mock(); + plugin = MockBukkit.load(QuickShopTest.class); + json = new JSONFile(plugin, "messages"); + json.create(); + yaml = new YAMLFile(plugin, "messages"); + yaml.create(); + test.add("test"); + json.set("test.list", test); + yaml.set("test.list", test); + json.set("test.int", 13); + yaml.set("test.int", 13); + json.set("test.boolean", true); + yaml.set("test.boolean", true); + json.set("test.short", (short) 1); + yaml.set("test.short", (short) 1); + json.set("test.long", (long) 1); + yaml.set("test.long", (long) 1); + json.set("test.byte", (byte) 1); + yaml.set("test.byte", (byte) 1); + json.set("test.double", (double) 1); + yaml.set("test.double", (double) 1); + } + + @Test + void get() { + assertEquals( + "{0}", + json.get("signs.item") + ); + assertEquals( + "{0}", + yaml.get("signs.item") + ); + } + + @Test + void getString() { + final Optional optionalS = json.getString("shop-staff-cleared"); + final Optional optionalSS = yaml.getString("shop-staff-cleared"); + + if (!optionalS.isPresent() || !optionalSS.isPresent()) { + throw new IllegalArgumentException("There no path called 'shop-staff-cleared'"); + } + + assertEquals( + "&aSuccessfully removed all staff for your shop.", + optionalS.get() + ); + assertEquals( + "&aSuccessfully removed all staff for your shop.", + optionalSS.get() + ); + } + + @Test + void set() { + json.set("test.test", "test"); + yaml.set("test.test", "test"); + assertEquals( + "{0}", + json.get("signs.item") + ); + assertEquals( + "{0}", + yaml.get("signs.item") + ); + } + + @Test + void create() { + json.create(); + yaml.create(); + } + + @Test + void save() { + json.save(); + yaml.save(); + } + + @Test + void getWithFallback() { + assertEquals( + "&aSuccessfully removed all staff for your shop.", + json.get("shop-staff-cleared", "test") + ); + assertEquals( + "&aSuccessfully removed all staff for your shop.", + yaml.get("shop-staff-cleared", "test") + ); + } + + @Test + void getOrSet() { + assertEquals( + "test", + json.getOrSet("test.test123", "test") + ); + assertEquals( + "test", + yaml.getOrSet("test.test123", "test") + ); + assertEquals( + "test", + json.getOrSet("test.test123", "test") + ); + assertEquals( + "test", + yaml.getOrSet("test.test123", "test") + ); + } + + @Test + void getStringList() { + assertEquals( + test, + json.getStringList("test.list") + ); + assertEquals( + test, + yaml.getStringList("test.list") + ); + } + + @Test + void getInt() { + assertEquals( + 13, + json.getInt("test.int") + ); + assertEquals( + 13, + yaml.getInt("test.int") + ); + } + + @Test + void getDouble() { + assertEquals( + 1, + json.getDouble("test.short") + ); + assertEquals( + 1, + yaml.getDouble("test.short") + ); + } + + @Test + void getLong() { + assertEquals( + 1, + json.getLong("test.short") + ); + assertEquals( + 1, + yaml.getLong("test.short") + ); + } + + @Test + void getByte() { + assertEquals( + (byte) 1, + json.getByte("test.short") + ); + assertEquals( + (byte) 1, + yaml.getByte("test.short") + ); + } + + @Test + void getShort() { + assertEquals( + (short) 1, + json.getShort("test.short") + ); + assertEquals( + (short) 1, + yaml.getShort("test.short") + ); + } + + @Test + void getBoolean() { + assertTrue( + json.getBoolean("test.boolean") + ); + assertTrue( + yaml.getBoolean("test.boolean") + ); + } + + @Test + void createSection() { + json.createSection("test.section"); + yaml.createSection("test.section"); + } + + @Test + void getSection() { + assertTrue( + () -> !(json.getSection("test.section") instanceof MckFileConfiguration) + ); + assertTrue( + () -> !(yaml.getSection("test.section") instanceof MckFileConfiguration) + ); + } + + @Test + void getOrCreateSection() { + assertTrue( + () -> !(json.getOrCreateSection("test.section") instanceof MckFileConfiguration) + ); + assertTrue( + () -> !(yaml.getOrCreateSection("test.section") instanceof MckFileConfiguration) + ); + } + + @AfterEach + void stop() { + json.save(); + yaml.save(); + MockBukkit.unload(); + } + +} diff --git a/src/test/java/org/maxgamer/quickshop/File/JSONFileTest.java b/src/test/java/org/maxgamer/quickshop/File/JSONFileTest.java deleted file mode 100644 index 9f2fba7b2..000000000 --- a/src/test/java/org/maxgamer/quickshop/File/JSONFileTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.maxgamer.quickshop.File; - -import be.seeseemelk.mockbukkit.MockBukkit; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.maxgamer.quickshop.QuickShopTest; -import static org.junit.jupiter.api.Assertions.*; - -final class JSONFileTest { - - private QuickShopTest plugin; - private IFile json; - - @BeforeEach - void start() { - MockBukkit.mock(); - plugin = MockBukkit.load(QuickShopTest.class); - json = new JSONFile(plugin, "messages"); - json.create(); - } - - @Test - void get() { - assertEquals( - json.get("signs.item"), - "{0}" - ); - } - - @Test - void set() { - json.set("test.test", "test"); - assertEquals( - json.get("signs.item"), - "{0}" - ); - } - - @AfterEach - void stop() { - json.save(); - MockBukkit.unload(); - } - -} \ No newline at end of file diff --git a/src/test/java/org/maxgamer/quickshop/File/YAMLFileTest.java b/src/test/java/org/maxgamer/quickshop/File/YAMLFileTest.java deleted file mode 100644 index 0e8770cde..000000000 --- a/src/test/java/org/maxgamer/quickshop/File/YAMLFileTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.maxgamer.quickshop.File; - -import be.seeseemelk.mockbukkit.MockBukkit; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.maxgamer.quickshop.QuickShopTest; - -import static org.junit.jupiter.api.Assertions.*; - -final class YAMLFileTest { - - private QuickShopTest plugin; - private IFile yaml; - - @BeforeEach - void start() { - MockBukkit.mock(); - plugin = MockBukkit.load(QuickShopTest.class); - yaml = new YAMLFile(plugin, "messages"); - - yaml.create(); - } - - @Test - void get() { - assertEquals( - yaml.get("signs.item"), - "{0}" - ); - } - - @Test - void set() { - yaml.set("test.test", "test"); - assertEquals( - yaml.get("test.test"), - "test" - ); - } - - @AfterEach - void stop() { - yaml.save(); - MockBukkit.unload(); - } - -} \ No newline at end of file