Hook StateMachineModelFactory and StateMachineFactory together

- Change so that machine id used in StateMachineFactory
  can use same id in StateMachineModelFactory which now
  extended with method build(String machineId).
- Polish repo and jpa classes.
- Fixes #255
This commit is contained in:
Janne Valkealahti
2016-09-25 10:08:57 +01:00
parent 842442520c
commit 49bae38eb3
13 changed files with 191 additions and 24 deletions

View File

@@ -152,7 +152,7 @@ public abstract class AbstractStateMachineFactory<S, E> extends LifecycleObjectS
*/
@SuppressWarnings("unchecked")
public StateMachine<S, E> getStateMachine(UUID uuid, String machineId) {
StateMachineModel<S, E> stateMachineModel = resolveStateMachineModel();
StateMachineModel<S, E> stateMachineModel = resolveStateMachineModel(machineId);
if (stateMachineModel.getConfigurationData().isVerifierEnabled()) {
StateMachineModelVerifier<S, E> verifier = stateMachineModel.getConfigurationData().getVerifier();
if (verifier == null) {
@@ -355,11 +355,11 @@ public abstract class AbstractStateMachineFactory<S, E> extends LifecycleObjectS
}
}
protected StateMachineModel<S, E> resolveStateMachineModel() {
protected StateMachineModel<S, E> resolveStateMachineModel(String machineId) {
if (stateMachineModelFactory == null) {
return defaultStateMachineModel;
} else {
StateMachineModel<S, E> m = stateMachineModelFactory.build();
StateMachineModel<S, E> m = stateMachineModelFactory.build(machineId);
if (m.getConfigurationData() == null) {
// if model doesn't have explicit configuration data,
// get it from default model

View File

@@ -39,7 +39,8 @@ import org.springframework.util.Assert;
* @param <S> the type of state
* @param <E> the type of event
*/
public abstract class AbstractStateMachineModelFactory<S, E> implements StateMachineComponentResolver<S, E>, BeanFactoryAware, ResourceLoaderAware {
public abstract class AbstractStateMachineModelFactory<S, E>
implements StateMachineComponentResolver<S, E>, StateMachineModelFactory<S, E>, BeanFactoryAware, ResourceLoaderAware {
private BeanFactory beanFactory;
private ResourceLoader resourceLoader = new DefaultResourceLoader();
@@ -76,6 +77,14 @@ public abstract class AbstractStateMachineModelFactory<S, E> implements StateMac
this.resourceLoader = resourceLoader;
}
@Override
public StateMachineModel<S, E> build(String machineId) {
return build();
}
@Override
public abstract StateMachineModel<S, E> build();
/**
* Sets the state machine component resolver.
*

View File

@@ -31,4 +31,15 @@ public interface StateMachineModelFactory<S, E> {
* @return the state machine model
*/
StateMachineModel<S, E> build();
/**
* Builds the state machine model with a given {@code machineId}.
* Implementation is free to choose what to do with a given {@code machineId}
* but usually it might map to a different configurations supported
* by storage or repository in a factory.
*
* @param machineId the machine id
* @return the state machine model
*/
StateMachineModel<S, E> build(String machineId);
}

View File

@@ -194,6 +194,11 @@ public class StateMachineModelFactoryTests extends AbstractStateMachineTests {
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public StateMachineModel<String, String> build(String machineId) {
return build();
}
}
@Override

View File

@@ -70,6 +70,11 @@ public class DocsConfigurationSampleTests8 {
statesData, transitionsData);
return stateMachineModel;
}
@Override
public StateMachineModel<String, String> build(String machineId) {
return build();
}
}
// end::snippetB[]
}

View File

@@ -35,8 +35,9 @@ public class JpaRepositoryState implements RepositoryState {
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
protected String state;
protected boolean initial;
private String machineId;
private String state;
private boolean initial;
/**
* Instantiates a new jpa repository state.
@@ -44,6 +45,11 @@ public class JpaRepositoryState implements RepositoryState {
public JpaRepositoryState() {
}
/**
* Instantiates a new jpa repository state.
*
* @param state the state
*/
public JpaRepositoryState(String state) {
this.state = state;
}
@@ -55,17 +61,36 @@ public class JpaRepositoryState implements RepositoryState {
* @param initial the initial
*/
public JpaRepositoryState(String state, boolean initial) {
super();
this(null, state, initial);
}
/**
* Instantiates a new jpa repository state.
*
* @param machineId the machine id
* @param state the state
* @param initial the initial
*/
public JpaRepositoryState(String machineId, String state, boolean initial) {
this.machineId = machineId;
this.state = state;
this.initial = initial;
}
@Override
public String getMachineId() {
return machineId;
}
public void setMachineId(String machineId) {
this.machineId = machineId;
}
@Override
public String getState() {
return state;
}
@Override
public void setState(String state) {
this.state = state;
}
@@ -75,7 +100,6 @@ public class JpaRepositoryState implements RepositoryState {
return initial;
}
@Override
public void setInitial(boolean initial) {
this.initial = initial;
}

View File

@@ -35,6 +35,7 @@ public class JpaRepositoryTransition implements RepositoryTransition {
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String machineId;
private String source;
private String target;
private String event;
@@ -43,6 +44,7 @@ public class JpaRepositoryTransition implements RepositoryTransition {
* Instantiates a new jpa repository transition.
*/
public JpaRepositoryTransition() {
this(null, null, null);
}
/**
@@ -53,17 +55,38 @@ public class JpaRepositoryTransition implements RepositoryTransition {
* @param event the event
*/
public JpaRepositoryTransition(String source, String target, String event) {
this(null, source, target, event);
}
/**
* Instantiates a new jpa repository transition.
*
* @param machineId the machine id
* @param source the source
* @param target the target
* @param event the event
*/
public JpaRepositoryTransition(String machineId, String source, String target, String event) {
this.machineId = machineId;
this.source = source;
this.target = target;
this.event = event;
}
@Override
public String getMachineId() {
return machineId;
}
public void setMachineId(String machineId) {
this.machineId = machineId;
}
@Override
public String getSource() {
return source;
}
@Override
public void setSource(String source) {
this.source = source;
}
@@ -73,7 +96,6 @@ public class JpaRepositoryTransition implements RepositoryTransition {
return target;
}
@Override
public void setTarget(String target) {
this.target = target;
}
@@ -83,7 +105,6 @@ public class JpaRepositoryTransition implements RepositoryTransition {
return event;
}
@Override
public void setEvent(String event) {
this.event = event;
}

View File

@@ -18,6 +18,8 @@ package org.springframework.statemachine.data.jpa;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import java.util.List;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -80,6 +82,42 @@ public class JpaRepositoryTests {
context.close();
}
@Test
public void testRepository3() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(Config.class);
context.refresh();
JpaStateRepository statesRepository = context.getBean(JpaStateRepository.class);
JpaRepositoryState state1 = new JpaRepositoryState("machine1", "S1", true);
statesRepository.save(state1);
JpaRepositoryState state2 = new JpaRepositoryState("machine2", "S2", false);
statesRepository.save(state2);
List<JpaRepositoryState> findByMachineId1 = statesRepository.findByMachineId("machine1");
List<JpaRepositoryState> findByMachineId2 = statesRepository.findByMachineId("machine2");
assertThat(findByMachineId1.size(), is(1));
assertThat(findByMachineId2.size(), is(1));
assertThat(findByMachineId1.get(0).getMachineId(), is("machine1"));
assertThat(findByMachineId2.get(0).getMachineId(), is("machine2"));
JpaTransitionRepository transitionsRepository = context.getBean(JpaTransitionRepository.class);
JpaRepositoryTransition transition1 = new JpaRepositoryTransition("machine1", "S1", "S2", "E1");
JpaRepositoryTransition transition2 = new JpaRepositoryTransition("machine2", "S3", "S4", "E2");
transitionsRepository.save(transition1);
transitionsRepository.save(transition2);
List<JpaRepositoryTransition> findByMachineId3 = transitionsRepository.findByMachineId("machine1");
List<JpaRepositoryTransition> findByMachineId4 = transitionsRepository.findByMachineId("machine2");
assertThat(findByMachineId3.size(), is(1));
assertThat(findByMachineId4.size(), is(1));
assertThat(findByMachineId3.get(0).getMachineId(), is("machine1"));
assertThat(findByMachineId4.get(0).getMachineId(), is("machine2"));
context.close();
}
@Test
public void testAutowire() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

View File

@@ -23,11 +23,24 @@ package org.springframework.statemachine.data;
*/
public interface RepositoryState {
/**
* Gets the machine id.
*
* @return the machine id
*/
String getMachineId();
/**
* Gets the state.
*
* @return the state
*/
String getState();
void setState(String state);
/**
* Checks if is initial.
*
* @return true, if is initial
*/
boolean isInitial();
void setInitial(boolean initial);
}

View File

@@ -53,16 +53,21 @@ public class RepositoryStateMachineModelFactory implements StateMachineModelFact
@Override
public StateMachineModel<String, String> build() {
return build(null);
}
@Override
public StateMachineModel<String, String> build(String machineId) {
ConfigurationData<String, String> configurationData = new ConfigurationData<>();
Collection<StateData<String, String>> stateData = new ArrayList<>();
for (RepositoryState s : stateRepository.findAll()) {
for (RepositoryState s : stateRepository.findByMachineId(machineId)) {
stateData.add(new StateData<String, String>(s.getState(), s.isInitial()));
}
StatesData<String, String> statesData = new StatesData<>(stateData);
Collection<TransitionData<String, String>> transitionData = new ArrayList<>();
for (RepositoryTransition t : transitionRepository.findAll()) {
for (RepositoryTransition t : transitionRepository.findByMachineId(machineId)) {
transitionData.add(new TransitionData<String, String>(t.getSource(), t.getTarget(), t.getEvent()));
}
TransitionsData<String, String> transitionsData = new TransitionsData<>(transitionData);

View File

@@ -23,15 +23,31 @@ package org.springframework.statemachine.data;
*/
public interface RepositoryTransition {
/**
* Gets the machine id.
*
* @return the machine id
*/
String getMachineId();
/**
* Gets the source.
*
* @return the source
*/
String getSource();
void setSource(String source);
/**
* Gets the target.
*
* @return the target
*/
String getTarget();
void setTarget(String target);
/**
* Gets the event.
*
* @return the event
*/
String getEvent();
void setEvent(String event);
}

View File

@@ -15,6 +15,8 @@
*/
package org.springframework.statemachine.data;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.Repository;
@@ -28,4 +30,12 @@ import org.springframework.data.repository.Repository;
*/
@NoRepositoryBean
public interface StateRepository<S extends RepositoryState> extends CrudRepository<S, Long> {
/**
* Find states by machine id.
*
* @param machineId the machine id
* @return the list of transitions
*/
List<S> findByMachineId(String machineId);
}

View File

@@ -15,6 +15,8 @@
*/
package org.springframework.statemachine.data;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.Repository;
@@ -28,4 +30,12 @@ import org.springframework.data.repository.Repository;
*/
@NoRepositoryBean
public interface TransitionRepository<T extends RepositoryTransition> extends CrudRepository<T, Long> {
/**
* Find transitions by machine id.
*
* @param machineId the machine id
* @return the list of transitions
*/
List<T> findByMachineId(String machineId);
}