Add support for submachine refs

- Relates to #262
This commit is contained in:
Janne Valkealahti
2016-10-23 06:50:21 +01:00
parent 81e3c8697f
commit 83e59c2a60
5 changed files with 120 additions and 3 deletions

View File

@@ -51,6 +51,7 @@ public class JpaRepositoryState extends RepositoryState {
private String region;
private boolean initial;
private PseudoStateKind kind;
private String submachineId;
@OneToOne(fetch = FetchType.EAGER)
private JpaRepositoryState parentState;
@@ -227,11 +228,20 @@ public class JpaRepositoryState extends RepositoryState {
this.deferredEvents = deferredEvents;
}
@Override
public String getSubmachineId() {
return submachineId;
}
public void setSubmachineId(String submachineId) {
this.submachineId = submachineId;
}
@Override
public String toString() {
return "JpaRepositoryState [id=" + id + ", machineId=" + machineId + ", state=" + state + ", region=" + region
+ ", initial=" + initial + ", kind=" + kind + ", parentState=" + parentState + ", stateActions="
+ stateActions + ", entryActions=" + entryActions + ", exitActions=" + exitActions + ", deferredEvents="
+ deferredEvents + "]";
+ ", initial=" + initial + ", kind=" + kind + ", submachineId=" + submachineId + ", parentState="
+ parentState + ", stateActions=" + stateActions + ", entryActions=" + entryActions + ", exitActions="
+ exitActions + ", deferredEvents=" + deferredEvents + "]";
}
}

View File

@@ -515,6 +515,25 @@ public class JpaRepositoryTests extends AbstractJpaRepositoryTests {
plan.test();
}
@SuppressWarnings("unchecked")
@Test
public void testMachine13() throws Exception {
context.register(Config13.class, FactoryConfig.class);
context.refresh();
StateMachineFactory<String, String> stateMachineFactory = context.getBean(StateMachineFactory.class);
StateMachine<String, String> stateMachine = stateMachineFactory.getStateMachine();
StateMachineTestPlan<String, String> plan =
StateMachineTestPlanBuilder.<String, String>builder()
.stateMachine(stateMachine)
.step().expectStates("S1").and()
.step().sendEvent("E1").expectStates("S2", "S21").and()
.step().sendEvent("E3").expectStates("S2", "S22").and()
.step().sendEvent("E2").expectStates("S3").and()
.build();
plan.test();
}
@Test
public void testPopulate1() {
context.register(Config2.class);
@@ -729,6 +748,17 @@ public class JpaRepositoryTests extends AbstractJpaRepositoryTests {
}
}
@EnableAutoConfiguration
static class Config13 {
@Bean
public StateMachineJackson2RepositoryPopulatorFactoryBean jackson2RepositoryPopulatorFactoryBean() {
StateMachineJackson2RepositoryPopulatorFactoryBean factoryBean = new StateMachineJackson2RepositoryPopulatorFactoryBean();
factoryBean.setResources(new Resource[]{new ClassPathResource("data13.json")});
return factoryBean;
}
}
@Configuration
@EnableStateMachineFactory
public static class FactoryConfig extends StateMachineConfigurerAdapter<String, String> {

View File

@@ -0,0 +1,50 @@
[
{
"@id": "1",
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
"initial": true,
"state": "S1"
},
{
"@id": "2",
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
"submachineId": "machineS2",
"state": "S2"
},
{
"@id": "3",
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
"state": "S3"
},
{
"@id": "4",
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
"machineId": "machineS2",
"initial": true,
"state": "S21"
},
{
"@id": "5",
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState",
"machineId": "machineS2",
"state": "S22"
},
{
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition",
"source": "1",
"target": "2",
"event": "E1"
},
{
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition",
"source": "2",
"target": "3",
"event": "E2"
},
{
"_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition",
"source": "4",
"target": "5",
"event": "E3"
}
]

View File

@@ -96,4 +96,12 @@ public abstract class RepositoryState extends BaseRepositoryEntity {
* @return the deferred events
*/
public abstract Set<String> getDeferredEvents();
/**
* Gets the submachine id indicating that this is a submachine state
* and its structure is available from particular machine itself.
*
* @return the submachine id
*/
public abstract String getSubmachineId();
}

View File

@@ -85,6 +85,13 @@ public class RepositoryStateMachineModelFactory extends AbstractStateMachineMode
Collection<StateData<String, String>> stateDatas = new ArrayList<>();
for (RepositoryState s : stateRepository.findByMachineId(machineId)) {
// do recursive build to get states for a submachine
StateMachineModel<String, String> subStateMachineModel = null;
String submachineId = s.getSubmachineId();
if (submachineId != null) {
subStateMachineModel = build(submachineId);
}
Collection<Action<String, String>> stateActions = new ArrayList<Action<String, String>>();
Set<? extends RepositoryAction> repositoryStateActions = s.getStateActions();
if (repositoryStateActions != null) {
@@ -156,6 +163,18 @@ public class RepositoryStateMachineModelFactory extends AbstractStateMachineMode
}
}
stateData.setDeferred(s.getDeferredEvents());
if (subStateMachineModel != null) {
// copy are set parent as state we're currently on
Collection<StateData<String, String>> submachineStateData = new ArrayList<>();
Collection<StateData<String, String>> submachineStateDataOrig = subStateMachineModel.getStatesData().getStateData();
for (StateData<String, String> sd : submachineStateDataOrig) {
submachineStateData.add(new StateData<String, String>(s.getState(), sd.getRegion(), sd.getState(),
sd.getDeferred(), sd.getEntryActions(), sd.getExitActions(), sd.isInitial()));
}
stateData.setSubmachineStateData(submachineStateData);
}
stateDatas.add(stateData);
}
StatesData<String, String> statesData = new StatesData<>(stateDatas);