Refactoring

This commit is contained in:
filoghost 2020-07-25 10:23:59 +02:00
parent 6a00d49e06
commit cf8e5da6bf
44 changed files with 178 additions and 232 deletions

View File

@ -48,6 +48,7 @@ import org.bukkit.entity.Player;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
public class ChestCommands extends BaseJavaPlugin {
@ -55,8 +56,8 @@ public class ChestCommands extends BaseJavaPlugin {
public static final String CHAT_PREFIX = ChatColor.DARK_GREEN + "[" + ChatColor.GREEN + "ChestCommands" + ChatColor.DARK_GREEN + "] " + ChatColor.GREEN;
private static ChestCommands instance;
private static Path dataFolderPath;
private ConfigManager configManager;
private MenuManager menuManager;
@ -85,10 +86,11 @@ public class ChestCommands extends BaseJavaPlugin {
System.setProperty("ChestCommandsLoaded", "true");
instance = this;
dataFolderPath = getDataFolder().toPath();
Log.setLogger(getLogger());
BackendAPI.setImplementation(new DefaultBackendAPI());
configManager = new ConfigManager(getDataFolder().toPath());
configManager = new ConfigManager(getDataFolderPath());
menuManager = new MenuManager();
settings = new Settings();
lang = new Lang();
@ -148,13 +150,15 @@ public class ChestCommands extends BaseJavaPlugin {
Bukkit.getScheduler().runTaskTimer(this, new TickingTask(), 1L, 1L);
}
public static Path getDataFolderPath() {
return dataFolderPath;
}
@Override
public void onDisable() {
closeAllMenus();
}
public ErrorCollector load() {
ErrorCollector errorCollector = new PrintableErrorCollector();
menuManager.clear();

View File

@ -23,8 +23,8 @@ public class BroadcastAction extends Action {
private final RelativeString message;
public BroadcastAction(String action) {
message = RelativeString.of(Colors.addColors(action));
public BroadcastAction(String serializedAction) {
message = RelativeString.of(Colors.addColors(serializedAction));
}
@Override

View File

@ -24,11 +24,11 @@ public class GiveMoneyAction extends Action {
private double moneyToGive;
public GiveMoneyAction(String action) {
public GiveMoneyAction(String serializedAction) {
try {
moneyToGive = NumberParser.getStrictlyPositiveDouble(action);
moneyToGive = NumberParser.getStrictlyPositiveDouble(serializedAction);
} catch (ParseException e) {
disable(ChatColor.RED + "Invalid money amount \"" + action + "\": " + e.getMessage());
disable(ChatColor.RED + "Invalid money amount \"" + serializedAction + "\": " + e.getMessage());
}
}

View File

@ -22,8 +22,8 @@ public class SendMessageAction extends Action {
private final RelativeString message;
public SendMessageAction(String action) {
message = RelativeString.of(Colors.addColors(action));
public SendMessageAction(String serializedAction) {
message = RelativeString.of(Colors.addColors(serializedAction));
}
@Override

View File

@ -92,16 +92,11 @@ public class ConfigManager extends BaseConfigManager {
return rootDataFolder.resolve("menu");
}
/**
* Returns a list of YML menu files.
*/
public List<Path> getMenuPaths() throws IOException {
public List<Path> getMenuFiles() throws IOException {
Preconditions.checkState(Files.isDirectory(getMenusFolder()), "menus folder doesn't exist");
try (Stream<Path> paths = Files.walk(getMenusFolder(), FileVisitOption.FOLLOW_LINKS)) {
return paths.filter(Files::isRegularFile)
.filter(this::isYmlPath)
.collect(Collectors.toList());
return paths.filter(this::isYamlFile).collect(Collectors.toList());
}
}
@ -111,16 +106,16 @@ public class ConfigManager extends BaseConfigManager {
public List<LoadedMenu> tryLoadMenus(ErrorCollector errorCollector) {
List<LoadedMenu> loadedMenus = new ArrayList<>();
List<Path> menuPaths;
List<Path> menuFiles;
try {
menuPaths = getMenuPaths();
menuFiles = getMenuFiles();
} catch (IOException e) {
errorCollector.add(ErrorMessages.Config.menuListIOException(getMenusFolder()), e);
return Collections.emptyList();
}
for (Path menuFile : menuPaths) {
for (Path menuFile : menuFiles) {
ConfigLoader menuConfigLoader = new ConfigLoader(rootDataFolder, menuFile);
try {
@ -134,8 +129,8 @@ public class ConfigManager extends BaseConfigManager {
return loadedMenus;
}
private boolean isYmlPath(Path path) {
return path.getFileName().toString().toLowerCase().endsWith(".yml");
private boolean isYamlFile(Path path) {
return Files.isRegularFile(path) && path.getFileName().toString().toLowerCase().endsWith(".yml");
}
}

View File

@ -32,9 +32,8 @@ public class CustomPlaceholders {
public void load(Config config, ErrorCollector errorCollector) {
placeholders.clear();
for (String key : config.getKeys(false)) {
String placeholder = key;
String replacement = Colors.addColors(config.getString(key));
for (String placeholder : config.getKeys(false)) {
String replacement = Colors.addColors(config.getString(placeholder));
if (placeholder.length() == 0) {
errorCollector.add(ErrorMessages.Config.emptyPlaceholder(config.getSourceFile()));
@ -50,14 +49,14 @@ public class CustomPlaceholders {
}
}
public List<String> replaceAll(List<String> input) {
public List<String> replacePlaceholders(List<String> input) {
if (input == null) {
return null;
}
return CollectionUtils.transform(input, this::replaceAll);
return CollectionUtils.transform(input, this::replacePlaceholders);
}
public String replaceAll(String input) {
public String replacePlaceholders(String input) {
if (input == null) {
return null;
}

View File

@ -26,6 +26,5 @@ public interface PluginHook {
default void checkEnabledState() {
Preconditions.checkState(isEnabled(), "Plugin hook " + getClass().getSimpleName() + " is not enabled");
}
}

View File

@ -18,11 +18,11 @@ import me.filoghost.chestcommands.action.Action;
import me.filoghost.chestcommands.action.OpenMenuAction;
import me.filoghost.chestcommands.api.ClickResult;
import me.filoghost.chestcommands.api.MenuInventory;
import me.filoghost.chestcommands.icon.requirement.PermissionChecker;
import me.filoghost.chestcommands.icon.requirement.RequiredExpLevel;
import me.filoghost.chestcommands.icon.requirement.RequiredItem;
import me.filoghost.chestcommands.icon.requirement.RequiredItems;
import me.filoghost.chestcommands.icon.requirement.RequiredMoney;
import me.filoghost.chestcommands.icon.requirement.RequiredPermission;
import me.filoghost.chestcommands.icon.requirement.Requirement;
import me.filoghost.chestcommands.util.Preconditions;
import me.filoghost.chestcommands.util.collection.CollectionUtils;
@ -35,9 +35,9 @@ import java.util.List;
public class InternalConfigurableIcon extends BaseConfigurableIcon implements RefreshableIcon {
private PermissionChecker viewPermission;
private RequiredPermission viewPermission;
private PermissionChecker clickPermission;
private RequiredPermission clickPermission;
private RequiredMoney requiredMoney;
private RequiredExpLevel requiredExpLevel;
private RequiredItems requiredItems;
@ -60,7 +60,7 @@ public class InternalConfigurableIcon extends BaseConfigurableIcon implements Re
}
public void setClickPermission(String permission) {
this.clickPermission = new PermissionChecker(permission);
this.clickPermission = new RequiredPermission(permission);
}
public void setNoClickPermissionMessage(String clickNoPermissionMessage) {
@ -68,7 +68,7 @@ public class InternalConfigurableIcon extends BaseConfigurableIcon implements Re
}
public void setViewPermission(String viewPermission) {
this.viewPermission = new PermissionChecker(viewPermission);
this.viewPermission = new RequiredPermission(viewPermission);
}
public void setRequiredMoney(double requiredMoney) {
@ -123,13 +123,14 @@ public class InternalConfigurableIcon extends BaseConfigurableIcon implements Re
@Override
public ClickResult onClick(MenuInventory menuInventory, Player player) {
// Check all the requirements
boolean hasAllRequirements = Requirement.hasAll(player, clickPermission, requiredMoney, requiredExpLevel, requiredItems);
Requirement[] requirements = {clickPermission, requiredMoney, requiredExpLevel, requiredItems};
boolean hasAllRequirements = Requirement.hasAllCosts(player, requirements);
if (!hasAllRequirements) {
return clickResult;
}
// If all requirements are satisfied, take their cost
boolean takenAllCosts = Requirement.takeAllCosts(player, clickPermission, requiredMoney, requiredExpLevel, requiredItems);
boolean takenAllCosts = Requirement.takeAllCosts(player, requirements);
if (!takenAllCosts) {
return clickResult;
}

View File

@ -26,10 +26,6 @@ public class RequiredExpLevel implements Requirement {
Preconditions.checkArgument(levels > 0, "levels must be positive");
this.levels = levels;
}
public int getLevels() {
return levels;
}
@Override
public boolean hasCost(Player player) {

View File

@ -30,10 +30,6 @@ public class RequiredItems implements Requirement {
Preconditions.notEmpty(items, "items");
this.items = ImmutableList.copyOf(items);
}
public List<RequiredItem> geItems() {
return items;
}
@Override
public boolean hasCost(Player player) {

View File

@ -28,10 +28,6 @@ public class RequiredMoney implements Requirement {
Preconditions.checkArgument(moneyAmount > 0.0, "money amount must be positive");
this.moneyAmount = moneyAmount;
}
public double getAmount() {
return moneyAmount;
}
@Override
public boolean hasCost(Player player) {

View File

@ -18,13 +18,13 @@ import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.util.Strings;
import org.bukkit.entity.Player;
public class PermissionChecker implements Requirement {
public class RequiredPermission implements Requirement {
private final String permission;
private final boolean negated;
private String noPermissionMessage;
public PermissionChecker(String permission) {
public RequiredPermission(String permission) {
if (permission != null) {
permission = permission.trim();
}

View File

@ -22,7 +22,7 @@ public interface Requirement {
boolean takeCost(Player player);
static boolean hasAll(Player player, Requirement... requirements) {
static boolean hasAllCosts(Player player, Requirement... requirements) {
for (Requirement requirement : requirements) {
if (requirement != null && !requirement.hasCost(player)) {
return false;

View File

@ -80,7 +80,7 @@ public enum Upgrade {
private static List<Path> getMenuFiles(ConfigManager configManager) throws UpgradeTaskException {
try {
return configManager.getMenuPaths();
return configManager.getMenuFiles();
} catch (IOException e) {
throw new UpgradeTaskException(ErrorMessages.Upgrade.menuListIOException, e);
}

View File

@ -131,7 +131,7 @@ public class MenuNodeExpandUpgradeTask extends UpgradeTask {
private void expandInlineList(ConfigSection config, String node, String separator) {
if (config.isSet(node)) {
if (config.isString(node)) {
config.set(node, getSeparatedValues(config.getString(node), separator));
config.set(node, splitListElements(config.getString(node), separator));
setSaveRequired();
}
}
@ -144,7 +144,7 @@ public class MenuNodeExpandUpgradeTask extends UpgradeTask {
}
}
private List<String> getSeparatedValues(String input, String separator) {
private List<String> splitListElements(String input, String separator) {
if (separator == null || separator.length() == 0) {
separator = ";";
}

View File

@ -17,6 +17,7 @@ package me.filoghost.chestcommands.listener;
import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.Permissions;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
@ -25,14 +26,17 @@ public class JoinListener implements Listener {
@EventHandler
public void onJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
if (ChestCommands.getLastLoadErrors().hasErrors() && event.getPlayer().hasPermission(Permissions.SEE_ERRORS)) {
event.getPlayer().sendMessage(ChestCommands.CHAT_PREFIX + ChatColor.RED + "The plugin found " + ChestCommands.getLastLoadErrors().getErrorsCount() + " error(s) last time it was loaded. You can see them by doing \"/cc reload\" in the console.");
if (ChestCommands.getLastLoadErrors().hasErrors() && player.hasPermission(Permissions.SEE_ERRORS)) {
player.sendMessage(
ChestCommands.CHAT_PREFIX + ChatColor.RED + "The plugin found " + ChestCommands.getLastLoadErrors().getErrorsCount()
+ " error(s) last time it was loaded. You can see them by doing \"/cc reload\" in the console.");
}
if (ChestCommands.hasNewVersion() && ChestCommands.getSettings().update_notifications && event.getPlayer().hasPermission(Permissions.UPDATE_NOTIFICATIONS)) {
event.getPlayer().sendMessage(ChestCommands.CHAT_PREFIX + "Found an update: " + ChestCommands.getNewVersion() + ". Download:");
event.getPlayer().sendMessage(ChatColor.DARK_GREEN + ">> " + ChatColor.GREEN + "http://dev.bukkit.org/bukkit-plugins/chest-commands");
if (ChestCommands.hasNewVersion() && ChestCommands.getSettings().update_notifications && player.hasPermission(Permissions.UPDATE_NOTIFICATIONS)) {
player.sendMessage(ChestCommands.CHAT_PREFIX + "Found an update: " + ChestCommands.getNewVersion() + ". Download:");
player.sendMessage(ChatColor.DARK_GREEN + ">> " + ChatColor.GREEN + "http://dev.bukkit.org/bukkit-plugins/chest-commands");
}
}

View File

@ -14,6 +14,7 @@
*/
package me.filoghost.chestcommands.logging;
import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.config.framework.mapped.MappedConfig;
import me.filoghost.chestcommands.parsing.icon.IconSettings;
@ -26,7 +27,7 @@ public class ErrorMessages {
public static final String readIOException = "I/O exception while reading file";
public static final String createDefaultIOException = "I/O exception while creating default file";
public static final String writeDataIOException = "I/O exception while writing data to file";
public static final String createDataFolderIOException = "Plugin failed to load, couldn't create data folder";
public static final String createDataFolderIOException = "plugin failed to load, couldn't create data folder";
public static final String invalidYamlSyntax = "invalid YAML syntax";
public static final String valueNotSet = "value is not set";
@ -202,8 +203,14 @@ public class ErrorMessages {
}
}
private static String formatPath(Path path) {
return path.subpath(2, path.getNameCount()).toString(); // Remove "/plugins/ChestCommands" prefix
if (path.startsWith(ChestCommands.getDataFolderPath())) {
// Remove "/plugins/ChestCommands" prefix
return path.subpath(ChestCommands.getDataFolderPath().getNameCount(), path.getNameCount()).toString();
} else {
return path.toString();
}
}
}

View File

@ -36,7 +36,7 @@ import java.util.regex.Pattern;
public class ActionParser {
private static final Map<Pattern, IconCommandFactory> actionsByPrefix = new HashMap<>();
private static final Map<Pattern, ActionFactory> actionsByPrefix = new HashMap<>();
static {
actionsByPrefix.put(actionPattern("console:"), ConsoleCommandAction::new);
@ -56,20 +56,20 @@ public class ActionParser {
}
public static Action parseAction(String input) {
for (Entry<Pattern, IconCommandFactory> entry : actionsByPrefix.entrySet()) {
for (Entry<Pattern, ActionFactory> entry : actionsByPrefix.entrySet()) {
Matcher matcher = entry.getKey().matcher(input);
if (matcher.find()) {
// Remove the action prefix and trim the spaces
String serializedAction = matcher.replaceFirst("").trim();
return entry.getValue().create(ChestCommands.getCustomPlaceholders().replaceAll(serializedAction));
return entry.getValue().create(ChestCommands.getCustomPlaceholders().replacePlaceholders(serializedAction));
}
}
return new PlayerCommandAction(ChestCommands.getCustomPlaceholders().replaceAll(input)); // Default action, no match found
return new PlayerCommandAction(ChestCommands.getCustomPlaceholders().replacePlaceholders(input)); // Default action, no match found
}
private interface IconCommandFactory {
private interface ActionFactory {
Action create(String actionString);

View File

@ -12,13 +12,11 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.action.Action;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ActionParser;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
import java.util.ArrayList;
import java.util.List;
@ -27,7 +25,7 @@ public class ActionsAttribute implements ApplicableIconAttribute {
private final List<Action> actions;
public ActionsAttribute(List<String> serializedActions, AttributeErrorCollector attributeErrorCollector) {
public ActionsAttribute(List<String> serializedActions, AttributeErrorHandler errorHandler) {
actions = new ArrayList<>();
for (String serializedAction : serializedActions) {

View File

@ -12,19 +12,17 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.logging.ErrorMessages;
import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
public class AmountAttribute implements ApplicableIconAttribute {
private final int amount;
public AmountAttribute(int amount, AttributeErrorCollector attributeErrorCollector) throws ParseException {
public AmountAttribute(int amount, AttributeErrorHandler errorHandler) throws ParseException {
if (amount < 0) {
throw new ParseException(ErrorMessages.Parsing.zeroOrPositive);
}

View File

@ -12,7 +12,7 @@
* 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;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;

View File

@ -0,0 +1,23 @@
/*
* 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.attribute;
import me.filoghost.chestcommands.parsing.ParseException;
public interface AttributeErrorHandler {
void onListElementError(String listElement, ParseException e);
}

View File

@ -12,20 +12,18 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ItemMetaParser;
import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
import org.bukkit.DyeColor;
public class BannerColorAttribute implements ApplicableIconAttribute {
private final DyeColor dyeColor;
public BannerColorAttribute(String serializedDyeColor, AttributeErrorCollector attributeErrorCollector) throws ParseException {
public BannerColorAttribute(String serializedDyeColor, AttributeErrorHandler errorHandler) throws ParseException {
this.dyeColor = ItemMetaParser.parseDyeColor(serializedDyeColor);
}

View File

@ -12,13 +12,11 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ItemMetaParser;
import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
import org.bukkit.block.banner.Pattern;
import java.util.ArrayList;
@ -28,7 +26,7 @@ public class BannerPatternsAttribute implements ApplicableIconAttribute {
private final List<Pattern> patterns;
public BannerPatternsAttribute(List<String> serializedPatterns, AttributeErrorCollector attributeErrorCollector) {
public BannerPatternsAttribute(List<String> serializedPatterns, AttributeErrorHandler errorHandler) {
patterns = new ArrayList<>();
for (String serializedPattern : serializedPatterns) {
@ -40,7 +38,7 @@ public class BannerPatternsAttribute implements ApplicableIconAttribute {
Pattern pattern = ItemMetaParser.parseBannerPattern(serializedPattern);
patterns.add(pattern);
} catch (ParseException e) {
attributeErrorCollector.addListElementError(serializedPattern, e);
errorHandler.onListElementError(serializedPattern, e);
}
}

View File

@ -12,17 +12,15 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
public class ClickPermissionAttribute implements ApplicableIconAttribute {
private final String clickPermission;
public ClickPermissionAttribute(String clickPermission, AttributeErrorCollector attributeErrorCollector) {
public ClickPermissionAttribute(String clickPermission, AttributeErrorHandler errorHandler) {
this.clickPermission = clickPermission;
}

View File

@ -12,17 +12,15 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
public class ClickPermissionMessageAttribute implements ApplicableIconAttribute {
private final String clickPermissionMessage;
public ClickPermissionMessageAttribute(String clickPermissionMessage, AttributeErrorCollector attributeErrorCollector) {
public ClickPermissionMessageAttribute(String clickPermissionMessage, AttributeErrorHandler errorHandler) {
this.clickPermissionMessage = clickPermissionMessage;
}

View File

@ -12,17 +12,15 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
public class DurabilityAttribute implements ApplicableIconAttribute {
private final short durability;
public DurabilityAttribute(short durability, AttributeErrorCollector attributeErrorCollector) {
public DurabilityAttribute(short durability, AttributeErrorHandler errorHandler) {
this.durability = durability;
}

View File

@ -12,13 +12,11 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.EnchantmentParser;
import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
import org.bukkit.enchantments.Enchantment;
import java.util.HashMap;
@ -29,7 +27,7 @@ public class EnchantmentsAttribute implements ApplicableIconAttribute {
private final Map<Enchantment, Integer> enchantments;
public EnchantmentsAttribute(List<String> serializedEnchantments, AttributeErrorCollector attributeErrorCollector) {
public EnchantmentsAttribute(List<String> serializedEnchantments, AttributeErrorHandler errorHandler) {
enchantments = new HashMap<>();
for (String serializedEnchantment : serializedEnchantments) {
@ -41,7 +39,7 @@ public class EnchantmentsAttribute implements ApplicableIconAttribute {
EnchantmentParser.EnchantmentDetails enchantment = EnchantmentParser.parseEnchantment(serializedEnchantment);
enchantments.put(enchantment.getEnchantment(), enchantment.getLevel());
} catch (ParseException e) {
attributeErrorCollector.addListElementError(serializedEnchantment, e);
errorHandler.onListElementError(serializedEnchantment, e);
}
}
}

View File

@ -12,19 +12,17 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.logging.ErrorMessages;
import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
public class ExpLevelsAttribute implements ApplicableIconAttribute {
private final int expLevels;
public ExpLevelsAttribute(int expLevels, AttributeErrorCollector attributeErrorCollector) throws ParseException {
public ExpLevelsAttribute(int expLevels, AttributeErrorHandler errorHandler) throws ParseException {
if (expLevels < 0) {
throw new ParseException(ErrorMessages.Parsing.zeroOrPositive);
}

View File

@ -12,7 +12,7 @@
* 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;
package me.filoghost.chestcommands.parsing.attribute;
public interface IconAttribute {

View File

@ -12,18 +12,16 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.api.ClickResult;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
public class KeepOpenAttribute implements ApplicableIconAttribute {
private final ClickResult clickResult;
public KeepOpenAttribute(boolean keepOpen, AttributeErrorCollector attributeErrorCollector) {
public KeepOpenAttribute(boolean keepOpen, AttributeErrorHandler errorHandler) {
if (keepOpen) {
this.clickResult = ClickResult.KEEP_OPEN;
} else {

View File

@ -12,20 +12,18 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ItemMetaParser;
import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
import org.bukkit.Color;
public class LeatherColorAttribute implements ApplicableIconAttribute {
private final Color color;
public LeatherColorAttribute(String serializedColor, AttributeErrorCollector attributeErrorCollector) throws ParseException {
public LeatherColorAttribute(String serializedColor, AttributeErrorHandler errorHandler) throws ParseException {
this.color = ItemMetaParser.parseRGBColor(serializedColor);
}

View File

@ -12,12 +12,10 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
import me.filoghost.chestcommands.util.Colors;
import me.filoghost.chestcommands.util.collection.CollectionUtils;
import org.bukkit.ChatColor;
@ -28,8 +26,8 @@ public class LoreAttribute implements ApplicableIconAttribute {
private final List<String> lore;
public LoreAttribute(List<String> lore, AttributeErrorCollector attributeErrorCollector) {
this.lore = ChestCommands.getCustomPlaceholders().replaceAll(colorLore(lore));
public LoreAttribute(List<String> lore, AttributeErrorHandler errorHandler) {
this.lore = ChestCommands.getCustomPlaceholders().replacePlaceholders(colorLore(lore));
}
private List<String> colorLore(List<String> input) {

View File

@ -12,13 +12,11 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.logging.ErrorMessages;
import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
import me.filoghost.chestcommands.util.MaterialsHelper;
import org.bukkit.Material;
@ -28,7 +26,7 @@ public class MaterialAttribute implements ApplicableIconAttribute {
private final Material material;
public MaterialAttribute(String serializedMaterial, AttributeErrorCollector attributeErrorCollector) throws ParseException {
public MaterialAttribute(String serializedMaterial, AttributeErrorHandler errorHandler) throws ParseException {
Optional<Material> material = MaterialsHelper.matchMaterial(serializedMaterial);
if (!material.isPresent() || MaterialsHelper.isAir(material.get())) {

View File

@ -12,12 +12,10 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
import me.filoghost.chestcommands.util.nbt.parser.MojangsonParseException;
import me.filoghost.chestcommands.util.nbt.parser.MojangsonParser;
@ -25,7 +23,7 @@ public class NBTDataAttribute implements ApplicableIconAttribute {
private final String nbtData;
public NBTDataAttribute(String nbtData, AttributeErrorCollector attributeErrorCollector) throws ParseException {
public NBTDataAttribute(String nbtData, AttributeErrorHandler errorHandler) throws ParseException {
try {
// Check that NBT syntax is valid before applying it to the icon
MojangsonParser.parse(nbtData);

View File

@ -12,12 +12,10 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.ChestCommands;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
import me.filoghost.chestcommands.util.Colors;
import org.bukkit.ChatColor;
@ -25,8 +23,8 @@ public class NameAttribute implements ApplicableIconAttribute {
private final String name;
public NameAttribute(String name, AttributeErrorCollector attributeErrorCollector) {
this.name = ChestCommands.getCustomPlaceholders().replaceAll(colorName(name));
public NameAttribute(String name, AttributeErrorHandler errorHandler) {
this.name = ChestCommands.getCustomPlaceholders().replacePlaceholders(colorName(name));
}
private String colorName(String input) {

View File

@ -12,16 +12,13 @@
* 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.attributes;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
import me.filoghost.chestcommands.parsing.icon.IconAttribute;
package me.filoghost.chestcommands.parsing.attribute;
public class PositionAttribute implements IconAttribute {
private final int position;
public PositionAttribute(int position, AttributeErrorCollector attributeErrorCollector) {
public PositionAttribute(int position, AttributeErrorHandler errorHandler) {
this.position = position;
}

View File

@ -12,19 +12,17 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.logging.ErrorMessages;
import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
public class PriceAttribute implements ApplicableIconAttribute {
private final double price;
public PriceAttribute(double price, AttributeErrorCollector attributeErrorCollector) throws ParseException {
public PriceAttribute(double price, AttributeErrorHandler errorHandler) throws ParseException {
if (price < 0) {
throw new ParseException(ErrorMessages.Parsing.zeroOrPositive);
}

View File

@ -12,14 +12,12 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.icon.requirement.RequiredItem;
import me.filoghost.chestcommands.parsing.ItemStackParser;
import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
import java.util.ArrayList;
import java.util.List;
@ -28,7 +26,7 @@ public class RequiredItemsAttribute implements ApplicableIconAttribute {
private final List<RequiredItem> requiredItems;
public RequiredItemsAttribute(List<String> serializedRequiredItems, AttributeErrorCollector attributeErrorCollector) {
public RequiredItemsAttribute(List<String> serializedRequiredItems, AttributeErrorHandler errorHandler) {
requiredItems = new ArrayList<>();
for (String serializedItem : serializedRequiredItems) {
@ -40,7 +38,7 @@ public class RequiredItemsAttribute implements ApplicableIconAttribute {
}
requiredItems.add(requiredItem);
} catch (ParseException e) {
attributeErrorCollector.addListElementError(serializedItem, e);
errorHandler.onListElementError(serializedItem, e);
}
}
}

View File

@ -12,17 +12,15 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
public class SkullOwnerAttribute implements ApplicableIconAttribute {
private final String skullOwner;
public SkullOwnerAttribute(String skullOwner, AttributeErrorCollector attributeErrorCollector) {
public SkullOwnerAttribute(String skullOwner, AttributeErrorHandler errorHandler) {
this.skullOwner = skullOwner;
}

View File

@ -12,17 +12,15 @@
* 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.attributes;
package me.filoghost.chestcommands.parsing.attribute;
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.parsing.icon.ApplicableIconAttribute;
import me.filoghost.chestcommands.parsing.icon.AttributeErrorCollector;
public class ViewPermissionAttribute implements ApplicableIconAttribute {
private final String viewPermission;
public ViewPermissionAttribute(String viewPermission, AttributeErrorCollector attributeErrorCollector) {
public ViewPermissionAttribute(String viewPermission, AttributeErrorHandler errorHandler) {
this.viewPermission = viewPermission;
}

View File

@ -1,37 +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;
import me.filoghost.chestcommands.logging.ErrorMessages;
import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.util.logging.ErrorCollector;
public class AttributeErrorCollector {
private final ErrorCollector errorCollector;
private final IconSettings iconSettings;
private final String attributeName;
public AttributeErrorCollector(ErrorCollector errorCollector, IconSettings iconSettings, String attributeName) {
this.errorCollector = errorCollector;
this.iconSettings = iconSettings;
this.attributeName = attributeName;
}
public void addListElementError(String listElement, ParseException e) {
errorCollector.add(ErrorMessages.Menu.invalidAttributeListElement(iconSettings, attributeName, listElement), e);
}
}

View File

@ -19,26 +19,29 @@ import me.filoghost.chestcommands.config.framework.exception.ConfigValueExceptio
import me.filoghost.chestcommands.icon.InternalConfigurableIcon;
import me.filoghost.chestcommands.logging.ErrorMessages;
import me.filoghost.chestcommands.parsing.ParseException;
import me.filoghost.chestcommands.parsing.icon.attributes.ActionsAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.AmountAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.BannerColorAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.BannerPatternsAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.ClickPermissionAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.ClickPermissionMessageAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.DurabilityAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.EnchantmentsAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.ExpLevelsAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.KeepOpenAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.LeatherColorAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.LoreAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.MaterialAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.NBTDataAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.NameAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.PositionAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.PriceAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.RequiredItemsAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.SkullOwnerAttribute;
import me.filoghost.chestcommands.parsing.icon.attributes.ViewPermissionAttribute;
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.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 me.filoghost.chestcommands.util.Preconditions;
import me.filoghost.chestcommands.util.logging.ErrorCollector;
@ -58,7 +61,7 @@ public class IconSettings {
private MaterialAttribute materialAttribute;
private final List<ApplicableIconAttribute> applicableAttributes;
public static final Map<String, IconNodeHandler> iconNodeHandlers = new HashMap<>();
public static final Map<String, AttributeParser> iconNodeHandlers = new HashMap<>();
static {
addIconNodeHandler(IconSettingsNode.POSITION_X, ValueExtractor.INT, PositionAttribute::new, IconSettings::setPositionX);
addIconNodeHandler(IconSettingsNode.POSITION_Y, ValueExtractor.INT, PositionAttribute::new, IconSettings::setPositionY);
@ -141,7 +144,7 @@ public class IconSettings {
String node,
ValueExtractor<V> valueExtractor,
AttributeFactory<V, A> attributeFactory,
AttributeCallback<A> callback) {
AttributeApplier<A> callback) {
addIconNodeHandler(node, (iconSettings, config, configNode, parseContext) -> {
V value = valueExtractor.getValue(config, configNode);
A iconAttribute = attributeFactory.create(value, parseContext);
@ -149,7 +152,7 @@ public class IconSettings {
});
}
private static void addIconNodeHandler(String node, IconNodeHandler iconNodeHandler) {
private static void addIconNodeHandler(String node, AttributeParser iconNodeHandler) {
Preconditions.checkState(!iconNodeHandlers.containsKey(node), "Handler already exists for attribute " + node);
iconNodeHandlers.put(node, iconNodeHandler);
}
@ -161,22 +164,24 @@ public class IconSettings {
}
public void loadFrom(ConfigSection config, ErrorCollector errorCollector) {
for (String attributeKey : config.getKeys(false)) {
for (String attributeName : config.getKeys(false)) {
try {
IconNodeHandler nodeHandler = iconNodeHandlers.get(attributeKey);
if (nodeHandler == null) {
AttributeParser attributeParser = iconNodeHandlers.get(attributeName);
if (attributeParser == null) {
throw new ParseException(ErrorMessages.Parsing.unknownAttribute);
}
AttributeErrorCollector attributeErrorCollector = new AttributeErrorCollector(errorCollector, this, attributeKey);
nodeHandler.handle(this, config, attributeKey, attributeErrorCollector);
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, attributeKey), e);
errorCollector.add(ErrorMessages.Menu.invalidAttribute(this, attributeName), e);
}
}
}
private interface ValueExtractor<V> {
V getValue(ConfigSection config, String key) throws ConfigValueException;
@ -192,21 +197,20 @@ public class IconSettings {
private interface AttributeFactory<V, A extends IconAttribute> {
A create(V value, AttributeErrorCollector attributeErrorCollector) throws ParseException;
A create(V value, AttributeErrorHandler errorHandler) throws ParseException;
}
private interface AttributeCallback<A extends IconAttribute> {
private interface AttributeApplier<A extends IconAttribute> {
void apply(IconSettings iconSettings, A attribute);
}
private interface IconNodeHandler {
private interface AttributeParser {
void handle(IconSettings iconSettings, ConfigSection config, String node, AttributeErrorCollector attributeErrorCollector) throws ParseException, ConfigValueException;
void parse(IconSettings iconSettings, ConfigSection config, String node, AttributeErrorHandler errorHandler) throws ParseException, ConfigValueException;
}
}

View File

@ -39,22 +39,22 @@ public enum DefaultPlaceholders implements Placeholder {
});
private final String text;
private final Function<Player, String> getReplacementFunction;
private final String placeholderText;
private final Function<Player, String> placeholderReplacer;
DefaultPlaceholders(String text, Function<Player, String> getReplacementFunction) {
this.text = text;
this.getReplacementFunction = getReplacementFunction;
DefaultPlaceholders(String placeholderText, Function<Player, String> placeholderReplacer) {
this.placeholderText = placeholderText;
this.placeholderReplacer = placeholderReplacer;
}
@Override
public String getPlaceholderText() {
return text;
return placeholderText;
}
@Override
public String getReplacementText(Player player) {
return getReplacementFunction.apply(player);
return placeholderReplacer.apply(player);
}
}