Refactor ItemSettings

This commit is contained in:
filoghost 2020-07-28 12:04:03 +02:00
parent a1c7f9d24d
commit 92310bc4ab
7 changed files with 225 additions and 249 deletions

View File

@ -20,7 +20,7 @@ import me.filoghost.chestcommands.config.framework.ConfigLoader;
import me.filoghost.chestcommands.config.framework.ConfigSection; import me.filoghost.chestcommands.config.framework.ConfigSection;
import me.filoghost.chestcommands.config.framework.exception.ConfigLoadException; import me.filoghost.chestcommands.config.framework.exception.ConfigLoadException;
import me.filoghost.chestcommands.config.framework.exception.ConfigSaveException; import me.filoghost.chestcommands.config.framework.exception.ConfigSaveException;
import me.filoghost.chestcommands.parsing.icon.IconSettingsNode; import me.filoghost.chestcommands.parsing.icon.AttributeType;
import me.filoghost.chestcommands.parsing.menu.MenuSettingsNode; import me.filoghost.chestcommands.parsing.menu.MenuSettingsNode;
import me.filoghost.chestcommands.util.Strings; import me.filoghost.chestcommands.util.Strings;
@ -85,45 +85,45 @@ public class MenuNodeExpandUpgradeTask extends UpgradeTask {
} }
private void upgradeIcon(ConfigSection section) { private void upgradeIcon(ConfigSection section) {
expandInlineList(section, IconSettingsNode.ACTIONS, legacyCommandSeparator); expandInlineList(section, AttributeType.ACTIONS.getAttributeName(), legacyCommandSeparator);
expandInlineList(section, IconSettingsNode.ENCHANTMENTS, ";"); expandInlineList(section, AttributeType.ENCHANTMENTS.getAttributeName(), ";");
expandSingletonList(section, IconSettingsNode.REQUIRED_ITEMS); expandSingletonList(section, AttributeType.REQUIRED_ITEMS.getAttributeName());
expandInlineItemstack(section); expandInlineItemstack(section);
} }
private void expandInlineItemstack(ConfigSection section) { private void expandInlineItemstack(ConfigSection section) {
String material = section.getString(IconSettingsNode.MATERIAL); String material = section.getString(AttributeType.MATERIAL.getAttributeName());
if (material == null) { if (material == null) {
return; return;
} }
if (material.contains(",")) { if (material.contains(",")) {
String[] parts = Strings.trimmedSplit(material, ",", 2); String[] parts = Strings.trimmedSplit(material, ",", 2);
if (!section.isSet(IconSettingsNode.AMOUNT)) { if (!section.isSet(AttributeType.AMOUNT.getAttributeName())) {
try { try {
section.set(IconSettingsNode.AMOUNT, Integer.parseInt(parts[1])); section.set(AttributeType.AMOUNT.getAttributeName(), Integer.parseInt(parts[1]));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
section.set(IconSettingsNode.AMOUNT, parts[1]); section.set(AttributeType.AMOUNT.getAttributeName(), parts[1]);
} }
} }
material = parts[0]; material = parts[0];
section.set(IconSettingsNode.MATERIAL, material); section.set(AttributeType.MATERIAL.getAttributeName(), material);
setSaveRequired(); setSaveRequired();
} }
if (material.contains(":")) { if (material.contains(":")) {
String[] parts = Strings.trimmedSplit(material, ":", 2); String[] parts = Strings.trimmedSplit(material, ":", 2);
if (!section.isSet(IconSettingsNode.DURABILITY)) { if (!section.isSet(AttributeType.DURABILITY.getAttributeName())) {
try { try {
section.set(IconSettingsNode.DURABILITY, Integer.parseInt(parts[1])); section.set(AttributeType.DURABILITY.getAttributeName(), Integer.parseInt(parts[1]));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
section.set(IconSettingsNode.DURABILITY, parts[1]); section.set(AttributeType.DURABILITY.getAttributeName(), parts[1]);
} }
} }
material = parts[0]; material = parts[0];
section.set(IconSettingsNode.MATERIAL, material); section.set(AttributeType.MATERIAL.getAttributeName(), material);
setSaveRequired(); setSaveRequired();
} }
} }

