From 75a4da811eac88871572a7318270ce21bbb4667d Mon Sep 17 00:00:00 2001 From: Janne Valkealahti Date: Sat, 30 May 2015 18:01:21 +0100 Subject: [PATCH] Ref doc updates --- docs/src/reference/asciidoc/sm.adoc | 78 +++++++++++- .../docs/DocsConfigurationSampleTests.java | 111 ++++++++++++++++++ 2 files changed, 188 insertions(+), 1 deletion(-) diff --git a/docs/src/reference/asciidoc/sm.adoc b/docs/src/reference/asciidoc/sm.adoc index 976e0115..26fcbb92 100644 --- a/docs/src/reference/asciidoc/sm.adoc +++ b/docs/src/reference/asciidoc/sm.adoc @@ -90,7 +90,7 @@ simple _Guard_ is created as a bean and attached to transition between states `S1` and `S2`. Secondly a simple spel expression can be used as a guard where -expression must return a `Boolean` value. Behind a scenes this spel +expression must return a `BOOLEAN` value. Behind a scenes this spel based guard is a _SpelExpressionGuard_. This was attached to transition between states `S2` and `S3`. Both guard in above sample always evaluate to true. @@ -229,6 +229,82 @@ specifially handle a case that same bean will be called by a different state machines. This limitation is something which will be resolved in future releases. +[[sm-actions]] +== Using Actions +Actions are one of the most useful components from user perspective to +interact and collaborate with a state machine. Actions can be executed +in various places in a state machine and its states lifecycle like +entering or exiting states or during a transitions. + +[source,java,indent=0] +---- +include::samples/DocsConfigurationSampleTests.java[tags=snippetVA] +---- + +Above `action1` and `action2` beans are attached to states entry and +exit respectively. + +[source,java,indent=0] +---- +include::samples/DocsConfigurationSampleTests.java[tags=snippetVD] +---- + +You can directly implement _Action_ as an anonymous function or create +a your own implementation and define appropriate implementation as a +bean. + +In `action3` a SpEL expression is used to send event *Events.E1* into +a state machine. + +[NOTE] +==== +_StateContext_ is described in section <>. +==== + +=== SpEL Expressions with Actions +It is also possible to use SpEL expressions as a replacement for a +full _Action_ implementation. + +[[sm-guards]] +== Using Guards +Above `guard1` and `guard2` beans are attached to states entry and +exit respectively. + +[source,java,indent=0] +---- +include::samples/DocsConfigurationSampleTests.java[tags=snippetVB] +---- + +You can directly implement _Guard_ as an anonymous function or create +a your own implementation and define appropriate implementation as a +bean. In above sample `guardExpression` is simply checking if extended +state variable `myvar` evaluates to _TRUE_. + +[source,java,indent=0] +---- +include::samples/DocsConfigurationSampleTests.java[tags=snippetVC] +---- + +[NOTE] +==== +_StateContext_ is described in section <>. +==== + +=== SpEL Expressions with Guards +It is also possible to use SpEL expressions as a replacement for a +full _Guard_ implementation. Only requirement is that expression needs +to return a *Boolean* value to satisfy _Guard_ implementation. This is +demonstrated with a _guardExpression()_ function which takes an +expression as an argument. + +[[sm-statecontext]] +== Using StateContext +_StateContext_ is a domain object representing a current status of a +state machine within a transition or an action. Context gives an +access to a various information like event, message headers, extended +state variables, current trasition and a top-level state machine in +case there is a need to send events to a futher processing. + [[sm-triggers]] == Triggering Transitions Driving a statemachine is done via transitions which are triggerred diff --git a/spring-statemachine-core/src/test/java/org/springframework/statemachine/docs/DocsConfigurationSampleTests.java b/spring-statemachine-core/src/test/java/org/springframework/statemachine/docs/DocsConfigurationSampleTests.java index 0b67911f..176cbd36 100644 --- a/spring-statemachine-core/src/test/java/org/springframework/statemachine/docs/DocsConfigurationSampleTests.java +++ b/spring-statemachine-core/src/test/java/org/springframework/statemachine/docs/DocsConfigurationSampleTests.java @@ -25,12 +25,16 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.expression.Expression; +import org.springframework.expression.ExpressionParser; +import org.springframework.expression.spel.standard.SpelExpressionParser; import org.springframework.messaging.Message; import org.springframework.messaging.support.MessageBuilder; import org.springframework.statemachine.AbstractStateMachineTests; import org.springframework.statemachine.StateContext; import org.springframework.statemachine.StateMachine; import org.springframework.statemachine.action.Action; +import org.springframework.statemachine.action.SpelExpressionAction; import org.springframework.statemachine.annotation.OnTransition; import org.springframework.statemachine.annotation.WithStateMachine; import org.springframework.statemachine.config.EnableStateMachine; @@ -574,4 +578,111 @@ public class DocsConfigurationSampleTests extends AbstractStateMachineTests { } // end::snippetU[] + @Configuration + @EnableStateMachine + public static class Config16 extends EnumStateMachineConfigurerAdapter { + +// tag::snippetVA[] + @Override + public void configure(StateMachineStateConfigurer states) + throws Exception { + states + .withStates() + .initial(States.SI) + .state(States.S1, action1(), action2()) + .state(States.S2, action1(), action2()) + .state(States.S3, action1(), action3()); + } +// end::snippetVA[] + +// tag::snippetVB[] + @Override + public void configure(StateMachineTransitionConfigurer transitions) + throws Exception { + transitions + .withExternal() + .source(States.SI).target(States.S1) + .event(Events.E1) + .guard(guard1()) + .and() + .withExternal() + .source(States.S1).target(States.S2) + .event(Events.E1) + .guard(guard2()) + .and() + .withExternal() + .source(States.S2).target(States.S3) + .event(Events.E2) + .guardExpression("extendedState.variables.get('myvar')"); + } +// end::snippetVB[] + +// tag::snippetVC[] + @Bean + public Guard guard1() { + return new Guard() { + + @Override + public boolean evaluate(StateContext context) { + return true; + } + }; + } + + @Bean + public BaseGuard guard2() { + return new BaseGuard(); + } + + static class BaseGuard implements Guard { + + @Override + public boolean evaluate(StateContext context) { + return false; + } + } +// end::snippetVC[] + +// tag::snippetVD[] + @Bean + public Action action1() { + return new Action() { + + @Override + public void execute(StateContext context) { + } + }; + } + + @Bean + public BaseAction action2() { + return new BaseAction(); + } + + @Bean + public SpelAction action3() { + ExpressionParser parser = new SpelExpressionParser(); + return new SpelAction( + parser.parseExpression( + "stateMachine.sendEvent(T(org.springframework.statemachine.docs.Events).E1)")); + } + + static class BaseAction implements Action { + + @Override + public void execute(StateContext context) { + } + } + + static class SpelAction extends SpelExpressionAction { + + public SpelAction(Expression expression) { + super(expression); + } + } + +// end::snippetVD[] + + } + }