mirror of
https://github.com/SimplexDevelopment/FreedomNetworkSuite.git
synced 2024-12-22 11:37:38 +00:00
Minor tweaks to GenericConfig & ContextProvider
# Changes: - Changed Configuration#getList(String, Class) to Configuration#getCollection(String, Class) - Renamed GenericConfiguration -> GenericConfig - Implemented semantics for GenericConfig#getCollection and GenericConfig#getStringList - Adjusted return value of ContextProvider#fromString to return Optional<T> instead of @Nullable T - Adjusted classes which used previous API methods to use the newly updated ones.
This commit is contained in:
parent
26f4e0746b
commit
4681fc9596
@ -32,6 +32,7 @@ import fns.patchwork.utils.logging.FNS4J;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -156,50 +157,19 @@ public final class BukkitDelegate extends Command implements PluginIdentifiableC
|
||||
if (argTypes.length > args.length)
|
||||
return;
|
||||
|
||||
final Player p = (sender instanceof Player player) ? player : null;
|
||||
|
||||
final Object[] objects = new Object[argTypes.length + 1];
|
||||
|
||||
for (int i = 0; i < argTypes.length; i++)
|
||||
{
|
||||
final Class<?> argType = argTypes[i];
|
||||
final String arg = args[i];
|
||||
parseArguments(args, provider, argTypes, objects);
|
||||
|
||||
if (argType.equals(String.class))
|
||||
{
|
||||
if (i == argTypes.length - 1)
|
||||
{
|
||||
final String[] reasonArgs = Arrays.copyOfRange(args, i, args.length - 1);
|
||||
final String reason = String.join(" ", reasonArgs);
|
||||
objects[i] = reason;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (argType.equals(Location.class))
|
||||
{
|
||||
final String[] locationArgs = Arrays.copyOfRange(args, i, i + 3);
|
||||
final String location = String.join(" ", locationArgs);
|
||||
objects[i] = location;
|
||||
}
|
||||
|
||||
final Object obj = provider.fromString(arg, argType);
|
||||
if (obj == null)
|
||||
{
|
||||
FNS4J.getLogger("Datura")
|
||||
.error("Failed to parse argument " + arg + " for type " + argType.getName());
|
||||
return;
|
||||
}
|
||||
objects[i] = obj;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (noConsole)
|
||||
{
|
||||
command.getSubcommands()
|
||||
.get(node)
|
||||
.invoke(command, (Player) sender, objects);
|
||||
.invoke(command, p, objects);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -215,11 +185,55 @@ public final class BukkitDelegate extends Command implements PluginIdentifiableC
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> tabComplete(final CommandSender sender, final String alias, final String[] args)
|
||||
private void parseArguments(@NotNull String @NotNull [] args,
|
||||
ContextProvider provider,
|
||||
Class<?>[] argTypes,
|
||||
Object[] objects)
|
||||
{
|
||||
for (int i = 0; i < argTypes.length; i++)
|
||||
{
|
||||
final Class<?> argType = argTypes[i];
|
||||
String arg = args[i];
|
||||
|
||||
boolean wasResolved = false;
|
||||
|
||||
if (argType.equals(String.class) && (i == argTypes.length - 1))
|
||||
{
|
||||
final String[] reasonArgs = Arrays.copyOfRange(args, i, args.length - 1);
|
||||
final String reason = String.join(" ", reasonArgs);
|
||||
objects[i] = reason;
|
||||
wasResolved = true;
|
||||
}
|
||||
|
||||
if (argType.equals(Location.class))
|
||||
{
|
||||
final String[] locationArgs = Arrays.copyOfRange(args, i, i + 3);
|
||||
arg = String.join(" ", locationArgs);
|
||||
}
|
||||
|
||||
if (!wasResolved)
|
||||
{
|
||||
final Optional<?> obj = provider.fromString(arg, argType);
|
||||
if (obj.isEmpty())
|
||||
{
|
||||
FNS4J.getLogger("Datura")
|
||||
.error("Failed to parse argument " + arg + " for type " + argType.getName());
|
||||
continue;
|
||||
}
|
||||
objects[i] = obj.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<String> tabComplete(final @NotNull CommandSender sender, final @NotNull String alias,
|
||||
final String[] args)
|
||||
{
|
||||
final Set<Completion> completions = command.getCompletions();
|
||||
final List<String> results = new ArrayList<>();
|
||||
final Set<Completion> completions = command.getCompletions();
|
||||
|
||||
if (completions == null || completions.isEmpty())
|
||||
return results;
|
||||
|
||||
if (args.length == 0)
|
||||
{
|
||||
|
@ -25,6 +25,7 @@ package fns.patchwork.config;
|
||||
|
||||
import fns.patchwork.provider.Context;
|
||||
import fns.patchwork.provider.ContextProvider;
|
||||
import java.util.Collection;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
import java.io.File;
|
||||
@ -87,7 +88,7 @@ public interface Configuration
|
||||
* @param clazz The class of the type.
|
||||
* @return The List object.
|
||||
*/
|
||||
<T> @Unmodifiable List<T> getList(String path, Class<T> clazz);
|
||||
<T> @Unmodifiable Collection<T> getCollection(String path, Class<T> clazz);
|
||||
|
||||
/**
|
||||
* Gets a List object from the associated path. The List that is returned will be the String values which are stored
|
||||
|
@ -26,7 +26,9 @@ package fns.patchwork.config;
|
||||
import com.electronwill.nightconfig.core.Config;
|
||||
import com.electronwill.nightconfig.core.ConfigFormat;
|
||||
import com.electronwill.nightconfig.core.UnmodifiableConfig;
|
||||
import fns.patchwork.provider.ContextProvider;
|
||||
import fns.patchwork.utils.FileUtils;
|
||||
import fns.patchwork.utils.logging.FNS4J;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
@ -34,26 +36,28 @@ import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
public final class GenericConfiguration implements Configuration
|
||||
public final class GenericConfig implements Configuration
|
||||
{
|
||||
private static final ContextProvider PROVIDER = new ContextProvider();
|
||||
private final File configFile;
|
||||
private final String fileName;
|
||||
private final Config config;
|
||||
private final ConfigType configType;
|
||||
|
||||
public GenericConfiguration(@NotNull final ConfigType configType,
|
||||
@Nullable final JavaPlugin plugin,
|
||||
@NotNull final File dataFolder,
|
||||
@NotNull final String fileName,
|
||||
final boolean isConcurrent) throws IOException
|
||||
public GenericConfig(@NotNull final ConfigType configType,
|
||||
@Nullable final JavaPlugin plugin,
|
||||
@NotNull final File dataFolder,
|
||||
@NotNull final String fileName,
|
||||
final boolean isConcurrent) throws IOException
|
||||
{
|
||||
if (!fileName.endsWith(configType.getExtension()))
|
||||
throw new IllegalArgumentException("File name must end with " + configType.getExtension() + "!");
|
||||
@ -78,20 +82,20 @@ public final class GenericConfiguration implements Configuration
|
||||
this.load();
|
||||
}
|
||||
|
||||
public GenericConfiguration(final ConfigType type, final File dataFolder, final String fileName)
|
||||
public GenericConfig(final ConfigType type, final File dataFolder, final String fileName)
|
||||
throws IOException
|
||||
{
|
||||
this(type, null, dataFolder, fileName, false);
|
||||
}
|
||||
|
||||
public GenericConfiguration(final ConfigType type, final JavaPlugin plugin, final String fileName)
|
||||
public GenericConfig(final ConfigType type, final JavaPlugin plugin, final String fileName)
|
||||
throws IOException
|
||||
{
|
||||
this(type, plugin, plugin.getDataFolder(), fileName, false);
|
||||
}
|
||||
|
||||
public GenericConfiguration(final ConfigType type, final File dataFolder, final String fileName,
|
||||
final boolean isConcurrent)
|
||||
public GenericConfig(final ConfigType type, final File dataFolder, final String fileName,
|
||||
final boolean isConcurrent)
|
||||
throws IOException
|
||||
{
|
||||
this(type, null, dataFolder, fileName, isConcurrent);
|
||||
@ -114,8 +118,10 @@ public final class GenericConfiguration implements Configuration
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() throws IOException {
|
||||
try (final FileReader reader = new FileReader(this.configFile)) {
|
||||
public void load() throws IOException
|
||||
{
|
||||
try (final FileReader reader = new FileReader(this.configFile))
|
||||
{
|
||||
this.config.clear();
|
||||
|
||||
final UnmodifiableConfig parsed = this.configType.getParser().parse(reader).unmodifiable();
|
||||
@ -145,7 +151,7 @@ public final class GenericConfiguration implements Configuration
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(String path)
|
||||
public boolean getBoolean(final String path)
|
||||
{
|
||||
if (!(this.getConfig().get(path) instanceof Boolean))
|
||||
throw new IllegalArgumentException(String.format("Value at path %s is not a boolean!", path));
|
||||
@ -153,22 +159,70 @@ public final class GenericConfiguration implements Configuration
|
||||
return this.getConfig().get(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ApiStatus.Internal
|
||||
public @Unmodifiable <T> List<T> getList(String path, Class<T> clazz)
|
||||
{
|
||||
// TODO: Figure out how to parse lists with Night Config.
|
||||
|
||||
return new ArrayList<>();
|
||||
/*
|
||||
* I am pretty sure that this works, but not really.
|
||||
* This is sort of a shot in the dark because Night Config did specify that they support collections
|
||||
* in TOML and JSON files, but there is no specific get method for objects that are not primitives.
|
||||
* Additionally, not all primitives are natively supported.
|
||||
*/
|
||||
@Override
|
||||
public @Unmodifiable <T> Collection<T> getCollection(String path, Class<T> clazz)
|
||||
{
|
||||
if (!(this.getConfig().get(path) instanceof Collection<?>))
|
||||
throw new IllegalArgumentException(String.format("Value at path %s is not a collection!", path));
|
||||
|
||||
final Collection<?> collection = this.getConfig().get(path);
|
||||
final Collection<T> collected = new ArrayList<>();
|
||||
|
||||
collection.stream()
|
||||
.map(obj ->
|
||||
{
|
||||
final Optional<T> optional;
|
||||
|
||||
if (obj instanceof String string)
|
||||
optional = PROVIDER.fromString(string, clazz);
|
||||
else if (clazz.isInstance(obj))
|
||||
optional = Optional.of(clazz.cast(obj));
|
||||
else
|
||||
optional = Optional.empty();
|
||||
|
||||
return optional;
|
||||
})
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.collect(Collectors.toCollection(() -> collected));
|
||||
|
||||
return collected;
|
||||
}
|
||||
|
||||
/*
|
||||
* I am pretty sure that this works, but not really.
|
||||
* This is sort of a shot in the dark because Night Config did specify that they support collections
|
||||
* in TOML and JSON files, but there is no specific get method for objects that are not primitives.
|
||||
* Additionally, not all primitives are natively supported.
|
||||
*/
|
||||
@Override
|
||||
@ApiStatus.Internal
|
||||
public @Unmodifiable List<String> getStringList(String path)
|
||||
{
|
||||
// TODO: Figure out how to parse lists with Night Config.
|
||||
if (!(this.getConfig().get(path) instanceof Collection<?> c))
|
||||
throw new IllegalArgumentException(String.format("Value at path %s is not a collection!", path));
|
||||
|
||||
return new ArrayList<>();
|
||||
final Collection<?> collection = this.getConfig().get(path);
|
||||
final List<String> list = new ArrayList<>();
|
||||
|
||||
if (c.isEmpty() || !(c.toArray()[0] instanceof String))
|
||||
{
|
||||
FNS4J.PATCHWORK.warn(String.format("Collection at path %s is empty or does not contain strings!", path));
|
||||
FNS4J.PATCHWORK.warn("Returning empty list!");
|
||||
return list;
|
||||
}
|
||||
|
||||
collection.stream()
|
||||
.map(String.class::cast)
|
||||
.collect(Collectors.toCollection(() -> list));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -195,20 +249,22 @@ public final class GenericConfiguration implements Configuration
|
||||
@Override
|
||||
public <T> Optional<T> get(String path, Class<T> clazz)
|
||||
{
|
||||
// I love ternary statements, sorry Allink :)
|
||||
return clazz.isInstance(this.getConfig().get(path)) ?
|
||||
Optional.of(clazz.cast(this.getConfig().get(path))) :
|
||||
Optional.empty();
|
||||
return this.getConfig()
|
||||
.getOptional(path)
|
||||
.filter(clazz::isInstance)
|
||||
.map(clazz::cast);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getOrDefault(String path, Class<T> clazz, T fallback)
|
||||
{
|
||||
return this.get(path, clazz).orElse(fallback);
|
||||
return this.get(path, clazz)
|
||||
.orElse(fallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void set(final String path, final T value) {
|
||||
public <T> void set(final String path, final T value)
|
||||
{
|
||||
this.config.set(path, value);
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ public final class WrappedBukkitConfiguration implements Configuration
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> getList(String path, Class<T> clazz)
|
||||
public <T> List<T> getCollection(String path, Class<T> clazz)
|
||||
{
|
||||
return this.contextProvider.getList(this.getStringList(path), clazz);
|
||||
}
|
||||
@ -132,7 +132,7 @@ public final class WrappedBukkitConfiguration implements Configuration
|
||||
@Override
|
||||
public <T> Optional<T> get(String path, Class<T> clazz)
|
||||
{
|
||||
return Optional.ofNullable(this.contextProvider.fromString(path, clazz));
|
||||
return this.contextProvider.fromString(path, clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -26,6 +26,7 @@ package fns.patchwork.provider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -60,7 +61,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public class ContextProvider
|
||||
{
|
||||
public <T> T fromString(final String string, final Class<T> clazz)
|
||||
public <T> Optional<T> fromString(final String string, final Class<T> clazz)
|
||||
{
|
||||
return Stream.of(toBoolean(string, clazz),
|
||||
toLong(string, clazz),
|
||||
@ -74,9 +75,9 @@ public class ContextProvider
|
||||
toLocation(string, clazz),
|
||||
toComponent(string, clazz))
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst()
|
||||
.filter(clazz::isInstance)
|
||||
.map(clazz::cast)
|
||||
.orElse(null);
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
private @Nullable Boolean toBoolean(final String string, final Class<?> clazz)
|
||||
@ -227,10 +228,9 @@ public class ContextProvider
|
||||
public @NotNull <T> List<@Nullable T> getList(final List<String> resolvable, final Class<T> clazz)
|
||||
{
|
||||
final List<T> resolved = new ArrayList<>();
|
||||
for (final String entry : resolvable)
|
||||
{
|
||||
resolved.add(this.fromString(entry, clazz));
|
||||
}
|
||||
|
||||
resolvable.forEach(entry -> this.fromString(entry, clazz).ifPresent(resolved::add));
|
||||
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import fns.veritas.bukkit.BukkitNative;
|
||||
import fns.veritas.bukkit.ServerListener;
|
||||
import fns.veritas.client.BotClient;
|
||||
import fns.veritas.client.BotConfig;
|
||||
import java.io.IOException;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class Aggregate
|
||||
@ -40,13 +41,30 @@ public class Aggregate
|
||||
|
||||
public Aggregate(final Veritas plugin)
|
||||
{
|
||||
BotClient bot1;
|
||||
this.plugin = plugin;
|
||||
this.bot = new BotClient(new BotConfig(plugin));
|
||||
|
||||
try
|
||||
{
|
||||
bot1 = new BotClient(new BotConfig(plugin));
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
getLogger().error("Failed to load bot config! Shutting down...");
|
||||
getLogger().error(ex);
|
||||
this.bot = null;
|
||||
this.serverListener = null;
|
||||
this.bukkitNativeListener = null;
|
||||
Bukkit.getPluginManager().disablePlugin(plugin);
|
||||
return;
|
||||
}
|
||||
|
||||
this.bukkitNativeListener = new BukkitNative(plugin);
|
||||
this.serverListener = new ServerListener(plugin);
|
||||
|
||||
Bukkit.getServer().getPluginManager().registerEvents(this.getBukkitNativeListener(), plugin);
|
||||
this.getServerListener().minecraftChatBound().subscribe();
|
||||
this.bot = bot1;
|
||||
}
|
||||
|
||||
public static FNS4J getLogger()
|
||||
|
@ -24,7 +24,8 @@
|
||||
package fns.veritas.client;
|
||||
|
||||
import discord4j.common.util.Snowflake;
|
||||
import fns.patchwork.config.WrappedBukkitConfiguration;
|
||||
import fns.patchwork.config.ConfigType;
|
||||
import fns.patchwork.config.GenericConfig;
|
||||
import fns.veritas.Aggregate;
|
||||
import fns.veritas.Veritas;
|
||||
import java.io.File;
|
||||
@ -41,12 +42,11 @@ public class BotConfig
|
||||
public static final String GUILD_ID = "guild_id";
|
||||
@NonNls
|
||||
private static final String BOT_TOKEN = "bot_token";
|
||||
private final WrappedBukkitConfiguration config;
|
||||
private final GenericConfig config;
|
||||
|
||||
public BotConfig(final Veritas plugin)
|
||||
public BotConfig(final Veritas plugin) throws IOException
|
||||
{
|
||||
this.config = new WrappedBukkitConfiguration(f0(plugin),
|
||||
new File(plugin.getDataFolder(), "config.yml"));
|
||||
this.config = new GenericConfig(ConfigType.TOML, plugin, "config.toml");
|
||||
}
|
||||
|
||||
public String getToken()
|
||||
|
Loading…
Reference in New Issue
Block a user