Skip to content

Commit

Permalink
* Added WIP Annotation Example (Which currently does nothing)
Browse files Browse the repository at this point in the history
* Building with shadowJar now to confirm deployment works and deployment sizes
* Cleaned up README
* Added examples for matching, prefix, and validation
  • Loading branch information
SethFalco committed Dec 4, 2019
1 parent 0daa0be commit a029bd7
Show file tree
Hide file tree
Showing 30 changed files with 735 additions and 57 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2019-2019 Elypia CIC
Copyright [yyyy] [name of copyright owner]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
34 changes: 20 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,44 @@
# Commandler Example [![Discord][discord-members]][discord] [![GitLab Pipeline Status][gitlab-build]][gitlab] [![Coverage][gitlab-coverage]][gitlab] [![Donate][donate-shield]][elypia-donate]
# Commandler Examples [![discord-members]][Discord] [![gitlab-build]][gitlab] [![gitlab-coverage]][gitlab] [![donate-shield]][elypia-donate]

## About
This is a bunch of examples that creates minimal console applications using
[Commandler][commandler]. This will have multiple projects in, utilization and
demonstrating various features found in Commandler; some example may also use multiple features to
show how they can be used together.
These are examples that creates minimal console applications using
[Commandler]. This will have multiple projects in, utilizating and
demonstrating various features found in Commandler; some example may also use multiple
features to show how they can be used together.

**This repository is intended for the purpose of example code and general intergration testing.
It's encouraged to reference or learn from this code but it's not written with deployment in mind.**
**This repository is intended for the purpose of example code and general
intergration testing. It's encouraged to reference or learn from this
code but it's not written with deployment in mind.**

## Examples
This will list all examples and what they may demonstrate for users.
All examples will list the dependencies they have that are optional for Commandler
such as the `org.elypia.commandler:validation` module, or runtime dependencies
for types of configuration.

| Name | Dependencies | Description |
|------|--------------|-------------|
| `simple-controller-example` | `org.yaml:snakeyaml` | Uses Commandler to create a simple chatbot with a controller and two static commands; configured with YAML.
| Name | Description |
|-----------------------------|-------------------------------------------------------------------|
| `annotation-example` | Configures Commandler with annotations. |
| `javax-validation-example` | Validate command parameters with `javax.validation`. |
| `match-dispatcher-example` | Match commands with regular expression. |
| `prefix-example` | Single controller with a command, with statically defined prefix. |
| `simple-controller-example` | Single controller and two static commands. |


## Open-Source
This project is licenced under the Apache 2.0 project, don't be afraid to derive or reference
from this project all you want!
from this project all you want.

## Support
Should any problems occur, come visit us over on [Discord][discord]! We're always around and
Should any problems occur, come visit us over on [Discord]! We're always around and
there are ample developers that would be willing to help; if it's a problem with the library
itself then we'll make sure to get it sorted.

[discord]: https://discord.gg/hprGMaM "Discord Invite"
[Discord]: https://discord.gg/hprGMaM "Discord Invite"
[discord-members]: https://discordapp.com/api/guilds/184657525990359041/widget.png "Discord Shield"
[gitlab]: https://gitlab.com/Elypia/commandler-examples/commits/master "Repository on GitLab"
[gitlab-build]: https://gitlab.com/Elypia/commandler-examples/badges/master/pipeline.svg "GitLab Build Shield"
[gitlab-coverage]: https://gitlab.com/Elypia/commandler-examples/badges/master/coverage.svg "GitLab Coverage Shield"
[donate-shield]: https://img.shields.io/badge/Elypia-Donate-blueviolet "Donate Shield"
[elypia-donate]: https://elypia.org/donate "Donate to Elypia"
[commandler]: https://gitlab.com/Elypia/commandler "Commandler on GitLab"
[Commandler]: https://gitlab.com/Elypia/commandler "Commandler on GitLab"
14 changes: 14 additions & 0 deletions annotation-example/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
dependencies {
implementation "org.elypia.commandler:annotation:${version}"

// TODO: We're not actually using this, Commandler is just getting mad without it.
runtimeOnly "org.yaml:snakeyaml:1.25"
}

