Add complex showcase sm sample

This commit is contained in:
Janne Valkealahti
2015-03-07 19:23:40 +00:00
parent 5bdf642005
commit fe0f7ebb95
11 changed files with 320 additions and 0 deletions

View File

@@ -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);
}
}

View File

@@ -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";
}
}

View File

@@ -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>

View File

@@ -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 | | | | |
| | | | | | |<------| | | | |
| | | | | | | +--------------+ | | |
| | +---------------+ | | +------------------------------+ | |
| | | | | |
| +-------------------------+ +--------------------------------------------+ |
| |
+---------------------------------------------------------------------------------------------+

View File

@@ -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;
}
}
}