/*
* Copyright 2016-2017 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.uml;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
import org.springframework.statemachine.config.model.DefaultStateMachineComponentResolver;
import org.springframework.statemachine.config.model.StateData;
import org.springframework.statemachine.config.model.StateMachineModel;
import org.springframework.statemachine.config.model.StateMachineModelFactory;
import org.springframework.statemachine.config.model.TransitionData;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
import org.springframework.statemachine.state.PseudoStateKind;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.transition.TransitionKind;
import org.springframework.util.ObjectUtils;
public class UmlStateMachineModelFactoryTests extends AbstractUmlTests {
@Override
protected AnnotationConfigApplicationContext buildContext() {
return new AnnotationConfigApplicationContext();
}
@Test
public void testSimpleFlat1() {
context.refresh();
Resource model1 = new ClassPathResource("org/springframework/statemachine/uml/simple-flat.uml");
UmlStateMachineModelFactory builder = new UmlStateMachineModelFactory(model1);
builder.registerAction("action1", new LatchAction());
builder.setBeanFactory(context);
assertThat(model1.exists(), is(true));
StateMachineModel<String, String> stateMachineModel = builder.build();
assertThat(stateMachineModel, notNullValue());
Collection<StateData<String, String>> stateDatas = stateMachineModel.getStatesData().getStateData();
assertThat(stateDatas.size(), is(2));
for (StateData<String, String> stateData : stateDatas) {
if (stateData.getState().equals("S1")) {
assertThat(stateData.isInitial(), is(true));
} else if (stateData.getState().equals("S2")) {
assertThat(stateData.isInitial(), is(false));
} else {
throw new IllegalArgumentException();
}
}
}
@Test
public void testSimpleFlat2() {
context.refresh();
Resource model1 = new ClassPathResource("org/springframework/statemachine/uml/simple-flat.uml");
DefaultStateMachineComponentResolver<String, String> resolver = new DefaultStateMachineComponentResolver<>();
resolver.registerAction("action1", new LatchAction());
UmlStateMachineModelFactory builder = new UmlStateMachineModelFactory(model1);
builder.setStateMachineComponentResolver(resolver);
assertThat(model1.exists(), is(true));
StateMachineModel<String, String> stateMachineModel = builder.build();
assertThat(stateMachineModel, notNullValue());
Collection<StateData<String, String>> stateDatas = stateMachineModel.getStatesData().getStateData();
assertThat(stateDatas.size(), is(2));
for (StateData<String, String> stateData : stateDatas) {
if (stateData.getState().equals("S1")) {
assertThat(stateData.isInitial(), is(true));
} else if (stateData.getState().equals("S2")) {
assertThat(stateData.isInitial(), is(false));
} else {
throw new IllegalArgumentException();
}
}
}
@Test
public void testSimpleSubmachine() {
context.refresh();
Resource model1 = new ClassPathResource("org/springframework/statemachine/uml/simple-submachine.uml");
UmlStateMachineModelFactory builder = new UmlStateMachineModelFactory(model1);
builder.setBeanFactory(context);
assertThat(model1.exists(), is(true));
StateMachineModel<String, String> stateMachineModel = builder.build();
assertThat(stateMachineModel, notNullValue());
Collection<StateData<String, String>> stateDatas = stateMachineModel.getStatesData().getStateData();
assertThat(stateDatas.size(), is(4));
for (StateData<String, String> stateData : stateDatas) {
if (stateData.getState().equals("S1")) {
assertThat(stateData.isInitial(), is(true));
assertThat(stateData.getParent(), nullValue());
} else if (stateData.getState().equals("S2")) {
assertThat(stateData.isInitial(), is(false));
assertThat(stateData.getParent(), nullValue());
} else if (stateData.getState().equals("S11")) {
assertThat(stateData.isInitial(), is(true));
assertThat(stateData.getParent(), is("S1"));
} else if (stateData.getState().equals("S12")) {
assertThat(stateData.isInitial(), is(false));
assertThat(stateData.getParent(), is("S1"));
} else {
throw new IllegalArgumentException();
}
}
}
@Test
public void testSimpleRootRegions() {
context.refresh();
Resource model1 = new ClassPathResource("org/springframework/statemachine/uml/simple-root-regions.uml");
UmlStateMachineModelFactory builder = new UmlStateMachineModelFactory(model1);
builder.setBeanFactory(context);
assertThat(model1.exists(), is(true));
StateMachineModel<String, String> stateMachineModel = builder.build();
assertThat(stateMachineModel, notNullValue());
Collection<StateData<String, String>> stateDatas = stateMachineModel.getStatesData().getStateData();
assertThat(stateDatas.size(), is(4));
for (StateData<String, String> stateData : stateDatas) {
if (stateData.getState().equals("S1")) {
assertThat(stateData.isInitial(), is(true));
assertThat(stateData.getRegion(), notNullValue());
} else if (stateData.getState().equals("S2")) {
assertThat(stateData.isInitial(), is(false));
assertThat(stateData.getRegion(), notNullValue());
} else if (stateData.getState().equals("S3")) {
assertThat(stateData.isInitial(), is(true));
assertThat(stateData.getRegion(), notNullValue());
} else if (stateData.getState().equals("S4")) {
assertThat(stateData.isInitial(), is(false));
assertThat(stateData.getRegion(), notNullValue());
} else {
throw new IllegalArgumentException();
}
}
}
@Test
public void testSimpleFlatEnd() {
context.refresh();
Resource model1 = new ClassPathResource("org/springframework/statemachine/uml/simple-flat-end.uml");
UmlStateMachineModelFactory builder = new UmlStateMachineModelFactory(model1);
builder.setBeanFactory(context);
assertThat(model1.exists(), is(true));
StateMachineModel<String, String> stateMachineModel = builder.build();
assertThat(stateMachineModel, notNullValue());
Collection<StateData<String, String>> stateDatas = stateMachineModel.getStatesData().getStateData();
assertThat(stateDatas.size(), is(3));
for (StateData<String, String> stateData : stateDatas) {
if (stateData.getState().equals("S1")) {
assertThat(stateData.isInitial(), is(true));
assertThat(stateData.isEnd(), is(false));
} else if (stateData.getState().equals("S2")) {
assertThat(stateData.isInitial(), is(false));
assertThat(stateData.isEnd(), is(false));
} else if (stateData.getState().equals("S3")) {
assertThat(stateData.isEnd(), is(true));
} else {
throw new IllegalArgumentException();
}
}
}
@Test
public void testSimpleEntryExit() {
context.refresh();
Resource model1 = new ClassPathResource("org/springframework/statemachine/uml/simple-entryexit.uml");
UmlStateMachineModelFactory builder = new UmlStateMachineModelFactory(model1);
builder.setBeanFactory(context);
assertThat(model1.exists(), is(true));
StateMachineModel<String, String> stateMachineModel = builder.build();
assertThat(stateMachineModel, notNullValue());
Collection<StateData<String, String>> stateDatas = stateMachineModel.getStatesData().getStateData();
assertThat(stateDatas.size(), is(8));
for (StateData<String, String> stateData : stateDatas) {
if (stateData.getState().equals("S1")) {
assertThat(stateData.isInitial(), is(true));
} else if (stateData.getState().equals("S2")) {
assertThat(stateData.isInitial(), is(false));
} else if (stateData.getState().equals("S21")) {
assertThat(stateData.isInitial(), is(true));
} else if (stateData.getState().equals("S22")) {
assertThat(stateData.isInitial(), is(false));
} else if (stateData.getState().equals("S3")) {
assertThat(stateData.isInitial(), is(false));
} else if (stateData.getState().equals("S4")) {
assertThat(stateData.isInitial(), is(false));
} else if (stateData.getState().equals("ENTRY")) {
assertThat(stateData.isInitial(), is(false));
assertThat(stateData.getPseudoStateKind(), is(PseudoStateKind.ENTRY));
} else if (stateData.getState().equals("EXIT")) {
assertThat(stateData.getPseudoStateKind(), is(PseudoStateKind.EXIT));
assertThat(stateData.isInitial(), is(false));
} else {
throw new IllegalArgumentException();
}
}
assertThat(stateMachineModel.getTransitionsData().getEntrys().size(), is(1));
assertThat(stateMachineModel.getTransitionsData().getExits().size(), is(1));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleFlatMachine() throws Exception {
context.register(Config2.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
LatchAction action1 = context.getBean("action1", LatchAction.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), contains("S1"));
stateMachine.sendEvent("E1");
assertThat(action1.latch.await(2, TimeUnit.SECONDS), is(true));
assertThat(stateMachine.getState().getIds(), contains("S2"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleSubmachineMachine() throws Exception {
context.register(Config3.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), contains("S1", "S11"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), contains("S1", "S12"));
stateMachine.sendEvent("E2");
assertThat(stateMachine.getState().getIds(), contains("S2"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleRootRegionsMachine() throws Exception {
context.register(Config4.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1", "S3"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S3"));
stateMachine.sendEvent("E2");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S4"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleEntryExitMachine() throws Exception {
context.register(Config5.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E3");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S22"));
stateMachine.sendEvent("E4");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S4"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleChoice1() {
context.register(Config6.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent(MessageBuilder.withPayload("E1").setHeader("choice", "s2").build());
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleChoice2() {
context.register(Config6.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent(MessageBuilder.withPayload("E1").setHeader("choice", "s3").build());
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S3"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleChoice3() {
context.register(Config6.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S4"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleForkJoin() {
context.register(Config7.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("SI"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S20", "S30"));
stateMachine.sendEvent("E2");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21", "S30"));
stateMachine.sendEvent("E3");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("SF"));
}
@Test
@SuppressWarnings("unchecked")
public void testMultiJoinForkJoin1() {
context.register(Config20.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("SI"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S20", "S30"));
stateMachine.sendEvent("E2");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21", "S30"));
stateMachine.sendEvent("E3");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S4"));
}
@Test
@SuppressWarnings("unchecked")
public void testMultiJoinForkJoin2() {
context.register(Config20.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
stateMachine.getExtendedState().getVariables().put("foo", "bar");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("SI"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S20", "S30"));
stateMachine.sendEvent("E2");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21", "S30"));
stateMachine.sendEvent("E3");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("SF"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleHistoryShallow() {
context.register(Config8.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S20"));
stateMachine.sendEvent("E2");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21"));
stateMachine.sendEvent("E3");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E4");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleHistoryDeep() {
context.register(Config9.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21", "S211"));
stateMachine.sendEvent("E2");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21", "S212"));
stateMachine.sendEvent("E3");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E4");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21", "S212"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleJunction1() {
context.register(Config10.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2"));
stateMachine.sendEvent(MessageBuilder.withPayload("E4").setHeader("junction", "s5").build());
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S5"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleJunction2() {
context.register(Config10.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E2");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S3"));
stateMachine.sendEvent(MessageBuilder.withPayload("E4").setHeader("junction", "s6").build());
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S6"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleJunction3() {
context.register(Config10.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E3");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S4"));
stateMachine.sendEvent("E4");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S7"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleActions() throws Exception {
context.register(Config11.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
LatchAction e1Action = context.getBean("e1Action", LatchAction.class);
LatchAction s1Exit = context.getBean("s1Exit", LatchAction.class);
LatchAction s2Entry = context.getBean("s2Entry", LatchAction.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2"));
assertThat(e1Action.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(s1Exit.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(s2Entry.latch.await(1, TimeUnit.SECONDS), is(true));
}
@Test
public void testSimpleEventDefer() {
context.refresh();
Resource model1 = new ClassPathResource("org/springframework/statemachine/uml/simple-eventdefer.uml");
UmlStateMachineModelFactory builder = new UmlStateMachineModelFactory(model1);
assertThat(model1.exists(), is(true));
StateMachineModel<String, String> stateMachineModel = builder.build();
assertThat(stateMachineModel, notNullValue());
Collection<StateData<String, String>> stateDatas = stateMachineModel.getStatesData().getStateData();
assertThat(stateDatas.size(), is(3));
for (StateData<String, String> stateData : stateDatas) {
if (stateData.getState().equals("S1")) {
assertThat(stateData.isInitial(), is(true));
assertThat(stateData.getDeferred().size(), is(1));
assertThat(stateData.getDeferred().iterator().next(), is("E2"));
} else if (stateData.getState().equals("S2")) {
assertThat(stateData.isInitial(), is(false));
assertThat(stateData.getDeferred().size(), is(0));
} else if (stateData.getState().equals("S3")) {
assertThat(stateData.isInitial(), is(false));
assertThat(stateData.getDeferred().size(), is(0));
} else {
throw new IllegalArgumentException();
}
}
}
@Test
public void testSimpleTransitionTypes() {
context.refresh();
Resource model1 = new ClassPathResource("org/springframework/statemachine/uml/simple-transitiontypes.uml");
UmlStateMachineModelFactory builder = new UmlStateMachineModelFactory(model1);
assertThat(model1.exists(), is(true));
StateMachineModel<String, String> stateMachineModel = builder.build();
assertThat(stateMachineModel, notNullValue());
Collection<StateData<String, String>> stateDatas = stateMachineModel.getStatesData().getStateData();
Collection<TransitionData<String, String>> transitionDatas = stateMachineModel.getTransitionsData().getTransitions();
assertThat(stateDatas.size(), is(2));
assertThat(transitionDatas.size(), is(3));
for (TransitionData<String, String> transitionData : transitionDatas) {
if (transitionData.getEvent().equals("E1")) {
assertThat(transitionData.getKind(), is(TransitionKind.EXTERNAL));
} else if (transitionData.getEvent().equals("E2")) {
assertThat(transitionData.getKind(), is(TransitionKind.LOCAL));
} else if (transitionData.getEvent().equals("E3")) {
assertThat(transitionData.getKind(), is(TransitionKind.INTERNAL));
} else {
throw new IllegalArgumentException();
}
}
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleHistoryDefault() {
context.register(Config12.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E4");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S22"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleTimers1() throws Exception {
context.register(Config13.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
LatchAction s3Entry = context.getBean("s3Entry", LatchAction.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E1");
assertThat(s3Entry.latch.await(2, TimeUnit.SECONDS), is(true));
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S3"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleTimers2() throws Exception {
context.register(Config13.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
LatchAction s5Entry = context.getBean("s5Entry", LatchAction.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E2");
assertThat(s5Entry.latch.await(2, TimeUnit.SECONDS), is(true));
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S5"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleGuardsDeny1() throws Exception {
context.register(Config14.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleGuardsDeny2() throws Exception {
context.register(Config14.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E2");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S3"));
}
@Test
@SuppressWarnings("unchecked")
public void testInitialActions() throws Exception {
context.register(Config15.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
LatchAction initialAction = context.getBean("initialAction", LatchAction.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
assertThat(initialAction.latch.await(1, TimeUnit.SECONDS), is(true));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleSpelsAllow() throws Exception {
context.register(Config16.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent(MessageBuilder.withPayload("E1").setHeader("foo", "bar").build());
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2"));
assertThat(stateMachine.getExtendedState().get("myvar1", String.class), is("myvalue1"));
assertThat(stateMachine.getExtendedState().get("myvar2", String.class), is("myvalue2"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleSpelsDeny() throws Exception {
context.register(Config16.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
}
@Test
public void testSimpleFlatMultipleToEnds() throws Exception {
context.register(Config17.class);
context.refresh();
}
@Test
public void testSimpleFlatMultipleToEndsViachoices() throws Exception {
context.register(Config18.class);
context.refresh();
}
@Test
public void testBrokenModelShadowEntries() throws Exception {
context.register(Config19.class);
context.refresh();
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleSubmachineRef() throws Exception {
context.register(Config21.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S20"));
stateMachine.sendEvent("E2");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21", "S30"));
stateMachine.sendEvent("E3");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21", "S31"));
stateMachine.sendEvent("E4");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S3"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleStateActions() throws Exception {
context.register(Config22.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
LatchAction e1Action = context.getBean("e1Action", LatchAction.class);
LatchAction e2Action = context.getBean("e2Action", LatchAction.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
assertThat(e1Action.latch.await(1, TimeUnit.SECONDS), is(true));
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2"));
assertThat(e2Action.latch.await(1, TimeUnit.SECONDS), is(true));
stateMachine.sendEvent("E2");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S3"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleLocaltransitionExternalSuperDoesEntryExitToSub() {
context.register(Config23.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
assertThat(stateMachine, notNullValue());
TestListener listener = new TestListener();
stateMachine.addStateListener(listener);
stateMachine.start();
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21"));
listener.reset();
stateMachine.sendEvent("E20");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21"));
assertThat(listener.exited.size(), is(2));
assertThat(listener.entered.size(), is(2));
assertThat(listener.exited, containsInAnyOrder("S2", "S21"));
assertThat(listener.entered, containsInAnyOrder("S2", "S21"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleLocaltransitionLocalSuperDoesNotEntryExitToSub() {
context.register(Config23.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
assertThat(stateMachine, notNullValue());
TestListener listener = new TestListener();
stateMachine.addStateListener(listener);
stateMachine.start();
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21"));
listener.reset();
stateMachine.sendEvent("E30");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21"));
assertThat(listener.exited.size(), is(1));
assertThat(listener.entered.size(), is(1));
assertThat(listener.exited, containsInAnyOrder("S21"));
assertThat(listener.entered, containsInAnyOrder("S21"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleLocaltransitionExternalToNonInitialSuperDoesEntryExitToSub() {
context.register(Config23.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
assertThat(stateMachine, notNullValue());
TestListener listener = new TestListener();
stateMachine.addStateListener(listener);
stateMachine.start();
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21"));
listener.reset();
stateMachine.sendEvent("E21");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S22"));
assertThat(listener.exited.size(), is(2));
assertThat(listener.entered.size(), is(2));
assertThat(listener.exited, containsInAnyOrder("S2", "S21"));
assertThat(listener.entered, containsInAnyOrder("S2", "S22"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleLocaltransitionLocalToNonInitialSuperDoesNotEntryExitToSub() {
context.register(Config23.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
assertThat(stateMachine, notNullValue());
TestListener listener = new TestListener();
stateMachine.addStateListener(listener);
stateMachine.start();
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21"));
listener.reset();
stateMachine.sendEvent("E31");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S22"));
assertThat(listener.exited.size(), is(1));
assertThat(listener.entered.size(), is(1));
assertThat(listener.exited, containsInAnyOrder("S21"));
assertThat(listener.entered, containsInAnyOrder("S22"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleLocaltransitionExternalSuperDoesEntryExitToParent() {
context.register(Config23.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
assertThat(stateMachine, notNullValue());
TestListener listener = new TestListener();
stateMachine.addStateListener(listener);
stateMachine.start();
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21"));
listener.reset();
stateMachine.sendEvent("E22");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21"));
assertThat(listener.exited.size(), is(2));
assertThat(listener.entered.size(), is(2));
assertThat(listener.exited, containsInAnyOrder("S2", "S21"));
assertThat(listener.entered, containsInAnyOrder("S2", "S21"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleLocaltransitionLocalSuperDoesNotEntryExitToParent() {
context.register(Config23.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
assertThat(stateMachine, notNullValue());
TestListener listener = new TestListener();
stateMachine.addStateListener(listener);
stateMachine.start();
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21"));
listener.reset();
stateMachine.sendEvent("E32");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21"));
assertThat(listener.exited.size(), is(1));
assertThat(listener.entered.size(), is(1));
assertThat(listener.exited, containsInAnyOrder("S21"));
assertThat(listener.entered, containsInAnyOrder("S21"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleLocaltransitionExternalToNonInitialSuperDoesEntryExitToParent() {
context.register(Config23.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
assertThat(stateMachine, notNullValue());
TestListener listener = new TestListener();
stateMachine.addStateListener(listener);
stateMachine.start();
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21"));
listener.reset();
stateMachine.sendEvent("E21");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S22"));
assertThat(listener.exited.size(), is(2));
assertThat(listener.entered.size(), is(2));
assertThat(listener.exited, containsInAnyOrder("S2", "S21"));
assertThat(listener.entered, containsInAnyOrder("S2", "S22"));
listener.reset();
stateMachine.sendEvent("E23");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S22"));
assertThat(listener.exited.size(), is(2));
assertThat(listener.entered.size(), is(2));
assertThat(listener.exited, containsInAnyOrder("S2", "S22"));
assertThat(listener.entered, containsInAnyOrder("S2", "S22"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleLocaltransitionLocalToNonInitialSuperDoesNotEntryExitToParent() {
context.register(Config23.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
assertThat(stateMachine, notNullValue());
TestListener listener = new TestListener();
stateMachine.addStateListener(listener);
stateMachine.start();
stateMachine.sendEvent("E1");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S21"));
listener.reset();
stateMachine.sendEvent("E31");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S22"));
assertThat(listener.exited.size(), is(1));
assertThat(listener.entered.size(), is(1));
assertThat(listener.exited, containsInAnyOrder("S21"));
assertThat(listener.entered, containsInAnyOrder("S22"));
listener.reset();
stateMachine.sendEvent("E33");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S22"));
assertThat(listener.exited.size(), is(1));
assertThat(listener.entered.size(), is(1));
assertThat(listener.exited, containsInAnyOrder("S22"));
assertThat(listener.entered, containsInAnyOrder("S22"));
}
@Test
@SuppressWarnings("unchecked")
public void testSimpleConnectionPointRefMachine() throws Exception {
context.register(Config24.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent("E3");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2", "S22"));
stateMachine.sendEvent("E4");
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S4"));
}
@Test
public void testConnectionPointRef() {
context.refresh();
Resource model1 = new ClassPathResource("org/springframework/statemachine/uml/simple-connectionpointref.uml");
UmlStateMachineModelFactory builder = new UmlStateMachineModelFactory(model1);
builder.setBeanFactory(context);
assertThat(model1.exists(), is(true));
StateMachineModel<String, String> stateMachineModel = builder.build();
assertThat(stateMachineModel, notNullValue());
Collection<StateData<String, String>> stateDatas = stateMachineModel.getStatesData().getStateData();
assertThat(stateDatas.size(), is(8));
for (StateData<String, String> stateData : stateDatas) {
if (stateData.getState().equals("S1")) {
assertThat(stateData.isInitial(), is(true));
} else if (stateData.getState().equals("S2")) {
assertThat(stateData.isInitial(), is(false));
} else if (stateData.getState().equals("S21")) {
assertThat(stateData.isInitial(), is(true));
} else if (stateData.getState().equals("S22")) {
assertThat(stateData.isInitial(), is(false));
} else if (stateData.getState().equals("S3")) {
assertThat(stateData.isInitial(), is(false));
} else if (stateData.getState().equals("S4")) {
assertThat(stateData.isInitial(), is(false));
} else if (stateData.getState().equals("ENTRY")) {
assertThat(stateData.isInitial(), is(false));
assertThat(stateData.getPseudoStateKind(), is(PseudoStateKind.ENTRY));
} else if (stateData.getState().equals("EXIT")) {
assertThat(stateData.getPseudoStateKind(), is(PseudoStateKind.EXIT));
assertThat(stateData.isInitial(), is(false));
} else {
throw new IllegalArgumentException();
}
}
assertThat(stateMachineModel.getTransitionsData().getEntrys().size(), is(1));
assertThat(stateMachineModel.getTransitionsData().getExits().size(), is(1));
}
@Test
@SuppressWarnings("unchecked")
public void testActionWithTransitionChoice1() throws InterruptedException {
context.register(Config25.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
LatchAction s1ToChoice = context.getBean("s1ToChoice", LatchAction.class);
LatchAction choiceToS2 = context.getBean("choiceToS2", LatchAction.class);
LatchAction choiceToS4 = context.getBean("choiceToS4", LatchAction.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent(MessageBuilder.withPayload("E1").setHeader("choice", "s2").build());
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2"));
assertThat(s1ToChoice.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(choiceToS2.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(choiceToS4.latch.await(1, TimeUnit.SECONDS), is(false));
}
@Test
@SuppressWarnings("unchecked")
public void testActionWithTransitionChoice2() throws InterruptedException {
context.register(Config25.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
LatchAction s1ToChoice = context.getBean("s1ToChoice", LatchAction.class);
LatchAction choiceToS2 = context.getBean("choiceToS2", LatchAction.class);
LatchAction choiceToS4 = context.getBean("choiceToS4", LatchAction.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent(MessageBuilder.withPayload("E1").build());
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S4"));
assertThat(s1ToChoice.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(choiceToS2.latch.await(1, TimeUnit.SECONDS), is(false));
assertThat(choiceToS4.latch.await(1, TimeUnit.SECONDS), is(true));
}
@Test
@SuppressWarnings("unchecked")
public void testActionWithTransitionChoice3() throws InterruptedException {
context.register(Config25.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
LatchAction s1ToChoice = context.getBean("s1ToChoice", LatchAction.class);
LatchAction choiceToS2 = context.getBean("choiceToS2", LatchAction.class);
LatchAction choiceToS4 = context.getBean("choiceToS4", LatchAction.class);
LatchAction choice1ToChoice2 = context.getBean("choice1ToChoice2", LatchAction.class);
LatchAction choiceToS5 = context.getBean("choiceToS5", LatchAction.class);
LatchAction choiceToS6 = context.getBean("choiceToS6", LatchAction.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent(MessageBuilder.withPayload("E1").setHeader("choice", "choice2").build());
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S6"));
assertThat(s1ToChoice.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(choiceToS2.latch.await(1, TimeUnit.SECONDS), is(false));
assertThat(choiceToS4.latch.await(1, TimeUnit.SECONDS), is(false));
assertThat(choice1ToChoice2.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(choiceToS5.latch.await(1, TimeUnit.SECONDS), is(false));
assertThat(choiceToS6.latch.await(1, TimeUnit.SECONDS), is(true));
}
@Test
@SuppressWarnings("unchecked")
public void testActionWithTransitionJunction1() throws InterruptedException {
context.register(Config26.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
LatchAction s1ToChoice = context.getBean("s1ToChoice", LatchAction.class);
LatchAction choiceToS2 = context.getBean("choiceToS2", LatchAction.class);
LatchAction choiceToS4 = context.getBean("choiceToS4", LatchAction.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent(MessageBuilder.withPayload("E1").setHeader("choice", "s2").build());
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S2"));
assertThat(s1ToChoice.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(choiceToS2.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(choiceToS4.latch.await(1, TimeUnit.SECONDS), is(false));
}
@Test
@SuppressWarnings("unchecked")
public void testActionWithTransitionJunction2() throws InterruptedException {
context.register(Config26.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
LatchAction s1ToChoice = context.getBean("s1ToChoice", LatchAction.class);
LatchAction choiceToS2 = context.getBean("choiceToS2", LatchAction.class);
LatchAction choiceToS4 = context.getBean("choiceToS4", LatchAction.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent(MessageBuilder.withPayload("E1").build());
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S4"));
assertThat(s1ToChoice.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(choiceToS2.latch.await(1, TimeUnit.SECONDS), is(false));
assertThat(choiceToS4.latch.await(1, TimeUnit.SECONDS), is(true));
}
@Test
@SuppressWarnings("unchecked")
public void testActionWithTransitionJunction3() throws InterruptedException {
context.register(Config26.class);
context.refresh();
StateMachine<String, String> stateMachine = context.getBean(StateMachine.class);
LatchAction s1ToChoice = context.getBean("s1ToChoice", LatchAction.class);
LatchAction choiceToS2 = context.getBean("choiceToS2", LatchAction.class);
LatchAction choiceToS4 = context.getBean("choiceToS4", LatchAction.class);
LatchAction choice1ToChoice2 = context.getBean("choice1ToChoice2", LatchAction.class);
LatchAction choiceToS5 = context.getBean("choiceToS5", LatchAction.class);
LatchAction choiceToS6 = context.getBean("choiceToS6", LatchAction.class);
stateMachine.start();
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S1"));
stateMachine.sendEvent(MessageBuilder.withPayload("E1").setHeader("choice", "choice2").build());
assertThat(stateMachine.getState().getIds(), containsInAnyOrder("S6"));
assertThat(s1ToChoice.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(choiceToS2.latch.await(1, TimeUnit.SECONDS), is(false));
assertThat(choiceToS4.latch.await(1, TimeUnit.SECONDS), is(false));
assertThat(choice1ToChoice2.latch.await(1, TimeUnit.SECONDS), is(true));
assertThat(choiceToS5.latch.await(1, TimeUnit.SECONDS), is(false));
assertThat(choiceToS6.latch.await(1, TimeUnit.SECONDS), is(true));
}
@Configuration
@EnableStateMachine
public static class Config2 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
Resource model = new ClassPathResource("org/springframework/statemachine/uml/simple-flat.uml");
return new UmlStateMachineModelFactory(model);
}
@Bean
public Action<String, String> action1() {
return new LatchAction();
}
}
@Configuration
@EnableStateMachine
public static class Config3 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
Resource model = new ClassPathResource("org/springframework/statemachine/uml/simple-submachine.uml");
return new UmlStateMachineModelFactory(model);
}
}
@Configuration
@EnableStateMachine
public static class Config4 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
Resource model = new ClassPathResource("org/springframework/statemachine/uml/simple-root-regions.uml");
return new UmlStateMachineModelFactory(model);
}
}
@Configuration
@EnableStateMachine
public static class Config5 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
Resource model = new ClassPathResource("org/springframework/statemachine/uml/simple-entryexit.uml");
return new UmlStateMachineModelFactory(model);
}
}
@Configuration
@EnableStateMachine
public static class Config6 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
Resource model = new ClassPathResource("org/springframework/statemachine/uml/simple-choice.uml");
return new UmlStateMachineModelFactory(model);
}
@Bean
public ChoiceGuard s2Guard() {
return new ChoiceGuard("s2");
}
@Bean
public ChoiceGuard s3Guard() {
return new ChoiceGuard("s3");
}
}
@Configuration
@EnableStateMachine
public static class Config7 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
Resource model = new ClassPathResource("org/springframework/statemachine/uml/simple-forkjoin.uml");
return new UmlStateMachineModelFactory(model);
}
}
@Configuration
@EnableStateMachine
public static class Config8 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
Resource model = new ClassPathResource("org/springframework/statemachine/uml/simple-history-shallow.uml");
return new UmlStateMachineModelFactory(model);
}
}
@Configuration
@EnableStateMachine
public static class Config9 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
Resource model = new ClassPathResource("org/springframework/statemachine/uml/simple-history-deep.uml");
return new UmlStateMachineModelFactory(model);
}
}
@Configuration
@EnableStateMachine
public static class Config10 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
Resource model = new ClassPathResource("org/springframework/statemachine/uml/simple-junction.uml");
return new UmlStateMachineModelFactory(model);
}
@Bean
public JunctionGuard s5Guard() {
return new JunctionGuard("s5");
}
@Bean
public JunctionGuard s6Guard() {
return new JunctionGuard("s6");
}
}
@Configuration
@EnableStateMachine
public static class Config11 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new UmlStateMachineModelFactory("classpath:org/springframework/statemachine/uml/simple-actions.uml");
}
@Bean
public LatchAction s1Exit() {
return new LatchAction();
}
@Bean
public LatchAction s2Entry() {
return new LatchAction();
}
@Bean
public LatchAction e1Action() {
return new LatchAction();
}
}
@Configuration
@EnableStateMachine
public static class Config12 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new UmlStateMachineModelFactory("classpath:org/springframework/statemachine/uml/simple-history-default.uml");
}
}
@Configuration
@EnableStateMachine
public static class Config13 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new UmlStateMachineModelFactory("classpath:org/springframework/statemachine/uml/simple-timers.uml");
}
@Bean
public LatchAction s3Entry() {
return new LatchAction();
}
@Bean
public LatchAction s5Entry() {
return new LatchAction();
}
}
@Configuration
@EnableStateMachine
public static class Config14 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new UmlStateMachineModelFactory("classpath:org/springframework/statemachine/uml/simple-guards.uml");
}
@Bean
public SimpleGuard denyGuard() {
return new SimpleGuard(false);
}
}
@Configuration
@EnableStateMachine
public static class Config15 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new UmlStateMachineModelFactory("classpath:org/springframework/statemachine/uml/initial-actions.uml");
}
@Bean
public LatchAction initialAction() {
return new LatchAction();
}
}
@Configuration
@EnableStateMachine
public static class Config16 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new UmlStateMachineModelFactory("classpath:org/springframework/statemachine/uml/simple-spels.uml");
}
}
@Configuration
@EnableStateMachine
public static class Config17 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new UmlStateMachineModelFactory("classpath:org/springframework/statemachine/uml/simple-flat-multiple-to-end.uml");
}
}
@Configuration
@EnableStateMachine
public static class Config18 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new UmlStateMachineModelFactory("classpath:org/springframework/statemachine/uml/simple-flat-multiple-to-end-viachoices.uml");
}
}
@Configuration
@EnableStateMachine
public static class Config19 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new UmlStateMachineModelFactory("classpath:org/springframework/statemachine/uml/broken-model-shadowentries.uml");
}
}
@Configuration
@EnableStateMachine
public static class Config20 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
Resource model = new ClassPathResource("org/springframework/statemachine/uml/multijoin-forkjoin.uml");
return new UmlStateMachineModelFactory(model);
}
}
@Configuration
@EnableStateMachine
public static class Config21 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new UmlStateMachineModelFactory("classpath:org/springframework/statemachine/uml/simple-submachineref.uml");
}
}
@Configuration
@EnableStateMachine
public static class Config22 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new UmlStateMachineModelFactory("classpath:org/springframework/statemachine/uml/simple-state-actions.uml");
}
@Bean
public LatchAction e1Action() {
return new LatchAction();
}
@Bean
public LatchAction e2Action() {
return new LatchAction();
}
}
@Configuration
@EnableStateMachine
public static class Config23 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
return new UmlStateMachineModelFactory("classpath:org/springframework/statemachine/uml/simple-localtransition.uml");
}
}
@Configuration
@EnableStateMachine
public static class Config24 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
Resource model = new ClassPathResource("org/springframework/statemachine/uml/simple-connectionpointref.uml");
return new UmlStateMachineModelFactory(model);
}
}
@Configuration
@EnableStateMachine
public static class Config25 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
Resource model = new ClassPathResource("org/springframework/statemachine/uml/action-with-transition-choice.uml");
return new UmlStateMachineModelFactory(model);
}
@Bean
public ChoiceGuard s2Guard() {
return new ChoiceGuard("s2");
}
@Bean
public ChoiceGuard s3Guard() {
return new ChoiceGuard("s3");
}
@Bean
public ChoiceGuard s5Guard() {
return new ChoiceGuard("s5");
}
@Bean
public ChoiceGuard choice2Guard() {
return new ChoiceGuard("choice2");
}
@Bean
public LatchAction s1ToChoice() {
return new LatchAction();
}
@Bean
public LatchAction choiceToS2() {
return new LatchAction();
}
@Bean
public LatchAction choiceToS4() {
return new LatchAction();
}
@Bean
public LatchAction choice1ToChoice2() {
return new LatchAction();
}
@Bean
public LatchAction choiceToS5() {
return new LatchAction();
}
@Bean
public LatchAction choiceToS6() {
return new LatchAction();
}
}
@Configuration
@EnableStateMachine
public static class Config26 extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model
.withModel()
.factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
Resource model = new ClassPathResource("org/springframework/statemachine/uml/action-with-transition-junction.uml");
return new UmlStateMachineModelFactory(model);
}
@Bean
public ChoiceGuard s2Guard() {
return new ChoiceGuard("s2");
}
@Bean
public ChoiceGuard s3Guard() {
return new ChoiceGuard("s3");
}
@Bean
public ChoiceGuard s5Guard() {
return new ChoiceGuard("s5");
}
@Bean
public ChoiceGuard choice2Guard() {
return new ChoiceGuard("choice2");
}
@Bean
public LatchAction s1ToChoice() {
return new LatchAction();
}
@Bean
public LatchAction choiceToS2() {
return new LatchAction();
}
@Bean
public LatchAction choiceToS4() {
return new LatchAction();
}
@Bean
public LatchAction choice1ToChoice2() {
return new LatchAction();
}
@Bean
public LatchAction choiceToS5() {
return new LatchAction();
}
@Bean
public LatchAction choiceToS6() {
return new LatchAction();
}
}
public static class LatchAction implements Action<String, String> {
CountDownLatch latch = new CountDownLatch(1);
@Override
public void execute(StateContext<String, String> context) {
latch.countDown();
}
}
private static class ChoiceGuard implements Guard<String, String> {
private final String match;
public ChoiceGuard(String match) {
this.match = match;
}
@Override
public boolean evaluate(StateContext<String, String> context) {
return ObjectUtils.nullSafeEquals(match, context.getMessageHeaders().get("choice", String.class));
}
}
private static class SimpleGuard implements Guard<String, String> {
private final boolean deny;
public SimpleGuard(boolean deny) {
this.deny = deny;
}
@Override
public boolean evaluate(StateContext<String, String> context) {
return deny;
}
}
private static class JunctionGuard implements Guard<String, String> {
private final String match;
public JunctionGuard(String match) {
this.match = match;
}
@Override
public boolean evaluate(StateContext<String, String> context) {
return ObjectUtils.nullSafeEquals(match, context.getMessageHeaders().get("junction", String.class));
}
}
private static class TestListener extends StateMachineListenerAdapter<String, String> {
final ArrayList<String> entered = new ArrayList<>();
final ArrayList<String> exited = new ArrayList<>();
@Override
public void stateEntered(State<String, String> state) {
entered.add(state.getId());
}
@Override
public void stateExited(State<String, String> state) {
exited.add(state.getId());
}
public void reset() {
entered.clear();
exited.clear();
}
}
}