Add base system for StateMachinePersister
- New concepts easing persisting operations. - Base implementation of a persister which user can use instead of doing things manually to build a state machine context. Supports basic sm model but doesn't yet 'understand' deep and complex mixed models. - Fixed some features in sm reset functionality if root machine only have regions. - Relates to #184
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* 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.springframework.statemachine.persist;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.statemachine.ExtendedState;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.StateMachineContext;
|
||||
import org.springframework.statemachine.StateMachinePersist;
|
||||
import org.springframework.statemachine.access.StateMachineAccess;
|
||||
import org.springframework.statemachine.access.StateMachineFunction;
|
||||
import org.springframework.statemachine.region.Region;
|
||||
import org.springframework.statemachine.state.AbstractState;
|
||||
import org.springframework.statemachine.state.State;
|
||||
import org.springframework.statemachine.support.DefaultExtendedState;
|
||||
import org.springframework.statemachine.support.DefaultStateMachineContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Base implementation of a {@link StateMachinePersister} easing persist
|
||||
* operations with a {@link StateMachinePersist}.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
* @param <S> the type of state
|
||||
* @param <E> the type of event
|
||||
* @param <T> the type of context object
|
||||
*/
|
||||
public abstract class AbstractStateMachinePersister<S, E, T> implements StateMachinePersister<S, E, T> {
|
||||
|
||||
private final StateMachinePersist<S, E, T> stateMachinePersist;
|
||||
|
||||
/**
|
||||
* Instantiates a new abstract state machine persister.
|
||||
*
|
||||
* @param stateMachinePersist the state machine persist
|
||||
*/
|
||||
public AbstractStateMachinePersister(StateMachinePersist<S, E, T> stateMachinePersist) {
|
||||
Assert.notNull(stateMachinePersist, "StateMachinePersist must be set");
|
||||
this.stateMachinePersist = stateMachinePersist;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void persist(StateMachine<S, E> stateMachine, T contextOjb) throws Exception {
|
||||
stateMachinePersist.write(buildStateMachineContext(stateMachine), contextOjb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final StateMachine<S, E> reset(StateMachine<S, E> stateMachine, T contextOjb) throws Exception {
|
||||
final StateMachineContext<S, E> context = stateMachinePersist.read(contextOjb);
|
||||
stateMachine.stop();
|
||||
stateMachine.getStateMachineAccessor().doWithAllRegions(new StateMachineFunction<StateMachineAccess<S, E>>() {
|
||||
|
||||
@Override
|
||||
public void apply(StateMachineAccess<S, E> function) {
|
||||
function.resetStateMachine(context);
|
||||
}
|
||||
});
|
||||
stateMachine.start();
|
||||
return stateMachine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the state machine context which is used for persist operation.
|
||||
*
|
||||
* @param stateMachine the state machine
|
||||
* @return the state machine context
|
||||
*/
|
||||
protected StateMachineContext<S, E> buildStateMachineContext(StateMachine<S, E> stateMachine) {
|
||||
// TODO: need to make this fully recursive
|
||||
ExtendedState extendedState = new DefaultExtendedState();
|
||||
extendedState.getVariables().putAll(stateMachine.getExtendedState().getVariables());
|
||||
|
||||
ArrayList<StateMachineContext<S, E>> childs = new ArrayList<StateMachineContext<S, E>>();
|
||||
S id = null;
|
||||
State<S, E> state = stateMachine.getState();
|
||||
if (state.isSubmachineState()) {
|
||||
Collection<S> ids1 = state.getIds();
|
||||
@SuppressWarnings("unchecked")
|
||||
S[] ids2 = (S[]) ids1.toArray();
|
||||
// TODO: can this be empty as then we'd get error?
|
||||
id = ids2[ids2.length-1];
|
||||
} else if (state.isOrthogonal()) {
|
||||
Collection<Region<S, E>> regions = ((AbstractState<S, E>)state).getRegions();
|
||||
for (Region<S, E> r : regions) {
|
||||
S s = r.getState().getId();
|
||||
childs.add(new DefaultStateMachineContext<S, E>(s, null, null, null));
|
||||
}
|
||||
} else {
|
||||
id = state.getId();
|
||||
}
|
||||
|
||||
return new DefaultStateMachineContext<S, E>(childs, id, null, null,
|
||||
extendedState);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* 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.springframework.statemachine.persist;
|
||||
|
||||
import org.springframework.statemachine.StateMachinePersist;
|
||||
|
||||
/**
|
||||
* Default implementation of a {@link StateMachinePersister}.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
* @param <S> the type of state
|
||||
* @param <E> the type of event
|
||||
* @param <T> the type of context object
|
||||
*/
|
||||
public class DefaultStateMachinePersister<S, E, T> extends AbstractStateMachinePersister<S, E, T> {
|
||||
|
||||
/**
|
||||
* Instantiates a new default state machine persister.
|
||||
*
|
||||
* @param stateMachinePersist the state machine persist
|
||||
*/
|
||||
public DefaultStateMachinePersister(StateMachinePersist<S, E, T> stateMachinePersist) {
|
||||
super(stateMachinePersist);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* 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.springframework.statemachine.persist;
|
||||
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
|
||||
/**
|
||||
* Interface persisting a {@link StateMachine}.
|
||||
*
|
||||
* @author Janne Valkealahti
|
||||
*
|
||||
* @param <S> the type of state
|
||||
* @param <E> the type of event
|
||||
* @param <T> the type of context object
|
||||
*/
|
||||
public interface StateMachinePersister<S, E, T> {
|
||||
|
||||
/**
|
||||
* Persist a state machine with a given context object.
|
||||
*
|
||||
* @param stateMachine the state machine
|
||||
* @param contextOjb the context ojb
|
||||
* @throws Exception the exception in case or any persist error
|
||||
*/
|
||||
void persist(StateMachine<S, E> stateMachine, T contextOjb) throws Exception;
|
||||
|
||||
/**
|
||||
* Reset a state machine with a given context object.
|
||||
* Returned machine has been reseted and is ready to be used.
|
||||
*
|
||||
* @param stateMachine the state machine
|
||||
* @param contextOjb the context ojb
|
||||
* @return the state machine
|
||||
* @throws Exception the exception in case or any persist error
|
||||
*/
|
||||
StateMachine<S, E> reset(StateMachine<S, E> stateMachine, T contextOjb) throws Exception;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015 the original author or authors.
|
||||
* Copyright 2015-2016 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -493,6 +493,7 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
|
||||
@Override
|
||||
public void resetStateMachine(StateMachineContext<S, E> stateMachineContext) {
|
||||
// TODO: this function needs a serious rewrite
|
||||
if (stateMachineContext == null) {
|
||||
log.info("Got null context, resetting to initial state and clearing extended state");
|
||||
currentState = initialState;
|
||||
@@ -503,13 +504,10 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
log.debug("Request to reset state machine: stateMachine=[" + this + "] stateMachineContext=[" + stateMachineContext + "]");
|
||||
}
|
||||
S state = stateMachineContext.getState();
|
||||
if (state == null) {
|
||||
return;
|
||||
}
|
||||
boolean stateSet = false;
|
||||
for (State<S, E> s : getStates()) {
|
||||
for (State<S, E> ss : s.getStates()) {
|
||||
if (ss.getIds().contains(state)) {
|
||||
if (state != null && ss.getIds().contains(state)) {
|
||||
currentState = s;
|
||||
// TODO: not sure about starting submachine/regions here, though
|
||||
// needed if we only transit to super state or reset regions
|
||||
@@ -548,6 +546,25 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
||||
}
|
||||
stateSet = true;
|
||||
break;
|
||||
} else if (!stateMachineContext.getChilds().isEmpty()) {
|
||||
// we're here because root machine only have regions
|
||||
if (s.isOrthogonal()) {
|
||||
Collection<Region<S, E>> regions = ((AbstractState<S, E>)s).getRegions();
|
||||
for (Region<S, E> region : regions) {
|
||||
for (final StateMachineContext<S, E> child : stateMachineContext.getChilds()) {
|
||||
((StateMachine<S, E>)region).getStateMachineAccessor().doWithRegion(new StateMachineFunction<StateMachineAccess<S,E>>() {
|
||||
|
||||
@Override
|
||||
public void apply(StateMachineAccess<S, E> function) {
|
||||
function.resetStateMachine(child);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
for (Region<S, E> region : regions) {
|
||||
region.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (stateSet) {
|
||||
|
||||
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
*
|
||||
* 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.springframework.statemachine.persist;
|
||||
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.statemachine.AbstractStateMachineTests;
|
||||
import org.springframework.statemachine.StateMachine;
|
||||
import org.springframework.statemachine.StateMachineContext;
|
||||
import org.springframework.statemachine.StateMachinePersist;
|
||||
import org.springframework.statemachine.StateMachineSystemConstants;
|
||||
import org.springframework.statemachine.config.EnableStateMachine;
|
||||
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
|
||||
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
|
||||
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
|
||||
|
||||
public class StateMachinePersistTests extends AbstractStateMachineTests {
|
||||
|
||||
@Override
|
||||
protected AnnotationConfigApplicationContext buildContext() {
|
||||
return new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testSimplePersist1() throws Exception {
|
||||
context.register(Config1.class);
|
||||
context.refresh();
|
||||
StateMachine<String, String> stateMachine = context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, StateMachine.class);
|
||||
stateMachine.start();
|
||||
stateMachine.sendEvent("E1");
|
||||
assertThat(stateMachine.getState().getIds(), contains("S2"));
|
||||
|
||||
InMemoryStateMachinePersist1 stateMachinePersist = new InMemoryStateMachinePersist1();
|
||||
StateMachinePersister<String, String, String> persister = new DefaultStateMachinePersister<>(stateMachinePersist);
|
||||
|
||||
persister.persist(stateMachine, "xxx");
|
||||
persister.reset(stateMachine, "xxx");
|
||||
assertThat(stateMachine.getState().getIds(), contains("S2"));
|
||||
|
||||
stateMachine.sendEvent("E2");
|
||||
assertThat(stateMachine.getState().getIds(), contains("S3"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testSimplePersist2() throws Exception {
|
||||
context.register(Config2.class);
|
||||
context.refresh();
|
||||
StateMachine<TestStates, TestEvents> stateMachine = context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, StateMachine.class);
|
||||
stateMachine.start();
|
||||
stateMachine.sendEvent(TestEvents.E1);
|
||||
assertThat(stateMachine.getState().getIds(), contains(TestStates.S2));
|
||||
|
||||
InMemoryStateMachinePersist2 stateMachinePersist = new InMemoryStateMachinePersist2();
|
||||
StateMachinePersister<TestStates, TestEvents, String> persister = new DefaultStateMachinePersister<>(stateMachinePersist);
|
||||
|
||||
persister.persist(stateMachine, "xxx");
|
||||
persister.reset(stateMachine, "xxx");
|
||||
assertThat(stateMachine.getState().getIds(), contains(TestStates.S2));
|
||||
|
||||
stateMachine.sendEvent(TestEvents.E2);
|
||||
assertThat(stateMachine.getState().getIds(), contains(TestStates.S3));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testExtendedState() throws Exception {
|
||||
context.register(Config1.class);
|
||||
context.refresh();
|
||||
StateMachine<String, String> stateMachine = context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, StateMachine.class);
|
||||
stateMachine.start();
|
||||
|
||||
stateMachine.getExtendedState().getVariables().put("foo", "bar");
|
||||
|
||||
InMemoryStateMachinePersist1 stateMachinePersist = new InMemoryStateMachinePersist1();
|
||||
StateMachinePersister<String, String, String> persister = new DefaultStateMachinePersister<>(stateMachinePersist);
|
||||
|
||||
persister.persist(stateMachine, "xxx");
|
||||
stateMachine.getExtendedState().getVariables().remove("foo");
|
||||
stateMachine = persister.reset(stateMachine, "xxx");
|
||||
|
||||
assertThat(stateMachine.getExtendedState().get("foo", String.class), is("bar"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testSubStates() throws Exception {
|
||||
context.register(Config3.class);
|
||||
context.refresh();
|
||||
StateMachine<String, String> stateMachine = context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, StateMachine.class);
|
||||
stateMachine.start();
|
||||
stateMachine.sendEvent("E1");
|
||||
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21"));
|
||||
stateMachine.sendEvent("E3");
|
||||
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S22"));
|
||||
|
||||
InMemoryStateMachinePersist1 stateMachinePersist = new InMemoryStateMachinePersist1();
|
||||
StateMachinePersister<String, String, String> persister = new DefaultStateMachinePersister<>(stateMachinePersist);
|
||||
|
||||
persister.persist(stateMachine, "xxx");
|
||||
stateMachine = persister.reset(stateMachine, "xxx");
|
||||
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S22"));
|
||||
|
||||
stateMachine.sendEvent("E2");
|
||||
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S3", "S31"));
|
||||
|
||||
stateMachine = persister.reset(stateMachine, "xxx");
|
||||
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S22"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testRegions() throws Exception {
|
||||
context.register(Config4.class);
|
||||
context.refresh();
|
||||
StateMachine<String, String> stateMachine = context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, StateMachine.class);
|
||||
stateMachine.start();
|
||||
|
||||
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S11", "S21", "S31"));
|
||||
|
||||
stateMachine.sendEvent("E1");
|
||||
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S12", "S21", "S31"));
|
||||
stateMachine.sendEvent("E2");
|
||||
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S12", "S22", "S31"));
|
||||
stateMachine.sendEvent("E3");
|
||||
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S12", "S22", "S32"));
|
||||
|
||||
InMemoryStateMachinePersist1 stateMachinePersist = new InMemoryStateMachinePersist1();
|
||||
StateMachinePersister<String, String, String> persister = new DefaultStateMachinePersister<>(stateMachinePersist);
|
||||
|
||||
persister.persist(stateMachine, "xxx");
|
||||
stateMachine = persister.reset(stateMachine, "xxx");
|
||||
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S12", "S22", "S32"));
|
||||
|
||||
stateMachine.sendEvent("E4");
|
||||
stateMachine.sendEvent("E5");
|
||||
stateMachine.sendEvent("E6");
|
||||
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S13", "S23", "S33"));
|
||||
|
||||
stateMachine = persister.reset(stateMachine, "xxx");
|
||||
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S12", "S22", "S32"));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
static class Config1 extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineStateConfigurer<String, String> states) throws Exception {
|
||||
states
|
||||
.withStates()
|
||||
.initial("S1")
|
||||
.state("S1")
|
||||
.state("S2")
|
||||
.state("S3");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineTransitionConfigurer<String, String> transitions) throws Exception {
|
||||
transitions
|
||||
.withExternal()
|
||||
.source("S1")
|
||||
.target("S2")
|
||||
.event("E1")
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("S2")
|
||||
.target("S3")
|
||||
.event("E2");
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
static class Config2 extends StateMachineConfigurerAdapter<TestStates, TestEvents> {
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineStateConfigurer<TestStates, TestEvents> states) throws Exception {
|
||||
states
|
||||
.withStates()
|
||||
.initial(TestStates.S1)
|
||||
.state(TestStates.S1)
|
||||
.state(TestStates.S2)
|
||||
.state(TestStates.S3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineTransitionConfigurer<TestStates, TestEvents> transitions) throws Exception {
|
||||
transitions
|
||||
.withExternal()
|
||||
.source(TestStates.S1)
|
||||
.target(TestStates.S2)
|
||||
.event(TestEvents.E1)
|
||||
.and()
|
||||
.withExternal()
|
||||
.source(TestStates.S2)
|
||||
.target(TestStates.S3)
|
||||
.event(TestEvents.E2);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
static class Config3 extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineStateConfigurer<String, String> states) throws Exception {
|
||||
states
|
||||
.withStates()
|
||||
.initial("S1")
|
||||
.state("S1")
|
||||
.state("S2")
|
||||
.state("S3")
|
||||
.and()
|
||||
.withStates()
|
||||
.parent("S2")
|
||||
.initial("S21")
|
||||
.state("S21")
|
||||
.state("S22")
|
||||
.and()
|
||||
.withStates()
|
||||
.parent("S3")
|
||||
.initial("S31")
|
||||
.state("S31")
|
||||
.state("S32");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineTransitionConfigurer<String, String> transitions) throws Exception {
|
||||
transitions
|
||||
.withExternal()
|
||||
.source("S1")
|
||||
.target("S2")
|
||||
.event("E1")
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("S2")
|
||||
.target("S3")
|
||||
.event("E2")
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("S21")
|
||||
.target("S22")
|
||||
.event("E3");
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableStateMachine
|
||||
static class Config4 extends StateMachineConfigurerAdapter<String, String> {
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineStateConfigurer<String, String> states) throws Exception {
|
||||
states
|
||||
.withStates()
|
||||
.initial("S11")
|
||||
.state("S11")
|
||||
.state("S12")
|
||||
.state("S13")
|
||||
.and()
|
||||
.withStates()
|
||||
.initial("S21")
|
||||
.state("S21")
|
||||
.state("S22")
|
||||
.state("S23")
|
||||
.and()
|
||||
.withStates()
|
||||
.initial("S31")
|
||||
.state("S31")
|
||||
.state("S32")
|
||||
.state("S33");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(StateMachineTransitionConfigurer<String, String> transitions) throws Exception {
|
||||
transitions
|
||||
.withExternal()
|
||||
.source("S11")
|
||||
.target("S12")
|
||||
.event("E1")
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("S21")
|
||||
.target("S22")
|
||||
.event("E2")
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("S31")
|
||||
.target("S32")
|
||||
.event("E3")
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("S12")
|
||||
.target("S13")
|
||||
.event("E4")
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("S22")
|
||||
.target("S23")
|
||||
.event("E5")
|
||||
.and()
|
||||
.withExternal()
|
||||
.source("S32")
|
||||
.target("S33")
|
||||
.event("E6");
|
||||
}
|
||||
}
|
||||
|
||||
static class InMemoryStateMachinePersist1 implements StateMachinePersist<String, String, String> {
|
||||
|
||||
private final HashMap<String, StateMachineContext<String, String>> contexts = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void write(StateMachineContext<String, String> context, String contextOjb) throws Exception {
|
||||
contexts.put(contextOjb, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateMachineContext<String, String> read(String contextOjb) throws Exception {
|
||||
return contexts.get(contextOjb);
|
||||
}
|
||||
}
|
||||
|
||||
static class InMemoryStateMachinePersist2 implements StateMachinePersist<TestStates, TestEvents, String> {
|
||||
|
||||
private final HashMap<String, StateMachineContext<TestStates, TestEvents>> contexts = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void write(StateMachineContext<TestStates, TestEvents> context, String contextOjb) throws Exception {
|
||||
contexts.put(contextOjb, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StateMachineContext<TestStates, TestEvents> read(String contextOjb) throws Exception {
|
||||
return contexts.get(contextOjb);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user