shadowJar {
manifest {
attributes 'Implementation-Title' : this.name,
'Implementation-Version' : version,
'Main-Class' : "org.elypia.example.annotation-example.AnnotationExample"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,16 @@
* limitations under the License.
*/

package org.elypia.example;
package org.elypia.example.annotationexample;

import org.elypia.commandler.Commandler;
import org.slf4j.*;

/**
* Our main class, this will initialize Commandler and run the framework.
*
* @author [email protected] (Syed Seth)
* @author [email protected] (Seth Falco)
*/
public class Example {

/** Logging with SLF4J. */
private static final Logger logger = LoggerFactory.getLogger(Example.class);
public class AnnotationExample {

public static void main(String[] args) {
// Setup Commandler, this will initialize Commandler and perform any validation.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright 2019-2019 Elypia CIC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.elypia.example.annotationexample;

import org.elypia.commandler.annotation.*;
import org.elypia.commandler.api.Controller;

import java.util.stream.IntStream;

/**
* The utility controller, this controller contains multiple commands
* which are created per method and defined via annotations.
*
* @author [email protected] (Seth Falco)
*/
@ControllerData
@Aliases("utils")
@Help(name = "Utilities", description = "Random utilities to add some quick generic functionality.")
public class UtilityController implements Controller {

/**
* Creates a static command, just a basic input/output command.
*
* @return The text "pong!".
*/
@Static
@CommandData
@Aliases("ping")
@Help(name = "ping!", description = "Check if the application is still responsive.")
public String ping() {
return "pong!";
}

/**
* Utilizes Commandler lists, a list is a single parameter which
* is comma seperated rather than space seperated.
*
* @param numbers An array of numbers to sum.
* @return All of the numbers summed together.
*/
@Static
@CommandData
@Aliases("sum")
@Help(name = "Sum", description = "Add up a bunch of integer numbers.")
public int sum(@Param @Help(name = "numbers", description = "All the numbers I should sum together.") int[] numbers) {
return IntStream.of(numbers).sum();
}
}
10 changes: 10 additions & 0 deletions annotation-example/src/main/resources/application.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<configuration xmlns="https://commandler.elypia.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://commandler.elypia.org application.xsd">
<application>
<name>Annotation Example</name>
</application>
<commandler>
<dispatcher>org.elypia.commandler.dispatchers.StandardDispatcher</dispatcher>
</commandler>
</configuration>
30 changes: 30 additions & 0 deletions annotation-example/src/main/resources/logback.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.1" encoding="UTF-8"?>
<!--
~ Copyright 2019-2019 Elypia CIC
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<configuration>
<logger name="org.jboss" level="WARN"/>
<logger name="org.jboss.weld.Validator" level="ERROR"/>

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%highlight([%-5p]) [%blue(%d{MM/dd, UTC}) %green(%d{HH:mm:ss, UTC})] %blue([%logger]) %msg%n</pattern>
</encoder>
</appender>

<root level="ALL">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
18 changes: 12 additions & 6 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
plugins {
id 'com.github.johnrengelman.shadow' version '5.2.0' apply false
}

allprojects() {
apply plugin: "idea"
apply plugin: "jacoco"

group = "org.elypia"
version = "0.0.0"
version = "4.0.0"
description = "An example project to demonstrate the usage of Commandler."

repositories {
Expand All @@ -12,12 +16,14 @@ allprojects() {
}

jacoco {
toolVersion = "0.8.4"
toolVersion = "0.8.5"
}
}

subprojects() {
apply plugin: "java"
apply plugin: "com.github.johnrengelman.shadow"

/** Adds the commandlerdoc task for exporting docs for your Commandler application. */
// apply plugin: "org.elypia.commandler" version "1.0.0"

Expand All @@ -28,18 +34,18 @@ subprojects() {

dependencies {
// The core of Commandler, always required for any Commandler application.
implementation "org.elypia.commandler:core:4.0.0"
implementation "org.elypia.commandler:core:${version}"

// A console integration for Commandler to handle commands in console.
implementation "org.elypia.commandler:console:4.0.0"
implementation "org.elypia.commandler:console:${version}"

// Logging
implementation "org.slf4j:slf4j-api:1.7.28"
implementation "org.slf4j:slf4j-api:1.7.29"
runtimeOnly "ch.qos.logback:logback-classic:1.2.3"

// Testing
testImplementation "org.junit.jupiter:junit-jupiter:5.5.2"
testImplementation "org.mockito:mockito-core:3.0.0"
testImplementation "org.mockito:mockito-core:3.2.0"
}

/** Testing */
Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
16 changes: 16 additions & 0 deletions javax-validation-example/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
dependencies {
// Allows Configuration with YAML (Apache Commons Configuration will pick this up on it's own.)
runtimeOnly "org.yaml:snakeyaml:1.25"

// An optional dependency which provides an implementation which
// performs validation with javax.validation annotations or XML.
implementation "org.elypia.commandler:validation:${version}"
}

shadowJar {
manifest {
attributes 'Implementation-Title' : this.name,
'Implementation-Version' : version,
'Main-Class' : "org.elypia.example.javaxvalidation.JavaxValidationExample"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright 2019-2019 Elypia CIC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.elypia.example.javaxvalidation;

import org.elypia.commandler.api.Controller;
import org.slf4j.*;

import javax.inject.Singleton;
import javax.validation.constraints.*;
import java.util.concurrent.ThreadLocalRandom;

/**
* This is a quick mock up of a hotter colder game controller.
* This isn't made with multiple sessions in mind, it's just for
* our quick little console application.
*
* @author [email protected] (Seth Falco)
*/
@Singleton
public class HotColdController implements Controller {

private Logger logger = LoggerFactory.getLogger(HotColdController.class);

private static final int MAX_VALUE = 100;
private static final int NO_GAME = -1;

/**
* The current value the player must guess, or {@link #NO_GAME}
* if no game session is currently active.
*/
private int value;

/** The distance between the users previous guess and the {@link #value}. */
private int previousDistance;

/**
* Instantiate the controller and initialize
* the {@link #value} with {@link #NO_GAME} to indicate no game is in progress.
*/
public HotColdController() {
value = NO_GAME;
previousDistance = NO_GAME;
}

public String start() {
if (value != NO_GAME)
return "A game is already in progress, finish it up to start another.";

value = ThreadLocalRandom.current().nextInt(MAX_VALUE) + 1;
logger.debug("Generated the value {} for the user to guess.", value);
return "I've thought of a number, care to take a guess?";
}

/**
* This is a normal command like any other, but before the command
* is executed we'll cross-check the parameters provided by the user
* against the validation mapping configured for javax.validation.
*
* @param guess The players guess.
* @return The message to respond back.
*/
public String guess(@Min(1) @Max(MAX_VALUE) int guess) {
if (value == NO_GAME)
return "A game hasn't been started yet, start one first.";

int distance = Math.abs(value - guess);

if (previousDistance == NO_GAME) {
previousDistance = distance;
logger.debug("Previous distance is now set to {}.", previousDistance);
return "You've made your first guess, I'll tell you if you're hotter or colder for now on!";
}

if (distance == 0) {
value = previousDistance = NO_GAME;
return "You win!";
}

if (distance < previousDistance) {
previousDistance = distance;
return "You're getting warmer.";
} else if (distance > previousDistance) {
previousDistance = distance;
return "You're getting colder.";
}

return "It's around the same temperature.";
}
}
Loading

0 comments on commit a029bd7

Please sign in to comment.