Add source to event not accepted stage
- It makes sense to give source state when event is not accepted. - Polish - Relates #150
This commit is contained in:
@@ -107,7 +107,7 @@ public interface StateContext<S, E> {
|
|||||||
State<S,E> getSource();
|
State<S,E> getSource();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the tarter state of this context. Generally target
|
* Gets the target state of this context. Generally target
|
||||||
* is where a state machine going to which may be different
|
* is where a state machine going to which may be different
|
||||||
* than what the transition target is.
|
* than what the transition target is.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
|||||||
public boolean sendEvent(Message<E> event) {
|
public boolean sendEvent(Message<E> event) {
|
||||||
if (hasStateMachineError()) {
|
if (hasStateMachineError()) {
|
||||||
// TODO: should we throw exception?
|
// TODO: should we throw exception?
|
||||||
notifyEventNotAccepted(buildStateContext(Stage.EVENT_NOT_ACCEPTED, event, null, getRelayStateMachine()));
|
notifyEventNotAccepted(buildStateContext(Stage.EVENT_NOT_ACCEPTED, event, null, getRelayStateMachine(), getState(), null));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,18 +185,18 @@ public abstract class AbstractStateMachine<S, E> extends StateMachineObjectSuppo
|
|||||||
event = getStateMachineInterceptors().preEvent(event, this);
|
event = getStateMachineInterceptors().preEvent(event, this);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.info("Event " + event + " threw exception in interceptors, not accepting event");
|
log.info("Event " + event + " threw exception in interceptors, not accepting event");
|
||||||
notifyEventNotAccepted(buildStateContext(Stage.EVENT_NOT_ACCEPTED, event, null, getRelayStateMachine()));
|
notifyEventNotAccepted(buildStateContext(Stage.EVENT_NOT_ACCEPTED, event, null, getRelayStateMachine(), getState(), null));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isComplete() || !isRunning()) {
|
if (isComplete() || !isRunning()) {
|
||||||
notifyEventNotAccepted(buildStateContext(Stage.EVENT_NOT_ACCEPTED, event, null, getRelayStateMachine()));
|
notifyEventNotAccepted(buildStateContext(Stage.EVENT_NOT_ACCEPTED, event, null, getRelayStateMachine(), getState(), null));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
boolean accepted = acceptEvent(event);
|
boolean accepted = acceptEvent(event);
|
||||||
stateMachineExecutor.execute();
|
stateMachineExecutor.execute();
|
||||||
if (!accepted) {
|
if (!accepted) {
|
||||||
notifyEventNotAccepted(buildStateContext(Stage.EVENT_NOT_ACCEPTED, event, null, getRelayStateMachine()));
|
notifyEventNotAccepted(buildStateContext(Stage.EVENT_NOT_ACCEPTED, event, null, getRelayStateMachine(), getState(), null));
|
||||||
}
|
}
|
||||||
return accepted;
|
return accepted;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import static org.hamcrest.Matchers.hasSize;
|
|||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
import static org.hamcrest.Matchers.notNullValue;
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
import static org.hamcrest.Matchers.nullValue;
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
|
import static org.hamcrest.Matchers.sameInstance;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -150,6 +151,55 @@ public class StateContextTests extends AbstractStateMachineTests {
|
|||||||
assertThat(listener.contexts.get(18).getTransition(), notNullValue());
|
assertThat(listener.contexts.get(18).getTransition(), notNullValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Test
|
||||||
|
public void testEventNotAccepted() throws Exception {
|
||||||
|
context.register(Config1.class);
|
||||||
|
context.refresh();
|
||||||
|
StateMachine<States, Events> machine = context.getBean(StateMachineSystemConstants.DEFAULT_ID_STATEMACHINE, StateMachine.class);
|
||||||
|
|
||||||
|
TestStateMachineListener listener = new TestStateMachineListener();
|
||||||
|
machine.addStateListener(listener);
|
||||||
|
|
||||||
|
machine.start();
|
||||||
|
listener.contexts.clear();
|
||||||
|
|
||||||
|
machine.sendEvent(Events.J);
|
||||||
|
|
||||||
|
// all nested machines sends these
|
||||||
|
assertThat(listener.contexts, contains(
|
||||||
|
hasStage(Stage.EVENT_NOT_ACCEPTED),
|
||||||
|
hasStage(Stage.EVENT_NOT_ACCEPTED),
|
||||||
|
hasStage(Stage.EVENT_NOT_ACCEPTED)
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
assertThat(listener.contexts.get(0).getStage(), is(Stage.EVENT_NOT_ACCEPTED));
|
||||||
|
assertThat(listener.contexts.get(0).getTransition(), nullValue());
|
||||||
|
assertThat(listener.contexts.get(0).getEvent(), is(Events.J));
|
||||||
|
assertThat(listener.contexts.get(0).getSource(), notNullValue());
|
||||||
|
assertThat(listener.contexts.get(0).getSource().getId(), is(States.S11));
|
||||||
|
assertThat(listener.contexts.get(0).getTarget(), nullValue());
|
||||||
|
|
||||||
|
assertThat(listener.contexts.get(1).getStage(), is(Stage.EVENT_NOT_ACCEPTED));
|
||||||
|
assertThat(listener.contexts.get(1).getTransition(), nullValue());
|
||||||
|
assertThat(listener.contexts.get(1).getEvent(), is(Events.J));
|
||||||
|
assertThat(listener.contexts.get(1).getSource(), notNullValue());
|
||||||
|
assertThat(listener.contexts.get(1).getSource().getId(), is(States.S1));
|
||||||
|
assertThat(listener.contexts.get(1).getTarget(), nullValue());
|
||||||
|
|
||||||
|
assertThat(listener.contexts.get(2).getStage(), is(Stage.EVENT_NOT_ACCEPTED));
|
||||||
|
assertThat(listener.contexts.get(2).getTransition(), nullValue());
|
||||||
|
assertThat(listener.contexts.get(2).getEvent(), is(Events.J));
|
||||||
|
assertThat(listener.contexts.get(2).getSource(), notNullValue());
|
||||||
|
assertThat(listener.contexts.get(2).getSource().getId(), is(States.S0));
|
||||||
|
assertThat(listener.contexts.get(2).getTarget(), nullValue());
|
||||||
|
|
||||||
|
// TODO: I wonder if these should be different machines
|
||||||
|
assertThat(listener.contexts.get(0).getStateMachine(), sameInstance(listener.contexts.get(1).getStateMachine()));
|
||||||
|
assertThat(listener.contexts.get(0).getStateMachine(), sameInstance(listener.contexts.get(2).getStateMachine()));
|
||||||
|
}
|
||||||
|
|
||||||
static class TestStateMachineListener extends StateMachineListenerAdapter<States, Events> {
|
static class TestStateMachineListener extends StateMachineListenerAdapter<States, Events> {
|
||||||
|
|
||||||
ArrayList<StateContext<States, Events>> contexts = new ArrayList<>();
|
ArrayList<StateContext<States, Events>> contexts = new ArrayList<>();
|
||||||
@@ -269,7 +319,10 @@ public class StateContextTests extends AbstractStateMachineTests {
|
|||||||
.source(States.S211).target(States.S212).event(Events.I)
|
.source(States.S211).target(States.S212).event(Events.I)
|
||||||
.and()
|
.and()
|
||||||
.withExternal()
|
.withExternal()
|
||||||
.source(States.S12).target(States.S212).event(Events.I);
|
.source(States.S12).target(States.S212).event(Events.I)
|
||||||
|
.and()
|
||||||
|
.withExternal()
|
||||||
|
.source(States.S212).target(States.S211).event(Events.J);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,7 +348,7 @@ public class StateContextTests extends AbstractStateMachineTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static enum Events {
|
public static enum Events {
|
||||||
A, B, C, D, E, F, G, H, I
|
A, B, C, D, E, F, G, H, I, J
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class FooAction implements Action<States, Events> {
|
private static class FooAction implements Action<States, Events> {
|
||||||
|
|||||||
Reference in New Issue
Block a user