Skip to content

Commit ff26624

Browse files
author
Marcel Overdijk
committed
Added Spring Boot Starter
1 parent 723d9f5 commit ff26624

44 files changed

Lines changed: 2136 additions & 154 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Changes.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,14 @@ This documents the history of significant changes to `rivescript-java`.
66

77
This update focuses on new features and bug fixes.
88

9+
* **API Breaking Changes:**
10+
* The `load` and `call` methods of the `ObjectHandler` interface now
11+
require the `RiveScript` instance as an additional (first) argument.
12+
913
* **Changes:**
14+
* Add RiveScript Spring Boot Starter module (#34).
15+
A dedicated RiveScript Spring Boot Starter sample is available under
16+
`/samples/spring-bootstarter-rsbot` for reference.
1017
* Add JSR-223 Scripting `ObjectHandler` to support object macros written in
1118
any JSR-223 compliant scripting language. The `rivescript-core` distro
1219
comes bundled with out-of-the-box support for JavaScript, Groovy and Ruby

README.md

Lines changed: 91 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ dependencies {
7070
}
7171
```
7272

73+
If you want to use RiveScript in a Spring Boot application see the
74+
Spring Boot Starter [section](#spring-boot-starter).
75+
7376
## Usage
7477

7578
When used as a library for writing your own chatbot, the synopsis is as follows:
@@ -167,6 +170,76 @@ The `<star>` tags in RiveScript will capture the user's "raw" input, so you can
167170
write replies to get the user's e-mail address or store foreign characters in
168171
their name.
169172
173+
## Spring Boot Starter
174+
175+
Add the `rivescript-spring-boot-starter` dependency to your project:
176+
177+
_Maven_:
178+
179+
```xml
180+
<dependency>
181+
<groupId>com.rivescript</groupId>
182+
<artifactId>rivescript-spring-boot-starter</artifactId>
183+
<version>0.8.1</version>
184+
</dependency>
185+
```
186+
187+
_Gradle_:
188+
189+
```groovy
190+
dependencies {
191+
compile "com.rivescript:rivescript-spring-boot-starter:0.8.1"
192+
}
193+
```
194+
195+
The starter will automatically add the `rivescript-core` dependency to your
196+
project and trigger the auto configuration to create the `RiveScript` bot
197+
instance.
198+
199+
Although the auto configuration will use sensible defaults to create the bot
200+
instance, the following properties can be specified inside your
201+
`application.properties`/`application.yml` file (or as command line switches)
202+
to customize the auto configuration behaviour:
203+
204+
```txt
205+
rivescript:
206+
enabled: true # Enable RiveScript for the application.
207+
source-path: classpath:/rivescript/ # The comma-separated list of RiveScript source files and/or directories.
208+
file-extensions: .rive, .rs # The comma-separated list of RiveScript file extensions to load.
209+
throw-exceptions: false # Enable throw exceptions.
210+
strict: true # Enable strict syntax checking.
211+
utf8: false # Enable UTF-8 mode.
212+
unicode-punctuation: [.,!?;:] # The unicode punctuation pattern (only used when UTF-8 mode is enabled).
213+
force-case: false # Enable forcing triggers to lowercase.
214+
depth: 50 # The recursion depth limit.
215+
error-messages: # The custom error message overrides. For instance `rivescript.error-messages.deepRecursion=Custom Deep Recursion Detected Message`
216+
object-handlers: # The comma-separated list of object handler names to register (currently supported: `groovy`, `javascript`, `ruby`).
217+
```
218+
219+
To automatically register custom Java subroutines and/or non-default supported
220+
object handlers in the created `RiveScript` bot instance, define appropriate
221+
beans in your application context like:
222+
223+
```java
224+
@Bean
225+
public Map<String, Subroutine> subroutines() {
226+
// The key is the name of the Java object macro to register.
227+
Map<String, Subroutine> subroutines = new HashMap<>();
228+
subroutines.put("subroutine1", new Subroutine1());
229+
subroutines.put("subroutine2", new Subroutine2());
230+
return subroutines;
231+
}
232+
233+
@Bean
234+
public Map<String, ObjectHandler> objectHandlers() {
235+
// The key is the name of the programming language to register.
236+
Map<String, ObjectHandler> objectHandlers = new HashMap<>();
237+
objectHandlers.put("handler1", new ObjectHandler1());
238+
objectHandlers.put("handler2", new ObjectHandler2());
239+
return objectHandlers;
240+
}
241+
```
242+
170243
## Building
171244
172245
To compile, test, build all jars and docs run:
@@ -177,22 +250,29 @@ To install all jars into your local Maven cache run:
177250
178251
./gradlew install
179252
180-
## RSBot Demo Script
253+
## Samples
254+
255+
The `/samples` folder contains various samples of Java RiveScript bot implementations.
256+
257+
* `rsbot` - The `RSBot.java` is a simple implementation using the `com.rivescript.cmd.Shell`.
181258
182-
The `RSBot.java` is a simple implementation of a Java RiveScript bot. You
183-
can use it to quickly chat with the Eliza-based bot in the `Aiden/` folder.
259+
These commands may be used at your input prompt in RSBot:
184260
185-
These commands may be used at your input prompt in RSBot:
261+
/quit - Quit the program
262+
/dump topics - Dump the internal topic/trigger/reply struct (debugging)
263+
/dump sorted - Dump the internal trigger sort buffers (debugging)
264+
/last - Print the last trigger you matched.
186265
187-
/quit - Quit the program
188-
/dump topics - Dump the internal topic/trigger/reply struct (debugging)
189-
/dump sorted - Dump the internal trigger sort buffers (debugging)
190-
/last - Print the last trigger you matched.
266+
To execute `RSBot` to begin chatting with the demo Eliza-based run:
191267
192-
To execute `RSBot` to begin chatting with the demo Eliza-based bot that
193-
tends to ship with RiveScript libraries run:
268+
./gradlew :rivescript-samples-rsbot:runBot --console plain
194269
195-
./gradlew :rivescript-samples-rsbot:runBot --console plain
270+
* `spring-boot-starter-rsbot` - This example uses the RiveScript Spring Boot Starter to
271+
auto-configure the `RiveScript` bot instance.
272+
273+
To begin chatting with the demo bot run:
274+
275+
./gradlew :rivescript-samples-spring-boot-starter-rsbot:bootRun --console plain
196276
197277
## Authors
198278

build.gradle

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ buildscript {
77
}
88

99
ext {
10-
groovyVersion = "2.4.8"
11-
hamcrestVersion = "1.3"
12-
junitVersion = "4.12"
13-
jrubyVersion = "9.1.7.0"
14-
jsonVersion = "20160810"
15-
mockitoVersion = "1.10.19"
16-
slf4jVersion = "1.7.22"
10+
groovyVersion = "2.4.8"
11+
hamcrestVersion = "1.3"
12+
junitVersion = "4.12"
13+
jrubyVersion = "9.1.7.0"
14+
jsonVersion = "20160810"
15+
mockitoVersion = "1.10.19"
16+
slf4jVersion = "1.7.22"
17+
springBootVersion = "1.5.1.RELEASE"
1718
ext.javadocLinks = [
1819
"http://docs.oracle.com/javase/7/docs/api/",
1920
"http://docs.oracle.com/javaee/7/api/"
@@ -200,6 +201,18 @@ project("rivescript-core") {
200201
}
201202
}
202203

204+
project("rivescript-spring-boot-starter") {
205+
206+
description = "RiveScript Spring Boot Starter"
207+
208+
dependencies {
209+
compile project(":rivescript-core")
210+
compile "org.springframework.boot:spring-boot:${springBootVersion}"
211+
compile "org.springframework.boot:spring-boot-autoconfigure:${springBootVersion}"
212+
testCompile "org.springframework.boot:spring-boot-test:${springBootVersion}"
213+
}
214+
}
215+
203216
configure(rootProject) {
204217

205218
description = "RiveScript"
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#Mon Feb 20 22:34:13 CET 2017
1+
#Wed Mar 01 22:24:10 CET 2017
22
distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-3.4-bin.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-3.4-all.zip

rivescript-core/src/integration-test/java/com/rivescript/BaseIT.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,6 @@
3737
*/
3838
public class BaseIT {
3939

40-
protected static final String ERR_DEEP_RECURSION_DETECTED = "ERR: Deep Recursion Detected";
41-
protected static final String ERR_NO_REPLY_MATCHED = "ERR: No Reply Matched";
42-
protected static final String ERR_OBJECT_NOT_FOUND = "[ERR: Object Not Found]";
43-
protected static final String ERR_REPLIES_NOT_SORTED = "ERR: Replies Not Sorted";
44-
4540
protected RiveScript rs;
4641
protected String username = "local-user";
4742

rivescript-core/src/integration-test/java/com/rivescript/GroovyObjectIT.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import org.junit.Before;
2727
import org.junit.Test;
2828

29+
import static com.rivescript.RiveScript.DEFAULT_OBJECT_NOT_FOUND_MESSAGE;
30+
2931
/**
3032
* Integration tests for {@link GroovyHandler}.
3133
*
@@ -36,7 +38,7 @@ public class GroovyObjectIT extends BaseIT {
3638
@Before
3739
public void setUp() {
3840
rs = new RiveScript();
39-
rs.setHandler("groovy", new GroovyHandler(rs));
41+
rs.setHandler("groovy", new GroovyHandler());
4042
setUp(new String[] {
4143
"> object reverse groovy",
4244
" def msg = args.join(' ')",
@@ -69,6 +71,6 @@ public void testSetName() {
6971
@Test
7072
public void testNoGroovyHandler() {
7173
rs.removeHandler("groovy");
72-
assertReply("reverse hello world", ERR_OBJECT_NOT_FOUND);
74+
assertReply("reverse hello world", DEFAULT_OBJECT_NOT_FOUND_MESSAGE);
7375
}
7476
}

rivescript-core/src/integration-test/java/com/rivescript/JavaObjectIT.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import org.junit.Before;
2828
import org.junit.Test;
2929

30+
import static com.rivescript.RiveScript.DEFAULT_OBJECT_NOT_FOUND_MESSAGE;
31+
3032
/**
3133
* Integration tests for Java {@link Subroutine}.
3234
*
@@ -78,6 +80,6 @@ public void testSetName() {
7880
@Test
7981
public void testRemoveSubroutine() {
8082
rs.removeSubroutine("reverse");
81-
assertReply("reverse hello world", ERR_OBJECT_NOT_FOUND);
83+
assertReply("reverse hello world", DEFAULT_OBJECT_NOT_FOUND_MESSAGE);
8284
}
8385
}

rivescript-core/src/integration-test/java/com/rivescript/JavaScriptObjectIT.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import org.junit.Before;
2727
import org.junit.Test;
2828

29+
import static com.rivescript.RiveScript.DEFAULT_OBJECT_NOT_FOUND_MESSAGE;
30+
2931
/**
3032
* Integration tests for {@link JavaScriptHandler}.
3133
*
@@ -36,7 +38,7 @@ public class JavaScriptObjectIT extends BaseIT {
3638
@Before
3739
public void setUp() {
3840
rs = new RiveScript();
39-
rs.setHandler("javascript", new JavaScriptHandler(rs));
41+
rs.setHandler("javascript", new JavaScriptHandler());
4042
setUp(new String[] {
4143
"> object reverse javascript",
4244
" var msg = args.join(' ');",
@@ -69,6 +71,6 @@ public void testSetName() {
6971
@Test
7072
public void testNoJavaScriptHandler() {
7173
rs.removeHandler("javascript");
72-
assertReply("reverse hello world", ERR_OBJECT_NOT_FOUND);
74+
assertReply("reverse hello world", DEFAULT_OBJECT_NOT_FOUND_MESSAGE);
7375
}
7476
}

rivescript-core/src/integration-test/java/com/rivescript/ObjectIT.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import java.util.HashMap;
2828
import java.util.Map;
2929

30+
import static com.rivescript.RiveScript.DEFAULT_OBJECT_NOT_FOUND_MESSAGE;
31+
3032
/**
3133
* @author Noah Petherbridge
3234
* @author Marcel Overdijk
@@ -53,20 +55,20 @@ public void testMacroParsing() {
5355
"- <call>goodbye</call>"
5456
});
5557
assertReply("Hello", "Hello world!");
56-
assertReply("goodbye", ERR_OBJECT_NOT_FOUND);
58+
assertReply("goodbye", DEFAULT_OBJECT_NOT_FOUND_MESSAGE);
5759
}
5860

5961
private static class MockHandler implements ObjectHandler {
6062

6163
private Map<String, String> codes = new HashMap<>();
6264

6365
@Override
64-
public void load(String name, String[] code) {
66+
public void load(RiveScript rs, String name, String[] code) {
6567
codes.put(name, StringUtils.join(code, "\n"));
6668
}
6769

6870
@Override
69-
public String call(String name, String[] fields) {
71+
public String call(RiveScript rs, String name, String[] fields) {
7072
return codes.get(name);
7173
}
7274
}

rivescript-core/src/integration-test/java/com/rivescript/ReplyIT.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import java.util.HashMap;
2626
import java.util.Map;
2727

28+
import static com.rivescript.RiveScript.DEFAULT_DEEP_RECURSION_MESSAGE;
29+
2830
/**
2931
* @author Noah Petherbridge
3032
* @author Marcel Overdijk
@@ -139,7 +141,7 @@ public void testRedirects() {
139141
assertReply("hi there", "Hi there!");
140142
assertReply("my name is Kirsle", "That's my botmaster's name too.");
141143
assertReply("call me kirsle", "That's my botmaster's name too.");
142-
assertReply("one", ERR_DEEP_RECURSION_DETECTED);
144+
assertReply("one", DEFAULT_DEEP_RECURSION_MESSAGE);
143145
}
144146

145147
@Test

0 commit comments

Comments
 (0)