Add complex showcase sm sample
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
package demo.showcase;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.shell.Bootstrap;
|
||||
import org.springframework.statemachine.StateContext;
|
||||
import org.springframework.statemachine.action.Action;
|
||||
import org.springframework.statemachine.config.EnableStateMachine;
|
||||
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
|
||||
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
|
||||
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
|
||||
import org.springframework.statemachine.guard.Guard;
|
||||
|
||||
@Configuration
|
||||
public class Application {
|
||||
|
||||
//tag::snippetA[]
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
static class StateMachineConfig
|
||||
extends EnumStateMachineConfigurerAdapter<States, Events> {
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineStateConfigurer<States, Events> states)
|
||||
throws Exception {
|
||||
states
|
||||
.withStates()
|
||||
.initial(States.S0)
|
||||
.state(States.S0)
|
||||
.and()
|
||||
.withStates()
|
||||
.parent(States.S0)
|
||||
.initial(States.S1)
|
||||
.state(States.S1)
|
||||
.and()
|
||||
.withStates()
|
||||
.parent(States.S1)
|
||||
.initial(States.S11)
|
||||
.state(States.S11)
|
||||
.and()
|
||||
.withStates()
|
||||
.parent(States.S0)
|
||||
.state(States.S2)
|
||||
.and()
|
||||
.withStates()
|
||||
.parent(States.S2)
|
||||
.initial(States.S21)
|
||||
.state(States.S21)
|
||||
.and()
|
||||
.withStates()
|
||||
.parent(States.S21)
|
||||
.initial(States.S211)
|
||||
.state(States.S211);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
|
||||
throws Exception {
|
||||
transitions
|
||||
.withExternal()
|
||||
.source(States.S1).target(States.S1).event(Events.A)
|
||||
.action(fooAction())
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(States.S1).target(States.S11).event(Events.B)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(States.S21).target(States.S211).event(Events.B)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(States.S1).target(States.S2).event(Events.C)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(States.S2).target(States.S1).event(Events.C)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(States.S1).target(States.S0).event(Events.D)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(States.S211).target(States.S21).event(Events.D)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(States.S0).target(States.S211).event(Events.E)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(States.S1).target(States.S211).event(Events.F)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(States.S2).target(States.S11).event(Events.F)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(States.S11).target(States.S211).event(Events.G)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(States.S211).target(States.S0).event(Events.G)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(States.S21).target(States.S21).event(Events.H)
|
||||
.guard(fooGuard());
|
||||
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FooGuard fooGuard() {
|
||||
return new FooGuard();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FooAction fooAction() {
|
||||
return new FooAction();
|
||||
}
|
||||
|
||||
}
|
||||
//end::snippetA[]
|
||||
|
||||
//tag::snippetB[]
|
||||
public static enum States {
|
||||
S0, S1, S11, S2, S21, S211
|
||||
}
|
||||
//end::snippetB[]
|
||||
|
||||
//tag::snippetC[]
|
||||
public static enum Events {
|
||||
A, B, C, D, E, F, G, H
|
||||
}
|
||||
//end::snippetC[]
|
||||
|
||||
// tag::snippetD[]
|
||||
private static class FooAction implements Action<States, Events> {
|
||||
|
||||
@Override
|
||||
public void execute(StateContext<States, Events> context) {
|
||||
context.getExtendedState().getVariables().put("foo", 1);
|
||||
}
|
||||
}
|
||||
|
||||
// end::snippetD[]
|
||||
|
||||
// tag::snippetE[]
|
||||
private static class FooGuard implements Guard<States, Events> {
|
||||
|
||||
@Override
|
||||
public boolean evaluate(StateContext<States, Events> context) {
|
||||
Object foo = context.getExtendedState().getVariables().get("foo");
|
||||
return !(foo == null || !foo.equals(1));
|
||||
}
|
||||
}
|
||||
// end::snippetE[]
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Bootstrap.main(args);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package demo.showcase;
|
||||
|
||||
import org.springframework.shell.core.annotation.CliCommand;
|
||||
import org.springframework.shell.core.annotation.CliOption;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import demo.AbstractStateMachineCommands;
|
||||
import demo.showcase.Application.Events;
|
||||
import demo.showcase.Application.States;
|
||||
|
||||
@Component
|
||||
public class StateMachineCommands extends AbstractStateMachineCommands<States, Events> {
|
||||
|
||||
@CliCommand(value = "sm event", help = "Sends an event to a state machine")
|
||||
public String event(@CliOption(key = { "", "event" }, mandatory = true, help = "The event") final Events event) {
|
||||
getStateMachine().sendEvent(event);
|
||||
return "Event " + event + " send";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
|
||||
<context:component-scan base-package="demo" />
|
||||
</beans>
|
||||
@@ -0,0 +1,33 @@
|
||||
+---------------------------------------------------------------------------------------------+
|
||||
| S0 |
|
||||
+---------------------------------------------------------------------------------------------+
|
||||
| entry/ |
|
||||
| exit/ |
|
||||
| +-------------------------+ +--------------------------------------------+ |
|
||||
| *-->| S1 | | S2 | |
|
||||
| +-------------------------+ C +--------------------------------------------+ |
|
||||
| | entry/ | | entry/ H | |
|
||||
| D | exit/ |----->| exit/ +-------------------+ | |
|
||||
|<<---------| | | | H[foo.equals(1)]; | | |
|
||||
| | +---------------+ | C | +------------------------------+ | | |
|
||||
| | *-->| S11 | |<-----| *-->| S21 |<--+ | |
|
||||
| | +---------------+ | | +------------------------------+ | |
|
||||
| +--| | entry/ | | F | | entry/ | | |
|
||||
| A| | | exit/ |<---------| | exit/ | | |
|
||||
| +->| | | | | | +--------------+ | | |
|
||||
| A[foo 1]; | B | | | | | *-->| s211 | | | |
|
||||
| |---->| | | | F | +--------------+ | | |
|
||||
| | | | |-------------------->| entry/ | | G | |
|
||||
| | | | | | G | | exit/ |----------------->|
|
||||
| | | |------------------------>| | | | |
|
||||
| | | | | | | B | | | E | |
|
||||
| | | | | | |------>| |<-----------------|
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | D | | | | |
|
||||
| | | | | | |<------| | | | |
|
||||
| | | | | | | +--------------+ | | |
|
||||
| | +---------------+ | | +------------------------------+ | |
|
||||
| | | | | |
|
||||
| +-------------------------+ +--------------------------------------------+ |
|
||||
| |
|
||||
+---------------------------------------------------------------------------------------------+
|
||||
@@ -0,0 +1,41 @@
|
||||
package demo.showcase;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.statemachine.EnumStateMachine;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.StateMachineSystemConstants;
|
||||
|
||||
import demo.CommonConfiguration;
|
||||
import demo.showcase.Application.Events;
|
||||
import demo.showcase.Application.States;
|
||||
|
||||
public class ShowcaseTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@Test
|
||||
public void testApplication() {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
context.register(CommonConfiguration.class, Application.class);
|
||||
context.refresh();
|
||||
@SuppressWarnings("unchecked")
|
||||
StateMachine<States,Events> machine = context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, EnumStateMachine.class);
|
||||
|
||||
machine.start();
|
||||
|
||||
machine.sendEvent(Events.A);
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void clean() {
|
||||
if (context != null) {
|
||||
context.close();
|
||||
context = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user