View File

@ -14,7 +14,7 @@
*/ */
package me.filoghost.chestcommands.legacy.upgrade; package me.filoghost.chestcommands.legacy.upgrade;
import me.filoghost.chestcommands.parsing.icon.IconSettingsNode; import me.filoghost.chestcommands.parsing.icon.AttributeType;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -28,13 +28,13 @@ public class MenuNodeRenameUpgradeTask extends RegexUpgradeTask {
addSubNodeReplacer("open-action", "open-actions"); addSubNodeReplacer("open-action", "open-actions");
addSubNodeReplacer("id", "material"); addSubNodeReplacer("id", "material");
addSubNodeReplacer("ID", IconSettingsNode.MATERIAL); addSubNodeReplacer("ID", AttributeType.MATERIAL.getAttributeName());
addSubNodeReplacer("DATA-VALUE", IconSettingsNode.DURABILITY); addSubNodeReplacer("DATA-VALUE", AttributeType.DURABILITY.getAttributeName());
addSubNodeReplacer("NBT", IconSettingsNode.NBT_DATA); addSubNodeReplacer("NBT", AttributeType.NBT_DATA.getAttributeName());
addSubNodeReplacer("ENCHANTMENT", IconSettingsNode.ENCHANTMENTS); addSubNodeReplacer("ENCHANTMENT", AttributeType.ENCHANTMENTS.getAttributeName());
addSubNodeReplacer("COMMAND", IconSettingsNode.ACTIONS); addSubNodeReplacer("COMMAND", AttributeType.ACTIONS.getAttributeName());
addSubNodeReplacer("COMMANDS", IconSettingsNode.ACTIONS); addSubNodeReplacer("COMMANDS", AttributeType.ACTIONS.getAttributeName());
addSubNodeReplacer("REQUIRED-ITEM", IconSettingsNode.REQUIRED_ITEMS); addSubNodeReplacer("REQUIRED-ITEM", AttributeType.REQUIRED_ITEMS.getAttributeName());
} }
private void addSubNodeReplacer(String oldNode, String newNode) { private void addSubNodeReplacer(String oldNode, String newNode) {

View File

@ -16,6 +16,7 @@ package me.filoghost.chestcommands.logging;
import me.filoghost.chestcommands.ChestCommands; import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.config.framework.mapped.MappedConfig; import me.filoghost.chestcommands.config.framework.mapped.MappedConfig;
import me.filoghost.chestcommands.parsing.icon.AttributeType;
import me.filoghost.chestcommands.parsing.icon.IconSettings; import me.filoghost.chestcommands.parsing.icon.IconSettings;
import java.nio.file.Path; import java.nio.file.Path;
@ -169,12 +170,16 @@ public class ErrorMessages {
return "the menu \"" + formatPath(menuFile) + "\" " + errorMessage; return "the menu \"" + formatPath(menuFile) + "\" " + errorMessage;
} }
public static String invalidAttribute(IconSettings iconSettings, AttributeType attributeType) {
return invalidAttribute(iconSettings, attributeType.getAttributeName());
}
public static String invalidAttribute(IconSettings iconSettings, String attributeName) { public static String invalidAttribute(IconSettings iconSettings, String attributeName) {
return iconError(iconSettings, "has an invalid attribute \"" + attributeName + "\""); return iconError(iconSettings, "has an invalid attribute \"" + attributeName + "\"");
} }
public static String missingAttribute(IconSettings iconSettings, String attributeName) { public static String missingAttribute(IconSettings iconSettings, AttributeType attributeType) {
return iconError(iconSettings, "is missing the attribute \"" + attributeName + "\""); return iconError(iconSettings, "is missing the attribute \"" + attributeType.getAttributeName() + "\"");
} }
public static String invalidAttributeListElement(IconSettings iconSettings, String attributeName, String listElement) { public static String invalidAttributeListElement(IconSettings iconSettings, String attributeName, String listElement) {

View File

@ -0,0 +1,139 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package me.filoghost.chestcommands.parsing.icon;
import me.filoghost.chestcommands.config.framework.ConfigPath;
import me.filoghost.chestcommands.config.framework.ConfigSection;
import me.filoghost.chestcommands.config.framework.exception.ConfigValueException;
import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.attribute.ActionsAttribute;
import me.filoghost.chestcommands.parsing.attribute.AmountAttribute;
import me.filoghost.chestcommands.parsing.attribute.AttributeErrorHandler;
import me.filoghost.chestcommands.parsing.attribute.BannerColorAttribute;
import me.filoghost.chestcommands.parsing.attribute.BannerPatternsAttribute;
import me.filoghost.chestcommands.parsing.attribute.ClickPermissionAttribute;
import me.filoghost.chestcommands.parsing.attribute.ClickPermissionMessageAttribute;
import me.filoghost.chestcommands.parsing.attribute.DurabilityAttribute;
import me.filoghost.chestcommands.parsing.attribute.EnchantmentsAttribute;
import me.filoghost.chestcommands.parsing.attribute.ExpLevelsAttribute;
import me.filoghost.chestcommands.parsing.attribute.IconAttribute;
import me.filoghost.chestcommands.parsing.attribute.KeepOpenAttribute;
import me.filoghost.chestcommands.parsing.attribute.LeatherColorAttribute;
import me.filoghost.chestcommands.parsing.attribute.LoreAttribute;
import me.filoghost.chestcommands.parsing.attribute.MaterialAttribute;
import me.filoghost.chestcommands.parsing.attribute.NBTDataAttribute;
import me.filoghost.chestcommands.parsing.attribute.NameAttribute;
import me.filoghost.chestcommands.parsing.attribute.PositionAttribute;
import me.filoghost.chestcommands.parsing.attribute.PriceAttribute;
import me.filoghost.chestcommands.parsing.attribute.RequiredItemsAttribute;
import me.filoghost.chestcommands.parsing.attribute.SkullOwnerAttribute;
import me.filoghost.chestcommands.parsing.attribute.ViewPermissionAttribute;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public enum AttributeType implements ConfigPath {
POSITION_X("POSITION-X", ValueExtractor.INT, PositionAttribute::new),
POSITION_Y("POSITION-Y", ValueExtractor.INT, PositionAttribute::new),
MATERIAL("MATERIAL", ValueExtractor.STRING, MaterialAttribute::new),
DURABILITY("DURABILITY", ValueExtractor.SHORT, DurabilityAttribute::new),
AMOUNT("AMOUNT", ValueExtractor.INT, AmountAttribute::new),
NAME("NAME", ValueExtractor.STRING, NameAttribute::new),
LORE("LORE", ValueExtractor.STRING_LIST, LoreAttribute::new),
NBT_DATA("NBT-DATA", ValueExtractor.STRING, NBTDataAttribute::new),
LEATHER_COLOR("COLOR", ValueExtractor.STRING, LeatherColorAttribute::new),
SKULL_OWNER("SKULL-OWNER", ValueExtractor.STRING, SkullOwnerAttribute::new),
BANNER_COLOR("BANNER-COLOR", ValueExtractor.STRING, BannerColorAttribute::new),
BANNER_PATTERNS("BANNER-PATTERNS", ValueExtractor.STRING_LIST, BannerPatternsAttribute::new),
PRICE("PRICE", ValueExtractor.DOUBLE, PriceAttribute::new),
EXP_LEVELS("LEVELS", ValueExtractor.INT, ExpLevelsAttribute::new),
CLICK_PERMISSION("PERMISSION", ValueExtractor.STRING, ClickPermissionAttribute::new),
CLICK_PERMISSION_MESSAGE("PERMISSION-MESSAGE", ValueExtractor.STRING, ClickPermissionMessageAttribute::new),
VIEW_PERMISSION("VIEW-PERMISSION", ValueExtractor.STRING, ViewPermissionAttribute::new),
KEEP_OPEN("KEEP-OPEN", ValueExtractor.BOOLEAN, KeepOpenAttribute::new),
ACTIONS("ACTIONS", ValueExtractor.STRING_LIST, ActionsAttribute::new),
ENCHANTMENTS("ENCHANTMENTS", ValueExtractor.STRING_LIST, EnchantmentsAttribute::new),
REQUIRED_ITEMS("REQUIRED-ITEMS", ValueExtractor.STRING_LIST, RequiredItemsAttribute::new);
private static final Map<String, AttributeType> parsersByAttributeName;
static {
parsersByAttributeName = new HashMap<>();
for (AttributeType attributeParser : values()) {
parsersByAttributeName.put(attributeParser.getAttributeName(), attributeParser);
}
}
private final String attributeName;
private final AttributeParser attributeParser;
<V> AttributeType(String attributeName, ValueExtractor<V> valueExtractor, AttributeFactory<V, ?> attributeFactory) {
this.attributeName = attributeName;
this.attributeParser = (ConfigSection config, String node, AttributeErrorHandler errorHandler) -> {
V configValue = valueExtractor.getValue(config, node);
return attributeFactory.create(configValue, errorHandler);
};
}
public String getAttributeName() {
return attributeName;
}
public AttributeParser getParser() {
return attributeParser;
}
@Override
public String getConfigPath() {
return attributeName;
}
public static AttributeType fromAttributeName(String attributeName) {
return parsersByAttributeName.get(attributeName);
}
@FunctionalInterface
private interface ValueExtractor<V> {
V getValue(ConfigSection config, String key) throws ConfigValueException;
ValueExtractor<Integer> INT = ConfigSection::getRequiredInt;
ValueExtractor<Double> DOUBLE = ConfigSection::getRequiredDouble;
ValueExtractor<Short> SHORT = ConfigSection::getRequiredShort;
ValueExtractor<Boolean> BOOLEAN = ConfigSection::getRequiredBoolean;
ValueExtractor<String> STRING = ConfigSection::getRequiredString;
ValueExtractor<List<String>> STRING_LIST = ConfigSection::getRequiredStringList;
}
@FunctionalInterface
private interface AttributeFactory<V, A extends IconAttribute> {
A create(V value, AttributeErrorHandler errorHandler) throws ParseException;
}
@FunctionalInterface
public interface AttributeParser {
IconAttribute parse(ConfigSection config, String node, AttributeErrorHandler errorHandler) throws ParseException, ConfigValueException;
}
}

View File

@ -19,72 +19,63 @@ import me.filoghost.chestcommands.config.framework.exception.ConfigValueExceptio
import me.filoghost.chestcommands.icon.InternalConfigurableIcon; import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.logging.ErrorMessages; import me.filoghost.chestcommands.logging.ErrorMessages;
import me.filoghost.chestcommands.parsing.ParseException; import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.attribute.ActionsAttribute;
import me.filoghost.chestcommands.parsing.attribute.AmountAttribute;
import me.filoghost.chestcommands.parsing.attribute.ApplicableIconAttribute; import me.filoghost.chestcommands.parsing.attribute.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.attribute.AttributeErrorHandler; import me.filoghost.chestcommands.parsing.attribute.AttributeErrorHandler;
import me.filoghost.chestcommands.parsing.attribute.BannerColorAttribute;
import me.filoghost.chestcommands.parsing.attribute.BannerPatternsAttribute;
import me.filoghost.chestcommands.parsing.attribute.ClickPermissionAttribute;
import me.filoghost.chestcommands.parsing.attribute.ClickPermissionMessageAttribute;
import me.filoghost.chestcommands.parsing.attribute.DurabilityAttribute;
import me.filoghost.chestcommands.parsing.attribute.EnchantmentsAttribute;
import me.filoghost.chestcommands.parsing.attribute.ExpLevelsAttribute;
import me.filoghost.chestcommands.parsing.attribute.IconAttribute; import me.filoghost.chestcommands.parsing.attribute.IconAttribute;
import me.filoghost.chestcommands.parsing.attribute.KeepOpenAttribute;
import me.filoghost.chestcommands.parsing.attribute.LeatherColorAttribute;
import me.filoghost.chestcommands.parsing.attribute.LoreAttribute;
import me.filoghost.chestcommands.parsing.attribute.MaterialAttribute;
import me.filoghost.chestcommands.parsing.attribute.NBTDataAttribute;
import me.filoghost.chestcommands.parsing.attribute.NameAttribute;
import me.filoghost.chestcommands.parsing.attribute.PositionAttribute;
import me.filoghost.chestcommands.parsing.attribute.PriceAttribute;
import me.filoghost.chestcommands.parsing.attribute.RequiredItemsAttribute;
import me.filoghost.chestcommands.parsing.attribute.SkullOwnerAttribute;
import me.filoghost.chestcommands.parsing.attribute.ViewPermissionAttribute;
import me.filoghost.chestcommands.util.Preconditions;
import me.filoghost.chestcommands.util.logging.ErrorCollector; import me.filoghost.chestcommands.util.logging.ErrorCollector;
import org.bukkit.Material;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
public class IconSettings { public class IconSettings {
private final Path menuFile; private final Path menuFile;
private final String iconName; private final String iconName;
private final Map<AttributeType, IconAttribute> attributes;
private PositionAttribute positionX; public IconSettings(Path menuFile, String iconName) {
private PositionAttribute positionY; this.menuFile = menuFile;
private MaterialAttribute materialAttribute; this.iconName = iconName;
private final List<ApplicableIconAttribute> applicableAttributes; this.attributes = new EnumMap<>(AttributeType.class);
}
public static final Map<String, AttributeParser> iconNodeHandlers = new HashMap<>(); public InternalConfigurableIcon createIcon() {
static { InternalConfigurableIcon icon = new InternalConfigurableIcon(Material.BEDROCK);
addIconNodeHandler(IconSettingsNode.POSITION_X, ValueExtractor.INT, PositionAttribute::new, IconSettings::setPositionX);
addIconNodeHandler(IconSettingsNode.POSITION_Y, ValueExtractor.INT, PositionAttribute::new, IconSettings::setPositionY);
addIconNodeHandler(IconSettingsNode.MATERIAL, ValueExtractor.STRING, MaterialAttribute::new, IconSettings::setMaterialAttribute);
addApplicableIconNodeHandler(IconSettingsNode.DURABILITY, ValueExtractor.SHORT, DurabilityAttribute::new); for (IconAttribute attribute : attributes.values()) {
addApplicableIconNodeHandler(IconSettingsNode.AMOUNT, ValueExtractor.INT, AmountAttribute::new); if (attribute instanceof ApplicableIconAttribute) {
addApplicableIconNodeHandler(IconSettingsNode.NAME, ValueExtractor.STRING, NameAttribute::new); ((ApplicableIconAttribute) attribute).apply(icon);
addApplicableIconNodeHandler(IconSettingsNode.LORE, ValueExtractor.STRING_LIST, LoreAttribute::new); }
addApplicableIconNodeHandler(IconSettingsNode.NBT_DATA, ValueExtractor.STRING, NBTDataAttribute::new); }
addApplicableIconNodeHandler(IconSettingsNode.LEATHER_COLOR, ValueExtractor.STRING, LeatherColorAttribute::new);
addApplicableIconNodeHandler(IconSettingsNode.SKULL_OWNER, ValueExtractor.STRING, SkullOwnerAttribute::new); return icon;
addApplicableIconNodeHandler(IconSettingsNode.BANNER_COLOR, ValueExtractor.STRING, BannerColorAttribute::new); }
addApplicableIconNodeHandler(IconSettingsNode.BANNER_PATTERNS, ValueExtractor.STRING_LIST, BannerPatternsAttribute::new);
addApplicableIconNodeHandler(IconSettingsNode.PRICE, ValueExtractor.DOUBLE, PriceAttribute::new); public IconAttribute getAttributeValue(AttributeType attributeType) {
addApplicableIconNodeHandler(IconSettingsNode.EXP_LEVELS, ValueExtractor.INT, ExpLevelsAttribute::new); return attributes.get(attributeType);
addApplicableIconNodeHandler(IconSettingsNode.CLICK_PERMISSION, ValueExtractor.STRING, ClickPermissionAttribute::new); }
addApplicableIconNodeHandler(IconSettingsNode.CLICK_PERMISSION_MESSAGE, ValueExtractor.STRING, ClickPermissionMessageAttribute::new);
addApplicableIconNodeHandler(IconSettingsNode.VIEW_PERMISSION, ValueExtractor.STRING, ViewPermissionAttribute::new); public void loadFrom(ConfigSection config, ErrorCollector errorCollector) {
addApplicableIconNodeHandler(IconSettingsNode.KEEP_OPEN, ValueExtractor.BOOLEAN, KeepOpenAttribute::new); for (String attributeName : config.getKeys(false)) {
addApplicableIconNodeHandler(IconSettingsNode.ACTIONS, ValueExtractor.STRING_LIST, ActionsAttribute::new); try {
addApplicableIconNodeHandler(IconSettingsNode.ENCHANTMENTS, ValueExtractor.STRING_LIST, EnchantmentsAttribute::new); AttributeType attributeType = AttributeType.fromAttributeName(attributeName);
addApplicableIconNodeHandler(IconSettingsNode.REQUIRED_ITEMS, ValueExtractor.STRING_LIST, RequiredItemsAttribute::new); if (attributeType == null) {
throw new ParseException(ErrorMessages.Parsing.unknownAttribute);
}
AttributeErrorHandler errorHandler = (String listElement, ParseException e) -> {
errorCollector.add(ErrorMessages.Menu.invalidAttributeListElement(this, attributeName, listElement), e);
};
IconAttribute iconAttribute = attributeType.getParser().parse(config, attributeName, errorHandler);
attributes.put(attributeType, iconAttribute);
} catch (ParseException | ConfigValueException e) {
errorCollector.add(ErrorMessages.Menu.invalidAttribute(this, attributeName), e);
}
}
} }
public Path getMenuFile() { public Path getMenuFile() {
@ -95,122 +86,4 @@ public class IconSettings {
return iconName; return iconName;
} }
public PositionAttribute getPositionX() {
return positionX;
}
private void setPositionX(PositionAttribute positionAttribute) {
this.positionX = positionAttribute;
}
public PositionAttribute getPositionY() {
return positionY;
}
private void setPositionY(PositionAttribute positionAttribute) {
this.positionY = positionAttribute;
}
public MaterialAttribute getMaterialAttribute() {
return materialAttribute;
}
private void setMaterialAttribute(MaterialAttribute materialAttribute) {
this.materialAttribute = materialAttribute;
}
public void addApplicableAttribute(ApplicableIconAttribute iconAttribute) {
applicableAttributes.add(iconAttribute);
}
public void applyAttributesTo(InternalConfigurableIcon icon) {
if (materialAttribute != null) {
materialAttribute.apply(icon);
}
for (ApplicableIconAttribute attribute : applicableAttributes) {
attribute.apply(icon);
}
}
public static <V, A extends ApplicableIconAttribute> void addApplicableIconNodeHandler(
String node,
ValueExtractor<V> valueExtractor,
AttributeFactory<V, A> attributeFactory) {
addIconNodeHandler(node, valueExtractor, attributeFactory, IconSettings::addApplicableAttribute);
}
public static <V, A extends IconAttribute> void addIconNodeHandler(
String node,
ValueExtractor<V> valueExtractor,
AttributeFactory<V, A> attributeFactory,
AttributeApplier<A> callback) {
addIconNodeHandler(node, (iconSettings, config, configNode, parseContext) -> {
V value = valueExtractor.getValue(config, configNode);
A iconAttribute = attributeFactory.create(value, parseContext);
callback.apply(iconSettings, iconAttribute);
});
}
private static void addIconNodeHandler(String node, AttributeParser iconNodeHandler) {
Preconditions.checkState(!iconNodeHandlers.containsKey(node), "Handler already exists for attribute " + node);
iconNodeHandlers.put(node, iconNodeHandler);
}
public IconSettings(Path menuFile, String iconName) {
this.menuFile = menuFile;
this.iconName = iconName;
this.applicableAttributes = new ArrayList<>();
}
public void loadFrom(ConfigSection config, ErrorCollector errorCollector) {
for (String attributeName : config.getKeys(false)) {
try {
AttributeParser attributeParser = iconNodeHandlers.get(attributeName);
if (attributeParser == null) {
throw new ParseException(ErrorMessages.Parsing.unknownAttribute);
}
attributeParser.parse(this, config, attributeName, (String listElement, ParseException e) -> {
errorCollector.add(ErrorMessages.Menu.invalidAttributeListElement(this, attributeName, listElement), e);
});
} catch (ParseException | ConfigValueException e) {
errorCollector.add(ErrorMessages.Menu.invalidAttribute(this, attributeName), e);
}
}
}
private interface ValueExtractor<V> {
V getValue(ConfigSection config, String key) throws ConfigValueException;
ValueExtractor<Integer> INT = ConfigSection::getRequiredInt;
ValueExtractor<Double> DOUBLE = ConfigSection::getRequiredDouble;
ValueExtractor<Short> SHORT = ConfigSection::getRequiredShort;
ValueExtractor<Boolean> BOOLEAN = ConfigSection::getRequiredBoolean;
ValueExtractor<String> STRING = ConfigSection::getRequiredString;
ValueExtractor<List<String>> STRING_LIST = ConfigSection::getRequiredStringList;
}
private interface AttributeFactory<V, A extends IconAttribute> {
A create(V value, AttributeErrorHandler errorHandler) throws ParseException;
}
private interface AttributeApplier<A extends IconAttribute> {
void apply(IconSettings iconSettings, A attribute);
}
private interface AttributeParser {
void parse(IconSettings iconSettings, ConfigSection config, String node, AttributeErrorHandler errorHandler) throws ParseException, ConfigValueException;
}
} }

View File

@ -1,41 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package me.filoghost.chestcommands.parsing.icon;
public class IconSettingsNode {
public static final String
POSITION_X = "POSITION-X",
POSITION_Y = "POSITION-Y",
MATERIAL = "MATERIAL",
AMOUNT = "AMOUNT",
DURABILITY = "DURABILITY",
NBT_DATA = "NBT-DATA",
NAME = "NAME",
LORE = "LORE",
ENCHANTMENTS = "ENCHANTMENTS",
LEATHER_COLOR = "COLOR",
SKULL_OWNER = "SKULL-OWNER",
BANNER_COLOR = "BANNER-COLOR",
BANNER_PATTERNS = "BANNER-PATTERNS",
ACTIONS = "ACTIONS",
PRICE = "PRICE",
EXP_LEVELS = "LEVELS",
REQUIRED_ITEMS = "REQUIRED-ITEMS",
CLICK_PERMISSION = "PERMISSION",
CLICK_PERMISSION_MESSAGE = "PERMISSION-MESSAGE",
VIEW_PERMISSION = "VIEW-PERMISSION",
KEEP_OPEN = "KEEP-OPEN";
}

View File

@ -18,18 +18,17 @@ import me.filoghost.chestcommands.action.Action;
import me.filoghost.chestcommands.config.framework.Config; import me.filoghost.chestcommands.config.framework.Config;
import me.filoghost.chestcommands.config.framework.ConfigSection; import me.filoghost.chestcommands.config.framework.ConfigSection;
import me.filoghost.chestcommands.config.framework.exception.ConfigValueException; import me.filoghost.chestcommands.config.framework.exception.ConfigValueException;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.logging.ErrorMessages; import me.filoghost.chestcommands.logging.ErrorMessages;
import me.filoghost.chestcommands.menu.InternalIconMenu; import me.filoghost.chestcommands.menu.InternalIconMenu;
import me.filoghost.chestcommands.parsing.ActionParser; import me.filoghost.chestcommands.parsing.ActionParser;
import me.filoghost.chestcommands.parsing.ItemStackParser; import me.filoghost.chestcommands.parsing.ItemStackParser;
import me.filoghost.chestcommands.parsing.ParseException; import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.attribute.PositionAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeType;
import me.filoghost.chestcommands.parsing.icon.IconSettings; import me.filoghost.chestcommands.parsing.icon.IconSettings;
import me.filoghost.chestcommands.parsing.icon.IconSettingsNode;
import me.filoghost.chestcommands.util.Colors; import me.filoghost.chestcommands.util.Colors;
import me.filoghost.chestcommands.util.logging.ErrorCollector; import me.filoghost.chestcommands.util.logging.ErrorCollector;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -55,26 +54,29 @@ public class MenuParser {
private static void tryAddIconToMenu(InternalIconMenu iconMenu, IconSettings iconSettings, ErrorCollector errorCollector) { private static void tryAddIconToMenu(InternalIconMenu iconMenu, IconSettings iconSettings, ErrorCollector errorCollector) {
if (iconSettings.getPositionX() == null) { PositionAttribute positionX = (PositionAttribute) iconSettings.getAttributeValue(AttributeType.POSITION_X);
errorCollector.add(ErrorMessages.Menu.missingAttribute(iconSettings, IconSettingsNode.POSITION_X)); PositionAttribute positionY = (PositionAttribute) iconSettings.getAttributeValue(AttributeType.POSITION_Y);
if (positionX == null) {
errorCollector.add(ErrorMessages.Menu.missingAttribute(iconSettings, AttributeType.POSITION_X));
return; return;
} }
if (iconSettings.getPositionY() == null) { if (positionY == null) {
errorCollector.add(ErrorMessages.Menu.missingAttribute(iconSettings, IconSettingsNode.POSITION_Y)); errorCollector.add(ErrorMessages.Menu.missingAttribute(iconSettings, AttributeType.POSITION_Y));
return; return;
} }
int row = iconSettings.getPositionY().getPosition() - 1; int row = positionY.getPosition() - 1;
int column = iconSettings.getPositionX().getPosition() - 1; int column = positionX.getPosition() - 1;
if (row < 0 || row >= iconMenu.getRowCount()) { if (row < 0 || row >= iconMenu.getRowCount()) {
errorCollector.add(ErrorMessages.Menu.invalidAttribute(iconSettings, IconSettingsNode.POSITION_Y)) errorCollector.add(ErrorMessages.Menu.invalidAttribute(iconSettings, AttributeType.POSITION_Y))
.appendMessage("it must be between 1 and " + iconMenu.getRowCount()); .appendMessage("it must be between 1 and " + iconMenu.getRowCount());
return; return;
} }
if (column < 0 || column >= iconMenu.getColumnCount()) { if (column < 0 || column >= iconMenu.getColumnCount()) {
errorCollector.add(ErrorMessages.Menu.invalidAttribute(iconSettings, IconSettingsNode.POSITION_X)) errorCollector.add(ErrorMessages.Menu.invalidAttribute(iconSettings, AttributeType.POSITION_X))
.appendMessage(("it must be between 1 and " + iconMenu.getColumnCount())); .appendMessage(("it must be between 1 and " + iconMenu.getColumnCount()));
return; return;
} }
@ -83,13 +85,11 @@ public class MenuParser {
errorCollector.add(ErrorMessages.Menu.iconOverridesAnother(iconSettings)); errorCollector.add(ErrorMessages.Menu.iconOverridesAnother(iconSettings));
} }
if (iconSettings.getMaterialAttribute() == null) { if (iconSettings.getAttributeValue(AttributeType.MATERIAL) == null) {
errorCollector.add(ErrorMessages.Menu.missingAttribute(iconSettings, IconSettingsNode.MATERIAL)); errorCollector.add(ErrorMessages.Menu.missingAttribute(iconSettings, AttributeType.MATERIAL));
} }
InternalConfigurableIcon icon = new InternalConfigurableIcon(Material.BEDROCK); iconMenu.setIcon(row, column, iconSettings.createIcon());
iconSettings.applyAttributesTo(icon);
iconMenu.setIcon(row, column, icon);
} }