Skip to content

Commit

Permalink
Move standard captions to a provider (#658)
Browse files Browse the repository at this point in the history
* Move standard captions to a provider

* Remove unused caption
  • Loading branch information
jpenilla authored Jan 23, 2024
1 parent 5f5c64a commit 5db60e5
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import cloud.commandframework.arguments.suggestion.SuggestionFactory;
import cloud.commandframework.captions.CaptionFormatter;
import cloud.commandframework.captions.CaptionRegistry;
import cloud.commandframework.captions.StandardCaptionRegistryFactory;
import cloud.commandframework.captions.StandardCaptionsProvider;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.context.CommandContextFactory;
import cloud.commandframework.context.CommandInput;
Expand Down Expand Up @@ -143,7 +143,8 @@ protected CommandManager(
this.servicePipeline.registerServiceType(new TypeToken<CommandPostprocessor<C>>() {
}, new AcceptingCommandPostprocessor<>());
/* Create the caption registry */
this.captionRegistry = new StandardCaptionRegistryFactory<C>().create();
this.captionRegistry = CaptionRegistry.captionRegistry();
this.captionRegistry.registerProvider(new StandardCaptionsProvider<>());
/* Register default injectors */
this.parameterInjectorRegistry().registerInjector(
CommandContext.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public interface CaptionProvider<C> {
* @return the provider
*/
static <C> @NonNull CaptionProvider<C> constantProvider(final @NonNull Caption caption, final @NonNull String value) {
return CaptionProvider.<C>constantProvider().putCaptions(caption, value).build();
return CaptionProvider.<C>constantProvider().putCaption(caption, value).build();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@
import org.checkerframework.common.returnsreceiver.qual.This;

/**
* Registry that allows for messages to be configurable per-sender
* Registry that allows for messages to be configurable per-sender. Delegates to registered {@link CaptionProvider
* CaptionProviders}.
*
* @param <C> Command sender type
* @param <C> command sender type
*/
@API(status = API.Status.STABLE)
public interface CaptionRegistry<C> {
Expand All @@ -58,4 +59,14 @@ public interface CaptionRegistry<C> {
* @return {@code this}
*/
@This @NonNull CaptionRegistry<C> registerProvider(@NonNull CaptionProvider<C> provider);

/**
* Creates a new caption registry with no providers registered.
*
* @param <C> command sender type
* @return new caption registry
*/
static <C> CaptionRegistry<C> captionRegistry() {
return new CaptionRegistryImpl<>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,38 @@
//
package cloud.commandframework.captions;

import java.util.function.BiFunction;
import java.util.LinkedList;
import org.apiguardian.api.API;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.common.returnsreceiver.qual.This;

/**
* Caption registry that delegates to factory methods
*
* @param <C> Command sender type
*/
@API(status = API.Status.STABLE)
public interface FactoryDelegatingCaptionRegistry<C> extends CaptionRegistry<C> {
@API(status = API.Status.INTERNAL)
public final class CaptionRegistryImpl<C> implements CaptionRegistry<C> {

/**
* Register a message factory
*
* @param caption Caption key
* @param factory Message factory
*/
void registerMessageFactory(
@NonNull Caption caption,
@NonNull BiFunction<Caption, C, String> factory
);
private final LinkedList<@NonNull CaptionProvider<C>> providers = new LinkedList<>();

CaptionRegistryImpl() {
}

@Override
public @NonNull String caption(
final @NonNull Caption caption,
final @NonNull C sender
) {
for (final CaptionProvider<C> provider : this.providers) {
final String result = provider.provide(caption, sender);
if (result != null) {
return result;
}
}
throw new IllegalArgumentException(String.format("There is no caption stored with key '%s'", caption));
}

@Override
public @This @NonNull CaptionRegistry<C> registerProvider(
final @NonNull CaptionProvider<C> provider
) {
this.providers.addFirst(provider);
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,25 @@
//
package cloud.commandframework.captions;

import org.apiguardian.api.API;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
* Factory creating {@link StandardCaptionRegistry} instances
* Caption provider that delegates to another provider.
*
* @param <C> Command sender type
* @param <C> command sender type
*/
@API(status = API.Status.STABLE)
public final class StandardCaptionRegistryFactory<C> {
public abstract class DelegatingCaptionProvider<C> implements CaptionProvider<C> {

/**
* Create a new simple caption registry instance
* Returns the provider to delegate to.
*
* @return Created instance
* @return delegate provider
*/
public @NonNull StandardCaptionRegistry<C> create() {
return new StandardCaptionRegistry<>();
public abstract @NonNull CaptionProvider<C> delegate();

@Override
public final @Nullable String provide(final @NonNull Caption caption, final @NonNull C recipient) {
return this.delegate().provide(caption, recipient);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ public final class StandardCaptionKeys {

private static final Collection<Caption> RECOGNIZED_CAPTIONS = new LinkedList<>();

/**
* Variables: None
*/
public static final Caption ARGUMENT_PARSE_FAILURE_NO_INPUT_PROVIDED = of("argument.parse.failure.no_input_was_provided");
/**
* Variables: {@code <input>}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,17 @@
//
package cloud.commandframework.captions;

import java.util.LinkedList;
import org.apiguardian.api.API;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.common.returnsreceiver.qual.This;

/**
* Caption registry that registers constant values for all {@link StandardCaptionKeys}.
* Provides default captions for all {@link StandardCaptionKeys}.
*
* @param <C> the command sender type
* @param <C> command sender type
*/
@API(status = API.Status.STABLE)
public class StandardCaptionRegistry<C> implements CaptionRegistry<C> {
public final class StandardCaptionsProvider<C> extends DelegatingCaptionProvider<C> {

/**
* Default caption for {@link StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_NO_INPUT_PROVIDED}.
*/
public static final String ARGUMENT_PARSE_FAILURE_NO_INPUT_PROVIDED = "No input was provided";
/**
* Default caption for {@link StandardCaptionKeys#ARGUMENT_PARSE_FAILURE_BOOLEAN}.
*/
Expand Down Expand Up @@ -109,88 +103,64 @@ public class StandardCaptionRegistry<C> implements CaptionRegistry<C> {
*/
public static final String ARGUMENT_PARSE_FAILURE_EITHER = "Could not resolve <primary> or <fallback> from '<input>'";

private final LinkedList<@NonNull CaptionProvider<C>> providers = new LinkedList<>();

protected StandardCaptionRegistry() {
this.registerProvider(
CaptionProvider.<C>constantProvider()
.putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_NO_INPUT_PROVIDED,
ARGUMENT_PARSE_FAILURE_NO_INPUT_PROVIDED
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_BOOLEAN,
ARGUMENT_PARSE_FAILURE_BOOLEAN
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_NUMBER,
ARGUMENT_PARSE_FAILURE_NUMBER
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_CHAR,
ARGUMENT_PARSE_FAILURE_CHAR
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_ENUM,
ARGUMENT_PARSE_FAILURE_ENUM
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_STRING,
ARGUMENT_PARSE_FAILURE_STRING
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_UUID,
ARGUMENT_PARSE_FAILURE_UUID
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_REGEX,
ARGUMENT_PARSE_FAILURE_REGEX
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_COLOR,
ARGUMENT_PARSE_FAILURE_COLOR
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_DURATION,
ARGUMENT_PARSE_FAILURE_DURATION
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_UNKNOWN_FLAG,
ARGUMENT_PARSE_FAILURE_FLAG_UNKNOWN_FLAG
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_DUPLICATE_FLAG,
ARGUMENT_PARSE_FAILURE_FLAG_DUPLICATE_FLAG
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_NO_FLAG_STARTED,
ARGUMENT_PARSE_FAILURE_FLAG_NO_FLAG_STARTED
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_MISSING_ARGUMENT,
ARGUMENT_PARSE_FAILURE_FLAG_MISSING_ARGUMENT
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_NO_PERMISSION,
ARGUMENT_PARSE_FAILURE_FLAG_NO_PERMISSION
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_AGGREGATE_MISSING_INPUT,
ARGUMENT_PARSE_FAILURE_AGGREGATE_MISSING_INPUT
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_AGGREGATE_COMPONENT_FAILURE,
ARGUMENT_PARSE_FAILURE_AGGREGATE_COMPONENT_FAILURE
).putCaptions(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_EITHER,
ARGUMENT_PARSE_FAILURE_EITHER
).build()
);
}

@Override
public final @NonNull String caption(
final @NonNull Caption caption,
final @NonNull C sender
) {
for (final CaptionProvider<C> provider : this.providers) {
final String result = provider.provide(caption, sender);
if (result != null) {
return result;
}
}
throw new IllegalArgumentException(String.format("There is no caption stored with key '%s'", caption));
}
private static final CaptionProvider<?> PROVIDER = CaptionProvider.constantProvider()
.putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_BOOLEAN,
ARGUMENT_PARSE_FAILURE_BOOLEAN
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_NUMBER,
ARGUMENT_PARSE_FAILURE_NUMBER
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_CHAR,
ARGUMENT_PARSE_FAILURE_CHAR
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_ENUM,
ARGUMENT_PARSE_FAILURE_ENUM
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_STRING,
ARGUMENT_PARSE_FAILURE_STRING
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_UUID,
ARGUMENT_PARSE_FAILURE_UUID
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_REGEX,
ARGUMENT_PARSE_FAILURE_REGEX
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_COLOR,
ARGUMENT_PARSE_FAILURE_COLOR
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_DURATION,
ARGUMENT_PARSE_FAILURE_DURATION
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_UNKNOWN_FLAG,
ARGUMENT_PARSE_FAILURE_FLAG_UNKNOWN_FLAG
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_DUPLICATE_FLAG,
ARGUMENT_PARSE_FAILURE_FLAG_DUPLICATE_FLAG
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_NO_FLAG_STARTED,
ARGUMENT_PARSE_FAILURE_FLAG_NO_FLAG_STARTED
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_MISSING_ARGUMENT,
ARGUMENT_PARSE_FAILURE_FLAG_MISSING_ARGUMENT
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_FLAG_NO_PERMISSION,
ARGUMENT_PARSE_FAILURE_FLAG_NO_PERMISSION
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_AGGREGATE_MISSING_INPUT,
ARGUMENT_PARSE_FAILURE_AGGREGATE_MISSING_INPUT
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_AGGREGATE_COMPONENT_FAILURE,
ARGUMENT_PARSE_FAILURE_AGGREGATE_COMPONENT_FAILURE
).putCaption(
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_EITHER,
ARGUMENT_PARSE_FAILURE_EITHER
)
.build();

@SuppressWarnings("unchecked")
@Override
public final @This @NonNull StandardCaptionRegistry<C> registerProvider(
final @NonNull CaptionProvider<C> provider
) {
this.providers.addFirst(provider);
return this;
public @NonNull CaptionProvider<C> delegate() {
return (CaptionProvider<C>) PROVIDER;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
headerComments = true,
jacksonIntegration = false,
builderVisibility = Value.Style.BuilderVisibility.SAME,
defaultAsDefault = true
defaultAsDefault = true,
depluralize = true
)
@InjectAnnotation(
type = API.class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
import cloud.commandframework.TestCommandSender;
import cloud.commandframework.captions.Caption;
import cloud.commandframework.captions.CaptionProvider;
import cloud.commandframework.captions.CaptionRegistry;
import cloud.commandframework.captions.StandardCaptionKeys;
import cloud.commandframework.captions.StandardCaptionRegistry;
import cloud.commandframework.captions.StandardCaptionRegistryFactory;
import cloud.commandframework.captions.StandardCaptionsProvider;
import java.util.stream.Stream;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -39,13 +39,14 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;

class StandardCaptionRegistryTest {
class CaptionRegistryTest {

private StandardCaptionRegistry<TestCommandSender> captionRegistry;
private CaptionRegistry<TestCommandSender> captionRegistry;

@BeforeEach
void setup() {
this.captionRegistry = new StandardCaptionRegistryFactory<TestCommandSender>().create();
this.captionRegistry = CaptionRegistry.captionRegistry();
this.captionRegistry.registerProvider(new StandardCaptionsProvider<>());
}

@ParameterizedTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import cloud.commandframework.CloudCapability;
import cloud.commandframework.CommandManager;
import cloud.commandframework.captions.Caption;
import cloud.commandframework.captions.FactoryDelegatingCaptionRegistry;
import cloud.commandframework.captions.CaptionProvider;
import cloud.commandframework.exceptions.ArgumentParseException;
import cloud.commandframework.exceptions.CommandExecutionException;
import cloud.commandframework.exceptions.InvalidCommandSenderException;
Expand Down Expand Up @@ -126,12 +126,9 @@ public PircBotXCommandManager(
this.commandPrefix = commandPrefix;
this.userMapper = userMapper;
this.pircBotX.getConfiguration().getListenerManager().addListener(new CloudListenerAdapter<>(this));
if (this.captionRegistry() instanceof FactoryDelegatingCaptionRegistry) {
((FactoryDelegatingCaptionRegistry<C>) this.captionRegistry()).registerMessageFactory(
ARGUMENT_PARSE_FAILURE_USER_KEY,
(caption, user) -> ARGUMENT_PARSE_FAILURE_USER
);
}
this.captionRegistry().registerProvider(
CaptionProvider.constantProvider(ARGUMENT_PARSE_FAILURE_USER_KEY, ARGUMENT_PARSE_FAILURE_USER)
);
this.registerCommandPreProcessor(context -> context.commandContext().store(PIRCBOTX_META_KEY, pircBotX));
this.parserRegistry().registerParser(UserParser.userParser());

Expand Down

0 comments on commit 5db60e5

Please sign in to comment.