diff --git a/spring-statemachine-data/jpa/src/test/java/org/springframework/statemachine/data/jpa/JpaRepositoryTests.java b/spring-statemachine-data/jpa/src/test/java/org/springframework/statemachine/data/jpa/JpaRepositoryTests.java index beb8c929..7c00523d 100644 --- a/spring-statemachine-data/jpa/src/test/java/org/springframework/statemachine/data/jpa/JpaRepositoryTests.java +++ b/spring-statemachine-data/jpa/src/test/java/org/springframework/statemachine/data/jpa/JpaRepositoryTests.java @@ -443,6 +443,43 @@ public class JpaRepositoryTests extends AbstractJpaRepositoryTests { plan.test(); } + @SuppressWarnings("unchecked") + @Test + public void testMachine10() throws Exception { + context.register(Config10.class, FactoryConfig.class); + context.refresh(); + StateMachineFactory stateMachineFactory = context.getBean(StateMachineFactory.class); + StateMachine stateMachine = stateMachineFactory.getStateMachine(); + + StateMachineTestPlan plan = + StateMachineTestPlanBuilder.builder() + .stateMachine(stateMachine) + .step().expectStates("SI").and() + .step().sendEvent("E1").expectStates("S2", "S21", "S31").and() + .build(); + plan.test(); + } + + @SuppressWarnings("unchecked") + @Test + public void testMachine11() throws Exception { + context.register(Config11.class, FactoryConfig.class); + context.refresh(); + StateMachineFactory stateMachineFactory = context.getBean(StateMachineFactory.class); + StateMachine stateMachine = stateMachineFactory.getStateMachine(); + + StateMachineTestPlan plan = + StateMachineTestPlanBuilder.builder() + .stateMachine(stateMachine) + .step().expectStates("SI").and() + .step().sendEvent("E1").expectStates("S2", "S20", "S30").and() + .step().sendEvent("E2").expectStates("S2", "S21", "S30").and() + .step().sendEvent("E3").expectStates("S4").and() + .step().sendEvent("E4").expectStates("SI").and() + .build(); + plan.test(); + } + @Test public void testPopulate1() { context.register(Config2.class); @@ -624,6 +661,28 @@ public class JpaRepositoryTests extends AbstractJpaRepositoryTests { } } + @EnableAutoConfiguration + static class Config10 { + + @Bean + public StateMachineJackson2RepositoryPopulatorFactoryBean jackson2RepositoryPopulatorFactoryBean() { + StateMachineJackson2RepositoryPopulatorFactoryBean factoryBean = new StateMachineJackson2RepositoryPopulatorFactoryBean(); + factoryBean.setResources(new Resource[]{new ClassPathResource("data10.json")}); + return factoryBean; + } + } + + @EnableAutoConfiguration + static class Config11 { + + @Bean + public StateMachineJackson2RepositoryPopulatorFactoryBean jackson2RepositoryPopulatorFactoryBean() { + StateMachineJackson2RepositoryPopulatorFactoryBean factoryBean = new StateMachineJackson2RepositoryPopulatorFactoryBean(); + factoryBean.setResources(new Resource[]{new ClassPathResource("data11.json")}); + return factoryBean; + } + } + @Configuration @EnableStateMachineFactory public static class FactoryConfig extends StateMachineConfigurerAdapter { diff --git a/spring-statemachine-data/jpa/src/test/resources/data10.json b/spring-statemachine-data/jpa/src/test/resources/data10.json new file mode 100644 index 00000000..9504b952 --- /dev/null +++ b/spring-statemachine-data/jpa/src/test/resources/data10.json @@ -0,0 +1,71 @@ +[ + { + "@id": "1", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "initial": true, + "state": "SI" + }, + { + "@id": "2", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "state": "S1", + "kind": "FORK" + }, + { + "@id": "3", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "state": "S2" + }, + { + "@id": "4", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "state": "SF", + "kind": "END" + }, + { + "@id": "5", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "initial": true, + "region": "r2", + "parentState": "3", + "state": "S20" + }, + { + "@id": "6", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "region": "r2", + "parentState": "3", + "state": "S21" + }, + { + "@id": "7", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "initial": true, + "region": "r3", + "parentState": "3", + "state": "S30" + }, + { + "@id": "8", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "region": "r3", + "parentState": "3", + "state": "S31" + }, + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition", + "source": "1", + "target": "2", + "event": "E1" + }, + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition", + "source": "2", + "target": "6" + }, + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition", + "source": "2", + "target": "8" + } +] diff --git a/spring-statemachine-data/jpa/src/test/resources/data11.json b/spring-statemachine-data/jpa/src/test/resources/data11.json new file mode 100644 index 00000000..3ef5f3ed --- /dev/null +++ b/spring-statemachine-data/jpa/src/test/resources/data11.json @@ -0,0 +1,93 @@ +[ + { + "@id": "1", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "initial": true, + "state": "SI" + }, + { + "@id": "2", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "state": "S2" + }, + { + "@id": "3", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "state": "S3", + "kind": "JOIN" + }, + { + "@id": "4", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "state": "S4" + }, + { + "@id": "5", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "initial": true, + "region": "r2", + "parentState": "2", + "state": "S20" + }, + { + "@id": "6", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "region": "r2", + "parentState": "2", + "state": "S21" + }, + { + "@id": "7", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "initial": true, + "region": "r3", + "parentState": "2", + "state": "S30" + }, + { + "@id": "8", + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", + "region": "r3", + "parentState": "2", + "state": "S31" + }, + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition", + "source": "1", + "target": "2", + "event": "E1" + }, + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition", + "source": "5", + "target": "6", + "event": "E2" + }, + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition", + "source": "7", + "target": "8", + "event": "E3" + }, + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition", + "source": "7", + "target": "3" + }, + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition", + "source": "8", + "target": "3" + }, + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition", + "source": "3", + "target": "4" + }, + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition", + "source": "4", + "target": "1", + "event": "E4" + } +] diff --git a/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryStateMachineModelFactory.java b/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryStateMachineModelFactory.java index 02df20af..407b5030 100644 --- a/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryStateMachineModelFactory.java +++ b/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryStateMachineModelFactory.java @@ -161,6 +161,10 @@ public class RepositoryStateMachineModelFactory extends AbstractStateMachineMode Collection> historys = new ArrayList>(); Map>> choices = new HashMap>>(); Map>> junctions = new HashMap>>(); + Map> forks = new HashMap>(); + Map> joins = new HashMap>(); + + for (RepositoryTransition t : transitionRepository.findByMachineId(machineId)) { Collection> actions = new ArrayList>(); @@ -217,6 +221,20 @@ public class RepositoryStateMachineModelFactory extends AbstractStateMachineMode } else { list.addFirst(new JunctionData(t.getSource().getState(), t.getTarget().getState(), guard)); } + } else if (t.getSource().getKind() == PseudoStateKind.FORK) { + List list = forks.get(t.getSource().getState()); + if (list == null) { + list = new ArrayList(); + forks.put(t.getSource().getState(), list); + } + list.add(t.getTarget().getState()); + } else if (t.getTarget().getKind() == PseudoStateKind.JOIN) { + List list = joins.get(t.getTarget().getState()); + if (list == null) { + list = new ArrayList(); + joins.put(t.getTarget().getState(), list); + } + list.add(t.getSource().getState()); } else if (t.getSource().getKind() == PseudoStateKind.HISTORY_SHALLOW) { historys.add(new HistoryData(t.getSource().getState(), t.getTarget().getState())); } else if (t.getSource().getKind() == PseudoStateKind.HISTORY_DEEP) { @@ -229,7 +247,7 @@ public class RepositoryStateMachineModelFactory extends AbstractStateMachineMode HashMap>> junctionsCopy = new HashMap>>(); junctionsCopy.putAll(junctions); - TransitionsData transitionsData = new TransitionsData<>(transitionData, choicesCopy, junctionsCopy, null, null, + TransitionsData transitionsData = new TransitionsData<>(transitionData, choicesCopy, junctionsCopy, forks, joins, entrys, exits, historys); StateMachineModel stateMachineModel = new DefaultStateMachineModel<>(configurationData, statesData, transitionsData);