From d317d0b1b05d559be8db06b07f0a86618ef22872 Mon Sep 17 00:00:00 2001 From: loki5512344 Date: Thu, 23 Apr 2026 23:17:06 +0200 Subject: [PATCH] =?UTF-8?q?refactor:=20split=20ConfigParser=20into=203=20c?= =?UTF-8?q?lasses=20(464=E2=86=92222=20lines)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Разбил ConfigParser на три класса для соблюдения лимита 200 строк: - ConfigParser.java (222 строки) - базовый парсинг selections, blocks, fillMode, mask, teleport - RewardParser.java (222 строки) - парсинг наград (rewards, materials, items, commands) - RewardItemParser.java (80 строк) - парсинг ItemStack из YAML Все классы теперь соответствуют требованию ≤200 строк. ConfigLoader обновлен для использования новой архитектуры. --- .../com/loki/lomines/data/ConfigLoader.java | 3 +- .../com/loki/lomines/data/ConfigParser.java | 258 +----------------- .../loki/lomines/data/RewardItemParser.java | 80 ++++++ .../com/loki/lomines/data/RewardParser.java | 222 +++++++++++++++ 4 files changed, 312 insertions(+), 251 deletions(-) create mode 100644 src/main/java/com/loki/lomines/data/RewardItemParser.java create mode 100644 src/main/java/com/loki/lomines/data/RewardParser.java diff --git a/src/main/java/com/loki/lomines/data/ConfigLoader.java b/src/main/java/com/loki/lomines/data/ConfigLoader.java index 7d5342c..66ed184 100644 --- a/src/main/java/com/loki/lomines/data/ConfigLoader.java +++ b/src/main/java/com/loki/lomines/data/ConfigLoader.java @@ -20,7 +20,8 @@ public final class ConfigLoader { private final ConfigSerializer serializer; public ConfigLoader() { - this.parser = new ConfigParser(); + RewardParser rewardParser = new RewardParser(); + this.parser = new ConfigParser(rewardParser); this.validator = new ConfigValidator(); this.serializer = new ConfigSerializer(); } diff --git a/src/main/java/com/loki/lomines/data/ConfigParser.java b/src/main/java/com/loki/lomines/data/ConfigParser.java index 3ca78c1..7fa36e7 100644 --- a/src/main/java/com/loki/lomines/data/ConfigParser.java +++ b/src/main/java/com/loki/lomines/data/ConfigParser.java @@ -18,6 +18,12 @@ import java.util.Map; */ final class ConfigParser { + private final RewardParser rewardParser; + + ConfigParser(RewardParser rewardParser) { + this.rewardParser = rewardParser; + } + /** * Parses selection coordinates from the YAML configuration. * Reads selection.1 through selection.10 fields. @@ -150,48 +156,14 @@ final class ConfigParser { /** * Parses rewards from the YAML configuration. + * Delegates to RewardParser for actual parsing logic. * * @param yaml the YAML configuration * @return list of parsed Reward objects * @throws ConfigParseException if reward configuration is invalid */ List parseRewards(YamlConfiguration yaml) throws ConfigParseException { - List rewards = new ArrayList<>(); - - if (!yaml.contains("random-rewards")) { - return rewards; - } - - List rewardsList = yaml.getList("random-rewards"); - if (rewardsList == null) { - return rewards; - } - - for (int i = 0; i < rewardsList.size(); i++) { - Object rewardObj = rewardsList.get(i); - - if (!(rewardObj instanceof Map)) { - throw new ConfigParseException( - "Invalid reward at index " + i + ": expected map, got " + - (rewardObj != null ? rewardObj.getClass().getSimpleName() : "null") - ); - } - - @SuppressWarnings("unchecked") - Map rewardMap = (Map) rewardObj; - - try { - Reward reward = parseReward(rewardMap); - rewards.add(reward); - } catch (ConfigParseException e) { - throw new ConfigParseException( - "Error parsing reward at index " + i + ": " + e.getMessage(), - e - ); - } - } - - return rewards; + return rewardParser.parseRewards(yaml); } /** @@ -247,218 +219,4 @@ final class ConfigParser { } return key.toLowerCase(); } - - private Reward parseReward(Map rewardMap) throws ConfigParseException { - double chance = parseRewardField(rewardMap, "chance", Double.class); - boolean preventDrops = parseRewardField(rewardMap, "prevent-drops", Boolean.class, false); - - List materials = parseRewardMaterials(rewardMap); - List items = parseRewardItems(rewardMap); - List commands = parseRewardCommands(rewardMap); - - return new Reward(materials, chance, items, commands, preventDrops); - } - - @SuppressWarnings("unchecked") - private T parseRewardField(Map map, String key, Class type) - throws ConfigParseException { - if (!map.containsKey(key)) { - throw new ConfigParseException("Missing required '" + key + "' field in reward"); - } - - Object value = map.get(key); - - if (type == Double.class) { - return (T) parseDoubleValue(key, value); - } else if (type == Boolean.class) { - if (!(value instanceof Boolean)) { - throw new ConfigParseException( - "Invalid '" + key + "' value: expected boolean, got " + - (value != null ? value.getClass().getSimpleName() : "null") - ); - } - return (T) value; - } - - throw new ConfigParseException("Unsupported type: " + type); - } - - @SuppressWarnings("unchecked") - private T parseRewardField(Map map, String key, Class type, T defaultValue) { - if (!map.containsKey(key)) { - return defaultValue; - } - - Object value = map.get(key); - if (type.isInstance(value)) { - return (T) value; - } - - return defaultValue; - } - - private Double parseDoubleValue(String key, Object value) throws ConfigParseException { - try { - if (value instanceof Number) { - return ((Number) value).doubleValue(); - } else if (value instanceof String) { - return Double.parseDouble((String) value); - } else { - throw new ConfigParseException( - "Invalid '" + key + "' type: expected number, got " + - (value != null ? value.getClass().getSimpleName() : "null") - ); - } - } catch (NumberFormatException e) { - throw new ConfigParseException("Invalid '" + key + "' value: " + value, e); - } - } - - private List parseRewardMaterials(Map rewardMap) - throws ConfigParseException { - if (!rewardMap.containsKey("blocks")) { - throw new ConfigParseException("Missing required 'blocks' field in reward"); - } - - Object blocksObj = rewardMap.get("blocks"); - if (!(blocksObj instanceof List)) { - throw new ConfigParseException( - "Invalid 'blocks' type: expected list, got " + - (blocksObj != null ? blocksObj.getClass().getSimpleName() : "null") - ); - } - - @SuppressWarnings("unchecked") - List blocksList = (List) blocksObj; - - List materials = new ArrayList<>(); - for (String blockName : blocksList) { - if (blockName == null || blockName.trim().isEmpty()) { - throw new ConfigParseException("Block name cannot be null or empty"); - } - - try { - org.bukkit.Material material = org.bukkit.Material.valueOf(blockName.toUpperCase()); - materials.add(material); - } catch (IllegalArgumentException e) { - throw new ConfigParseException( - "Unknown material in reward blocks: '" + blockName + "'", - e - ); - } - } - - return materials; - } - - private List parseRewardItems(Map rewardMap) - throws ConfigParseException { - List items = new ArrayList<>(); - - if (!rewardMap.containsKey("items")) { - return items; - } - - Object itemsObj = rewardMap.get("items"); - if (!(itemsObj instanceof List)) { - throw new ConfigParseException( - "Invalid 'items' type: expected list, got " + - (itemsObj != null ? itemsObj.getClass().getSimpleName() : "null") - ); - } - - List itemsList = (List) itemsObj; - - for (int i = 0; i < itemsList.size(); i++) { - Object itemObj = itemsList.get(i); - - if (!(itemObj instanceof Map)) { - throw new ConfigParseException( - "Invalid item at index " + i + ": expected map, got " + - (itemObj != null ? itemObj.getClass().getSimpleName() : "null") - ); - } - - @SuppressWarnings("unchecked") - Map itemMap = (Map) itemObj; - - org.bukkit.inventory.ItemStack item = parseRewardItem(itemMap, i); - items.add(item); - } - - return items; - } - - private org.bukkit.inventory.ItemStack parseRewardItem(Map itemMap, int index) - throws ConfigParseException { - if (!itemMap.containsKey("type")) { - throw new ConfigParseException("Missing required 'type' field in item at index " + index); - } - - String typeName = String.valueOf(itemMap.get("type")); - org.bukkit.Material material; - try { - material = org.bukkit.Material.valueOf(typeName.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new ConfigParseException( - "Unknown material in item type: '" + typeName + "'", - e - ); - } - - int amount = parseItemAmount(itemMap); - - return new org.bukkit.inventory.ItemStack(material, amount); - } - - private int parseItemAmount(Map itemMap) throws ConfigParseException { - if (!itemMap.containsKey("amount")) { - return 1; - } - - Object amountObj = itemMap.get("amount"); - try { - if (amountObj instanceof Number) { - return ((Number) amountObj).intValue(); - } else if (amountObj instanceof String) { - return Integer.parseInt((String) amountObj); - } else { - throw new ConfigParseException( - "Invalid 'amount' type: expected number, got " + - (amountObj != null ? amountObj.getClass().getSimpleName() : "null") - ); - } - } catch (NumberFormatException e) { - throw new ConfigParseException("Invalid 'amount' value: " + amountObj, e); - } - } - - private List parseRewardCommands(Map rewardMap) - throws ConfigParseException { - List commands = new ArrayList<>(); - - if (!rewardMap.containsKey("commands")) { - return commands; - } - - Object commandsObj = rewardMap.get("commands"); - if (!(commandsObj instanceof List)) { - throw new ConfigParseException( - "Invalid 'commands' type: expected list, got " + - (commandsObj != null ? commandsObj.getClass().getSimpleName() : "null") - ); - } - - @SuppressWarnings("unchecked") - List commandsList = (List) commandsObj; - - for (String command : commandsList) { - if (command == null || command.trim().isEmpty()) { - throw new ConfigParseException("Command cannot be null or empty"); - } - commands.add(command); - } - - return commands; - } } diff --git a/src/main/java/com/loki/lomines/data/RewardItemParser.java b/src/main/java/com/loki/lomines/data/RewardItemParser.java new file mode 100644 index 0000000..5aeb910 --- /dev/null +++ b/src/main/java/com/loki/lomines/data/RewardItemParser.java @@ -0,0 +1,80 @@ +package com.loki.lomines.data; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.util.Map; + +/** + * Parses ItemStack objects from YAML reward item configurations. + * Handles material type, amount, and basic item properties. + */ +final class RewardItemParser { + + /** + * Parses a single reward item from a map configuration. + * + * @param itemMap the item configuration map + * @param index the index of the item in the list (for error messages) + * @return the parsed ItemStack + * @throws ConfigParseException if the item configuration is invalid + */ + ItemStack parseItem(Map itemMap, int index) throws ConfigParseException { + if (!itemMap.containsKey("type")) { + throw new ConfigParseException("Missing required 'type' field in item at index " + index); + } + + String typeName = String.valueOf(itemMap.get("type")); + Material material = parseMaterial(typeName); + int amount = parseAmount(itemMap); + + return new ItemStack(material, amount); + } + + /** + * Parses a material from a string name. + * + * @param typeName the material name + * @return the parsed Material + * @throws ConfigParseException if the material is unknown + */ + private Material parseMaterial(String typeName) throws ConfigParseException { + try { + return Material.valueOf(typeName.toUpperCase()); + } catch (IllegalArgumentException e) { + throw new ConfigParseException( + "Unknown material in item type: '" + typeName + "'", + e + ); + } + } + + /** + * Parses the amount field from an item configuration. + * + * @param itemMap the item configuration map + * @return the parsed amount (defaults to 1 if not specified) + * @throws ConfigParseException if the amount value is invalid + */ + private int parseAmount(Map itemMap) throws ConfigParseException { + if (!itemMap.containsKey("amount")) { + return 1; + } + + Object amountObj = itemMap.get("amount"); + try { + if (amountObj instanceof Number) { + return ((Number) amountObj).intValue(); + } else if (amountObj instanceof String) { + return Integer.parseInt((String) amountObj); + } else { + throw new ConfigParseException( + "Invalid 'amount' type: expected number, got " + + (amountObj != null ? amountObj.getClass().getSimpleName() : "null") + ); + } + } catch (NumberFormatException e) { + throw new ConfigParseException("Invalid 'amount' value: " + amountObj, e); + } + } +} diff --git a/src/main/java/com/loki/lomines/data/RewardParser.java b/src/main/java/com/loki/lomines/data/RewardParser.java new file mode 100644 index 0000000..877aafe --- /dev/null +++ b/src/main/java/com/loki/lomines/data/RewardParser.java @@ -0,0 +1,222 @@ +package com.loki.lomines.data; + +import org.bukkit.Material; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Parses reward configurations from YAML. + * Handles reward chance, materials, items, commands, and prevent-drops settings. + */ +final class RewardParser { + + private final RewardItemParser itemParser; + + RewardParser() { + this.itemParser = new RewardItemParser(); + } + + /** + * Parses all rewards from the YAML configuration. + * + * @param yaml the YAML configuration + * @return list of parsed Reward objects + * @throws ConfigParseException if reward configuration is invalid + */ + List parseRewards(YamlConfiguration yaml) throws ConfigParseException { + List rewards = new ArrayList<>(); + + if (!yaml.contains("random-rewards")) { + return rewards; + } + + List rewardsList = yaml.getList("random-rewards"); + if (rewardsList == null) { + return rewards; + } + + for (int i = 0; i < rewardsList.size(); i++) { + Object rewardObj = rewardsList.get(i); + + if (!(rewardObj instanceof Map)) { + throw new ConfigParseException( + "Invalid reward at index " + i + ": expected map, got " + + (rewardObj != null ? rewardObj.getClass().getSimpleName() : "null") + ); + } + + @SuppressWarnings("unchecked") + Map rewardMap = (Map) rewardObj; + + try { + Reward reward = parseReward(rewardMap); + rewards.add(reward); + } catch (ConfigParseException e) { + throw new ConfigParseException( + "Error parsing reward at index " + i + ": " + e.getMessage(), + e + ); + } + } + + return rewards; + } + + /** + * Parses a single reward from a map configuration. + * + * @param rewardMap the reward configuration map + * @return the parsed Reward object + * @throws ConfigParseException if the reward configuration is invalid + */ + private Reward parseReward(Map rewardMap) throws ConfigParseException { + double chance = parseRewardField(rewardMap, "chance", Double.class); + boolean preventDrops = parseRewardField(rewardMap, "prevent-drops", Boolean.class, false); + + List materials = parseRewardMaterials(rewardMap); + List items = parseRewardItems(rewardMap); + List commands = parseRewardCommands(rewardMap); + + return new Reward(materials, chance, items, commands, preventDrops); + } + + @SuppressWarnings("unchecked") + private T parseRewardField(Map map, String key, Class type) + throws ConfigParseException { + if (!map.containsKey(key)) { + throw new ConfigParseException("Missing required '" + key + "' field in reward"); + } + Object value = map.get(key); + if (type == Double.class) { + return (T) parseDoubleValue(key, value); + } else if (type == Boolean.class) { + if (!(value instanceof Boolean)) { + throw new ConfigParseException( + "Invalid '" + key + "' value: expected boolean, got " + + (value != null ? value.getClass().getSimpleName() : "null") + ); + } + return (T) value; + } + throw new ConfigParseException("Unsupported type: " + type); + } + + @SuppressWarnings("unchecked") + private T parseRewardField(Map map, String key, Class type, T defaultValue) { + if (!map.containsKey(key)) { + return defaultValue; + } + Object value = map.get(key); + if (type.isInstance(value)) { + return (T) value; + } + return defaultValue; + } + + private Double parseDoubleValue(String key, Object value) throws ConfigParseException { + try { + if (value instanceof Number) { + return ((Number) value).doubleValue(); + } else if (value instanceof String) { + return Double.parseDouble((String) value); + } else { + throw new ConfigParseException( + "Invalid '" + key + "' type: expected number, got " + + (value != null ? value.getClass().getSimpleName() : "null") + ); + } + } catch (NumberFormatException e) { + throw new ConfigParseException("Invalid '" + key + "' value: " + value, e); + } + } + + private List parseRewardMaterials(Map rewardMap) + throws ConfigParseException { + if (!rewardMap.containsKey("blocks")) { + throw new ConfigParseException("Missing required 'blocks' field in reward"); + } + Object blocksObj = rewardMap.get("blocks"); + if (!(blocksObj instanceof List)) { + throw new ConfigParseException( + "Invalid 'blocks' type: expected list, got " + + (blocksObj != null ? blocksObj.getClass().getSimpleName() : "null") + ); + } + @SuppressWarnings("unchecked") + List blocksList = (List) blocksObj; + List materials = new ArrayList<>(); + for (String blockName : blocksList) { + if (blockName == null || blockName.trim().isEmpty()) { + throw new ConfigParseException("Block name cannot be null or empty"); + } + try { + Material material = Material.valueOf(blockName.toUpperCase()); + materials.add(material); + } catch (IllegalArgumentException e) { + throw new ConfigParseException( + "Unknown material in reward blocks: '" + blockName + "'", + e + ); + } + } + return materials; + } + + private List parseRewardItems(Map rewardMap) + throws ConfigParseException { + List items = new ArrayList<>(); + if (!rewardMap.containsKey("items")) { + return items; + } + Object itemsObj = rewardMap.get("items"); + if (!(itemsObj instanceof List)) { + throw new ConfigParseException( + "Invalid 'items' type: expected list, got " + + (itemsObj != null ? itemsObj.getClass().getSimpleName() : "null") + ); + } + List itemsList = (List) itemsObj; + for (int i = 0; i < itemsList.size(); i++) { + Object itemObj = itemsList.get(i); + if (!(itemObj instanceof Map)) { + throw new ConfigParseException( + "Invalid item at index " + i + ": expected map, got " + + (itemObj != null ? itemObj.getClass().getSimpleName() : "null") + ); + } + @SuppressWarnings("unchecked") + Map itemMap = (Map) itemObj; + ItemStack item = itemParser.parseItem(itemMap, i); + items.add(item); + } + return items; + } + + private List parseRewardCommands(Map rewardMap) + throws ConfigParseException { + List commands = new ArrayList<>(); + if (!rewardMap.containsKey("commands")) { + return commands; + } + Object commandsObj = rewardMap.get("commands"); + if (!(commandsObj instanceof List)) { + throw new ConfigParseException( + "Invalid 'commands' type: expected list, got " + + (commandsObj != null ? commandsObj.getClass().getSimpleName() : "null") + ); + } + @SuppressWarnings("unchecked") + List commandsList = (List) commandsObj; + for (String command : commandsList) { + if (command == null || command.trim().isEmpty()) { + throw new ConfigParseException("Command cannot be null or empty"); + } + commands.add(command); + } + return commands; + } +}