org.springframework.statemachine.EnumStateMachineTests.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.statemachine.EnumStateMachineTests.java

Source

/*
 * Copyright 2015 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;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

import java.util.ArrayList;
import java.util.Collection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.task.SyncTaskExecutor;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.state.DefaultPseudoState;
import org.springframework.statemachine.state.EnumState;
import org.springframework.statemachine.state.PseudoState;
import org.springframework.statemachine.state.PseudoStateKind;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.transition.DefaultExternalTransition;
import org.springframework.statemachine.transition.DefaultInternalTransition;
import org.springframework.statemachine.transition.Transition;
import org.springframework.statemachine.trigger.EventTrigger;

public class EnumStateMachineTests extends AbstractStateMachineTests {

    @Test
    public void testSimpleStateSwitch() {
        PseudoState<TestStates, TestEvents> pseudoState = new DefaultPseudoState<TestStates, TestEvents>(
                PseudoStateKind.INITIAL);
        State<TestStates, TestEvents> stateSI = new EnumState<TestStates, TestEvents>(TestStates.SI, pseudoState);
        State<TestStates, TestEvents> stateS1 = new EnumState<TestStates, TestEvents>(TestStates.S1);
        State<TestStates, TestEvents> stateS2 = new EnumState<TestStates, TestEvents>(TestStates.S2);
        State<TestStates, TestEvents> stateS3 = new EnumState<TestStates, TestEvents>(TestStates.S3);

        Collection<State<TestStates, TestEvents>> states = new ArrayList<State<TestStates, TestEvents>>();
        states.add(stateSI);
        states.add(stateS1);
        states.add(stateS2);
        states.add(stateS3);

        Collection<Transition<TestStates, TestEvents>> transitions = new ArrayList<Transition<TestStates, TestEvents>>();

        Collection<Action<TestStates, TestEvents>> actionsFromSIToS1 = new ArrayList<Action<TestStates, TestEvents>>();
        actionsFromSIToS1.add(new LoggingAction("actionsFromSIToS1"));
        DefaultExternalTransition<TestStates, TestEvents> transitionFromSIToS1 = new DefaultExternalTransition<TestStates, TestEvents>(
                stateSI, stateS1, actionsFromSIToS1, TestEvents.E1, null,
                new EventTrigger<TestStates, TestEvents>(TestEvents.E1));

        Collection<Action<TestStates, TestEvents>> actionsFromS1ToS2 = new ArrayList<Action<TestStates, TestEvents>>();
        actionsFromS1ToS2.add(new LoggingAction("actionsFromS1ToS2"));
        DefaultExternalTransition<TestStates, TestEvents> transitionFromS1ToS2 = new DefaultExternalTransition<TestStates, TestEvents>(
                stateS1, stateS2, actionsFromS1ToS2, TestEvents.E2, null,
                new EventTrigger<TestStates, TestEvents>(TestEvents.E2));

        Collection<Action<TestStates, TestEvents>> actionsFromS2ToS3 = new ArrayList<Action<TestStates, TestEvents>>();
        actionsFromS1ToS2.add(new LoggingAction("actionsFromS2ToS3"));
        DefaultExternalTransition<TestStates, TestEvents> transitionFromS2ToS3 = new DefaultExternalTransition<TestStates, TestEvents>(
                stateS2, stateS3, actionsFromS2ToS3, TestEvents.E3, null,
                new EventTrigger<TestStates, TestEvents>(TestEvents.E3));

        transitions.add(transitionFromSIToS1);
        transitions.add(transitionFromS1ToS2);
        transitions.add(transitionFromS2ToS3);

        SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
        BeanFactory beanFactory = new DefaultListableBeanFactory();
        ObjectStateMachine<TestStates, TestEvents> machine = new ObjectStateMachine<TestStates, TestEvents>(states,
                transitions, stateSI);
        machine.setTaskExecutor(taskExecutor);
        machine.setBeanFactory(beanFactory);
        machine.afterPropertiesSet();
        machine.start();

        State<TestStates, TestEvents> initialState = machine.getInitialState();
        assertThat(initialState, is(stateSI));

        State<TestStates, TestEvents> state = machine.getState();
        assertThat(state, is(stateSI));

        machine.sendEvent(MessageBuilder.withPayload(TestEvents.E1).build());
        state = machine.getState();
        assertThat(state, is(stateS1));

        machine.sendEvent(MessageBuilder.withPayload(TestEvents.E2).build());
        state = machine.getState();
        assertThat(state, is(stateS2));

        // not processed
        machine.sendEvent(MessageBuilder.withPayload(TestEvents.E1).build());
        state = machine.getState();
        assertThat(state, is(stateS2));

        machine.sendEvent(MessageBuilder.withPayload(TestEvents.E3).build());
        state = machine.getState();
        assertThat(state, is(stateS3));
    }

    @Test
    public void testDeferredEvents() {
        PseudoState<TestStates, TestEvents> pseudoState = new DefaultPseudoState<TestStates, TestEvents>(
                PseudoStateKind.INITIAL);

        Collection<TestEvents> deferred = new ArrayList<TestEvents>();
        deferred.add(TestEvents.E2);
        deferred.add(TestEvents.E3);

        // states
        State<TestStates, TestEvents> stateSI = new EnumState<TestStates, TestEvents>(TestStates.SI, deferred, null,
                null, pseudoState);
        State<TestStates, TestEvents> stateS1 = new EnumState<TestStates, TestEvents>(TestStates.S1);
        State<TestStates, TestEvents> stateS2 = new EnumState<TestStates, TestEvents>(TestStates.S2);
        State<TestStates, TestEvents> stateS3 = new EnumState<TestStates, TestEvents>(TestStates.S3);

        Collection<State<TestStates, TestEvents>> states = new ArrayList<State<TestStates, TestEvents>>();
        states.add(stateSI);
        states.add(stateS1);
        states.add(stateS2);
        states.add(stateS3);

        // transitions
        Collection<Transition<TestStates, TestEvents>> transitions = new ArrayList<Transition<TestStates, TestEvents>>();

        Collection<Action<TestStates, TestEvents>> actionsFromSIToS1 = new ArrayList<Action<TestStates, TestEvents>>();
        actionsFromSIToS1.add(new LoggingAction("actionsFromSIToS1"));
        DefaultExternalTransition<TestStates, TestEvents> transitionFromSIToS1 = new DefaultExternalTransition<TestStates, TestEvents>(
                stateSI, stateS1, actionsFromSIToS1, TestEvents.E1, null,
                new EventTrigger<TestStates, TestEvents>(TestEvents.E1));

        Collection<Action<TestStates, TestEvents>> actionsFromS1ToS2 = new ArrayList<Action<TestStates, TestEvents>>();
        actionsFromS1ToS2.add(new LoggingAction("actionsFromS1ToS2"));
        DefaultExternalTransition<TestStates, TestEvents> transitionFromS1ToS2 = new DefaultExternalTransition<TestStates, TestEvents>(
                stateS1, stateS2, actionsFromS1ToS2, TestEvents.E2, null,
                new EventTrigger<TestStates, TestEvents>(TestEvents.E2));

        Collection<Action<TestStates, TestEvents>> actionsFromS2ToS3 = new ArrayList<Action<TestStates, TestEvents>>();
        actionsFromS1ToS2.add(new LoggingAction("actionsFromS2ToS3"));
        DefaultExternalTransition<TestStates, TestEvents> transitionFromS2ToS3 = new DefaultExternalTransition<TestStates, TestEvents>(
                stateS2, stateS3, actionsFromS2ToS3, TestEvents.E3, null,
                new EventTrigger<TestStates, TestEvents>(TestEvents.E3));

        transitions.add(transitionFromSIToS1);
        transitions.add(transitionFromS1ToS2);
        transitions.add(transitionFromS2ToS3);

        // create machine
        SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
        BeanFactory beanFactory = new DefaultListableBeanFactory();
        ObjectStateMachine<TestStates, TestEvents> machine = new ObjectStateMachine<TestStates, TestEvents>(states,
                transitions, stateSI);
        machine.setTaskExecutor(taskExecutor);
        machine.setBeanFactory(beanFactory);
        machine.afterPropertiesSet();
        machine.start();

        State<TestStates, TestEvents> initialState = machine.getInitialState();
        assertThat(initialState, is(stateSI));

        State<TestStates, TestEvents> state = machine.getState();
        assertThat(state, is(stateSI));

        machine.sendEvent(MessageBuilder.withPayload(TestEvents.E2).build());
        machine.sendEvent(MessageBuilder.withPayload(TestEvents.E3).build());
        state = machine.getState();
        assertThat(state, is(stateSI));

        machine.sendEvent(MessageBuilder.withPayload(TestEvents.E1).build());
        state = machine.getState();
        assertThat(state, is(stateS3));
    }

    @Test
    public void testInternalTransitions() {
        PseudoState<TestStates, TestEvents> pseudoState = new DefaultPseudoState<TestStates, TestEvents>(
                PseudoStateKind.INITIAL);
        State<TestStates, TestEvents> stateSI = new EnumState<TestStates, TestEvents>(TestStates.SI, pseudoState);

        Collection<State<TestStates, TestEvents>> states = new ArrayList<State<TestStates, TestEvents>>();
        states.add(stateSI);

        Collection<Action<TestStates, TestEvents>> actionsInSI = new ArrayList<Action<TestStates, TestEvents>>();
        actionsInSI.add(new LoggingAction("actionsInSI"));
        DefaultInternalTransition<TestStates, TestEvents> transitionInternalSI = new DefaultInternalTransition<TestStates, TestEvents>(
                stateSI, actionsInSI, TestEvents.E1, null, new EventTrigger<TestStates, TestEvents>(TestEvents.E1));

        // transitions
        Collection<Transition<TestStates, TestEvents>> transitions = new ArrayList<Transition<TestStates, TestEvents>>();
        transitions.add(transitionInternalSI);

        SyncTaskExecutor taskExecutor = new SyncTaskExecutor();
        BeanFactory beanFactory = new DefaultListableBeanFactory();
        ObjectStateMachine<TestStates, TestEvents> machine = new ObjectStateMachine<TestStates, TestEvents>(states,
                transitions, stateSI);
        machine.setTaskExecutor(taskExecutor);
        machine.setBeanFactory(beanFactory);
        machine.afterPropertiesSet();
        machine.start();

        machine.sendEvent(MessageBuilder.withPayload(TestEvents.E1).build());
    }

    private static class LoggingAction implements Action<TestStates, TestEvents> {

        private static final Log log = LogFactory.getLog(LoggingAction.class);

        private String message;

        public LoggingAction(String message) {
            this.message = message;
        }

        @Override
        public void execute(StateContext<TestStates, TestEvents> context) {
            log.info("Hello from LoggingAction " + message);
        }

    }

}