From 0b6f67ece42a687b7ae952ff35a69f9162627b15 Mon Sep 17 00:00:00 2001 From: Janne Valkealahti Date: Sun, 2 Oct 2016 14:42:12 +0100 Subject: [PATCH] Add repository config actions - Add action to RepositoryTransition, state/entry/exit actions to RepositoryState. - New ActionsRepository. - Relates to #262 --- docs/src/reference/asciidoc/samples/data.json | 32 +++++- .../data/jpa/JpaActionRepository.java | 12 +++ .../data/jpa/JpaRepositoryAction.java | 58 ++++++++++ .../data/jpa/JpaRepositoryState.java | 60 +++++++++++ .../data/jpa/JpaRepositoryTransition.java | 31 ++++++ .../data/jpa/JpaRepositoryTests.java | 50 +++++++++ .../statemachine/data/ActionRepository.java | 31 ++++++ .../statemachine/data/RepositoryAction.java | 39 +++++++ .../statemachine/data/RepositoryState.java | 23 ++++ .../RepositoryStateMachineModelFactory.java | 102 +++++++++++++++++- .../data/RepositoryTransition.java | 9 ++ .../datajpa/src/main/resources/data.json | 32 +++++- 12 files changed, 466 insertions(+), 13 deletions(-) create mode 100644 spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaActionRepository.java create mode 100644 spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaRepositoryAction.java create mode 100644 spring-statemachine-data/src/main/java/org/springframework/statemachine/data/ActionRepository.java create mode 100644 spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryAction.java diff --git a/docs/src/reference/asciidoc/samples/data.json b/docs/src/reference/asciidoc/samples/data.json index 2cdfb1d6..8fe62db4 100644 --- a/docs/src/reference/asciidoc/samples/data.json +++ b/docs/src/reference/asciidoc/samples/data.json @@ -2,17 +2,35 @@ { "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", "initial": true, - "state": "S1" + "state": "S1", + "exitActions": [ + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryAction", + "spel": "T(System).out.println('hello exit S1')" + } + ] }, { "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", "initial": false, - "state": "S2" + "state": "S2", + "entryActions": [ + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryAction", + "spel": "T(System).out.println('hello entry S2')" + } + ] }, { "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", "initial": false, - "state": "S3" + "state": "S3", + "stateActions": [ + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryAction", + "spel": "T(System).out.println('hello state S3')" + } + ] }, { "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition", @@ -24,6 +42,12 @@ "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition", "source": "S2", "target": "S3", - "event": "E2" + "event": "E2", + "actions": [ + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryAction", + "spel": "T(System).out.println('hello')" + } + ] } ] diff --git a/spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaActionRepository.java b/spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaActionRepository.java new file mode 100644 index 00000000..5fd6ae51 --- /dev/null +++ b/spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaActionRepository.java @@ -0,0 +1,12 @@ +package org.springframework.statemachine.data.jpa; + +import org.springframework.statemachine.data.ActionRepository; + +/** + * A {@link ActionRepository} interface for JPA used for actions. + * + * @author Janne Valkealahti + * + */ +public interface JpaActionRepository extends ActionRepository { +} diff --git a/spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaRepositoryAction.java b/spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaRepositoryAction.java new file mode 100644 index 00000000..05c3bc7d --- /dev/null +++ b/spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaRepositoryAction.java @@ -0,0 +1,58 @@ +/* + * 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.data.jpa; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; + +import org.springframework.statemachine.data.RepositoryAction; + +/** + * JPA entity for actions. + * + * @author Janne Valkealahti + * + */ +@Entity +public class JpaRepositoryAction implements RepositoryAction { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + + private String name; + private String spel; + + @Override + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String getSpel() { + return spel; + } + + public void setSpel(String spel) { + this.spel = spel; + } +} diff --git a/spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaRepositoryState.java b/spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaRepositoryState.java index 92ea5e0d..7960b7c9 100644 --- a/spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaRepositoryState.java +++ b/spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaRepositoryState.java @@ -15,10 +15,15 @@ */ package org.springframework.statemachine.data.jpa; +import java.util.Set; + +import javax.persistence.CascadeType; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.OneToMany; import org.springframework.statemachine.data.RepositoryState; @@ -40,6 +45,15 @@ public class JpaRepositoryState implements RepositoryState { private String state; private boolean initial; + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + private Set stateActions; + + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + private Set entryActions; + + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + private Set exitActions; + /** * Instantiates a new jpa repository state. */ @@ -85,10 +99,29 @@ public class JpaRepositoryState implements RepositoryState { * @param initial the initial */ public JpaRepositoryState(String machineId, String parentState, String state, boolean initial) { + this(machineId, parentState, state, initial, null, null, null); + } + + /** + * Instantiates a new jpa repository state. + * + * @param machineId the machine id + * @param parentState the parent state + * @param state the state + * @param initial the initial + * @param stateActions the state actions + * @param entryActions the entry actions + * @param exitActions the exit actions + */ + public JpaRepositoryState(String machineId, String parentState, String state, boolean initial, Set stateActions, + Set entryActions, Set exitActions) { this.machineId = machineId; this.parentState = parentState; this.state = state; this.initial = initial; + this.stateActions = stateActions; + this.entryActions = entryActions; + this.exitActions = exitActions; } @Override @@ -126,4 +159,31 @@ public class JpaRepositoryState implements RepositoryState { public void setInitial(boolean initial) { this.initial = initial; } + + @Override + public Set getStateActions() { + return stateActions; + } + + public void setStateActions(Set stateActions) { + this.stateActions = stateActions; + } + + @Override + public Set getEntryActions() { + return entryActions; + } + + public void setEntryActions(Set entryActions) { + this.entryActions = entryActions; + } + + @Override + public Set getExitActions() { + return exitActions; + } + + public void setExitActions(Set exitActions) { + this.exitActions = exitActions; + } } diff --git a/spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaRepositoryTransition.java b/spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaRepositoryTransition.java index a2ab5b5f..0df1a9b5 100644 --- a/spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaRepositoryTransition.java +++ b/spring-statemachine-data/jpa/src/main/java/org/springframework/statemachine/data/jpa/JpaRepositoryTransition.java @@ -15,10 +15,15 @@ */ package org.springframework.statemachine.data.jpa; +import java.util.Set; + +import javax.persistence.CascadeType; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; +import javax.persistence.OneToMany; import org.springframework.statemachine.data.RepositoryTransition; @@ -40,6 +45,9 @@ public class JpaRepositoryTransition implements RepositoryTransition { private String target; private String event; + @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + private Set actions; + /** * Instantiates a new jpa repository transition. */ @@ -67,10 +75,24 @@ public class JpaRepositoryTransition implements RepositoryTransition { * @param event the event */ public JpaRepositoryTransition(String machineId, String source, String target, String event) { + this(machineId, source, target, event, null); + } + + /** + * Instantiates a new jpa repository transition. + * + * @param machineId the machine id + * @param source the source + * @param target the target + * @param event the event + * @param actions the actions + */ + public JpaRepositoryTransition(String machineId, String source, String target, String event, Set actions) { this.machineId = machineId; this.source = source; this.target = target; this.event = event; + this.actions = actions; } @Override @@ -108,4 +130,13 @@ public class JpaRepositoryTransition implements RepositoryTransition { public void setEvent(String event) { this.event = event; } + + @Override + public Set getActions() { + return actions; + } + + public void setActions(Set actions) { + this.actions = actions; + } } 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 ea2e4cf4..f39b3e6d 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 @@ -18,7 +18,10 @@ package org.springframework.statemachine.data.jpa; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -133,6 +136,53 @@ public class JpaRepositoryTests extends AbstractJpaRepositoryTests { context.close(); } + @Test + public void testRepository4() { + context.register(Config.class); + context.refresh(); + + JpaActionRepository actionsRepository = context.getBean(JpaActionRepository.class); + JpaRepositoryAction action1 = new JpaRepositoryAction(); + action1.setSpel("spel1"); + action1.setName("action1"); + actionsRepository.save(action1); + + assertThat(actionsRepository.count(), is(1l)); + JpaRepositoryAction action11 = actionsRepository.findAll().iterator().next(); + assertThat(action1.getSpel(), is(action11.getSpel())); + assertThat(action1.getName(), is(action11.getName())); + } + + @Test + public void testRepository5() { + context.register(Config.class); + context.refresh(); + + JpaActionRepository actionsRepository = context.getBean(JpaActionRepository.class); + + JpaTransitionRepository transitionsRepository = context.getBean(JpaTransitionRepository.class); + JpaRepositoryTransition transition = new JpaRepositoryTransition("S1", "S2", "E1"); + + JpaRepositoryAction action1 = new JpaRepositoryAction(); + action1.setName("action1"); + + Set actions = new HashSet<>(Arrays.asList(action1)); + transition.setActions(actions); + + transitionsRepository.save(transition); + JpaRepositoryTransition transition2 = transitionsRepository.findAll().iterator().next(); + assertThat(transition2.getSource(), is("S1")); + assertThat(transition2.getTarget(), is("S2")); + assertThat(transition2.getEvent(), is("E1")); + + assertThat(actionsRepository.count(), is(1l)); + JpaRepositoryAction action11 = actionsRepository.findAll().iterator().next(); + assertThat(action1.getName(), is(action11.getName())); + + + assertThat(transition2.getActions().size(), is(1)); + } + @SuppressWarnings("unchecked") @Test public void testMachine2() throws Exception { diff --git a/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/ActionRepository.java b/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/ActionRepository.java new file mode 100644 index 00000000..95b86e4a --- /dev/null +++ b/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/ActionRepository.java @@ -0,0 +1,31 @@ +/* + * 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.data; + +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.NoRepositoryBean; +import org.springframework.data.repository.Repository; + +/** + * Generic {@link Repository} interface for actions. + * + * @author Janne Valkealahti + * + * @param the transition entity type + */ +@NoRepositoryBean +public interface ActionRepository extends CrudRepository { +} diff --git a/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryAction.java b/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryAction.java new file mode 100644 index 00000000..9871c1e6 --- /dev/null +++ b/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryAction.java @@ -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.data; + +/** + * Generic interface representing action entity. + * + * @author Janne Valkealahti + * + */ +public interface RepositoryAction { + + /** + * Gets the name. + * + * @return the name + */ + String getName(); + + /** + * Gets the spel. + * + * @return the spel + */ + String getSpel(); +} diff --git a/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryState.java b/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryState.java index c3152b95..8570457c 100644 --- a/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryState.java +++ b/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryState.java @@ -15,6 +15,8 @@ */ package org.springframework.statemachine.data; +import java.util.Set; + /** * Generic interface representing state entity. * @@ -50,4 +52,25 @@ public interface RepositoryState { * @return true, if is initial */ boolean isInitial(); + + /** + * Gets the state actions. + * + * @return the state actions + */ + Set getStateActions(); + + /** + * Gets the entry actions. + * + * @return the entry actions + */ + Set getEntryActions(); + + /** + * Gets the exit actions. + * + * @return the exit actions + */ + Set getExitActions(); } 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 cc9f54f2..50edfe50 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 @@ -17,7 +17,14 @@ package org.springframework.statemachine.data; import java.util.ArrayList; import java.util.Collection; +import java.util.Set; +import org.springframework.expression.spel.SpelCompilerMode; +import org.springframework.expression.spel.SpelParserConfiguration; +import org.springframework.expression.spel.standard.SpelExpressionParser; +import org.springframework.statemachine.action.Action; +import org.springframework.statemachine.action.SpelExpressionAction; +import org.springframework.statemachine.config.model.AbstractStateMachineModelFactory; import org.springframework.statemachine.config.model.ConfigurationData; import org.springframework.statemachine.config.model.DefaultStateMachineModel; import org.springframework.statemachine.config.model.StateData; @@ -26,6 +33,8 @@ import org.springframework.statemachine.config.model.StateMachineModelFactory; import org.springframework.statemachine.config.model.StatesData; import org.springframework.statemachine.config.model.TransitionData; import org.springframework.statemachine.config.model.TransitionsData; +import org.springframework.statemachine.transition.TransitionKind; +import org.springframework.util.StringUtils; /** * A generic {@link StateMachineModelFactory} which is backed by a Spring Data @@ -34,7 +43,8 @@ import org.springframework.statemachine.config.model.TransitionsData; * @author Janne Valkealahti * */ -public class RepositoryStateMachineModelFactory implements StateMachineModelFactory { +public class RepositoryStateMachineModelFactory extends AbstractStateMachineModelFactory + implements StateMachineModelFactory { private final StateRepository stateRepository; private final TransitionRepository transitionRepository; @@ -60,15 +70,97 @@ public class RepositoryStateMachineModelFactory implements StateMachineModelFact public StateMachineModel build(String machineId) { ConfigurationData configurationData = new ConfigurationData<>(); - Collection> stateData = new ArrayList<>(); + Collection> stateDatas = new ArrayList<>(); for (RepositoryState s : stateRepository.findByMachineId(machineId)) { - stateData.add(new StateData(s.getParentState(), null, s.getState(), s.isInitial())); + + Collection> stateActions = new ArrayList>(); + Set repositoryStateActions = s.getStateActions(); + if (repositoryStateActions != null) { + for (RepositoryAction repositoryAction : repositoryStateActions) { + Action 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(parser.parseExpression(repositoryAction.getSpel())); + } + if (action != null) { + stateActions.add(action); + } + } + } + + Collection> entryActions = new ArrayList>(); + Set repositoryEntryActions = s.getEntryActions(); + if (repositoryEntryActions != null) { + for (RepositoryAction repositoryAction : repositoryEntryActions) { + Action 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(parser.parseExpression(repositoryAction.getSpel())); + } + if (action != null) { + stateActions.add(action); + } + } + } + + Collection> exitActions = new ArrayList>(); + Set repositoryExitActions = s.getExitActions(); + if (repositoryExitActions != null) { + for (RepositoryAction repositoryAction : repositoryExitActions) { + Action 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(parser.parseExpression(repositoryAction.getSpel())); + } + if (action != null) { + stateActions.add(action); + } + } + } + + StateData stateData = new StateData(s.getParentState(), null, s.getState(), s.isInitial()); + stateData.setStateActions(stateActions); + stateData.setEntryActions(entryActions); + stateData.setExitActions(exitActions); + stateDatas.add(stateData); } - StatesData statesData = new StatesData<>(stateData); + StatesData statesData = new StatesData<>(stateDatas); Collection> transitionData = new ArrayList<>(); for (RepositoryTransition t : transitionRepository.findByMachineId(machineId)) { - transitionData.add(new TransitionData(t.getSource(), t.getTarget(), t.getEvent())); + + Collection> actions = new ArrayList>(); + Set repositoryActions = t.getActions(); + if (repositoryActions != null) { + for (RepositoryAction repositoryAction : repositoryActions) { + Action 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(parser.parseExpression(repositoryAction.getSpel())); + } + if (action != null) { + actions.add(action); + } + } + } + + transitionData.add(new TransitionData<>(t.getSource(), t.getTarget(), t.getEvent(), actions, null, TransitionKind.EXTERNAL)); } TransitionsData transitionsData = new TransitionsData<>(transitionData); diff --git a/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryTransition.java b/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryTransition.java index 743fafb3..0d6a566a 100644 --- a/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryTransition.java +++ b/spring-statemachine-data/src/main/java/org/springframework/statemachine/data/RepositoryTransition.java @@ -15,6 +15,8 @@ */ package org.springframework.statemachine.data; +import java.util.Set; + /** * Generic interface representing transition entity. * @@ -50,4 +52,11 @@ public interface RepositoryTransition { * @return the event */ String getEvent(); + + /** + * Gets the actions. + * + * @return the actions + */ + Set getActions(); } diff --git a/spring-statemachine-samples/datajpa/src/main/resources/data.json b/spring-statemachine-samples/datajpa/src/main/resources/data.json index 2cdfb1d6..8fe62db4 100644 --- a/spring-statemachine-samples/datajpa/src/main/resources/data.json +++ b/spring-statemachine-samples/datajpa/src/main/resources/data.json @@ -2,17 +2,35 @@ { "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", "initial": true, - "state": "S1" + "state": "S1", + "exitActions": [ + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryAction", + "spel": "T(System).out.println('hello exit S1')" + } + ] }, { "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", "initial": false, - "state": "S2" + "state": "S2", + "entryActions": [ + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryAction", + "spel": "T(System).out.println('hello entry S2')" + } + ] }, { "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryState", "initial": false, - "state": "S3" + "state": "S3", + "stateActions": [ + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryAction", + "spel": "T(System).out.println('hello state S3')" + } + ] }, { "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition", @@ -24,6 +42,12 @@ "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryTransition", "source": "S2", "target": "S3", - "event": "E2" + "event": "E2", + "actions": [ + { + "_class": "org.springframework.statemachine.data.jpa.JpaRepositoryAction", + "spel": "T(System).out.println('hello')" + } + ] } ]