Giter VIP home page Giter VIP logo

oktane's Introduction

Quality Gate Status Maven Central OSS Snapshot

Oktane is a high performance, highly configurable Java command framework used to map strings to methods, and execute them. It is built upon the Reactor framework to allow easy integration with reactive projects, such as Discord4J.

Inspired by Qmmands.

Guides can be found on the Wiki, Javadocs on gh-pages, example usage can be seen in the OktaneExample module, and an example using Discord4J and Spring here.

Usage

Context Creation

Your command context is a standard pojo used to pass contextual data into your commands. BeanProvider is a service container with the interface providing a default implementations.

public class OktaneCommandContext extends CommandContext {
    private final String user;
    
    public OktaneCommandContext(String user, BeanProvider beanProvider) {
        super(beanProvider);
        this.user = user;
    }
    
    public String user() {
        return user;
    }
}

Module Creation

To define a class as a module the class just needs to extend ModuleBase<T>. The @Aliases annotation is used to force an annotation processor to run. Methods that are public and return CommandResult or Mono<CommandResult> are designated as commands. When a class extends ModuleBase<T> a class will be generated that corresponds to each command method which will be used to invoke the commands at runtime, this approach means that there is no overhead vs a direct method call, if the module is not annotated then reflection will be used to invoke the methods (this is some magnitudes slower). The Aliases annotation tells the CommandHandler what strings to map to this method.

public class OktaneCommandModule extends ModuleBase<OktaneCommandContext> {
    @Aliases({"echo", "e"})
    public CommandResult pingPong(@Remainder String input) {
        return message(context().user() + " said: " + input);
    }
    
    @Aliases({"ping", "p"})
    public Mono<CommandResult> ping() {
        return sendWebRequest()
            .map(statusCode -> message("Got response: " + statusCode));
    }
}

CommandHandler Creation

The command handler is your interface for interacting with your commands.

public CommandHandler<OktaneCommandContext> commandHandler() {
    return CommandHandler.<OktaneCommandContext>builder()
        .withModule(OktaneCommandModule.class)
        .build();
}    

Command Invocation

To invoke a command you simply call to call excute on the command handler, pass it your command context, and the string input to parse.

OktaneCommandContext context = new OktaneCommandContext("Kieran", BeanProvider.get());
Mono<Result> result = commandHandlder.execute("echo Oktane is really cool :)", context);
result.ofType(CommandMessageResult.class)
    .map(CommandMessageResult::message)
    .subscribe(message -> System.out.println(message));

Granular Configuration

Modules and commands can be configured a fair amount.

@Name("My Module")                                                              // Can be used in help displays, all the modules and commands can be accessed via
                                                                                // CommandHandler#modules, and CommandHandler#commands 
@Description("This is a command module")                                        // Can be used in help displays
@Aliases({"a", "b"})                                                            // commands inside a group must have the group prefix to execute, e.g. "a echo"
@Singleton                                                                      // Makes the module a singleton (transient by default)
@Synchronised                                                                   // Makes it so that all commands in the module are synchronised on a shared lock
public class OktaneCommandModule extends ModuleBase<OktaneCommandContext> {
    
    @Name("Echo Command")                                                       // Can be used in help displays
    @Description("Echos input")                                                 // Can be used in help displays
    @Aliases({"echo", "e"})                                                     // Defines the different aliases that can invoke the command
    @Synchronised                                                               // Makes it so that the command is locally synchronised (public CommandResult synchronised ...)
    public CommandResult pingPong(
            @Name("User Input")                                                 // Can be used in help displays       
            @Description("The input to echo")                                   // Can be used in help displays
            @Remainder                                                          // Denotes the parameter as a remainder, so all the remaining text left to parse
                                                                                // will be passed into this parameter. There can only be one remainder, and it
                                                                                // must be the last parameter
            String input) {
        return message(context().user() + " said: " + input);
    }
}

Type Parsing

Oktane supports parsing all the primitive types, see PrimitiveTypeParserFactory, and allowing a user to define their own. Type parsers are added during the CommandHandler building stage using the withTypeParser method.

public class UserTypeParser implements TypeParser<User> {
    @Override
    public Mono<TypeParserResult<T>> parse(CommandContext context, Command command, String input) {
        return context.beanProvider().get(UserService.class)
            .getUser(input)
            .map(this::success)
            .switchOnEmpty(failure("Failed to parse %s as a valid user", input).mono());
    }
} 

