Fix action loading in uml

- Refactored actions loading code to eliminate duplicated code.
- Added relevant test case.
- Fixes #588
This commit is contained in:
Adar Wesley
2019-08-19 17:44:10 +03:00
committed by Janne Valkealahti
parent 16e32e4f78
commit a8a842fc2a
3 changed files with 103 additions and 54 deletions

View File

@@ -0,0 +1,39 @@
[
{
"@id": "3",
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryAction",
"spel": "false"
},
{
"@id": "4",
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryAction",
"spel": "false"
},
{
"@id": "5",
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryAction",
"spel": "false"
},
{
"@id": "1",
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
"initial": true,
"state": "S1",
"exitActions": ["3"]
},
{
"@id": "2",
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
"initial": false,
"state": "S2",
"entryActions": ["4"],
"stateActions": ["5"]
},
{
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition",
"source": "1",
"target": "2",
"event": "E1",
"kind": "EXTERNAL"
}
]

View File

@@ -95,62 +95,14 @@ public class RepositoryStateMachineModelFactory extends AbstractStateMachineMode
subStateMachineModel = build(submachineId);
}
Collection<Function<StateContext<String, String>, Mono<Void>>> stateActions = new ArrayList<>();
Set<? extends RepositoryAction> repositoryStateActions = s.getStateActions();
if (repositoryStateActions != null) {
for (RepositoryAction repositoryAction : repositoryStateActions) {
Action<String, String> action = null;
if (StringUtils.hasText(repositoryAction.getName())) {
action = resolveAction(repositoryAction.getName());
} else if (StringUtils.hasText(repositoryAction.getSpel())) {
SpelExpressionParser parser = new SpelExpressionParser(
new SpelParserConfiguration(SpelCompilerMode.MIXED, null));
Collection<Function<StateContext<String, String>, Mono<Void>>> stateActions =
loadStateActionsFromRepositoryState(s.getStateActions());
action = new SpelExpressionAction<String, String>(parser.parseExpression(repositoryAction.getSpel()));
}
if (action != null) {
stateActions.add(Actions.from(action));
}
}
}
Collection<Function<StateContext<String, String>, Mono<Void>>> entryActions =
loadStateActionsFromRepositoryState(s.getEntryActions());
Collection<Function<StateContext<String, String>, Mono<Void>>> entryActions = new ArrayList<>();
Set<? extends RepositoryAction> repositoryEntryActions = s.getEntryActions();
if (repositoryEntryActions != null) {
for (RepositoryAction repositoryAction : repositoryEntryActions) {
Action<String, String> action = null;
if (StringUtils.hasText(repositoryAction.getName())) {
action = resolveAction(repositoryAction.getName());
} else if (StringUtils.hasText(repositoryAction.getSpel())) {
SpelExpressionParser parser = new SpelExpressionParser(
new SpelParserConfiguration(SpelCompilerMode.MIXED, null));
action = new SpelExpressionAction<String, String>(parser.parseExpression(repositoryAction.getSpel()));
}
if (action != null) {
stateActions.add(Actions.from(action));
}
}
}
Collection<Function<StateContext<String, String>, Mono<Void>>> exitActions = new ArrayList<>();
Set<? extends RepositoryAction> repositoryExitActions = s.getExitActions();
if (repositoryExitActions != null) {
for (RepositoryAction repositoryAction : repositoryExitActions) {
Action<String, String> action = null;
if (StringUtils.hasText(repositoryAction.getName())) {
action = resolveAction(repositoryAction.getName());
} else if (StringUtils.hasText(repositoryAction.getSpel())) {
SpelExpressionParser parser = new SpelExpressionParser(
new SpelParserConfiguration(SpelCompilerMode.MIXED, null));
action = new SpelExpressionAction<String, String>(parser.parseExpression(repositoryAction.getSpel()));
}
if (action != null) {
stateActions.add(Actions.from(action));
}
}
}
Collection<Function<StateContext<String, String>, Mono<Void>>> exitActions =
loadStateActionsFromRepositoryState(s.getExitActions());
RepositoryState parentState = s.getParentState();
Object region = s.getRegion();
@@ -291,6 +243,28 @@ public class RepositoryStateMachineModelFactory extends AbstractStateMachineMode
return new DefaultStateMachineModel<>(null, statesData, transitionsData);
}
private Collection<Function<StateContext<String, String>, Mono<Void>>> loadStateActionsFromRepositoryState(
Set<? extends RepositoryAction> repositoryStateActions) {
Collection<Function<StateContext<String, String>, Mono<Void>>> stateActions = new ArrayList<>();
if (repositoryStateActions != null) {
for (RepositoryAction repositoryAction : repositoryStateActions) {
Action<String, String> action = null;
if (StringUtils.hasText(repositoryAction.getName())) {
action = resolveAction(repositoryAction.getName());
} else if (StringUtils.hasText(repositoryAction.getSpel())) {
SpelExpressionParser parser = new SpelExpressionParser(
new SpelParserConfiguration(SpelCompilerMode.MIXED, null));
action = new SpelExpressionAction<String, String>(parser.parseExpression(repositoryAction.getSpel()));
}
if (action != null) {
stateActions.add(Actions.from(action));
}
}
}
return stateActions;
}
private Guard<String, String> resolveGuard(RepositoryTransition t) {
Guard<String, String> guard = null;
RepositoryGuard repositoryGuard = t.getGuard();

View File

@@ -18,8 +18,13 @@ package org.springframework.statemachine.data;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.junit.After;
import org.junit.Before;
@@ -430,6 +435,26 @@ public abstract class AbstractRepositoryTests {
plan.test();
}
@SuppressWarnings("unchecked")
@Test
public void testMachine15() throws Exception {
context.register(getRegisteredClasses());
context.register(Config15.class, FactoryConfig.class);
context.refresh();
StateMachineFactory<String, String> stateMachineFactory = context.getBean(StateMachineFactory.class);
StateMachine<String, String> stateMachine = stateMachineFactory.getStateMachine();
Map<String, State<String, String>> states = stateMachine.getStates().stream().collect(Collectors.toMap((State<String, String> s1) -> s1.getId(), s2 -> s2));
assertEquals(2, states.size());
State<String,String> S1 = (State<String, String>) states.get("S1");
assertEquals(1, S1.getExitActions().size());
State<String,String> S2 = (State<String,String>)states.get("S2");
assertEquals(1, S2.getEntryActions().size());
assertEquals(1, S2.getStateActions().size());
}
@Configuration
public static class Config2 {
@@ -605,6 +630,17 @@ public abstract class AbstractRepositoryTests {
}
}
@Configuration
public static class Config15 {
@Bean
public StateMachineJackson2RepositoryPopulatorFactoryBean jackson2RepositoryPopulatorFactoryBean() {
StateMachineJackson2RepositoryPopulatorFactoryBean factoryBean = new StateMachineJackson2RepositoryPopulatorFactoryBean();
factoryBean.setResources(new Resource[]{new ClassPathResource("data15.json")});
return factoryBean;
}
}
@Configuration
@EnableStateMachineFactory
public static class FactoryConfig extends StateMachineConfigurerAdapter<String, String> {