Dependency Injection

Beans can be injected into module using the BeanProvider, any constructor arguments will be passed into the module on instantiation, the CommandHandler will inject itself and does not need to be added to a provider.

public class OktaneCommandModule extends ModuleBase<OktaneCommandContext> {
    private final CommandHandler<OktaneCommandContext> commandHandler;
    private final UserService userService;
    
    public OktaneCommandModule(
            CommandHandler<OktaneCommandContext> commandHandler,
            UserService userService) {
        this.commandHandler = commandHandler;
        this.userService = userService;
    }
    
    @Aliases({"commands", "c"})
    public CommandResult commandCount() {
        return message("There are " + commandHandler.commands().count() + " commands");
    }
    
    @Aliases({"users"})
    public Mono<CommandResult> listUsers() {
        return userService.getAll()
            .map(users -> message(users));
    }
}

oktane's People

Contributors

k-boyle avatar renovate-bot avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

oktane's Issues

Create unit tests

Current there are a lot of unit tests missing

  • CommandMap
  • CommandModuleFactory
  • CommandCallbackFactory
  • CommandHandler
  • PrimitiveTypeParser(s)

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • chore(deps): update dependency org.apache.maven.plugins:maven-gpg-plugin to v3.2.4
  • chore(deps): update dependency org.apache.maven.plugins:maven-source-plugin to v3.3.1
  • chore(deps): update maven-surefire.version to v3.3.1 (org.apache.maven.plugins:maven-failsafe-plugin, org.apache.maven.plugins:maven-surefire-plugin)
  • fix(deps): update jmh.version to v1.37 (org.openjdk.jmh:jmh-generator-annprocess, org.openjdk.jmh:jmh-core)
  • chore(deps): update actions/cache action to v4
  • chore(deps): update actions/checkout action to v4
  • chore(deps): update actions/setup-java action to v4
  • chore(deps): update actions/setup-python action to v5
  • fix(deps): update dependency com.google.guava:guava to v33
  • ๐Ÿ” Create all rate-limited PRs at once ๐Ÿ”

Edited/Blocked

These updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/build.yml
  • actions/checkout v2
  • actions/setup-java v2
  • actions/cache v2
  • actions/cache v2
.github/workflows/docs.yml
  • actions/checkout v2
  • actions/setup-java v2
  • JamesIves/github-pages-deploy-action 4.1.4
.github/workflows/release.yml
  • actions/checkout v2
  • actions/setup-python v2
  • actions/setup-java v2
maven
Oktane4J/pom.xml
  • com.discord4j:discord4j-core 3.1.7
OktaneBenchmark/pom.xml
  • org.openjdk.jmh:jmh-core 1.33
  • org.openjdk.jmh:jmh-generator-annprocess 1.33
OktaneCore/pom.xml
  • io.projectreactor:reactor-core 3.4.9
  • com.google.auto.service:auto-service 1.0
OktaneExample/pom.xml
pom.xml
  • com.google.guava:guava 30.1.1-jre
  • org.slf4j:slf4j-api 2.0.0-alpha3
  • org.junit.jupiter:junit-jupiter-api 5.7.2
  • org.junit.jupiter:junit-jupiter-params 5.7.2
  • org.junit.jupiter:junit-jupiter-engine 5.7.2
  • org.apache.maven.plugins:maven-surefire-plugin 3.0.0-M5
  • org.apache.maven.plugins:maven-failsafe-plugin 3.0.0-M5
  • org.apache.maven.plugins:maven-compiler-plugin 3.8.1
  • org.apache.maven.plugins:maven-javadoc-plugin 3.3.0
  • org.sonatype.plugins:nexus-staging-maven-plugin 1.6.8
  • org.apache.maven.plugins:maven-source-plugin 3.2.1
  • org.apache.maven.plugins:maven-javadoc-plugin 3.3.0
  • org.apache.maven.plugins:maven-gpg-plugin 3.0.1
  • org.codehaus.mojo:versions-maven-plugin 2.8.1
pip_requirements
.scripts/requirements.txt

  • Check this box to trigger a request for Renovate to run again on this repository

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: Cannot find preset's package (github>whitesource/merge-confidence:beta)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.